diff options
Diffstat (limited to 'Src/subst.c')
-rw-r--r-- | Src/subst.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/Src/subst.c b/Src/subst.c index b77dbd4a4..422c9c4e9 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -718,10 +718,12 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) int copied = 0; int arrasg = 0; int eval = 0; + int aspar = 0; int nojoin = 0; char inbrace = 0; /* != 0 means ${...}, otherwise $... */ char hkeys = 0; char hvals = 0; + int subexp; *s++ = '\0'; if (!ialnum(*s) && *s != '#' && *s != Pound && *s != '-' && @@ -813,6 +815,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) case 'e': eval = 1; break; + case 'P': + aspar = 1; + break; case 'c': whichlen = 1; @@ -949,7 +954,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) } else globsubst = 1; } else if (*s == '+') { - if (iident(s[1])) + if (iident(s[1]) || (aspar && isstring(s[1]) && + (s[2] == Inbrace || s[2] == Inpar))) chkset = 1, s++; else if (!inbrace) { *aptr = '$'; @@ -965,7 +971,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) globsubst = globsubst && !qt; idbeg = s; - if (s[-1] && isstring(*s) && (s[1] == Inbrace || s[1] == Inpar)) { + if ((subexp = (s[-1] && isstring(*s) && + (s[1] == Inbrace || s[1] == Inpar)))) { int sav; int quoted = *s == Qstring; @@ -973,17 +980,28 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) skipparens(*s, *s == Inpar ? Outpar : Outbrace, &s); sav = *s; *s = 0; - if (multsub(&val, &aval, &isarr, NULL) && quoted) { + if (multsub(&val, (aspar ? NULL : &aval), &isarr, NULL) && quoted) { isarr = -1; aval = alloc(sizeof(char *)); - } + aspar = 0; + } else if (aspar) + idbeg = val; if (isarr) isarr = -1; copied = 1; *s = sav; v = (Value) NULL; - } else { - if (!(v = fetchvalue(&s, (wantt ? -1 : + } else if (aspar) { + if ((v = getvalue(&s, 1))) { + val = idbeg = getstrvalue(v); + subexp = 1; + } else + vunset = 1; + } + if (!subexp || aspar) { + char *ov = val; + + if (!(v = fetchvalue((subexp ? &ov : &s), (wantt ? -1 : ((unset(KSHARRAYS) || inbrace) ? 1 : -1)), hkeys|hvals))) vunset = 1; @@ -1690,6 +1708,7 @@ modify(char **str, char **ptr) case 't': case 'l': case 'u': + case 'q': c = **ptr; break; @@ -1808,6 +1827,9 @@ modify(char **str, char **ptr) if (hsubl && hsubr) subst(©, hsubl, hsubr, gbal); break; + case 'q': + copy = bslashquote(copy, NULL, NULL, NULL, 0); + break; } tc = *tt; *tt = '\0'; @@ -1859,6 +1881,9 @@ modify(char **str, char **ptr) } } break; + case 'q': + *str = bslashquote(*str, NULL, NULL, NULL, 0); + break; } } if (rec < 0) { |