Skip to content

testsuite batch94: declare/unalias/exec/hash/unset diagnostics + ${a[@]@A} - #305

Merged
brianjfox merged 5 commits into
mainfrom
fix/testsuite-batch94
Jul 25, 2026
Merged

testsuite batch94: declare/unalias/exec/hash/unset diagnostics + ${a[@]@A}#305
brianjfox merged 5 commits into
mainfrom
fix/testsuite-batch94

Conversation

@brianjfox

Copy link
Copy Markdown
Owner

Batch 94 of bash 5.3 test-suite conformance work, driven by the errors test (2nd-largest byte-diff after intl). Five independent conformance fixes:

declare/typeset/local diagnostics — reject non-identifier operands (declare /bin/sh, a -z left after --) with not a valid identifier; reject -f/-F with an assignment (*cannot use -f' to make functions*); prefix a readonly-assignment failure with the builtin name and propagate its exit status; refuse +rclearing an existing readonly.local -` stays exempt as bash's save-options operand.

unalias / exec usage — bare unalias (no name) and exec with a bad option now print their usage lines.

set +o hashall — replaced the no-op with a real opt_hashall state wired through set -h/+h, set -o hashall, the -h invocation flag, $SHELLOPTS and $-. hash now fails with hashing disabled when off; $- drops h.

unset bad subscriptunset a[-2] on an empty/too-short indexed array now reports unset: [SUB]: bad array subscript (exit 1) instead of silently no-op'ing.

${a[@]@A} — the whole-array @A transform applied the per-element scalar operator (garbage declare -A a=<value> per element). Extracted declare -p's formatting into declare_var_string and reused it, so ${a[@]@A} recreates the array and eval "${a[@]@A}" round-trips byte for byte.

Scoreboard impact (byte-diffs vs bash 5.3)

test before after
errors 297 272
nameref 256 247
exp 44 40
assoc 88 86

No regressions in any other test. ctest 22/22 and run_diff all 234 scripts match bash.

Match bash's declare-family error handling:

- Reject a non-identifier operand (`declare /bin/sh', or a `-z' left as
  an operand after `--') with `not a valid identifier', reporting and
  skipping each while still processing the rest.  `local -' stays exempt
  as bash's special save-options operand.
- Reject `-f'/`-F' carrying an assignment (`declare -f f=...') with
  `cannot use `-f' to make functions'.
- Prefix a readonly-assignment failure with the builtin name
  (`declare: VAR: readonly variable') as bind_variable does, where a
  bare assignment and readonly/export stay unprefixed, and propagate the
  failed assignment's non-zero exit status.
- Refuse to clear an existing readonly attribute via `+r', reporting the
  variable as readonly and leaving the flag set.
`unalias' with neither `-a' nor a name operand now prints its usage
string and returns 2, and `exec' follows an invalid-option error with
its usage line, both matching bash.
`hashall' was accepted as a no-op.  Track it as opt_hashall (on by
default) and wire it through `set -h'/`+h', `set -o hashall', the `-h'
invocation flag, $SHELLOPTS and $-.  With hashing disabled every form of
the `hash' builtin now fails first with `hash: hashing disabled', and
`$-' drops the `h' flag, both matching bash.
`unset a[-2]' on an empty or too-short indexed array silently did
nothing.  array_unset now returns whether the subscript resolved in
range, and `unset' reports `unset: [SUB]: bad array subscript' (exit 1)
when a negative index falls below the first element, as bash does.  A
positive out-of-range index and an associative key remain no-ops.
The array `@A' transform applied the per-element scalar operator, so
${a[@]@A} produced a garbled `declare -A a=<element>' per value instead
of one statement recreating the array.  Extract declare -p's rendering
into declare_var_string and reuse it: ${a[@]@A} now emits the three
top-level words `declare', `-flags' and `name=(...)' -- staying three
words when quoted and IFS-splitting the last when unquoted -- so
`eval "${a[@]@A}"' round-trips byte for byte, matching bash.
@brianjfox
brianjfox merged commit 4a1671d into main Jul 25, 2026
1 check passed
@brianjfox
brianjfox deleted the fix/testsuite-batch94 branch July 25, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant