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

New feature: 'typeset -g' as in bash 4.2+

typeset -g allows directly manipulating the attributes of variables
at the global level from any context. This feature already exists
on bash 4.2 and later.

mksh (R50+), yash and zsh have this flag as well, but it's slightly
different: it ignores the current local scope, but a parent local
scope from a calling function may still be used -- whereas on bash,
'-g' always refers to the global scope. Since ksh93 uses static
scoping (see III.Q28 at <http://kornshell.com/doc/faq.html>), only
the bash behaviour makes sense here.

Note that the implementation needs to be done both in nv_setlist()
(name.c) and in b_typeset() (typeset.c) because assignments are
executed before the typeset built-in itself. Hence also the
pre-parsing of typeset options in sh_exec().

src/cmd/ksh93/include/nval.h:
- Add new NV_GLOBAL bit flag, using a previously unused bit that
  still falls within the 32-bit integer range.

src/cmd/ksh93/sh/xec.c: sh_exec():
- When pre-parsing typeset flags, make -g pass the NV_GLOBAL flag
  to the nv_setlist() call that processes shell assignments prior
  to running the command.

src/cmd/ksh93/sh/name.c: nv_setlist():
- When the NV_GLOBAL bit flag is passed, save the current variable
  tree pointer (sh.var_tree) as well as the current namespace
  (sh.namespace) and temporarily set the former to the global
  variable tree (sh.var_base) and the latter to NULL. This makes
  assignments global and ignores namesapces.

src/cmd/ksh93/bltins/typeset.c:
- b_typeset():
  - Use NV_GLOBAL bit flag for -g.
  - Allow combining -n with -g, permitting 'typeset -gn var' or
    'nameref -g var' to create a global nameref from a function.
  - Do not allow a nonsensical use of -g when using nested typeset
    to define member variables of 'typeset -T' types. (Type method
    functions can still use it as normal.)
- setall():
  - If NV_GLOBAL is passed, use sh.var_base and deactivate
    sh.namespace as in nv_setlist(). This allows attributes
    to be set correctly for global variables.

src/cmd/ksh93/tests/{functions,namespace}.sh:
- Add regression tests based on reproducers for problems found
  by @hyenias in preliminary versions of this feature.

Resolves: https://github.com/ksh93/ksh/issues/479
This commit is contained in:
Martijn Dekker 2022-06-01 17:14:51 +01:00
parent f73b8617dd
commit ea300089a1
11 changed files with 167 additions and 8 deletions

View file

@ -184,6 +184,7 @@ struct Namval
#define NV_NOSCOPE 0x80000 /* look only in current scope */
#define NV_NOFAIL 0x100000 /* return 0 on failure, no msg */
#define NV_NODISC NV_IDENT /* ignore disciplines */
#define NV_GLOBAL 0x20000000 /* create global variable, ignoring local scope */
#define NV_FUNCT NV_IDENT /* option for nv_create */
#define NV_BLTINOPT NV_ZFILL /* mark builtins in libcmd */