summaryrefslogtreecommitdiff
path: root/Src/lex.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2007-08-23 22:04:25 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2007-08-23 22:04:25 +0000
commitdb3ba137b34582a2810b0fb01b6ba451acbc1c9b (patch)
tree6d2f321cc78d9794a139221463bee6d3f89bde9e /Src/lex.c
parent437f67718cd03f1d2eff2331827c2e225dee4aaf (diff)
downloadzsh-db3ba137b34582a2810b0fb01b6ba451acbc1c9b.tar.gz
zsh-db3ba137b34582a2810b0fb01b6ba451acbc1c9b.zip
23795: improve ${(Q)...} with $'..'
Diffstat (limited to 'Src/lex.c')
-rw-r--r--Src/lex.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/Src/lex.c b/Src/lex.c
index 8bf90847a..a334dc722 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -1556,6 +1556,7 @@ mod_export int
parse_subst_string(char *s)
{
int c, l = strlen(s), err, olen, lexstop_ret;
+ char *ptr;
if (!*s || !strcmp(s, nulstring))
return 0;
@@ -1593,6 +1594,43 @@ parse_subst_string(char *s)
return 1;
}
#endif
+ /* Check for $'...' quoting. This needs special handling. */
+ for (ptr = s; *ptr; )
+ {
+ if (*ptr == String && ptr[1] == Snull)
+ {
+ char *t;
+ int len, tlen, diff;
+ t = getkeystring(ptr + 2, &len, GETKEYS_DOLLARS_QUOTE, NULL);
+ len += 2;
+ tlen = strlen(t);
+ diff = len - tlen;
+ /*
+ * Yuk.
+ * parse_subst_string() currently handles strings in-place.
+ * That's not so easy to fix without knowing whether
+ * additional memory should come off the heap or
+ * otherwise. So we cheat by copying the unquoted string
+ * into place, unless it's too long. That's not the
+ * normal case, but I'm worried there are are pathological
+ * cases with converting metafied multibyte strings.
+ * If someone can prove there aren't I will be very happy.
+ */
+ if (diff < 0) {
+ DPUTS(1, "$'...' subst too long: fix get_parse_string()");
+ return 1;
+ }
+ memcpy(ptr, t, tlen);
+ ptr += tlen;
+ if (diff > 0) {
+ char *dptr = ptr;
+ char *sptr = ptr + diff;
+ while ((*dptr++ = *sptr++))
+ ;
+ }
+ } else
+ ptr++;
+ }
return 0;
}