1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-13 19:52:20 +00:00

Improve custom type declaration command parsing (re: c5018f7c)

dcl_dehacktivate() actually left a bit of inconsistent state beyond
the current line because it did not clear the dummy builtins tree.
This caused assignments to variables of types whose definitions
were parsed but not executed to throw a "not found" error instead
of a syntax error, even beyond the current line.

There is also an opportunity for an optimisation. We do not need to
initialise and maintain the dummy builtins tree if we're never
going to use it. So move that to the check_typedef() function right
before the sh_addbuiltin() call: check there if the tree exists and
if not create it and open a view. If no 'typeset -T' or 'enum'
type definition command is executed, the tree is never created.

dcl_hacktivate() now basically does nothing until the tree is
needed, but it does still count the recursion level and install the
error_info.exit hook because we need this to dcl_dehacktivate() at
the correct time when the tree does exist.

dcl_dehacktivate() is amended to clear the tree -- except if we're
running shcomp, as shcomp parses the script line by line without
executing anything, so we need the dummies to persist beyond the
sh_parse() invocation for the entire script. (Note that we do not
need this workaround for dot scripts or noexec mode, as the script
is entirely parsed in a single sh_parse() call in those cases.)
This commit is contained in:
Martijn Dekker 2022-02-18 03:06:37 +00:00
parent b09ce2fa02
commit f43bb4981f
2 changed files with 18 additions and 5 deletions

View file

@ -234,7 +234,14 @@ static void check_typedef(struct comnod *tp, char intypeset)
}
}
if(cp)
{
if(!dcl_tree)
{
dcl_tree = dtopen(&_Nvdisc, Dtoset);
dtview(sh.bltin_tree, dcl_tree);
}
nv_onattr(sh_addbuiltin(cp, (Shbltin_f)SYSTRUE->nvalue.bfp, NIL(void*)), NV_BLTIN|BLT_DCL);
}
}
/*
* (De)activate an internal declaration built-ins tree into which check_typedef() can pre-add dummy type
@ -250,8 +257,7 @@ static void dcl_hacktivate(void)
{
if(dcl_recursion++)
return;
if(!dcl_tree)
dcl_tree = dtopen(&_Nvdisc, Dtoset);
if(dcl_tree)
dtview(sh.bltin_tree, dcl_tree);
orig_exit = error_info.exit;
error_info.exit = dcl_exit;
@ -261,7 +267,12 @@ static void dcl_dehacktivate(void)
if(!dcl_recursion || --dcl_recursion)
return;
error_info.exit = orig_exit;
if(dcl_tree)
{
dtview(sh.bltin_tree, NIL(Dt_t*));
if(!sh.shcomp)
dtclear(dcl_tree);
}
}
static noreturn void dcl_exit(int e)
{

View file

@ -658,6 +658,8 @@ if false
then typeset -T PARSER_t=(typeset name=foobar)
fi
PATH=/dev/null command -v PARSER_t >/dev/null && err_exit "PARSER_t incompletely defined though definition was never executed"
(PATH=/dev/null eval 'PARSER_t x=(name=y)') 2>/dev/null
(($?==3)) || err_exit "PARSER_t assignment not a syntax error though definition was never executed"
unset v
got=$( set +x; redirect 2>&1; typeset -T Subsh_t=(typeset -i x); Subsh_t -a v=( (x=1) (x=2) (x=3) ); typeset -p v )
@ -675,7 +677,7 @@ exp=': trap: is a special shell builtin'
# ======
# Bugs involving scripts without a #! path
# Hashbangless scripts are execeuted in a reinitialised fork of ksh, which is very bug-prone.
# Hashbangless scripts are executed in a reinitialised fork of ksh, which is very bug-prone.
# https://github.com/ksh93/ksh/issues/350
# Some of these fixed bugs don't involve types at all, but the tests need to go somewhere.
# Plus, invoking these from an environment with a bunch of types defined is an additional test.