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:
parent
b09ce2fa02
commit
f43bb4981f
2 changed files with 18 additions and 5 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue