From db3ba137b34582a2810b0fb01b6ba451acbc1c9b Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 23 Aug 2007 22:04:25 +0000 Subject: 23795: improve ${(Q)...} with $'..' --- ChangeLog | 5 +++++ Config/version.mk | 4 ++-- Src/lex.c | 38 ++++++++++++++++++++++++++++++++++++++ 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 + + * 23795: Src/lex.c: make ${(Q)...} handle $'...' correctly, + up to the problem of long flies in short ointments. + 2007-08-23 Peter Stephenson * 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.' -- cgit 1.4.1