From 879ef7e076289ff09d600dc3bb9c29ce441265db Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 19 Jun 2015 14:58:37 +0100 Subject: Expand non-assignment arguments in assign list consistently. --- Src/exec.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- Test/B02typeset.ztst | 2 +- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/Src/exec.c b/Src/exec.c index ef3e85948..967f86e23 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -3485,21 +3485,63 @@ execcmd(Estate state, int input, int output, int how, int last1) state->pc = assignspc; assigns = newlinklist(); while (postassigns--) { - Asgment asg = (Asgment)zhalloc(sizeof(struct asgment)); wordcode ac = *state->pc++; - int htok; char *name = ecgetstr(state, EC_DUPTOK, &htok); + Asgment asg; + int htok; local_list1(svl); DPUTS(wc_code(ac) != WC_ASSIGN, "BUG: bad assignment list for typeset"); if (htok) { init_list1(svl, name); + if (WC_ASSIGN_TYPE(ac) == WC_ASSIGN_SCALAR && + WC_ASSIGN_TYPE2(ac) == WC_ASSIGN_INC) { + char *data; + /* + * Special case: this is a name only, so + * it's not required to be a single + * expansion. Furthermore, for + * consistency with the builtin + * interface, it may expand into + * scalar assignments: + * ass=(one=two three=four) + * typeset a=b $ass + */ + /* Unused dummy value for name */ + (void)ecgetstr(state, EC_DUPTOK, &htok); + prefork(&svl, PREFORK_TYPESET); + if (errflag) { + state->pc = opc; + break; + } + globlist(&svl, 0); + if (errflag) { + state->pc = opc; + break; + } + while ((data = ugetnode(&svl))) { + char *ptr; + asg = (Asgment)zhalloc(sizeof(struct asgment)); + asg->is_array = 0; + if ((ptr = strchr(data, '='))) { + *ptr++ = '\0'; + asg->name = data; + asg->value.scalar = ptr; + } else { + asg->name = data; + asg->value.scalar = NULL; + } + uaddlinknode(assigns, &asg->node); + } + continue; + } prefork(&svl, PREFORK_SINGLE); - name= empty(&svl) ? "" : + name = empty(&svl) ? "" : (char *)getdata(firstnode(&svl)); } untokenize(name); + asg = (Asgment)zhalloc(sizeof(struct asgment)); asg->name = name; if (WC_ASSIGN_TYPE(ac) == WC_ASSIGN_SCALAR) { char *val = ecgetstr(state, EC_DUPTOK, &htok); diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst index 57a7caa12..1819b6c84 100644 --- a/Test/B02typeset.ztst +++ b/Test/B02typeset.ztst @@ -231,7 +231,7 @@ typeset -T THIS will not work 1:Tied array syntax -?(eval):typeset:1: -T requires names of scalar and array +?(eval):typeset:1: too many arguments for -T local array[2]=x 1:Illegal local array element assignment -- cgit 1.4.1