#!/usr/bin/gawk -f # /* vim: set filetype=awk : */ -*- awk -*- # # ----| xomo |-------------------------------------- # # _ _ _ _ _ (( # |=|=|=|=|=|.----------------------------. _))_ # |-|-|-|-|-|| a 'requirez' code bundle | ___\__/)_ # |_|_|_|_|_|'----------------------------'|_||_~~_|_| # # Built by "oelrawas" on Wed Nov 22 13:12:15 EST 2006. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; version 2. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc.,51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. # # /* vim: set filetype=awk : */ -*- awk -*- # ousXomo # #---- [about.awk ] ------------------------------------------ # /* vim: set filetype=awk : */ -*- awk -*- # #---- [commandLine.awk ] ------------------------------------------ # #---- [copyleft.awk ] ------------------------------------------ function copyleft() { about(Who,What,When,Why); print ""; print "This program is free software; you can redistribute it and/or"; print "modify it under the terms of the GNU Lesser General Public"; print "License as published by the Free Software Foundation; version 2.1."; print ""; print "This program is distributed in the hope that it will be useful" print "but WITHOUT ANY WARRANTY; without even the implied warranty of"; print "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU"; print "Lesser General Public License for more details."; print ""; print "You should have received a copy of the GNU Lesser General Public"; print "License along with this program; if not write to the Free Software"; print "Foundation Inc. 51 Franklin St Fifth Floor Boston MA 02110-1301 USA"; } function about(who,what,when,why) { print what " : " why; print "Copyright " when " " who ; } ##---- [prints.awk ] ------------------------------------------ function prints(a0,b0,c0,d0,e0,f0,g0,h0,i0,j0,k0,l0,m0,n0,o0,p0,q0,r0,s0,t0,u0,v0,w0,x0,y0,z0,\ a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1,\ a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,\ a3,b3,c3,d3,e3,f3,g3,h3,i3,j3,k3,l3,m3,n3,o3,p3,q3,r3,s3,t3,u3,v3,w3,x3,y3,z3,\ a4,b4,c4,d4,e4,f4,g4,h4,i4,j4,k4,l4,m4,n4,o4,p4,q4,r4,s4,t4,u4,v4,w4,x4,y4,z4,\ a5,b5,c5,d5,e5,f5,g5,h5,i5,j5,k5,l5,m5,n5,o5,p5,q5,r5,s5,t5,u5,v5,w5,x5,y5,z5,\ a6,b6,c6,d6,e6,f6,g6,h6,i6,j6,k6,l6,m6,n6,o6,p6,q6,r6,s6,t6,u6,v6,w6,x6,y6,z6,\ a7,b7,c7,d7,e7,f7,g7,h7,i7,j7,k7,l7,m7,n7,o7,p7,q7,r7,s7,t7,u7,v7,w7,x7,y7,z7,\ a8,b8,c8,d8,e8,f8,g8,h8,i8,j8,k8,l8,m8,n8,o8,p8,q8,r8,s8,t8,u8,v8,w8,x8,y8,z8,\ a9,b9,c9,d9,e9,f9,g9,h9,i9,j9,k9,l9,m9,n9,o9,p9,q9,r9,s9,t9,u9,v9) { prints26(a0,b0,c0,d0,e0,f0,g0,h0,i0,j0,k0,l0,m0,n0,o0,p0,q0,r0,s0,t0,u0,v0,w0,x0,y0,z0); prints26(a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1); prints26(a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2); prints26(a3,b3,c3,d3,e3,f3,g3,h3,i3,j3,k3,l3,m3,n3,o3,p3,q3,r3,s3,t3,u3,v3,w3,x3,y3,z3); prints26(a4,b4,c4,d4,e4,f4,g4,h4,i4,j4,k4,l4,m4,n4,o4,p4,q4,r4,s4,t4,u4,v4,w4,x4,y4,z4); prints26(a5,b5,c5,d5,e5,f5,g5,h5,i5,j5,k5,l5,m5,n5,o5,p5,q5,r5,s5,t5,u5,v5,w5,x5,y5,z5); prints26(a6,b6,c6,d6,e6,f6,g6,h6,i6,j6,k6,l6,m6,n6,o6,p6,q6,r6,s6,t6,u6,v6,w6,x6,y6,z6); prints26(a7,b7,c7,d7,e7,f7,g7,h7,i7,j7,k7,l7,m7,n7,o7,p7,q7,r7,s7,t7,u7,v7,w7,x7,y7,z7); prints26(a8,b8,c8,d8,e8,f8,g8,h8,i8,j8,k8,l8,m8,n8,o8,p8,q8,r8,s8,t8,u8,v8,w8,x8,y8,z8); prints26(a9,b9,c9,d9,e9,f9,g9,h9,i9,j9,k9,l9,m9,n9,o9,p9,q9,r9,s9,t9,u9); } function prints26(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) { if (a) {print prints1(a) } else {return 1}; if (b) {print prints1(b) } else {return 1}; if (c) {print prints1(c) } else {return 1}; if (d) {print prints1(d) } else {return 1}; if (e) {print prints1(e) } else {return 1}; if (f) {print prints1(f) } else {return 1}; if (g) {print prints1(g) } else {return 1}; if (h) {print prints1(h) } else {return 1}; if (i) {print prints1(i) } else {return 1}; if (j) {print prints1(j) } else {return 1}; if (k) {print prints1(k) } else {return 1}; if (l) {print prints1(l) } else {return 1}; if (m) {print prints1(m) } else {return 1}; if (n) {print prints1(n) } else {return 1}; if (o) {print prints1(o) } else {return 1}; if (p) {print prints1(p) } else {return 1}; if (q) {print prints1(q) } else {return 1}; if (r) {print prints1(r) } else {return 1}; if (s) {print prints1(s) } else {return 1}; if (t) {print prints1(t) } else {return 1}; if (u) {print prints1(u) } else {return 1}; if (v) {print prints1(v) } else {return 1}; if (w) {print prints1(w) } else {return 1}; if (x) {print prints1(x) } else {return 1}; if (y) {print prints1(y) } else {return 1}; if (z) {print prints1(z) } else {return 1}; } function prints1(x) { # if starts with a " ", then indent this string return x ~ /^ / ? " "x : x; } # #---- [getopt.awk ] ------------------------------------------ #!/usr/bin/gawk -f # getopt --- do C library getopt(3) function in awk # Author: arnold@gnu.ai.mit.edu (in the 1990s) # (and the clearArgs() function was added at the suggestion of Mathew Hall # Tue, 2 Aug 2005) # Valid options are passed to a function opt(opts,opt,arg) which # must be supplied outside this file. e.g. # # function opt(opts,flag,arg) { print opt "= [" arg "]" } # USAGE: # a call to "getOpts(String)" (e.g. getopts("ab:cd") ) # will lead to on call xoof opt for each valid argument function getOpts(opts, debug, tmp) { Optind = 1; # skip ARGV[0] Opterr = debug; # default is to diagnose while ((tmp = getopt(ARGC, ARGV, opts)) != -1) set(tmp, Optarg); clearARGV(debug); } # External variables: # Optind -- index of ARGV for first non-option argument # Optarg -- string value of argument to current option # Opterr -- if non-zero, print our own diagnostic # Optopt -- current option letter # Returns # -1 at end of options # ? for unrecognized option # a character representing the current option function getopt(argc, argv, options, thisopt, i) { if (length(options) == 0) # no options given return -1; if (argv[Optind] == "--") { # all done Optind++; _opti = 0; return -1; } else if (argv[Optind] !~ /^-[^: \t\n\f\r\v\b]/) { _opti = 0; return -1; } if (_opti == 0) _opti = 2; thisopt = substr(argv[Optind], _opti, 1); Optopt = thisopt; i = index(options, thisopt); if (i == 0) { if (Opterr) printf("%c -- invalid option\n", thisopt) > "/dev/stderr" if (_opti >= length(argv[Optind])) { Optind++; _opti = 0; } else _opti++; return "?"; } if (substr(options, i + 1, 1) == ":") { # get option argument if (length(substr(argv[Optind], _opti + 1)) > 0) Optarg = substr(argv[Optind], _opti + 1); else Optarg = argv[++Optind]; _opti = 0; } else Optarg = ""; if (_opti == 0 || _opti >= length(argv[Optind])) { Optind++; _opti = 0 } else _opti++; return thisopt; } function clearARGV(debug, i,n,tmp) { for(i=0;i<=ARGC;i++) if(i>=Optind ) { tmp[++n]=ARGV[i]; if(debug && i!=ARGC) printf("\trest ARGV[%d] = <%s>\n",i, ARGV[i]); } else { if(debug) printf("\tused ARGV[%d] = <%s>\n",i, ARGV[i]); } split("",ARGV,""); ARGC=0 for(i in tmp) ARGV[++ARGC]=tmp[i]; } # #---- [inits.awk ] ------------------------------------------ function inits(flags,str, argp,tmp,n,i,x) { argps(argp,flags); n=split(str,tmp," "); while(i < n) { i++; x=tmp[i]; if (sub(/^-/,"",x)) { if(argp[x]) { set(x,tmp[i+1]); i++ } else { set(x) } } else {bad("skipping " tmp[i-1] " " x)} } } function argps(argp,flags, x,n,tmp,i) { n=split(flags,tmp,""); for(i=1;i<=n;i++) if (tmp[i]==":") argp[tmp[i-1]]=1 } # #---- [bad.awk ] ------------------------------------------ #

Stuff

function bad(str) { print str >> "/dev/stderr"; fflush("/dev/stderr"); Errors++; Patience--; } function imPatient() { if (Patience<=0) { print "Aborting" >> "/dev/stderr"; fflush("/dev/stderr"); exit 1 } } function badIf(check,txt) { if (check) bad(txt); return check; } BEGIN { Who = "Tim Menzies"; What = "xomo"; When = "2006"; How = "b:cd:hlo:p:s:A:I:M:N:m:P:R:S:CX:"; Why = "generate effort/risk/bug estiamtes for projects "; } function usage() { about(Who,What,When,Why); prints("Usage(ous mod): "What" [FLAGS] "," ", " -A CHAR meta character; default= [" MetaC "]", " -I CHAR marker for the ignore columns; default= ["IgnoreC"]", " -M CHAR marker for columns to be maximized; default= ["MaxC"]", " -N CHAR marker for numeric columns; default= [" NumC "]", " -P WORD perform effort/risk/bug estimation for WORD; default = 'project'", " -R NUM repeat NUM times of times", " -S NUM set the random number seed to NUM", " (use NUM=0 for a randomly selected seed)", " -X NUM run example NUM", " -b NUM pause every NUM interations", " -c show copyright", " -d FILE read default values from FILE; default = 'defaults.dat'", " -h show help", " -l loud mode (print header line)", " -m CHAR marker for columns to be minimized; default= ["MinC"]", " -o CHAR output file sepertor", " -p FILE read project values from FILE, default = 'project.dat'", " -s STRING comma separated string of meta data for special variables", " "); } function defaults( pairs,i) { string2pairs(pairs, "b 100 d defaults.dat p project.dat o , " \ "P system R 30 S 1 m < M > N $ A = I ?", " "); for(i in pairs) set(i,pairs[i]) } function set(x,y) { if (x == "A") {return MetaC = y}; if (x == "I") {return IgnoreC = y}; if (x == "N") {return MaxC = y}; if (x == "M") {return NumC = y}; if (x == "m") {return MinC = y}; if (x == "P") {return Project = y}; if (x == "R") {return Repeats = y}; if (x == "S") {return (y ? srand(y) : srand() ) } if (x == "X") {demo(y); exit}; if (x == "s") {return parseSpec(y,Spec) }; if (x == "b") {return Pause = y}; if (x == "c") {copyleft(); exit}; if (x == "d") {return DefaultData = y}; if (x == "h") {usage(); exit}; if (x == "l") {return Loud = 1}; if (x == "o") {return OFS = y}; if (x == "p") {return ProjectData = y}; bad("?"x": usage: " What " " How); exit; } function parseSpec(str,out, tmp,i,j,k,doomed) { split(str,tmp,","); doomed= "[" IgnoreC MaxC MinC NumC "]"; for(i in tmp) { j = k = tmp[i] gsub(doomed,"",j); Spec[j]=k } } #### xomo main # #---- [effort.awk ] ------------------------------------------ # /* vim: set filetype=awk : */ -*- awk -*- # #---- [effort.awk] ------------------------------------------ #super sub #sizeAgg= sum of sub slocs o #pmBASIC = A* sizeAgg^E* SCED (e and Sced from super) #so subs can't have different values to super function efforts(dad,kids,sizeAgg,pmBasics,kid,pmBasic,pm,out) { if (subParts(dad,kids)) { for(kid in kids) sizeAgg += Ksloc(kid); pmBasics = A(dad)*sizeAgg^E(dad)*Sced(dad); for(kid in Kids) { pmBasic[kid] = pmBasics * Ksloc(kid)/sizeAgg pm[kid] = pmBasic[kid] * EffortMults16(kid) out += pm[kid] } } else { out= Effort(i) } return out } function subParts(x,l, i,n) { n=Slots[x,"child",0]; for(i=1;i<=n;i++) l[i]=Slots[x,"child",i] return n } function Effort(i) { return A(i)* Ksloc(i)^E(i) * Sced(i) * EffortMults16(i) } function EffortMults16(i) { return \ Rely(i) * Data(i) * Cplx(i)* \ Ruse(i) * Docu(i) * Time(i)* \ Stor(i) * Pvol(i) * Acap(i)* \ Pcap(i) * Pcon(i) * Apex(i)* \ Plex(i) * Ltex(i) * Tool(i)* \ Site(i) ; } function E(i) { return B(i) + 0.01*(Prec(i) + Flex(i) + Resl(i) + Team(i) + Pmat(i)) } function Ksloc(i){ return value(i,"ksloc") } function A(i) { return value(i, "A" ) } function B(i) { return value(i, "B" ) } function Acap(i) { return value(i,"acap") } function Apex(i) { return value(i,"apex") } function Cplx(i) { return value(i,"cplx") } function Data(i) { return value(i,"data") } function Docu(i) { return value(i,"docu") } function Flex(i) { return value(i,"flex") } function Ltex(i) { return value(i,"ltex") } function Pcap(i) { return value(i,"pcap") } function Pcon(i) { return value(i,"pcon") } function Plex(i) { return value(i,"plex") } function Pmat(i) { return value(i,"pmat") } function Prec(i) { return value(i,"prec") } function Pvol(i) { return value(i,"pvol") } function Rely(i) { return value(i,"rely") } function Resl(i) { return value(i,"resl") } function Ruse(i) { return value(i,"ruse") } function Sced(i) { return value(i,"sced") } function Site(i) { return value(i,"site") } function Stor(i) { return value(i,"stor") } function Team(i) { return value(i,"team") } function Time(i) { return value(i,"time") } function Tool(i) { return value(i,"tool") } BEGIN { string2pairs(Factors2Numbers, "1,vl,2,l,3,n,4,h,5,vh,6,xh"); } function value(frame,slot, s,t,w,n,x) { s = cachedSlot(frame,slot) if (slot in Type) { n = Factors2Numbers[s]; t = Type[slot]; x = Tunings[t,slot,n] } else { x=s } return x; } function cachedSlot(frame,slot) { if ((frame,slot) in Cache) return Cache[frame,slot]; return Cache[frame,slot] = slot(frame,slot,Slots) } function init(slots, aka) { string2pairs(aka,"yes,1,y,1,true,1,t,1,no,0,n,0,false,0"); readSlots(DefaultData, slots, aka); readSlots(ProjectData, slots, aka); #saya("slots",slots) } # #---- [array.awk ] ------------------------------------------ #

array.awk

# Ensures an array is empty function array(a) { split("",a,"") } # #---- [sims.awk ] ------------------------------------------ # /* vim: set filetype=awk : */ -*- awk -*-# /* vim: set filetype=awk : */ -*- awk -*- # #---- [sims.awk] ------------------------------------------ function sims(spec,n,slots,startHere, \ last,hdrString,tmp,max,out,i,hdr,sep) { #saya("slots",slots); if(! framep(startHere,slots)) return bad(startHere " unknown"); out = sims1(startHere); for(i in Cache) { hdr[++max] = i; last = split(i,tmp,SUBSEP); hdrString = hdrString sep headerWord(spec,tmp[last]) ; sep = OFS; } if (Loud) print MetaC hdrString,headerWord(spec,"risk"), headerWord(spec,"effort"),headerWord(spec,"defects") do { for(i=1;i<=max;i++) printf Cache[hdr[i]] OFS; print out; if (n) out=sims1(startHere); if (! (n % Pause)) bad(n); } while (--n > 0) } function sims1(start) { array(Cache); return sprintf("%.2f%s%.2f%s%.2f", Total_risk(start) , OFS, Effort(start) , OFS, Total_defects(start) / Ksloc(start) ) } function headerWord(spec,word) { return word in spec ? spec[word] : word } #### xomo support # #---- [maker.awk ] ------------------------------------------ # /* vim: set filetype=awk : */ -*- awk -*- # #---- [maker.awk] ------------------------------------------ function defineTables() { table(_Fx, # top left "tl,vl, l,n, h,vh", "vl, 2, 1, 0, 0, 0,"\ " l, 1, 0, 0, 0, 0"); table(_Fx, # top right "tr,vl, l, n, h,vh", "vl, 0, 0, 0, 1, 2,"\ " l, 0, 0, 0, 0, 1"); table(_Fx, # top right, strong "TR,vl, l, n, h,vh", "vl, 0, 0, 1, 2, 4,"\ " l, 0, 0, 0, 1, 2,"\ " n, 0, 0, 0, 0, 1"); table(_Fx, # top left, strong "TL,vl, l, n, h,vh", "vl, 4, 2, 1, 0, 0,"\ " l, 2, 1, 0, 0, 0,"\ " n, 1, 0, 0, 0, 0"); table(_Fx, # bottom left, strong "BL,vl, l, n, h, vh", "n, 1, 0, 0, 0, 0,"\ "h, 2, 1, 0, 0, 0,"\ "vh, 4, 2, 1, 0, 0"); table(_Fx, # bottom left "bl,vl, l, n, h, vh", "h, 1, 0, 0, 0, 0,"\ "vh, 2, 1, 0, 0, 0"); table(_Fx, # bottom right, strong "BR,vl, l, n, h, vh", "n, 0, 0, 0, 0, 1,"\ "h, 0, 0, 0, 1, 2,"\ "vh, 0, 0, 1, 2, 4"); table(_Fx, # bottom right "br,vl, l, n, h, vh", "h, 0, 0, 0, 0, 1,"\ "vh, 0, 0, 0, 1, 2"); } function tl(a,b) { deffx("tl",a ,b) } function Tl(a,b) { deffx("TL",a ,b) } function tr(a,b) { deffx("tr",a ,b) } function Tr(a,b) { deffx("TR",a ,b) } function bl(a,b) { deffx("bl",a ,b) } function Bl(a,b) { deffx("BL",a ,b) } function br(a,b) { deffx("tr",a ,b) } function Br(a,b) { deffx("BR",a ,b) } function deffx(goal,a,b, i,j) { for(i in _Fx) { j=i; if (sub("^" goal,a SUBSEP b,j)) { Fx[j]=_Fx[i] } } } # #---- [tables.awk ] ------------------------------------------ # /* vim: set filetype=awk : */ -*- awk -*- ##---- [tables.awk] ------------------------------------------ function table(arr,header,body) { return makeTable(arr,header,body) } function makeTable(arr,header,body, \ rowName,names,col,row, \ data,i,j,m,n,key,datum) { m=split(header,names,/,/); for(i=1;i<=m;i++) names[i] = trim(names[i]); key=names[1]; n=split(body,data,/,/); if (n % m) bad("table rows don't hold "m" items"); j=1; for(i=1;i<=n;i++) { datum = trim(data[i]); if (j==1) { rowName=datum } else { col=names[j]; if(datum != "") arr[key,rowName,col]=datum } j= (j==m) ? 1 : j + 1; } } function defineSymbols() { string2word(Type, "em", "rely,data,ruse,docu,cplx,time,stor,pvol,acap,"\ "pcap,pcon,apex,plex,ltex,tool,site,sced"); string2word(Type, "sf", "prec,flex,resl,team,pmat"); } function defineRisks() { tr("sced","rely"); Tr("sced","cplx"); Tr("sced","time"); tr("sced","pvol"); tl("sced","tool"); Tl("sced","pexp"); Tl("sced","pcap"); Tl("sced","apex"); Tl("sced","acap"); tl("sced","ltex"); tl("sced","pmat"); Bl("rely","acap"); Bl("rely","pcap"); Bl("cplx","acap"); Bl("cplx","pcap"); Bl("cplx","tool"); Bl("rely","pmat"); tl("pmat","acap"); Bl("stor","acap"); Bl("time","acap"); tl("tool","acap"); tl("tool","pcap"); tl("pmat","pcap"); Bl("stor","pcap"); Bl("time","pcap"); Tl("ltex","pcap"); bl("pvol","pexp"); tl("tool","pmat"); bl("time","tool"); tl("team","apex"); tl("team","sced"); tl("team","site"); } function defineTunings() { table(Tunings, # 1 2 3 4 5 6 "em , vl, l, n, h, vh, xh ", "time, , , 1.00, 1.11, 1.29, 1.63," \ "stor, , , 1.00, 1.05, 1.17, 1.46," \ "data, , 0.90, 1.00, 1.14, 1.28, ," \ "pvol, , 0.87, 1.00, 1.15, 1.30, ," \ "ruse, , 0.95, 1.00, 1.07, 1.15, 1.24," \ "rely, 0.82, 0.92, 1.00, 1.10, 1.26, ," \ "docu, 0.81, 0.91, 1.00, 1.11, 1.23, ," \ "acap, 1.42, 1.19, 1.00, 0.85, 0.71, ," \ "pcap, 1.34, 1.15, 1.00, 0.88, 0.76, ," \ "pcon, 1.29, 1.12, 1.00, 0.90, 0.81, ," \ "apex, 1.22, 1.10, 1.00, 0.88, 0.81, ," \ "plex, 1.19, 1.09, 1.00, 0.91, 0.85, ," \ "ltex, 1.20, 1.09, 1.00, 0.91, 0.84, ," \ "tool, 1.17, 1.09, 1.00, 0.90, 0.78, ," \ "sced, 1.43, 1.14, 1.00, 1.00, 1.00, ," \ "cplx, 0.73, 0.87, 1.00, 1.17, 1.34, 1.74," \ "site, 1.22, 1.09, 1.00, 0.93, 0.86, 0.80 " ); table(Tunings, "sf, vl, l, n, h, vh, xh " , "prec, 6.20, 4.96, 3.72, 2.48, 1.24, 0," \ "flex, 5.07, 4.05, 3.04, 2.03, 1.01, 0," \ "resl, 7.07, 5.65, 4.24, 2.83, 1.41, 0," \ "team, 5.48, 4.38, 3.29, 2.19, 1.01, 0," \ "pmat, 7.80, 6.24, 4.68, 3.12, 1.56, 0" ); table(Coqual, "c, prec,flex,resl,team,pmat", "xh,0.81, 1, 0.71,0.86,0.63," \ "vh,0.9, 1, 0.84,0.92,0.79, " \ "h, 0.95, 1, 0.92,0.96,0.9 , " \ "n,1,1,1,1,1, " \ "l,1.12,1,1.21,1.09,1.3, " \ "vl,1.24,1,1.41,1.18,1.58 "); table(Coqual, "c,rely,data,ruse,docu,cplx,time,stor,pvol,acap,pcap,pcon,apex,plex,ltex,tool,site,sced", "xh, , ,1.02, ,1.41,1.2 ,1.15,1.22, , , , , , , ,0.85, ," \ "vh,0.69,1.1,1.01,0.85,1.27,1.13,1.1,1.15,0.9,0.76,0.77,0.88,0.86,0.81,0.8,0.9,0.84,"\ "h, 0.85,1.05,1,0.92,1.13,1.06,1.05,1.08,0.95,0.88,0.88,0.94,0.94,0.91,0.9,0.95,0.92, "\ "n, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,"\ "l, 1.23,0.91,0.98,1.09,0.86,,,0.82,1.05,1.16,1.15,1.07,1.08,1.11,1.13,1.09,1.1,"\ "vl,1.45,,,1.18,0.71,,,,1.11,1.32,1.3,1.13,1.16,1.22,1.25,1.18,1.19"); table(Coqual, "d,prec,flex,resl,team,pmat", "xh,0.75,1,0.7,0.8,0.61,"\ "vh,0.87,1,0.84,0.9,0.78,"\ "h,0.94,1,0.92,0.95,0.89,"\ "n,1,1,1,1,1 ,"\ "l,1.17,1,1.22,1.13,1.33,"\ "vl,1.34,1,1.43,1.26,1.65"); table(Coqual, "d,rely,data,ruse,docu,cplx,time,stor,pvol,acap,pcap,pcon,apex,plex,ltex,tool,site,sced", "xh,,,1.02,,1.41,1.2,1.18,1.2,,,,,,,,0.83,,"\ "vh,0.69,1.1,1.01,0.85,1.27,1.13,1.12,1.13,0.83,0.85,0.8,0.82,0.86,0.88,0.91,0.89,0.84,"\ "h,0.85,1.05,1,0.93,1.13,1.06,1.06,1.06,0.91,0.93,0.9,0.91,0.93,0.91,0.96,0.95,0.92,"\ "n,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,"\ "l,1.23,0.91,0.98,1.09,0.86,,,0.83,1.1,1.09,1.13,1.11,1.09,1.07,1.05,1.1,1.1,"\ "vl,1.45,,,1.18,0.71,,,,1.2,1.17,1.25,1.22,1.17,1.13,1.1,1.2,1.19"); table(Coqual, "r,prec,flex,resl,team,pmat", "xh,0.7,1,0.76,0.75,0.73,"\ "vh,0.84,1,0.87,0.87,0.85,"\ "h,0.92,1,0.94,0.94,0.93,"\ "n,1,1,1,1,1 ,"\ "l,1.22,1,1.16,1.17,1.19,"\ "vl,1.43,1,1.32,1.34,1.38"); table(Coqual, "r,rely,data,ruse,docu,cplx,time,stor,pvol,acap,pcap,pcon,apex,plex,ltex,tool,site,sced", "xh,,,1.05,,1.32,1.08,1.08,1.16,,,,,,,,0.83,,"\ "vh,0.7,1.07,1.03,0.86,1.21,1.05,1.05,1.1,0.75,1,0.82,0.81,0.9,0.93,0.92,0.89,0.85,"\ "h ,0.85,1.04,1.02,0.93,1.1,1.03,1.03,1.05,0.87,1,0.91,0.91,0.95,0.97,0.96,0.95,0.92,"\ "n,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,"\ "l,1.22,0.93,0.95,1.08,0.88,,,0.86,1.17,1,1.11,1.12,1.05,1.04,1.05,1.1,1.09,"\ "vl,1.43,,,1.16,0.76,,,,1.33,1,1.22,1.24,1.11,1.07,1.09,1.2,1.18"); table(Drf, "r ,automated_analysis,peer_reviews,execution_testing_and_tools", "xh ,0.4 ,0.7 ,0.6, "\ "vh ,0.34 ,0.58 ,0.57, "\ "h ,0.27 ,0.5 ,0.5, "\ "n ,0.1 ,0.4 ,0.4, "\ "l ,0 ,0.25 ,0.23, "\ "vl ,0 ,0 ,0"); table(Drf, "d ,automated_analysis,peer_reviews,execution_testing_and_tools", "xh ,0.5 ,0.78 ,0.7, "\ "vh ,0.44 ,0.7 ,0.65, "\ "h ,0.28 ,0.54 ,0.54, "\ "n ,0.13 ,0.4 ,0.43, "\ "l ,0 ,0.28 ,0.23, "\ "vl ,0 ,0 ,0 "); table(Drf, "c ,automated_analysis,peer_reviews,execution_testing_and_tools", "xh ,0.55 ,0.83 ,0.88, "\ "vh ,0.48 ,0.73 ,0.78, "\ "h ,0.3 ,0.6 ,0.69, "\ "n ,0.2 ,0.48 ,0.58, "\ "l ,0.1 ,0.3 ,0.38, "\ "vl ,0 ,0 ,0 "); } # #---- [risk.awk ] ------------------------------------------ # /* vim: set filetype=awk : */ -*- awk -*- # #---- [risk.awk] ------------------------------------------ function oops(f,x,y, nx,ny,vx,vy,fx) { nx = Factors2Numbers[cachedSlot(f,x)]; ny = Factors2Numbers[cachedSlot(f,y)]; vx = value(f,x); vy = value(f,y); fx = Fx[x , y,nx,ny] return vx * vy * fx } function Product_risk(f) { return \ oops(f,"rely","acap") + oops(f,"rely","pcap") + oops(f,"cplx","acap") + \ oops(f,"cplx","pcap") + oops(f,"cplx","tool") + oops(f,"rely","pmat") + \ oops(f,"sced","cplx") + oops(f,"sced","rely") + oops(f,"sced","time") + \ oops(f,"ruse","apex") + oops(f,"ruse","ltex"); } function Schedule_risk(f) { return \ oops(f,"sced","rely") + oops(f,"sced","time") + oops(f,"sced","pvol") + \ oops(f,"sced","tool") + oops(f,"sced","acap") + oops(f,"sced","apex") + \ oops(f,"sced","pcap") + oops(f,"sced","plex") + oops(f,"sced","ltex") + \ oops(f,"sced","pmat"); } function Personnel_risk(f) { return \ oops(f,"pmat","acap") + oops(f,"stor","acap") + oops(f,"time","acap") + \ oops(f,"tool","acap") + oops(f,"tool","pcap") + oops(f,"ruse","apex") + \ oops(f,"ruse","ltex") + oops(f,"pmat","pcap") + oops(f,"stor","pcap") + \ oops(f,"time","pcap") + oops(f,"ltex","pcap") + oops(f,"pvol","plex") + \ oops(f,"sced","acap") + oops(f,"sced","apex") + oops(f,"sced","pcap") + \ oops(f,"sced","plex") + oops(f,"sced","ltex") + oops(f,"rely","acap") + \ oops(f,"rely","pcap") + oops(f,"cplx","acap") + oops(f,"cplx","pcap") + \ oops(f,"team","apex"); } function Process_risk(f) { return \ oops(f,"tool","pmat") + oops(f,"time","tool") + oops(f,"tool","pmat") + \ oops(f,"team","apex") + oops(f,"team","sced") + oops(f,"team","site") + \ oops(f,"sced","tool") + oops(f,"sced","pmat") + oops(f,"cplx","tool") + \ oops(f,"pmat","acap") + oops(f,"tool","acap") + oops(f,"tool","pcap") + \ oops(f,"pmat","pcap"); } function Platform_risk(f) { return \ oops(f,"sced","time") + oops(f,"sced","pvol") + oops(f,"stor","acap") + \ oops(f,"time","acap") + oops(f,"stor","pcap") + oops(f,"pvol","plex") + \ oops(f,"time","tool"); } function Reuse_risk(f) { return oops(f,"ruse","apex") + oops(f,"ruse","ltex"); } function Total_risk(f) { return (Schedule_risk(f) + Product_risk(f) + Personnel_risk(f) + \ Process_risk(f) + Platform_risk(f) + Reuse_risk(f))/3.73; } # #---- [defects.awk ] ------------------------------------------ # /* vim: set filetype=awk : */ -*- awk -*- # #---- [defects.awk] ------------------------------------------ function Total_defects(f, verbose) { return \ defects(f,"requirements","r", verbose) + \ defects(f,"design", "d", verbose) + \ defects(f,"coding", "c", verbose) } function defects(f,what,area,verbose, introduced,percentRemoved) { introduced = defectsIntroduced1(f,what,area); percentRemoved = defectsRemovedRatio(f,what,area); if (verbose) print "f",f,"area",area,"intro",introduced, "p",percentRemoved, "removed",percentRemoved*introduced return percentRemoved*introduced; } function defectsIntroduced1(f,what,area) { return areaWeight(area)*Ksloc(f)^defectsB(area) * defectsIntroduced2(f,area); } BEGIN { string2pairs(_DefectsB,"r,10,d,20,c,30") } function areaWeight(area) { return _DefectsB[area] } function defectsB(area) { return 1} function defectsIntroduced2(f,area, temp,out,x,s,n) { out=1; for(x in Type) { s = cachedSlot(f,x) n = Factors2Numbers[s] temp = Coqual[area,n,x]; out *= temp } return out; } function defectsRemovedRatio(f,what,area, auto,review,tool) { auto = drf(f,"automated_analysis",area); review = drf(f,"peer_reviews",area); tool = drf(f,"execution_testing_and_tools",area); return (1 - auto)*(1 - review)*(1 - tool); } function drf(f,x,area,n, out) { n= Factors2Numbers[cachedSlot(f,x)] out= Drf[area, n,x] return out } # #---- [nudge.awk ] ------------------------------------------ # /* vim: set filetype=awk : */ -*- awk -*- ##---- [nudge.awk] ------------------------------------------ # needs normal.awk function gaussian(m,std,nudgep,old,nudge, delta,up,down,got,retries) { if (nudgep) { delta = normal(1,nudge); up = old + (std * delta); down = old - (std * delta); retries = 128; while(retries-- ) { got=normal(m,std); if (got >= down && got <= up) return got; } return old; } else { return normal(m,std) } } function ratio(min,max,nudgep,old,nudge, delta) { if (min==max) return min; if (nudgep) { delta=(max-min)*nudge/2; min=most(min,old-delta); max=least(max,old+delta); }; return between(min,max); } function ratioInt(min,max,nudgep,old,nudge, out,delta,aLittle) { if(min==max) return min; if (nudgep) { delta=(max-min)*nudge/2; min=most(min,old-delta); max=least(max,old+delta); } else { aLittle = 0.499999; min=min - aLittle; max=max + aLittle; }; return round(between(min,max)); } function ordinal(range,nudgep,old,nudge, i,j,dim) { dim=range[_n]; if (nudgep) { i=indexOf(old,range); j=ratioInt(1,dim,1,i,nudge); } else { j=ratioInt(1,dim); }; return range[j]; } function nominal(range,nudgep,old,nudge) { if (nudgep && nudge==0) { return old} else { return ordinal(range,nudgep,old,nudge)} } function indexOf(x,range,i) { for(i in range) { if (i < 0 ) continue; if (range[i]==x) return i; }; bad(x " not in range \n"); } function framep(x,w) { return ("frame",x) in w } function slottypes(types) { string2bool(types,"of,int,normal,real,=") } function compute(what,y,z, p,o,n) { if (what=="int") return ratioInt(y,z, p,o,n); if (what=="normal") return gaussian(y,z, p,o,n); if (what=="real") return ratio( y,z, p,o,n); if (what=="of") return ordinal( y, p,o,n); } function badSlot(n,e,txt) { bad("W> skipping line " n": " txt " (code "e")") } function readSlots(f,w,aka, isa,types, n,mins,i,oldFS,\ oldRS, oldIgnore,keyword,parent,here,x) { slottypes(types); string2pairs(mins,"of,4,with,3,=,3,just,4,is,4") oldFS = FS; oldRS = RS; oldIgnore = IGNORECASE; FS = " "; RS = "\n"; IGNORECASE = 1; here = "system" w["frame", here] = 1; while((getline < f) > 0) { n++; sub(/[#%].*/,"",$0); if ($0 ~ /^[ \t]*$/) continue; if (NF < 3) { badSlot(n,1,"not enough fields"); continue}; for(i=1;i<=NF;i++) $i=trim($i); keyword = $2; if (! (keyword in mins)) { badSlot(n,2,"unknown keyword '"keyword"'"); continue} if (NF < mins[keyword]) { badSlot(n,3,"need at least "mins[keyword]" fields");continue} if (keyword == "with") { parent=$1; here =$3; if (!w["frame",parent]) { badSlot(n,4,"'"parent"' unknown"); continue}; if ( w["frame",here] ) { badSlot(n,5,"'"here"' multiple definitions"); continue}; w["frame",here] = 1; w[parent,"child", ++w[parent,"child",0]]= here; w[here, "parent"] = parent; continue; } x = $1; if (keyword == "is") { if (! ($3 in types)) { badSlot(n,6,"'"$3"' unknown type"); continue} w["slot",$1]=1 w[here,x,"x" ]= $3; if ($3 == "of" ) { w[here,x,"y"]=0 for(i=4;i<=NF;i++) w[here,x, ++w[here,x,"y"]] = v2i($i,aka) } else { w[here,x,"y"]= v2i($4,aka); w[here,x,"z"]=v2i($5,aka) } } if (! (("slot",x) in w)) { badSlot(n,7,"'"x"' unknown"); continue} if (keyword == "=") w[here,x,"="]= v2i($3,aka); if (keyword == "just") { isa = slotIsa(here,x,w); if ( w[isa,x,"x"]== "of") { w[here,x,"y"]=0 for(i=3;i<=NF;i++) w[here,x, ++w[here,x,"y"]]=v2i($i,aka) } else { w[here,x,"y"]= v2i($3,aka); w[here,x,"z"]= v2i($4,aka) } } } if (! n) bad("'"f"' not found"); close(f); FS=oldFS; RS=oldRS; IGNORECASE = oldIgnore; } function v2i(x,aka) { return (x in aka) ? aka[x] : x } function slotIsa(fr,sl, wme) { if ( ! (("frame",fr) in wme) ) { return bad("'" fr "' unknown frame") }; if ( ! (("slot", sl) in wme) ) { return bad("'" sl "' unknown slot" ) }; if ( (fr,sl,"x") in wme ) { return fr } if ( fr=="system" ) { return bad("'" sl "' not found in slot tree") } else { return slotIsa(wme[fr,"parent"],sl,wme) } } function slot(fr,sl,wme) { if ( ! (("frame",fr) in wme) ) { return bad("'" fr "' unknown frame") }; if ( ! (("slot", sl) in wme) ) { return bad("'" sl "' unknown slot") }; if ( (fr,sl,"=") in wme) { return wme[fr, sl ,"="] } if ( (fr,sl,"y") in wme) { return slot1(fr,sl,wme); } if ( fr=="system" ) { return bad("'" sl "' not found in slot tree") } else { return slot(wme[fr,"parent"],sl,wme) } } function slot1(fr,sl,wme) { if (wme["system",sl,"x"]== "of") { return slotItem(fr,sl,wme); } else { return compute(wme["system",sl,"x"],wme[fr,sl,"y"],wme[fr,sl,"z"]) } } function slotItem(fr,sl,wme, max,pos) { max = wme[fr,sl,"y"] pos = ratioInt(1,max); return wme[fr,sl,pos] } # #---- [string2word.awk ] ------------------------------------------ function string2word(words,word,str, tmp,i) { split(str,tmp,/,/); for(i in tmp) words[tmp[i]]=word; } # #---- [ranges.awk ] ------------------------------------------ function from(x,y,z) { return (z >= x && z <= y) ? z : bad(z " not in [" x ".." y "]"); } function round(x) { return x<0 ? int(x-0.5) : int(x+0.5) } function between(min,max) { return max==min ? min : min + ((max-min)*rand()) } function most(x,y) { return x > y ? x : y } function least(x,y) { return x < y ? x : y } function within(min,max,bias) { # pick a number between "min" and "max", with a little "bias" return min + (max - min)*rand()^bias # if bias = A >= 1 then mean = (max+min)*B is towards to "min" end # BIAS mean # ---- ---- # 1 0.5 # 2 0.33 # 3 0.25 # 4 0.2 # 5 0.17 # 6 0.14 # 7 0.13 # 8 0.11 # 9 0.10 # 10 0.09 # if bias = A < 1 then mean = (max+min)*B is towards the "max" end # BIAS mean # ---- ---- # 0.5 0.67 # 0.33 0.75 # 0.25 0.8 # 0.2 0.83 # 0.167 0.86 # 0.14 0.87 # 0.125 0.89 # 0.11 0.9 # 0.10 0.91 } # # #---- [trim.awk ] ------------------------------------------ #

trim.awk

Trim whitespace. function trim(str) { sub(/^[ \t]*/,"",str); sub(/[ \t]*$/,"",str); return str } # #---- [blab.awk ] ------------------------------------------ # /* vim: set filetype=awk : */ -*- awk -*- function blab(str) { print str >> "/dev/stderr"; fflush("/dev/stderr"); } # #---- [string2pairs.awk ] ------------------------------------------ function string2pairs(pairs,str, sep, n,i,tmp) { # generate list of booleans keyed by sub-strings of "str" n=split(str,tmp, (sep ? sep : ",")); for(i=1;i<=n;i=i+2) pairs[tmp[i]]=tmp[i+1]; return n; } # # #---- [demos.awk ] ------------------------------------------ # /* vim: set filetype=awk : */ -*- awk -*- # #---- [demos.awk] ------------------------------------------ function demo(n) { if (n==16) return demo16(); if (n==15) return demo15(); if (n==14) return demo14(); if (n==13) return demo13(); if (n==12) return demo12(); if (n==11) return demo11(); if (n==9) return demo9(); if (n==8) return demo8(); if (n==7) return demo7(); if (n==6) return demo6(); if (n==5) return demo5(); if (n==4) return demo4(); if (n==3) return demo3(); if (n==2) return demo2(); if (n==1) return demo1(); demo999(); } function demo999() { sims(Spec,Repeats,Slots,Project) } function demo16() { set("s","$>a, 0) { array(Cache) printf("%.2f\n", Effort(Project)); } } function demo2() { print ">" Project; print Effort(Project); print Effort(Project) array(Cache) print Effort(Project) saya("Cache",Cache) } function demo1() { print "hey! it runs!" } # #---- [string2bool.awk ] ------------------------------------------ function string2bool(bools,str, n,i,tmp) { # generate list of booleans keyed by sub-strings of "str" n=split(str,tmp,/,/); for(i=1;i<=n;i++) bools[tmp[i]]=1; } # #---- [data.awk] ------------------------------------------ # #---- [about.awk] ------------------------------------------ #### special library stuff # #---- [slottree.awk] ------------------------------------------ # Tool for specifying a tree of slots. # The root of the tree defines valid slot names/types/ranges. # Sub-nodes may specialize slot ranges, but not names or types. # Designed for a cost modeling system where the sub-nodes are # parts of of some software project # # #### standard stuff # BEGIN { array(Cache); # Place to store inferred data array(Slots); # Place to slots array(Fx); # Place to store risk effects } # start up BEGIN { defaults(); # default values for command-line stuff getOpts(How); # process command line init(Slots); # read the .dat files defineTables(); # must be before defineRisks defineSymbols(); defineTunings(); defineRisks(); demo(); # run demos }