1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Fix annoying usage/--help/--man message corruption

In a locale other than C/POSIX, ksh produces corrupted usage
messages for alternatives, e.g. this output of 'typeset -\?':
| Usage: typeset [-bflmnprstuxACHS] [-a[type]] [-i[base]] <..CUT..>
|                [-T[tname]] [-Z[n]] [name[=value]...]
|    Or:[name[=value]...]
| typeset[name[=value]...]
| [[name[=value]...]
| options[name[=value]...]
| ] -f [name...]

Correct output is:
| Usage: typeset [-bflmnprstuxACHS] [-a[type]] [-i[base]] <..CUT..>
|                [-T[tname]] [-Z[n]] [name[=value]...]
|    Or: typeset [ options ] -f [name...]

Similar corruption occurs in --help and --man output.
This bug is ancient: it's already in ksh 1993-12-28 s+.

ksh2020 has this fixed. A 'git bisect' run pinpointed the fix
to this commit, which fixes the ERROR_translating macro after
removing the AST-specific locale subsystem:
4abc061e
But making the same change in ksh 93u+m produced no results
(probably because we have not removed that subsystem).

However, disabling the use of translation macros in optget.sh
altogether (replacing them with dummies that were already coded in
a preprocessor directive fallback for a reduced standalone libast)
turns out to work. It's not as if there is actually any translation
anyway, so this effectively fixes this bug.

The actual cause of this bug remains mysterious, but should be
somewhere in the AST translation and/or locale subsystem.

src/lib/libast/misc/optget.c:
- Use fallback translation macros.

src/cmd/ksh93/tests/builtins.sh:
- Add regression tests for output of -?, --?x, --help and --man
  for a usage string with an alternative ("Or:") usage message.
  Before the fix, these failed when running the tests in the
  C.UTF-8 locale (as in 'bin/shtests -u builtins').
This commit is contained in:
Martijn Dekker 2020-07-16 04:23:40 +01:00
parent 8c7c60ec19
commit a42ac7e77a
2 changed files with 73 additions and 1 deletions

View file

@ -774,5 +774,77 @@ unset foo
[[ $(printf '%(%f)T') == $(printf '%(%Y.%m.%d-%H:%M:%S)T') ]] || err_exit 'date format %f is not the same as %Y.%m.%d-%H:%M:%S'
[[ $(printf '%(%q)T') == $(printf '%(%Qz)T') ]] && err_exit 'date format %q is the same as %Qz'
# ======
# Test various AST getopts usage/manual outputs
OPTIND=1
USAGE=$'
[-s8?
@(#)$Id: foo (ksh93) 2020-07-16 $
]
[+NAME?foo - bar]
[+DESC?Baz.]
[x:xylophone?Lorem.]
[y:ypsilon?Ipsum.]
[z:zeta?Sit.]
[ name=value ... ]
-y [ name ... ]
[+SEE ALSO?\bgetopts\b(1)]
'
function testusage {
getopts "$USAGE" dummy 2>&1
}
actual=$(testusage -\?)
expect='Usage: testusage [-xyz] [ name=value ... ]
Or: testusage [ options ] -y [ name ... ]'
[[ $actual == "$expect" ]] || err_exit "getopts: '-?' output" \
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
actual=$(testusage --\?x)
expect='Usage: testusage [ options | --help | --man ] [ name=value ... ]
Or: testusage [ options ] -y [ name ... ]
OPTIONS
-x, --xylophone Lorem.'
[[ $actual == "$expect" ]] || err_exit "getopts: '--?x' output" \
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
actual=$(testusage --help)
expect='Usage: testusage [ options | --help | --man ] [ name=value ... ]
Or: testusage [ options ] -y [ name ... ]
OPTIONS
-x, --xylophone Lorem.
-y, --ypsilon Ipsum.
-z, --zeta Sit.'
[[ $actual == "$expect" ]] || err_exit "getopts: '--help' output" \
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
actual=$(testusage --man)
expect='NAME
foo - bar
SYNOPSIS
foo [ options | --help | --man ] [ name=value ... ]
foo [ options | --help | --man ] -y [ name ... ]
DESC
Baz.
OPTIONS
-x, --xylophone Lorem.
-y, --ypsilon Ipsum.
-z, --zeta Sit.
SEE ALSO
getopts(1)
IMPLEMENTATION
version foo (ksh93) 2020-07-16'
[[ $actual == "$expect" ]] || err_exit "getopts: '--man' output" \
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
# ======
exit $((Errors<125?Errors:125))

View file

@ -176,7 +176,7 @@ static unsigned char map[UCHAR_MAX];
static Optstate_t state;
#if !_PACKAGE_astsa
#if 0 /* #if !_PACKAGE_astsa // this somehow corrupts "Or:" usage mesages, e.g. in 'typeset -\?' */
#define ID ast.id