From 711bc7f15b5ff56ffe82075ffe4366065fa62ebb Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 15 Jun 2026 01:50:22 +0800 Subject: [PATCH] fix(csv/parser): pre-type fns array so gawk doesn't empty the parse on Linux output_variable() built fns[length(fns)+1]; under gawk the first reference length(fns) typed fns as a scalar -> 'attempt to use scalar as an array' -> empty -e/variable output on Linux (BSD awk on macOS tolerated it). Add split("", fns), same fix as ini/parser. Adds a /csv/parser -e regression test (surfaced by xsh-lib/xsql query failures on Linux). Co-Authored-By: Claude Opus 4.8 (1M context) --- functions/csv/parser.awk | 5 +++++ test.sh | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/functions/csv/parser.awk b/functions/csv/parser.awk index 58dc615..4f1a92c 100644 --- a/functions/csv/parser.awk +++ b/functions/csv/parser.awk @@ -116,6 +116,11 @@ function output_table (array, m, n, ofs, i, j) { #? function output_variable (array, m, n, prefix, quote, single, i, j, fn, fns, fv) { i = 1 + # Pre-type `fns` as an array. Under gawk the first reference `length(fns)` in + # `fns[length(fns)+1]` below otherwise types it as a scalar, then the subscript + # fails with "attempt to use scalar as an array" (BSD awk on macOS tolerates + # it). This empties the parse on Linux — see xsh-lib/xsql query failures. + split("", fns) for (j=1;j<=n;j++) { fv = array[i "," j] fn = get_var_name(fv) diff --git a/test.sh b/test.sh index f9a50c0..f101a61 100644 --- a/test.sh +++ b/test.sh @@ -60,6 +60,18 @@ xsh log info "/json/parser" xsh log info "/uri/parser" [[ $(xsh /uri/parser -s https://github.com) == https ]] +# /csv/parser -e exercises output_variable(), which builds `fns[length(fns)+1]`. +# Under gawk (Linux) that typed `fns` as a scalar and emptied the parse; this +# asserts the variable output is populated on every shell/OS. +xsh log info "/csv/parser (-e variable output)" +__csv_tmp=$(mktemp "${TMPDIR:-/tmp}/xsh-csv-test.XXXXXXXX") +printf 'name,age\nalice,30\nbob,25\n' > "$__csv_tmp" +__csv_out=$(xsh /csv/parser -e "$__csv_tmp") +rm -f "$__csv_tmp" +[[ $__csv_out == *"FIELDS_name_ROWS"* ]] +[[ $__csv_out == *alice* ]] +[[ $__csv_out == *bob* ]] + # ---------- dotfile ---------- # Tests use a temporary repo with a .dotfilemap to avoid depending on any # real dotfile repository.