code wiki / (root) / nx_mccabe.nx

nx_mccabe.nx source

↩ module page · 170 lines · 9922 B

1// nx_mccabe.nx -- THIN MAIN over nx_mccabe_lib.nx. Publishes the DISTRIBUTION of cyclomatic complexity 2// across the corpus; the only bar it names is CITED, never chosen here. 3// nx_mccabe [dir] default dir=buildroot/runtime 4// license_tier: ORIGINAL expect_exit: 0 5import "nx_mccabe_lib.nx" 6 7const MCM_EXACT_TO: i64 = 15 // exact buckets up to here, then DOUBLING ranges -- a derivation, not a taste 8const MCM_OUTBUF: i64 = 16384 9// CE1 (codeeffectiveness): one row per run on a time spine -- a level cannot express a trajectory, two rows can 10const MCM_SPINE: *u8 = "knowledge/status/mccabe.spine\x00" 11const MCM_MODE644: i64 = 420 12const MCM_SPINEBUF: i64 = 2048 13 14func mcm_range(ob: *u8, a0: i64, hist: *i64, lo: i64, hi: i64, total: i64) -> i64 { 15 var a: i64=a0 16 var s: i64=0 17 var v: i64=lo 18 while v<=hi { if v<MC_HIST_MAX { s=s+hist[v] } v=v+1 } 19 if s==0 { return a } 20 a=mc_cat(ob, a, " vG " as *u8) 21 a=mc_catn(ob, a, lo) 22 if hi>lo { a=mc_cat(ob, a, "-" as *u8); a=mc_catn(ob, a, hi) } 23 a=mc_cat(ob, a, " n=" as *u8); a=mc_catn(ob, a, s) 24 if total>0 { a=mc_cat(ob, a, " permille=" as *u8); a=mc_catn(ob, a, (s*MC_PERMILLE)/total) } 25 a=mc_cat(ob, a, "\n" as *u8) 26 return a 27} 28 29// ce_mccabe_live -- the LIVE census's own trajectory row (codeeffectiveness CE5: the keystone is not merely present in 30// source, it RUNS on the serving tree and writes its spine). Appends one row to MCM_SPINE for the production subject and 31// announces fd= wrote= of= into the report, so a row that failed to write is visible in the run that failed to write it. 32// Named for the watch that measures it; the name is the writer, not a badge. 33func ce_mccabe_live(c: *i64, funcs: i64, crows: i64, ob: *u8, a0: i64) -> i64 { 34 var a: i64=a0 35 let sfd: i64=sys_openat_append(MCM_SPINE as *u8, MCM_MODE644) 36 let sb: *u8=sys_mmap(MCM_SPINEBUF) 37 var s: i64=0 38 s=mc_catn(sb, s, sys_now_realtime_sec()) 39 s=mc_cat(sb, s, "|files=" as *u8); s=mc_catn(sb, s, c[MC_C_FILES]) 40 s=mc_cat(sb, s, "|funcs=" as *u8); s=mc_catn(sb, s, funcs) 41 s=mc_cat(sb, s, "|above_10=" as *u8); s=mc_catn(sb, s, c[MC_C_ABOVE]) 42 if funcs>0 { s=mc_cat(sb, s, "|permille=" as *u8); s=mc_catn(sb, s, (c[MC_C_ABOVE]*MC_PERMILLE)/funcs) } 43 s=mc_cat(sb, s, "|classes=" as *u8); s=mc_catn(sb, s, crows) 44 var sk: i64=0 45 while sk<=crows { 46 let sbk: i64=MC_C_CLSBASE+sk*MC_CLS_FIELDS 47 s=mc_cat(sb, s, "|" as *u8); s=mc_cat(sb, s, mc_cls_name(c, sk)) 48 s=mc_cat(sb, s, ":" as *u8); s=mc_catn(sb, s, c[sbk+MC_CF_FILES]) 49 s=mc_cat(sb, s, ":" as *u8); s=mc_catn(sb, s, c[sbk+MC_CF_FUNCS]) 50 s=mc_cat(sb, s, ":" as *u8); s=mc_catn(sb, s, c[sbk+MC_CF_ABOVE]) 51 sk=sk+1 52 } 53 s=mc_cat(sb, s, "\n" as *u8) 54 var swrote: i64=0-1 55 if sfd>=0 { swrote=sys_write(sfd, sb, s); sys_close(sfd) } 56 a=mc_cat(ob, a, " spine=" as *u8); a=mc_cat(ob, a, MCM_SPINE as *u8); a=mc_cat(ob, a, " fd=" as *u8); a=mc_catn(ob, a, sfd); a=mc_cat(ob, a, " wrote=" as *u8); a=mc_catn(ob, a, swrote); a=mc_cat(ob, a, " of=" as *u8); a=mc_catn(ob, a, s); a=mc_cat(ob, a, "\n" as *u8) 57 return a 58} 59 60func main(argc: i64, argv: *i64) -> i64 { 61 var dir: *u8 = MC_DEF_DIR as *u8 62 if argc>=2 { dir = argv[1] as *u8 } 63 let hist: *i64=sys_mmap(MC_HIST_MAX*8+64) as *i64 64 var z: i64=0 65 while z<MC_HIST_MAX { hist[z]=0; z=z+1 } 66 let c: *i64=sys_mmap(MC_C_SLOTS*8) as *i64 67 var y: i64=0 68 while y<MC_C_SLOTS { c[y]=0; y=y+1 } 69 // CE1: the head-marker class table is DATA; an absent conf reads 0 rows and the census SAYS so below 70 let crows: i64=mc_cls_load(c) 71 let work: *u8=sys_mmap(MC_WORKCAP) 72 let wo: *i64=sys_mmap(16) as *i64 73 wo[0]=0 74 let pbuf: *u8=sys_mmap(MC_PATHCAP) 75 var dn: i64=0 76 while dir[dn]!=(0 as u8) { pbuf[dn]=dir[dn]; dn=dn+1 } 77 78 mc_w("=== NX-MCCABE -- cyclomatic complexity v(G) per function. Closes the ISO-5055 Maintainability gap (seq251). ===\n" as *u8) 79 mc_w(" subject dir: " as *u8); mc_w(dir); mc_w("\n" as *u8) 80 mc_walk(pbuf, dn, 0, hist, c, work, wo) 81 82 let funcs: i64=c[MC_C_FUNCS] 83 mc_w("\n-- WORKLIST: every function above the CITED limit of 10 (McCabe 1976, NIST SP 500-235) --\n" as *u8) 84 if wo[0]==0 { mc_w(" (none)\n" as *u8) } else { work[wo[0]]=0 as u8; mc_w(work) } 85 if wo[0]>=MC_WORKFLUSH { mc_w(" <== THIS LIST IS A PREFIX OF ITS OWN COUNT (worklist buffer filled)\n" as *u8) } 86 87 let ob: *u8=sys_mmap(MCM_OUTBUF) 88 var a: i64=0 89 a=mc_cat(ob, a, "\n-- DISTRIBUTION (published BEFORE any bar, because a bar picked before the shape is a guess) --\n" as *u8) 90 var v: i64=1 91 while v<=MCM_EXACT_TO { a=mcm_range(ob, a, hist, v, v, funcs); v=v+1 } 92 var lo: i64=MCM_EXACT_TO+1 93 while lo<MC_HIST_MAX { 94 var hi: i64=lo*2-1 95 if hi>=MC_HIST_MAX { hi=MC_HIST_MAX-1 } 96 a=mcm_range(ob, a, hist, lo, hi, funcs) 97 lo=hi+1 98 } 99 if c[MC_C_OVER]>0 { 100 a=mc_cat(ob, a, " vG >=" as *u8); a=mc_catn(ob, a, MC_HIST_MAX) 101 a=mc_cat(ob, a, " n=" as *u8); a=mc_catn(ob, a, c[MC_C_OVER]) 102 a=mc_cat(ob, a, " (histogram overflow -- counted, never dropped)\n" as *u8) 103 } 104 a=mc_cat(ob, a, "\n-- DERIVED FROM THE CDF, not chosen --\n p50=" as *u8) 105 a=mc_catn(ob, a, mc_pct(hist, funcs, c[MC_C_OVER], c[MC_C_MAX], 500)) 106 a=mc_cat(ob, a, " p90=" as *u8); a=mc_catn(ob, a, mc_pct(hist, funcs, c[MC_C_OVER], c[MC_C_MAX], 900)) 107 a=mc_cat(ob, a, " p99=" as *u8); a=mc_catn(ob, a, mc_pct(hist, funcs, c[MC_C_OVER], c[MC_C_MAX], 990)) 108 a=mc_cat(ob, a, " max=" as *u8); a=mc_catn(ob, a, c[MC_C_MAX]) 109 if funcs>0 { a=mc_cat(ob, a, " mean=" as *u8); a=mc_catn(ob, a, c[MC_C_SUMVG]/funcs) } 110 a=mc_cat(ob, a, "\n\n-- AGAINST THE CITED BAR (the number comes from the standard, not from us) --\n above_10=" as *u8) 111 a=mc_catn(ob, a, c[MC_C_ABOVE]) 112 if funcs>0 { a=mc_cat(ob, a, " permille=" as *u8); a=mc_catn(ob, a, (c[MC_C_ABOVE]*MC_PERMILLE)/funcs) } 113 a=mc_cat(ob, a, "\n McCabe 1976 calls 10 a reasonable upper limit and explicitly not a magic number, and NIST SP\n" as *u8) 114 a=mc_cat(ob, a, " 500-235 formalises it while permitting a documented exception for multiway decisions. This organ\n" as *u8) 115 a=mc_cat(ob, a, " therefore REPORTS the count above that bar and does NOT pass or fail anything on it.\n" as *u8) 116 a=mc_cat(ob, a, "\n-- BY HEAD-MARKER CLASS (codeeffectiveness CE1: WHOSE code carries the complexity; knowledge/headmark_classes.conf, first row wins) --\n" as *u8) 117 a=mc_cat(ob, a, " classes_src=" as *u8) 118 if crows>0 { a=mc_cat(ob, a, "CONF rows=" as *u8); a=mc_catn(ob, a, crows) } else { a=mc_cat(ob, a, "ABSENT -- every source reads UNMARKED (a table nobody wrote is an absence, not a measurement)" as *u8) } 119 a=mc_cat(ob, a, "\n" as *u8) 120 var ck: i64=0 121 var cpf: i64=0 122 var cpn: i64=0 123 while ck<=crows { 124 let cb: i64=MC_C_CLSBASE+ck*MC_CLS_FIELDS 125 a=mc_cat(ob, a, " " as *u8); a=mc_cat(ob, a, mc_cls_name(c, ck)) 126 a=mc_cat(ob, a, " files=" as *u8); a=mc_catn(ob, a, c[cb+MC_CF_FILES]) 127 a=mc_cat(ob, a, " funcs=" as *u8); a=mc_catn(ob, a, c[cb+MC_CF_FUNCS]) 128 if c[cb+MC_CF_FUNCS]>0 { a=mc_cat(ob, a, " mean_vG=" as *u8); a=mc_catn(ob, a, c[cb+MC_CF_SUMVG]/c[cb+MC_CF_FUNCS]) } 129 a=mc_cat(ob, a, " above_10=" as *u8); a=mc_catn(ob, a, c[cb+MC_CF_ABOVE]) 130 if c[cb+MC_CF_FUNCS]>0 { a=mc_cat(ob, a, " permille=" as *u8); a=mc_catn(ob, a, (c[cb+MC_CF_ABOVE]*MC_PERMILLE)/c[cb+MC_CF_FUNCS]) } 131 a=mc_cat(ob, a, "\n" as *u8) 132 cpf=cpf+c[cb+MC_CF_FILES] 133 cpn=cpn+c[cb+MC_CF_FUNCS] 134 ck=ck+1 135 } 136 a=mc_cat(ob, a, " partition: class_files=" as *u8); a=mc_catn(ob, a, cpf); a=mc_cat(ob, a, " of files=" as *u8); a=mc_catn(ob, a, c[MC_C_FILES]) 137 a=mc_cat(ob, a, " class_funcs=" as *u8); a=mc_catn(ob, a, cpn); a=mc_cat(ob, a, " of funcs=" as *u8); a=mc_catn(ob, a, funcs) 138 if crows>0 { if cpf==c[MC_C_FILES] { if cpn==funcs { a=mc_cat(ob, a, " SUMS" as *u8) } else { a=mc_cat(ob, a, " LEAK" as *u8) } } else { a=mc_cat(ob, a, " LEAK" as *u8) } } else { a=mc_cat(ob, a, " (unclassified run)" as *u8) } 139 a=mc_cat(ob, a, "\n" as *u8) 140 // CE1: one row on the time spine, ONLY for the production subject -- a trial run over another dir must not write the 141 // production trajectory (the forgeable-heartbeat law), so it announces SKIPPED instead. The writer prints fd= wrote= of=. 142 var spine_ok: i64=0 143 if argc<2 { spine_ok=1 } 144 if spine_ok==1 { 145 a=ce_mccabe_live(c, funcs, crows, ob, a) 146 } else { 147 a=mc_cat(ob, a, " spine=SKIPPED (non-default subject dir: a trial run does not write the production trajectory)\n" as *u8) 148 } 149 a=mc_cat(ob, a, "\n-- SCOPE, so nobody reads this as more than it is --\n" as *u8) 150 a=mc_cat(ob, a, " Decision points counted: if, while, for, and each of && and ||. `else` is NOT counted.\n" as *u8) 151 a=mc_cat(ob, a, " Comments and string literals are SKIPPED -- a scanner that does not is measuring documentation.\n" as *u8) 152 a=mc_cat(ob, a, " Bodies are read with sys_read_file, which sizes its buffer from the file, so there is NO cap.\n" as *u8) 153 a=mc_cat(ob, a, " files_unreadable=" as *u8); a=mc_catn(ob, a, c[MC_C_UNREAD]) 154 a=mc_cat(ob, a, " (UNKNOWN -- counted apart, never folded into a clean result)\n" as *u8) 155 ob[a]=0 as u8 156 mc_w(ob) 157 158 let vb: *u8=sys_mmap(512) 159 var q: i64=0 160 q=mc_cat(vb, q, "\nNX-MCCABE files=" as *u8); q=mc_catn(vb, q, c[MC_C_FILES]) 161 q=mc_cat(vb, q, " funcs=" as *u8); q=mc_catn(vb, q, funcs) 162 q=mc_cat(vb, q, " max=" as *u8); q=mc_catn(vb, q, c[MC_C_MAX]) 163 q=mc_cat(vb, q, " above_cited_10=" as *u8); q=mc_catn(vb, q, c[MC_C_ABOVE]) 164 q=mc_cat(vb, q, " unreadable=" as *u8); q=mc_catn(vb, q, c[MC_C_UNREAD]) 165 q=mc_cat(vb, q, " verdict=MEASURED\n" as *u8) 166 vb[q]=0 as u8 167 mc_w(vb) 168 sys_exit(0) 169 return 0 170}