diff --git a/NEWS b/NEWS index 37ce55414..6ffeb9b04 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,13 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2020-07-15: + +- The 'autoload', 'compound', 'float', 'functions', 'integer' and 'nameref' + default aliases have been converted into regular built-in commands, so + that 'unalias -a' does not remove them. Shell functions can now use + these names, which improves compatibility with POSIX shell scripts. + 2020-07-14: - Fixed a bug that caused 'set -b' to have no effect. diff --git a/src/cmd/ksh93/bltins/typeset.c b/src/cmd/ksh93/bltins/typeset.c index a46617726..3fe074f10 100644 --- a/src/cmd/ksh93/bltins/typeset.c +++ b/src/cmd/ksh93/bltins/typeset.c @@ -210,16 +210,39 @@ int b_typeset(int argc,register char *argv[],Shbltin_t *context) Namdecl_t *ntp = (Namdecl_t*)context->ptr; Dt_t *troot; int isfloat=0, shortint=0, sflag=0; - NOT_USED(argc); + char *new_argv[argc + 1]; + memset((void*)&tdata,0,sizeof(tdata)); tdata.sh = context->shp; - if(ntp) + troot = tdata.sh->var_tree; + if(ntp) /* custom declaration command added using enum */ { tdata.tp = ntp->tp; opt_info.disc = (Optdisc_t*)ntp->optinfof; optstring = ntp->optstring; } - troot = tdata.sh->var_tree; + else if(argv[0][0] != 't') /* not ypeset */ + { + new_argv[0] = "typeset"; + if(argv[0][0] == 'a') /* utoload == typeset -fu */ + new_argv[1] = "-fu"; + else if(argv[0][0] == 'c') /* ompound == typeset -C */ + new_argv[1] = "-C"; + else if(argv[0][1] == 'l') /* foat == typeset -lE */ + new_argv[1] = "-lE"; + else if(argv[0][1] == 'u') /* fnctions == typeset -f */ + new_argv[1] = "-f"; + else if(argv[0][0] == 'i') /* nteger == typeset -li */ + new_argv[1] = "-li"; + else if(argv[0][0] == 'n') /* ameref == typeset -n */ + new_argv[1] = "-n"; + else + errormsg(SH_DICT, ERROR_exit(128), "internal error"); + for (n = 1; n <= argc; n++) + new_argv[n + 1] = argv[n]; + argc++; + argv = new_argv; + } while((n = optget(argv,optstring))) { if(tdata.aflag==0) diff --git a/src/cmd/ksh93/data/aliases.c b/src/cmd/ksh93/data/aliases.c index 10192e0bc..734c7574c 100644 --- a/src/cmd/ksh93/data/aliases.c +++ b/src/cmd/ksh93/data/aliases.c @@ -29,13 +29,7 @@ const struct shtable2 shtab_aliases[] = { - "autoload", NV_NOFREE, "typeset -fu", - "compound", NV_NOFREE|BLT_DCL, "typeset -C", - "float", NV_NOFREE|BLT_DCL, "typeset -lE", - "functions", NV_NOFREE, "typeset -f", "history", NV_NOFREE, "hist -l", - "integer", NV_NOFREE|BLT_DCL, "typeset -li", - "nameref", NV_NOFREE|BLT_DCL, "typeset -n", "r", NV_NOFREE, "hist -s", "", 0, (char*)0 }; diff --git a/src/cmd/ksh93/data/builtins.c b/src/cmd/ksh93/data/builtins.c index e93cec0ba..8d4e9ea54 100644 --- a/src/cmd/ksh93/data/builtins.c +++ b/src/cmd/ksh93/data/builtins.c @@ -68,6 +68,12 @@ const struct shtable3 shtab_builtins[] = "break", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(break), "continue", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(break), "typeset", NV_BLTIN|BLT_ENV|BLT_SPC|BLT_DCL,bltin(typeset), + "autoload", NV_BLTIN|BLT_ENV, bltin(typeset), + "compound", NV_BLTIN|BLT_ENV|BLT_DCL, bltin(typeset), + "float", NV_BLTIN|BLT_ENV|BLT_DCL, bltin(typeset), + "functions", NV_BLTIN|BLT_ENV, bltin(typeset), + "integer", NV_BLTIN|BLT_ENV|BLT_DCL, bltin(typeset), + "nameref", NV_BLTIN|BLT_ENV|BLT_DCL, bltin(typeset), "test", NV_BLTIN|BLT_ENV, bltin(test), "[", NV_BLTIN|BLT_ENV, bltin(test), "let", NV_BLTIN|BLT_ENV, bltin(let), @@ -1745,29 +1751,30 @@ USAGE_LICENSE ; const char sh_opttypeset[] = -"+[-1c?\n@(#)$Id: typeset (AT&T Research) 2010-12-08 $\n]" +"+[-1c?\n@(#)$Id: typeset (AT&T Research/ksh93) 2020-07-15 $\n]" USAGE_LICENSE -"[+NAME?\f?\f - declare or display variables with attributes]" -"[+DESCRIPTION?Without the \b-f\b option, \b\f?\f\b sets, unsets, " +"[+NAME?typeset - declare or display variables with attributes]" +"[+DESCRIPTION?Without the \b-f\b option, \btypeset\b sets, unsets, " "or displays attributes of variables as specified with the " "options. If the first option is specified with a \b-\b " "then the attributes are set for each of the given \aname\as. " "If the first option is specified with a \b+\b, then the specified " "attributes are unset. If \b=\b\avalue\a is specified value is " "assigned before the attributes are set.]" -"[+?When \b\f?\f\b is called inside a function defined with the " +"[+?When \btypeset\b is called inside a function defined with the " "\bfunction\b reserved word, and \aname\a does not contain a " "\b.\b, then a local variable statically scoped to that function " "will be created.]" "[+?Not all option combinations are possible. For example, the numeric " "options \b-i\b, \b-E\b, and \b-F\b cannot be specified with " "the justification options \b-L\b, \b-R\b, and \b-Z\b.]" -"[+?Note that the following preset aliases are set by the shell:]{" - "[+compound?\b\f?\f -C\b.]" - "[+float?\b\f?\f -lE\b.]" - "[+functions?\b\f?\f -f\b.]" - "[+integer?\b\f?\f -li\b.]" - "[+nameref?\b\f?\f -n\b.]" +"[+?Note also the following builtin command equivalents:]{" + "[+autoload?\btypeset -fu\b]" + "[+compound?\btypeset -C\b]" + "[+float?\btypeset -lE\b]" + "[+functions?\btypeset -f\b]" + "[+integer?\btypeset -li\b]" + "[+nameref?\btypeset -n\b]" "}" "[+?If no \aname\as are specified then variables that have the specified " "options are displayed. If the first option is specified with " @@ -1780,7 +1787,7 @@ USAGE_LICENSE "[+?If \b-f\b is specified, then each \aname\a refers to a function " "and the only valid options are \b-u\b and \b-t\b. In this " "case no \b=\b\avalue\a can be specified.]" -"[+?\b\f?\f\b is built-in to the shell as a declaration command so that " +"[+?\btypeset\b is built in to the shell as a declaration command so that " "field splitting and pathname expansion are not performed on " "the arguments. Tilde expansion occurs on \avalue\a.]" #if 1 diff --git a/src/cmd/ksh93/include/builtins.h b/src/cmd/ksh93/include/builtins.h index f1d356a30..76d3a79f9 100644 --- a/src/cmd/ksh93/include/builtins.h +++ b/src/cmd/ksh93/include/builtins.h @@ -41,16 +41,25 @@ #define SYSCD (shgd->bltin_cmds+6) /* cd */ #define SYSBREAK (shgd->bltin_cmds+7) /* break */ #define SYSCONT (shgd->bltin_cmds+8) /* continue */ -#define SYSTYPESET (shgd->bltin_cmds+9) /* typeset */ -#define SYSTEST (shgd->bltin_cmds+10) /* test */ -#define SYSBRACKET (shgd->bltin_cmds+11) /* [ */ -#define SYSLET (shgd->bltin_cmds+12) /* let */ -#define SYSEXPORT (shgd->bltin_cmds+13) /* export */ -#define SYSDOT (shgd->bltin_cmds+14) /* . */ -#define SYSSOURCE (shgd->bltin_cmds+15) /* source */ -#define SYSRETURN (shgd->bltin_cmds+16) /* return */ + +#define SYSTYPESET (shgd->bltin_cmds+9) /* typeset \ */ + /* autoload | */ +#define SYSCOMPOUND (shgd->bltin_cmds+11) /* compound | */ + /* float >typeset range */ + /* functions | */ + /* integer | */ +#define SYSNAMEREF (shgd->bltin_cmds+15) /* nameref | */ +#define SYSTYPESET_END (shgd->bltin_cmds+15) /* / */ + +#define SYSTEST (shgd->bltin_cmds+16) /* test */ +#define SYSBRACKET (shgd->bltin_cmds+17) /* [ */ +#define SYSLET (shgd->bltin_cmds+18) /* let */ +#define SYSEXPORT (shgd->bltin_cmds+19) /* export */ +#define SYSDOT (shgd->bltin_cmds+20) /* . */ +#define SYSSOURCE (shgd->bltin_cmds+21) /* source */ +#define SYSRETURN (shgd->bltin_cmds+22) /* return */ #if SHOPT_BASH -# define SYSLOCAL (shgd->bltin_cmds+17) /* local */ +# define SYSLOCAL (shgd->bltin_cmds+23) /* local */ #else # define SYSLOCAL 0 #endif diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 8879bb3b5..3b21968c7 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -17,4 +17,4 @@ * David Korn * * * ***********************************************************************/ -#define SH_RELEASE "93u+m 2020-07-14" +#define SH_RELEASE "93u+m 2020-07-15" diff --git a/src/cmd/ksh93/sh.1 b/src/cmd/ksh93/sh.1 index 38ba1b5d4..000aad38e 100644 --- a/src/cmd/ksh93/sh.1 +++ b/src/cmd/ksh93/sh.1 @@ -788,20 +788,8 @@ but can be unset or redefined: .RS 20 .PD 0 .TP -.B "autoload=\(fmtypeset \-fu\(fm" -.TP -.B "compound=\(fmtypeset \-C\(fm" -.TP -.B "float=\(fmtypeset \-lE\(fm" -.TP -.B "functions=\(fmtypeset \-f\(fm" -.TP .B "history=\(fmhist \-l\(fm" .TP -.B "integer=\(fmtypeset \-li\(fm" -.TP -.B "nameref=\(fmtypeset \-n\(fm" -.TP .B "r=\(fmhist \-s\(fm" .PD .RE @@ -5476,10 +5464,10 @@ section from their manual page, and as a request to print a brief usage message. All these are printed on standard error. There are advanced output options as well; see -.B getopts --man +.B getopts \-\-man for more information. .PP -Commands that are preceded by one or two \(dg symbols below are +Commands that are preceded by a \(dg symbol below are .I special\ built-in\ commands and are treated specially in the following ways: .PD 0 @@ -5498,10 +5486,10 @@ that contains them to abort. .TP 4. They are not valid function names. -.TP -5. -Words -following a command preceded by \(dg\(dg +.PP +Commands that are preceded by a \(dd symbol below are +.IR declaration\ commands . +Any following words that are in the format of a variable assignment are expanded with the same rules as a variable assignment. This means that @@ -5509,9 +5497,6 @@ tilde substitution is performed after the .B = sign and field splitting and file name generation are not performed. -These are called -.I declaration\^ -built-ins. .PD .TP \(dg \f3:\fP \*(OK \f2arg\^\fP .\|.\|. \*(CK @@ -5600,6 +5585,12 @@ The exit status is non-zero if a is given, but no value, and no alias has been defined for the .IR name\^ . .TP +\f3autoload\fP \f2name\^\fP .\|.\|. +Marks each \f2name\fP undefined so that the \f3FPATH\fP variable will be +searched to find the function definition when the function is referenced. +The same as +.BR typeset\ \-fu . +.TP \f3bg\fP \*(OK \f2job\^\fP.\|.\|. \*(CK This command is only on systems that support job control. Puts each specified @@ -5830,6 +5821,13 @@ option causes to act like .BR "whence \-v" . .TP +\(dd \f3compound\fP \f2vname\fP\*(OK\f3=\fP\f2value\^\fP\*(CK .\|.\|. +Causes each +.I vname\^ +to be a compound variable. +The same as +.BR typeset\ \-C . +.TP \(dg \f3continue\fP \*(OK \f2n\^\fP \*(CK Resume the next iteration of the enclosing .BR for\^ , @@ -5874,7 +5872,7 @@ See .IR echo (1) for usage and description. .TP -\(dg\(dg \f3enum\fP \*(OK \f3\-i\fP \*(CK \f2type\^\fP\*(OK=(\f2value\^\fP .\|.\|.) \*(CK +\(dd \f3enum\fP \*(OK \f3\-i\fP \*(CK \f2type\^\fP\*(OK=(\f2value\^\fP .\|.\|.) \*(CK Creates a declaration command named \f2type\^\fP that is an integer type that allows one of the specified \f2value\fPs as enumeration names. If \f3=(\fP\f2value\^\ .\|.\|.\|\fP\f3)\fP is @@ -5883,6 +5881,8 @@ least two elements and the values are taken from this array variable. If .B -i is specified the values are case insensitive. +Declaration commands are created as special builtins that cannot be +removed or overridden by shell functions. .TP \(dg \f3eval\fP \*(OK \f2arg\^\fP .\|.\|. \*(CK The arguments are read as input @@ -5934,7 +5934,7 @@ option (see .B set below) turned on. .TP -\(dg\(dg \f3export\fP \*(OK \f3\-p\fP \*(CK \*(OK \f2name\^\fP\*(OK\f3=\fP\f2value\^\fP\*(CK \*(CK .\|.\|. +\(dg\(dd \f3export\fP \*(OK \f3\-p\fP \*(CK \*(OK \f2name\^\fP\*(OK\f3=\fP\f2value\^\fP\*(CK \*(CK .\|.\|. If .I name\^ is not given, @@ -5988,6 +5988,16 @@ See for a description of the format of .IR job . .TP +\(dd \f3float\fP \f2vname\fP\*(OK\f3=\fP\f2value\^\fP\*(CK .\|.\|. +Declares each \f2vname\fP to be a long floating point number. +The same as +.BR typeset\ \-lE . +.TP +\f3functions\fP \*(OK \f3\-Stux\^\fP \*(CK \*(OK \f2name\^\fP .\|.\|. \*(CK +Lists functions. +The same as +.BR typeset\ \-f . +.TP \f3getconf\fP \*(OK \f2name\^\fP \*(OK \f2pathname\^\fP \*(CK \*(CK Prints the current value of the configuration parameter given by .IR name . @@ -6201,6 +6211,11 @@ after the optional substitution \f2old\^\fP\f3=\fP\f2new\^\fP is performed. .TP +\(dd \f3integer\fP \f2vname\fP\*(OK\f3=\fP\f2value\^\fP\*(CK .\|.\|. +Declares each \f2vname\fP to be a long integer number. +The same as +.BR typeset\ \-li . +.TP \f3jobs\fP \*(OK \f3\-lnp\^\fP \*(CK \*(OK \f2job\^\fP \.\|.\|. \*(CK Lists information about each given job; or all active jobs if .I job @@ -6302,6 +6317,11 @@ The exit status is 0 if the value of the last expression is non-zero, and 1 otherwise. .TP +\(dd \f3nameref\fP \f2vname\fP\*(OK\f3=\fP\f2refname\^\fP\*(CK .\|.\|. +Declares each \f2vname\fP to be a variable name reference. +The same as +.BR typeset\ \-n . +.TP \f3print\fP \*(OK \f3\-CRenprsv\^\fP \*(CK \*(OK \f3\-u\fP \f2unit \^\fP\*(CK \*(OK \f3\-f\fP \f2format\^\fP \*(CK \*(OK \f2arg\^\fP .\|.\|. \*(CK With no options or with option .B \- @@ -6730,7 +6750,7 @@ or .B read has timed out. .TP -\(dg\(dg \f3readonly\fP \*(OK \f3\-p\fP \*(CK \*(OK \f2vname\fP\*(OK\f3=\fP\f2value\^\fP\*(CK \*(CK .\|.\|. +\(dg\(dd \f3readonly\fP \*(OK \f3\-p\fP \*(CK \*(OK \f2vname\fP\*(OK\f3=\fP\f2value\^\fP\*(CK \*(CK .\|.\|. If .I vname\^ is not given, @@ -7299,9 +7319,9 @@ for infinite loops. .TP \f3type\fP \*(OK \f3\-afp\fP \*(CK \f2name\^\fP .\|.\|. The same as -.BR whence\ -v . +.BR whence\ \-v . .TP -\(dg\(dg \f3typeset\fP \*(OK \f3\(+-ACHSfblmnprtux\^\fP \*(CK \*(OK \f3\(+-EFLRXZi\*(OK\f2n\^\fP\*(CK \*(CK \*(OK \f3\+-M \*(OK \f2mapname\fP \*(CK \*(CK \*(OK \f3\-T \*(OK \f2tname\fP=(\f2assign_list\fP) \*(CK \*(CK \*(OK \f3\-h \f2str\fP \*(CK \*(OK \f3\-a\fP \*(OK\f2type\fP\*(CK \*(CK \*(OK \f2vname\^\fP\*(OK\f3=\fP\f2value\^\fP \*(CK \^ \*(CK .\|.\|. +\(dg\(dd \f3typeset\fP \*(OK \f3\(+-ACHSfblmnprtux\^\fP \*(CK \*(OK \f3\(+-EFLRXZi\*(OK\f2n\^\fP\*(CK \*(CK \*(OK \f3\+-M \*(OK \f2mapname\fP \*(CK \*(CK \*(OK \f3\-T \*(OK \f2tname\fP=(\f2assign_list\fP) \*(CK \*(CK \*(OK \f3\-h \f2str\fP \*(CK \*(OK \f3\-a\fP \*(OK\f2type\fP\*(CK \*(CK \*(OK \f2vname\^\fP\*(OK\f3=\fP\f2value\^\fP \*(CK \^ \*(CK .\|.\|. Sets attributes and values for shell variables and functions. When invoked inside a function defined with the .B function @@ -7326,9 +7346,9 @@ expressions. .B \-C causes each .I vname\^ -to be a compound variable. +to be a compound variable. If .I value\^ -names a compound variable it is copied into +names a compound variable, it is copied into .IR vname . Otherwise, it unsets each .IR vname . diff --git a/src/cmd/ksh93/sh/parse.c b/src/cmd/ksh93/sh/parse.c index 9f07e552a..f1ee9528b 100644 --- a/src/cmd/ksh93/sh/parse.c +++ b/src/cmd/ksh93/sh/parse.c @@ -1478,7 +1478,7 @@ static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io) if(nv_isattr(np,BLT_DCL)) { assignment = 1; - if(np==SYSTYPESET) + if(np >= SYSTYPESET && np <= SYSTYPESET_END) lexp->intypeset = 1; key_on = 1; } @@ -1517,7 +1517,9 @@ static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io) int intypeset = lexp->intypeset; int type = 0; lexp->intypeset = 0; - if(t->comnamp==SYSTYPESET) + if(t->comnamp == SYSCOMPOUND) + type = NV_COMVAR; + else if((Namval_t*)t->comnamp >= SYSTYPESET && (Namval_t*)t->comnamp <= SYSTYPESET_END) { struct argnod *ap; for(ap=t->comarg->argnxt.ap;ap;ap=ap->argnxt.ap) diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index 87089bec2..e8b948763 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -1295,20 +1295,21 @@ int sh_exec(register const Shnode_t *t, int flags) } #endif /* SHOPT_BASH */ - if(np==SYSTYPESET || (np && np->nvalue.bfp==SYSTYPESET->nvalue.bfp)) + if(np && np->nvalue.bfp==SYSTYPESET->nvalue.bfp) { - if(np!=SYSTYPESET) + /* command calls b_typeset(); treat as a typeset variant */ + if(np < SYSTYPESET || np > SYSTYPESET_END) { shp->typeinit = np; tp = nv_type(np); } - if(checkopt(com,'C')) + if(np==SYSCOMPOUND || checkopt(com,'C')) flgs |= NV_COMVAR; if(checkopt(com,'S')) flgs |= NV_STATIC; if(checkopt(com,'m')) flgs |= NV_MOVE; - if(checkopt(com,'n')) + if(np==SYSNAMEREF || checkopt(com,'n')) flgs |= NV_NOREF; #if SHOPT_TYPEDEF else if(argn>=3 && checkopt(com,'T')) diff --git a/src/cmd/ksh93/tests/variables.sh b/src/cmd/ksh93/tests/variables.sh index 60554282d..c6e8c4203 100755 --- a/src/cmd/ksh93/tests/variables.sh +++ b/src/cmd/ksh93/tests/variables.sh @@ -496,8 +496,9 @@ chmod +x $tmp/script ) TIMEFORMAT='this is a test' [[ $(set +x; { { time :;} 2>&1;}) == "$TIMEFORMAT" ]] || err_exit 'TIMEFORMAT not working' +alias _test_alias=true : ${.sh.version} -[[ $(alias integer) == *.sh.* ]] && err_exit '.sh. prefixed to alias name' +[[ $(alias _test_alias) == *.sh.* ]] && err_exit '.sh. prefixed to alias name' : ${.sh.version} [[ $(whence rm) == *.sh.* ]] && err_exit '.sh. prefixed to tracked alias name' : ${.sh.version}