diff --git a/ANNOUNCE b/ANNOUNCE index 249f349778e5..144c8e2bd0da 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -23,6 +23,10 @@ New shell language features: after the decimal point if the TIMEFORAMT variable is not set. See also TIMEFORMAT under 'New features in shell variables' below. +- With in 'typeset -T' type declarations, the '_' automatic self-reference + variable now always refers to the type variable, even within discipline + function (such as .get or .getn) that are set for its subvariables. + New features in built-in commands: - When printing a function definition, 'typeset -f function_name' now diff --git a/NEWS b/NEWS index 9b2105139d17..b90627569873 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,16 @@ This documents significant changes in the dev branch of ksh 93u+m. For full details, see the git log at: https://github.com/ksh93/ksh Uppercase BUG_* IDs are shell bug IDs as used by the Modernish shell library. +2024-08-26: + +- [v1.1] Backported a change to '_' in types from the unreleased ksh 93v- + beta. If a 'typeset -T' type declaration sets a discipline function for + one of its subvariables (such as var.get() or var.getn()), then, within + that discipline function, the automatic '_' nameref now refers to the type + variable and no longer to the subvariable that the discipline function was + set for. This means '_' now always refers to the type variable when used + in a type declaration. + 2024-08-22: - Fixed: command lines containing certain specific kinds of syntax error diff --git a/src/cmd/ksh93/COMPATIBILITY b/src/cmd/ksh93/COMPATIBILITY index d3ad785990b5..ae20c2cbe9db 100644 --- a/src/cmd/ksh93/COMPATIBILITY +++ b/src/cmd/ksh93/COMPATIBILITY @@ -19,6 +19,13 @@ For more details, see the NEWS file and for complete details, see the git log. limited to two hexadecimal digits (yielding one byte). For multi-byte characters, \u and \U should be used instead. +5. If a 'typeset -T' type declaration sets a discipline function for + one of its subvariables (such as var.get() or var.getn()), then, + within that discipline function, the automatic '_' nameref now + refers to the type variable and no longer to the subvariable that + the discipline function was set for. This means '_' now always + refers to the type variable when used in a type declaration. + ____________________________________________________________________________ ksh 93u+m/1.0.9 vs. ksh 93u+ diff --git a/src/cmd/ksh93/include/name.h b/src/cmd/ksh93/include/name.h index a9885afab12f..bdc29943b7dd 100644 --- a/src/cmd/ksh93/include/name.h +++ b/src/cmd/ksh93/include/name.h @@ -216,6 +216,7 @@ extern void nv_outnode(Namval_t*,Sfio_t*, int, int); extern int nv_subsaved(Namval_t*, int); extern void nv_typename(Namval_t*, Sfio_t*); extern void nv_newtype(Namval_t*); +extern Namval_t *nv_typeparent(Namval_t*); extern int nv_istable(Namval_t*); extern size_t nv_datasize(Namval_t*, size_t*); extern Namfun_t *nv_mapchar(Namval_t*, const char*); diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 8060854e19ce..9866597f4a8e 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -18,7 +18,7 @@ #define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */ #define SH_RELEASE_SVER "1.1.0-alpha" /* semantic version number: https://semver.org */ -#define SH_RELEASE_DATE "2024-08-23" /* must be in this format for $((.sh.version)) */ +#define SH_RELEASE_DATE "2024-08-26" /* must be in this format for $((.sh.version)) */ #define SH_RELEASE_CPYR "(c) 2020-2024 Contributors to ksh " SH_RELEASE_FORK /* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */ diff --git a/src/cmd/ksh93/sh.1 b/src/cmd/ksh93/sh.1 index b979916bb701..38b69c923cdb 100644 --- a/src/cmd/ksh93/sh.1 +++ b/src/cmd/ksh93/sh.1 @@ -1682,7 +1682,10 @@ file when checking for mail. While defining a compound variable or a type, .B _ is initialized as a reference to the compound variable or type. -When a discipline function is invoked, +When a discipline function is invoked +for a variable that is not a type subvariable in the sense of +.I "Type Variables"\^ +below, then .B _ is initialized as a reference to the variable associated with the call to this function. @@ -4208,7 +4211,9 @@ is the subscript of the variable, and will contain the value being assigned inside the .B set discipline function. -The variable +If the variable is not a type subvariable in the sense of +.I "Type Variables"\^ +below, then the variable .B _ is a reference to the variable including the subscript if any. For the \f3set\fP discipline, diff --git a/src/cmd/ksh93/sh/nvtype.c b/src/cmd/ksh93/sh/nvtype.c index 378f3e2ff79c..34fc9f2f75f2 100644 --- a/src/cmd/ksh93/sh/nvtype.c +++ b/src/cmd/ksh93/sh/nvtype.c @@ -1469,3 +1469,14 @@ int sh_outtype(Sfio_t *out) dtinsert(sh.var_base,L_ARGNOD); return 0; } + +Namval_t *nv_typeparent(Namval_t *np) +{ + Namchld_t *fp; + Namtype_t *tp; + if(fp = (Namchld_t*)nv_hasdisc(np,&chtype_disc)) + return fp->ptype->parent; + if(tp = (Namtype_t*)nv_hasdisc(np,&type_disc)) + return tp->parent; + return NULL; +} diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index d73877abda5b..d48b72dc390b 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -715,6 +715,8 @@ static long set_instance(Namval_t *nq, Namval_t *node, struct Namref *nr) Namval_t *np; if(!nv_isattr(nq,NV_MINIMAL|NV_EXPORT|NV_ARRAY) && (np = nq->nvmeta) && nv_isarray(np)) nq = np; + else if(nv_isattr(nq,NV_MINIMAL)==NV_MINIMAL && !nv_type(nq) && (np = nv_typeparent(nq))) + nq = np; cp = nv_name(nq); memset(nr,0,sizeof(*nr)); nr->np = nq; diff --git a/src/cmd/ksh93/tests/types.sh b/src/cmd/ksh93/tests/types.sh index a554d963bb02..30d61721eb27 100755 --- a/src/cmd/ksh93/tests/types.sh +++ b/src/cmd/ksh93/tests/types.sh @@ -851,5 +851,32 @@ exp=$'( typeset TYPEVAR )\nOK' [[ $got == "$exp" ]] || err_exit 'type definition overriding regular built-in' \ "(expected $(printf %q "$exp"), got $(printf %q "$got"))" +# ====== +# As of 93u+m/1.1, _ in types always refers to the type variable, even within a member discipline function. +# Change backported from ksh 93v- 2013-07-27 and 2013-08-29. +case ${.sh.version} in +Version*93u+m/1.0* | Version*93??\ * | Version*93?\ *) + ;; +*) + typeset -T argnod_discfunc_test_t=( + typeset x + integer y=5 + function x.getn + { + ((.sh.value = ++_.y)) + typeset -p _ + } + ) + argnod_discfunc_test_t argnod_discfunc_obj + exp=$'typeset -n _=argnod_discfunc_obj\n6' + got=$(set +x; redirect 2>&1; print -r -- "${argnod_discfunc_obj.x}") + [[ $got == "$exp" ]] || err_exit "_ does not refer to the type variable in a member discipline function" \ + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" + got=$(set +x; redirect 2>&1; print -r -- "$((argnod_discfunc_obj.x))") + [[ $got == "$exp" ]] || err_exit "_ does not refer to the type variable in a member discipline function" \ + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" + ;; +esac + # ====== exit $((Errors<125?Errors:125))