diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2007-08-23 22:04:25 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2007-08-23 22:04:25 +0000 |
commit | db3ba137b34582a2810b0fb01b6ba451acbc1c9b (patch) | |
tree | 6d2f321cc78d9794a139221463bee6d3f89bde9e | |
parent | 437f67718cd03f1d2eff2331827c2e225dee4aaf (diff) | |
download | zsh-db3ba137b34582a2810b0fb01b6ba451acbc1c9b.tar.gz zsh-db3ba137b34582a2810b0fb01b6ba451acbc1c9b.tar.xz zsh-db3ba137b34582a2810b0fb01b6ba451acbc1c9b.zip |
23795: improve ${(Q)...} with $'..'
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Config/version.mk | 4 | ||||
-rw-r--r-- | Src/lex.c | 38 | ||||
-rw-r--r-- | Test/D04parameter.ztst | 5 |
4 files changed, 50 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog index a5b9e08f5..e24d47196 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-08-23 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 23795: Src/lex.c: make ${(Q)...} handle $'...' correctly, + up to the problem of long flies in short ointments. + 2007-08-23 Peter Stephenson <pws@csr.com> * unposted: Functions/Calendar/calendar_show: used subscript diff --git a/Config/version.mk b/Config/version.mk index 3fe2df89a..31848812e 100644 --- a/Config/version.mk +++ b/Config/version.mk @@ -27,5 +27,5 @@ # This must also serve as a shell script, so do not add spaces around the # `=' signs. -VERSION=4.3.4-dev-0 -VERSION_DATE='April 19, 2006' +VERSION=4.3.4-dev-1 +VERSION_DATE='August 1, 2007' 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; } diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 7f229e9a6..1910e60be 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -320,6 +320,11 @@ 0:${(Q)...} >and now even the pubs are shut. + foo="X$'\x41'$'\x42'Y" + print -r ${(Q)foo} +0:${(Q)...} with handling of $'...' +>XABY + psvar=(dog) setopt promptsubst foo='It shouldn'\''t $(happen) to a %1v.' |