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

Fix 'command' prefix in enum type def pre-parsing (re: 1dc18346)

Symptom:

$ ksh -c 'command enum -i P_t=(a b); P_t -A v=([f]=b); typeset -p v'
ksh: syntax error at line 1: `(' unexpected

Expected: no syntax error, and output of 'P_t -A v=([f]=b)'.

src/cmd/ksh93/sh/parse.c: check_typedef():
- For enum, skip over any possible 'command' prefixes before
  pre-parsing options with optget (or, technically, skip anything
  else that might come before 'enum', though I don't think anything
  else is possible).
- The sh_addbuiltin() call at the end to pre-add the builtin
  obtained the node pointer to the built-in and the node flags from
  the parser tree. This did not work if a 'command' prefix was
  present. However, we don't actually need this. For parsing
  purposes, the BLT_DCL flag for a declaration built-in is
  sufficient; this is what gets the parser to accept
  assignment-arguments including parentheses. So just apply that.
  In addition, let's point it to an actual dummy built-in, 'true'
  (SYSTRUE), so that if a user does run something like 'if false;
  then enum Foo_t=(...); fi', the leaked Foo_t dummy at least won't
  do anything (not even crash).
This commit is contained in:
Martijn Dekker 2021-11-28 00:31:46 +01:00
parent c9ca0ff531
commit 43cd8da2fe
2 changed files with 14 additions and 5 deletions

View file

@ -222,6 +222,9 @@ static void check_typedef(struct comnod *tp, char intypeset)
char **argv = dp->dolval + ARG_SPARE;
if(intypeset==2)
{
/* Skip over possible 'command' prefix(es) */
while(*argv && strcmp(*argv, SYSENUM->nvname))
argv++;
/* Skip over 'enum' options */
opt_info.index = 0;
while(optget(argv, sh_optenum))
@ -245,11 +248,7 @@ static void check_typedef(struct comnod *tp, char intypeset)
}
}
if(cp)
{
Namval_t *mp=(Namval_t*)tp->comnamp ,*bp;
bp = sh_addbuiltin(cp, (Shbltin_f)mp->nvalue.bfp, (void*)0);
nv_onattr(bp,nv_isattr(mp,NV_PUBLIC));
}
nv_onattr(sh_addbuiltin(cp, (Shbltin_f)SYSTRUE->nvalue.bfp, NIL(void*)), NV_BLTIN|BLT_DCL);
}
/*

View file

@ -146,5 +146,15 @@ a=orange; let "a+=2" 2>/dev/null && err_exit "arithmetic can assign out of range
a=green; let "a-=2" 2>/dev/null && err_exit "arithmetic can assign out of range (subtract)"
a=blue; let "a*=3" 2>/dev/null && err_exit "arithmetic can assign out of range (multiply)"
# ======
# Enum types should parse with 'command' prefix(es) and options and instantly
# recognise subsequent builtins it creates, even as a oneliner, even with
# shcomp. (This requires an ugly parser hack that this tests for.)
got=$(eval 2>&1 'command command command enum -i -i -iii --igno -ii PARSER_t=(r g b); '\
'command command PARSER_t -r -rrAAA -A -rArArA -Arrrrrrr hack=([C]=G); typeset -p hack')
exp='PARSER_t -r -A hack=([C]=g)'
[[ $got == "$exp" ]] || err_exit "incorrect typeset output for enum with command prefix and options" \
"(expected $(printf %q "$exp"); got $(printf %q "$got"))"
# ======
exit $((Errors<125?Errors:125))