1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-13 11:42:21 +00:00

typeset: add error msgs for incompatible options; improve usage msg

This adds informative error messages if incompatible options are
given. It also documents the exclusive -m, -n and -T options on
separate usage lines, as was already done with -f. The usage
message for incompatible options now looks something like this:

| $ ksh -c 'typeset -L10 -F -f -i foo'
| ksh: typeset: -i/-F/-E/-X cannot be used with -L/-R/-Z
| ksh: typeset: -f cannot be used with other options
| Usage: typeset [-bflmnprstuxACHS] [-a[type]] [-i[base]] [-E[n]]
|                [-F[n]] [-L[n]] [-M[mapping]] [-R[n]] [-X[n]]
|                [-h string] [-T[tname]] [-Z[n]] [name[=value]...]
|    Or: typeset -f [name...]
|    Or: typeset -m [name=name...]
|    Or: typeset -n [name=name...]
|    Or: typeset -T [tname[=(type definition)]...]
|  Help: typeset [ --help | --man ] 2>&1

(see also the previous commit, e21a053e)

Unfortunately the first "Usage" line has some redundancies with the
"Or:" lines showing separate usages. It doesn't seem to be possible
to avoid this; it's a flaw in how libast generates everything
(usage, help, manual) from one huge getopt(3) string. I still think
the three added "Or:" lines are an improvement as it wasn't
previously shown that these options need to be used on their own.

src/cmd/ksh93/bltins/typeset.c: b_typeset():
- Instead of only showing a generic usage message, add an
  informative error message if incompatible options were given.
- Conflicting options detection was failing because NV_LJUST and
  NV_EXPNOTE have the same bitmask value. Use a new 'isadjust'
  flag for -L/-R/-Z to remember if one of these was set.
- Detect conflict between -L/-R/-Z and a float option, not just -i.

src/cmd/ksh93/include/name.h, src/cmd/ksh93/data/msg.c:
- Add the two new error messages for incompatible options.

src/cmd/ksh93/data/builtins.c: sh_opttypeset[]:
- Add a space after 'float' in in "[+float?\btypeset -lE\b]" as
  this makes 'float' appear on its own line, improving formatting.
- Show -m, -n, -T on separate usage lines like -f, as none of these
  can be combined with other options.
- Remove "cannot be combined with other options" from -m and -n
  descriptions, as that should now be clear from the separate usage
  lines -- and even if not, the error message is now informative.

src/cmd/ksh93/sh.1, src/cmd/ksh93/COMPATIBILITY:
- Update.

src/cmd/ksh93/tests/types.sh:
- Remove obsolete test: 'typeset -RF' is no longer accepted.
  (It crashed in 93u+, so this is not an incompatibility...)

Resolves: https://github.com/ksh93/ksh/issues/48
This commit is contained in:
Martijn Dekker 2021-01-21 00:24:13 +00:00
parent e21a053e19
commit 0a10e76ccc
8 changed files with 58 additions and 17 deletions

3
NEWS
View file

@ -8,6 +8,9 @@ Any uppercase BUG_* names are modernish shell bug IDs.
- Fixed: executing a DEBUG trap in a command substitution had side effects
on the exit status ($?) of non-trap commands.
- The typeset builtin command now gives an informative error message if an
incompatible combination of options is given.
2021-01-19:
- Fixed a crash when using 'cd' in a virtual/non-forking subshell in a

View file

@ -68,8 +68,8 @@ For more details, see the NEWS file and for complete details, see the git log.
9. The 'print', 'printf' and 'echo' builtin commands now return a nonzero
exit status if an input/output error occurs.
10. The 'unalias' builtin will now return a non-zero status if it tries to
remove a previously set alias that is not currently set.
10. The 'typeset' builtin now properly detects and reports options that
cannot be used together if they are given as part of the same command.
____________________________________________________________________________

View file

@ -195,7 +195,7 @@ int b_typeset(int argc,register char *argv[],Shbltin_t *context)
const char *optstring = sh_opttypeset;
Namdecl_t *ntp = (Namdecl_t*)context->ptr;
Dt_t *troot;
int isfloat=0, shortint=0, sflag=0;
int isfloat=0, isadjust=0, shortint=0, sflag=0;
memset((void*)&tdata,0,sizeof(tdata));
tdata.sh = context->shp;
@ -297,6 +297,7 @@ int b_typeset(int argc,register char *argv[],Shbltin_t *context)
tdata.argnum = (int)opt_info.num;
if(tdata.argnum < 0)
errormsg(SH_DICT,ERROR_exit(1), e_badfield, tdata.argnum);
isadjust = 1;
if(n=='Z')
flag |= NV_ZFILL;
else
@ -377,18 +378,36 @@ endargs:
argv--;
if((flag&NV_ZFILL) && !(flag&NV_LJUST))
flag |= NV_RJUST;
if((flag&NV_INTEGER) && (flag&(NV_LJUST|NV_RJUST|NV_ZFILL)))
if((isfloat || flag&NV_INTEGER) && isadjust)
{
errormsg(SH_DICT,2,e_optincompat2,"-i/-F/-E/-X","-L/-R/-Z");
error_info.errors++;
}
if((flag&NV_BINARY) && (flag&(NV_LJUST|NV_UTOL|NV_LTOU)))
{
errormsg(SH_DICT,2,e_optincompat2,"-b","-L/-u/-l");
error_info.errors++;
}
if((flag&NV_MOVE) && (flag&~(NV_MOVE|NV_VARNAME|NV_ASSIGN)))
{
errormsg(SH_DICT,2,e_optincompat1,"-m");
error_info.errors++;
}
if((flag&NV_REF) && (flag&~(NV_REF|NV_IDENT|NV_ASSIGN)))
{
errormsg(SH_DICT,2,e_optincompat1,"-n");
error_info.errors++;
}
if((flag&NV_TYPE) && (flag&~(NV_TYPE|NV_VARNAME|NV_ASSIGN)))
{
errormsg(SH_DICT,2,e_optincompat1,"-T");
error_info.errors++;
}
if(troot==tdata.sh->fun_tree && ((isfloat || flag&~(NV_FUNCT|NV_TAGGED|NV_EXPORT|NV_LTOU))))
{
errormsg(SH_DICT,2,e_optincompat1,"-f");
error_info.errors++;
}
if(sflag && troot==tdata.sh->fun_tree)
{
/* static function */

View file

@ -1718,7 +1718,7 @@ USAGE_LICENSE
;
const char sh_opttypeset[] =
"+[-1c?\n@(#)$Id: typeset (AT&T Research/ksh93) 2020-07-15 $\n]"
"+[-1c?\n@(#)$Id: typeset (AT&T Research/ksh93) 2021-01-20 $\n]"
USAGE_LICENSE
"[+NAME?typeset - declare or display variables with attributes]"
"[+DESCRIPTION?Without the \b-f\b option, \btypeset\b sets, unsets, "
@ -1738,7 +1738,7 @@ USAGE_LICENSE
"[+?Note also the following builtin command equivalents:]{"
"[+autoload?\btypeset -fu\b]"
"[+compound?\btypeset -C\b]"
"[+float?\btypeset -lE\b]"
"[+float ?\btypeset -lE\b]"
"[+functions?\btypeset -f\b]"
"[+integer?\btypeset -li\b]"
"[+nameref?\btypeset -n\b]"
@ -1768,11 +1768,9 @@ USAGE_LICENSE
"[l?Without \b-i\b, sets character mapping to \btolower\b. When used "
"with \b-i\b, \b-E\b, or \b-F\b indicates long variant.]"
"[m?Move. The value is the name of a variable whose value will be "
"moved to \aname\a. The original variable will be unset. Cannot be "
"used with any other options.]"
"moved to \aname\a. The original variable will be unset.]"
"[n?Name reference. The value is the name of a variable that \aname\a "
"references. \aname\a cannot contain a \b.\b. Cannot be used with "
"any other options.]"
"references. \aname\a cannot contain a \b.\b.]"
"[p?Causes the output to be in a format that can be used as input to the "
"shell to recreate the attributes for variables.]"
"[r?Enables readonly. Once enabled it cannot be disabled. See "
@ -1830,6 +1828,9 @@ USAGE_LICENSE
"\n"
"\n[name[=value]...]\n"
" -f [name...]\n"
" -m [name=name...]\n"
" -n [name=name...]\n"
" -T [tname[=(type definition)]...]\n"
"\n"
"[+EXIT STATUS?]{"
"[+0?No errors occurred.]"

View file

@ -50,6 +50,8 @@ const char e_query[] = "no query process";
const char e_history[] = "no history file";
const char e_histopen[] = "cannot open history file";
const char e_option[] = "%s: bad option(s)";
const char e_optincompat1[] = "%s cannot be used with other options";
const char e_optincompat2[] = "%s cannot be used with %s";
const char e_toomany[] = "open file limit exceeded";
const char e_argtype[] = "invalid argument of type %c";
const char e_oneoperand[] = "one operand expected";

View file

@ -230,6 +230,8 @@ extern const Namdisc_t ENUM_disc;
extern char nv_local;
extern Dtdisc_t _Nvdisc;
extern const char *nv_discnames[];
extern const char e_optincompat1[];
extern const char e_optincompat2[];
extern const char e_subscript[];
extern const char e_nullset[];
extern const char e_notset[];

View file

@ -7799,13 +7799,30 @@ cannot be exported.
.PD
.PP
The
.B \-i
attribute cannot be specified along with
.BR \-i ,
.BR \-F ,
.BR \-E ,
and
.B \-X
options cannot be specified along with
.BR \-R ,
.BR \-L ,
.BR \-Z ,
or
.BR \-f .
.BR \-Z .
The
.B \-b
option cannot be specified along with
.BR \-L ,
.BR \-u ,
or
.BR \-l .
The
.BR \-f ,
.BR \-m ,
.BR \-n ,
and
.B \-T
options cannot be used together with any other option.
.PP
Using
.B \+

View file

@ -639,9 +639,6 @@ bar.foo+=(bam)
[[ ${bar.foo[0]} == bam ]] || err_exit 'appending to empty array variable in type does not create element 0'
# ======
# 'typeset -RF' should not create variables that cause crashes
"$SHELL" -c 'typeset -RF foo=1; test $foo' || err_exit 'typeset -RF does not work'
# Type names that have 'a' as the first letter should be functional
"$SHELL" -c 'typeset -T al=(typeset bar); al foo=(bar=testset)' || err_exit "type names that start with 'a' don't work"