From cc9bc2dd0b90cbf920794f15d0fce73fe04babac Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 22 Nov 2010 11:42:47 +0000 Subject: 28424: new POSIX_STRINGS option --- Doc/Zsh/options.yo | 27 +++++++++++++++++++++++++++ Src/options.c | 3 ++- Src/utils.c | 15 +++++++++++++-- Src/zsh.h | 1 + Test/A03quoting.ztst | 22 ++++++++++++++++++++++ 5 files changed, 65 insertions(+), 3 deletions(-) diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index d334f5829..467c92723 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -1891,6 +1891,33 @@ If multibyte character support is not compiled into the shell this option is ignored; all octets with the top bit set may be used in identifiers. This is non-standard but is the traditional zsh behaviour. ) +pindex(POSIX_STRINGS) +pindex(NO_POSIX_STRINGS) +pindex(POSIXSTRINGS) +pindex(NOPOSIXSTRINGS) +cindex(discarding embedded nulls in $'...') +cindex(embedded nulls, in $'...') +cindex(nulls, embedded in $'...') +item(tt(POSIX_STRINGS) )( +This option affects processing of quoted strings. Currently it only +affects the behaviour of null characters, i.e. character 0 in the +portable character set corresponding to US ASCII. + +When this option is not set, null characters embedded within strings +of the form tt($')var(...)tt(') are treated as ordinary characters. The +entire string is maintained within the shell and output to files where +necessary, although owing to restrictions of the library interface +the string is truncated at the null character in file names, environment +variables, or in arguments to external programs. + +When this option is set, the tt($')var(...)tt(') expression is truncated at +the null character. Note that remaining parts of the same string +beyond the termination of the quotes are not trunctated. + +For example, the command line argument tt(a$'b\0c'd) is treated with +the option off as the characters tt(a), tt(b), null, tt(c), tt(d), +and with the option on as the characters tt(a), tt(b), tt(d). +) pindex(POSIX_TRAPS) pindex(NO_POSIX_TRAPS) pindex(POSIXTRAPS) diff --git a/Src/options.c b/Src/options.c index a2d5e0855..00d552ad5 100644 --- a/Src/options.c +++ b/Src/options.c @@ -205,7 +205,8 @@ static struct optname optns[] = { {{NULL, "posixcd", OPT_EMULATE|OPT_BOURNE}, POSIXCD}, {{NULL, "posixidentifiers", OPT_EMULATE|OPT_BOURNE}, POSIXIDENTIFIERS}, {{NULL, "posixjobs", OPT_EMULATE|OPT_BOURNE}, POSIXJOBS}, -{{NULL, "posixtraps", OPT_EMULATE|OPT_BOURNE}, POSIXTRAPS}, +{{NULL, "posixstrings", OPT_EMULATE|OPT_BOURNE}, POSIXSTRINGS}, +{{NULL, "posixtraps", OPT_EMULATE|OPT_BOURNE}, POSIXTRAPS}, {{NULL, "printeightbit", 0}, PRINTEIGHTBIT}, {{NULL, "printexitvalue", 0}, PRINTEXITVALUE}, {{NULL, "privileged", OPT_SPECIAL}, PRIVILEGED}, diff --git a/Src/utils.c b/Src/utils.c index e788051cf..2e30c176a 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -5200,7 +5200,7 @@ getkeystring(char *s, int *len, int how, int *misc) char *buf, tmp[1]; char *t, *tdest = NULL, *u = NULL, *sstart = s, *tbuf = NULL; char svchar = '\0'; - int meta = 0, control = 0; + int meta = 0, control = 0, ignoring = 0; int i; #if defined(HAVE_WCHAR_H) && defined(HAVE_WCTOMB) && defined(__STDC_ISO_10646__) wint_t wval; @@ -5623,11 +5623,22 @@ getkeystring(char *s, int *len, int how, int *misc) if (how & GETKEY_DOLLAR_QUOTE) { char *t2; for (t2 = tbuf; t2 < t; t2++) { + /* + * In POSIX mode, an embedded NULL is discarded and + * terminates processing. It just does, that's why. + */ + if (isset(POSIXSTRINGS)) { + if (*t2 == '\0') + ignoring = 1; + if (ignoring) + break; + } if (imeta(*t2)) { *tdest++ = Meta; *tdest++ = *t2 ^ 32; - } else + } else { *tdest++ = *t2; + } } /* * Reset use of temporary buffer. diff --git a/Src/zsh.h b/Src/zsh.h index cc50826e5..1d793741a 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1992,6 +1992,7 @@ enum { POSIXCD, POSIXIDENTIFIERS, POSIXJOBS, + POSIXSTRINGS, POSIXTRAPS, PRINTEIGHTBIT, PRINTEXITVALUE, diff --git a/Test/A03quoting.ztst b/Test/A03quoting.ztst index f0f86e0b2..0cf0e8a02 100644 --- a/Test/A03quoting.ztst +++ b/Test/A03quoting.ztst @@ -42,6 +42,7 @@ unsetopt rcquotes 0:Yes RC_QUOTES with single quotes >' +# ' Deconfuse Emacs quoting rules print '<\u0041>' printf '%s\n' $'<\u0042>' @@ -52,3 +53,24 @@ > > > + + null1="$(print -r a$'b\0c'd)" + null2="$(setopt posixstrings; print -r a$'b\0c'd)" + for string in $null1 $null2; do + print ":" + for (( i = 1; i <= $#string; i++ )); do + char=$string[$i] + print $(( [#16] #char )) + done + done +0:Embedded null characters in $'...' strings. +>: +>16#61 +>16#62 +>16#0 +>16#63 +>16#64 +>: +>16#61 +>16#62 +>16#64 -- cgit 1.4.1