Fix --fmt with --by-percent producing zeros and warnings (#967)#971
Conversation
When --fmt is combined with --by-percent, the intermediate JSON uses blank_pct/comment_pct/code_pct keys, but print_format_n only reads the canonical blank/comment/code keys. The result was a flood of "Use of uninitialized value" warnings and a table of zeros. In load_json, alias *_pct keys to their canonical names so downstream formatting works unchanged. Also fall back from a missing 'language' field to the entry key (by-language reports don't carry one). Add a regression test under Unix/t/01_opts.t that asserts no "uninitialized value" warnings and non-zero output for --fmt=4 --by-percent=cm.
|
Maintainer pointed out that --fmt 3/4 --by-percent=cm tests/inputs crashes with "Illegal division by zero at cloc line 4892". This is a pre-existing defect on master, distinct from the JSON-key mismatch fixed in the previous commit, but in the same code path: generate_report computes the txt $data_line for every output style (then discards it for non-txt), so the division at line 4892 fires even when the active output is JSON. tests/inputs/issues/644/UInt8.cs has code=0, comment=0, blank=1, making $DEN=0 under --by-percent=cm. Add the same > 0 guards already used in diff_report (lines 3725, 4076) to the txt, yaml/json, csv/md, and SUM branches in generate_report. When the denominator is zero, print 0.00 instead of crashing. Extend the regression test to assert no "Illegal division by zero" on the full tests/inputs corpus for --fmt=3 and --fmt=4 with --by-percent=cm.
The earlier test only checked for absence of error strings on STDERR. Add a positive assertion that the empty-content file tests/inputs/issues/644/UInt8.cs (code=0, comment=0, blank=1) shows 0.00 across all three percentage columns. This catches silent regressions where the values become empty, NaN-like, or otherwise malformed without producing a "division by zero" message.
|
@AlDanial Thanks for surfacing those failing modes. I verified that the The reason it surfaces under Since it's in the same code path as #967, I've extended this PR to fix it too:
Verified clean against:
|
|
This is good progress. Couple of minor issues: 1) the SUM line for all |
Per maintainer review: with --fmt and --by-percent, the SUM line was the arithmetic sum of per-row percentages, which is meaningless (e.g. "SUM 6970.42 11787.25 31212.75" for --fmt 4 --by-percent=cm). Preserve the JSON's SUM block in load_json (previously deleted) and pass it to print_format_n. When --by-percent is active, replace the accumulated SUM cells with the aggregate from that block: - 't' mode: the JSON already stores 100/100/100, use directly. - 'c'/'cm'/'cb'/'cmb': the JSON stores raw counts; convert to aggregate percentages via compute_denominator(), the same logic the non-fmt text path uses. The Total column on the SUM row is then the sum of the corrected aggregates (e.g. 115.87 for --by-percent=cm), matching the layout of count mode where Total = blank+comment+code per row. Per-row Total in --fmt 2/4/5 under --by-percent is left as the sum of the row's percentages (open question for the maintainer: the JSON does not carry raw per-row counts in by-percent mode, so showing real line totals would require a JSON shape change). Add a regression test that compares the SUM row produced by --fmt 1-5 against the SUM row of the non-fmt text path (the source of truth) for --by-percent=cm on tests/inputs.
|
thank you! |
Summary
Fixes #967.
When
--fmtis combined with--by-percent, cloc round-trips its results through an intermediate JSON. That JSON usesblank_pct/comment_pct/code_pctkeys, butprint_format_nonly reads the canonicalblank/comment/code. The result was a stream ofUse of uninitialized valuewarnings on STDERR and a table of zeros.Repro (before this PR)
After
Changes
cloc— inload_json:*_pctkeys to their canonical names so the rest of the format pipeline works unchanged.languagefield to the entry key (by-language reports don't carry one), avoiding a separatelength(undef)warning.Unix/t/01_opts.t— regression test that asserts noUse of uninitialized valueon STDERR and non-zero output for--fmt=4 --by-percent=cm.Test plan
prove t/00_C.t t/01_opts.t t/02_git.t— all 952 tests pass (including 2 new).