Skip to content

Commit c0593b1

Browse files
committed
refactor(coverage): tighten LCOV record parsing and branch hit walk
Replaces verbose "%%|*" / "%%|*" parameter-expansion peels with a single IFS='|' read across the three pipe-delimited record formats this module emits (function, branch, function-coverage row), and folds the comma-separated arms split in compute_branch_hits into a one-line IFS=',' read -ra. Net -26 lines, no behavior change. Verified on /bin/bash 3.2.57 with the full unit suite in sequential and parallel modes, plus make sa and make lint.
1 parent fee2da3 commit c0593b1

1 file changed

Lines changed: 25 additions & 51 deletions

File tree

src/coverage.sh

Lines changed: 25 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -977,31 +977,17 @@ function bashunit::coverage::compute_branch_hits() {
977977
((++_sli))
978978
done <"$file"
979979

980-
local block=0
981-
local branch_entry decision_line arms rest remaining arm arm_start arm_end taken arm_index
980+
local block=0 decision_line _kind arms branch_entry
981+
local -a arm_specs=()
982+
local arm arm_index taken
982983
while IFS= read -r branch_entry; do
983984
[ -z "$branch_entry" ] && continue
984-
985-
decision_line="${branch_entry%%|*}"
986-
rest="${branch_entry#*|}"
987-
# Skip the kind field — reserved for future BRDA grouping but not
988-
# needed by this MVP output.
989-
arms="${rest#*|}"
985+
IFS='|' read -r decision_line _kind arms <<<"$branch_entry"
990986

991987
arm_index=0
992-
remaining="$arms"
993-
while [ -n "$remaining" ]; do
994-
arm="${remaining%%,*}"
995-
if [ "$arm" = "$remaining" ]; then
996-
remaining=""
997-
else
998-
remaining="${remaining#*,}"
999-
fi
1000-
1001-
arm_start="${arm%%:*}"
1002-
arm_end="${arm##*:}"
1003-
taken=$(bashunit::coverage::_arm_taken "$arm_start" "$arm_end")
1004-
988+
IFS=',' read -ra arm_specs <<<"$arms"
989+
for arm in "${arm_specs[@]}"; do
990+
taken=$(bashunit::coverage::_arm_taken "${arm%%:*}" "${arm##*:}")
1005991
echo "${decision_line}|${block}|${arm_index}|${taken}"
1006992
arm_index=$((arm_index + 1))
1007993
done
@@ -1263,26 +1249,20 @@ function bashunit::coverage::report_text_functions() {
12631249
fi
12641250
echo "${display_file}"
12651251

1266-
local fn_entry
1267-
while IFS= read -r fn_entry; do
1268-
[ -z "$fn_entry" ] && continue
1269-
local fn_name fn_start fn_end fn_rest
1270-
fn_name="${fn_entry%%|*}"
1271-
fn_rest="${fn_entry#*|}"
1272-
fn_start="${fn_rest%%|*}"
1273-
fn_end="${fn_rest#*|}"
1252+
local fn_name fn_start fn_end ln fn_executable fn_hit
1253+
local fn_pct fn_class color reset="$_BASHUNIT_COLOR_DEFAULT"
1254+
while IFS='|' read -r fn_name fn_start fn_end; do
1255+
[ -z "$fn_name" ] && continue
12741256

1275-
local fn_executable=0 fn_hit=0 ln
1257+
fn_executable=0
1258+
fn_hit=0
12761259
for ((ln = fn_start; ln <= fn_end; ln++)); do
1277-
local ln_content="${file_lines[$((ln - 1))]:-}"
1278-
if bashunit::coverage::is_executable_line "$ln_content" "$ln"; then
1279-
fn_executable=$((fn_executable + 1))
1280-
local ln_hits=${hits_by_line[$ln]:-0}
1281-
[ "$ln_hits" -gt 0 ] && fn_hit=$((fn_hit + 1))
1282-
fi
1260+
bashunit::coverage::is_executable_line \
1261+
"${file_lines[$((ln - 1))]:-}" "$ln" || continue
1262+
fn_executable=$((fn_executable + 1))
1263+
[ "${hits_by_line[$ln]:-0}" -gt 0 ] && fn_hit=$((fn_hit + 1))
12831264
done
12841265

1285-
local fn_pct fn_class color reset="$_BASHUNIT_COLOR_DEFAULT"
12861266
fn_pct=$(bashunit::coverage::calculate_percentage "$fn_hit" "$fn_executable")
12871267
fn_class=$(bashunit::coverage::get_coverage_class "$fn_pct")
12881268
color=$(bashunit::coverage::get_color_for_class "$fn_class")
@@ -1318,25 +1298,20 @@ function bashunit::coverage::report_lcov() {
13181298
[ -n "$hit_lineno" ] && hits_by_line[hit_lineno]=$hit_count
13191299
done < <(bashunit::coverage::get_all_line_hits "$file")
13201300

1321-
# Function records (FN/FNDA/FNF/FNH)
1322-
local fn_total=0 fn_hit=0
1323-
local fn_entry fn_name fn_start fn_end fn_rest
1301+
# Function records (FN/FNDA/FNF/FNH). Emit FN lines as we walk
1302+
# and buffer the matching FNDA lines for emission after, per
1303+
# LCOV convention.
1304+
local fn_total=0 fn_hit=0 fn_name fn_start fn_end fln any_hit
13241305
local -a fn_dn_records=()
13251306
local _fdi=0
1326-
while IFS= read -r fn_entry; do
1327-
[ -z "$fn_entry" ] && continue
1328-
fn_name="${fn_entry%%|*}"
1329-
fn_rest="${fn_entry#*|}"
1330-
fn_start="${fn_rest%%|*}"
1331-
fn_end="${fn_rest#*|}"
1307+
while IFS='|' read -r fn_name fn_start fn_end; do
1308+
[ -z "$fn_name" ] && continue
13321309
echo "FN:${fn_start},${fn_name}"
13331310
fn_total=$((fn_total + 1))
13341311

1335-
# Function is "hit" if any executable line in its range has hits
1336-
local fln any_hit=0
1312+
any_hit=0
13371313
for ((fln = fn_start; fln <= fn_end; fln++)); do
1338-
local fc="${hits_by_line[$fln]:-0}"
1339-
if [ "$fc" -gt 0 ]; then
1314+
if [ "${hits_by_line[$fln]:-0}" -gt 0 ]; then
13401315
any_hit=1
13411316
break
13421317
fi
@@ -1346,7 +1321,6 @@ function bashunit::coverage::report_lcov() {
13461321
[ "$any_hit" -eq 1 ] && fn_hit=$((fn_hit + 1))
13471322
done < <(bashunit::coverage::extract_functions "$file")
13481323

1349-
# Emit FNDA records grouped after FN records (per LCOV convention)
13501324
local fda
13511325
for fda in ${fn_dn_records[@]+"${fn_dn_records[@]}"}; do
13521326
echo "$fda"

0 commit comments

Comments
 (0)