1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-11 13:01:28 +02:00

27965, 27966: Improve ${(q)...}: newline appears as $'\n;,

This commit is contained in:
Peter Stephenson 2010-05-27 18:57:34 +00:00
parent 43ee0cd4fd
commit 147cedfb6f
5 changed files with 45 additions and 15 deletions

View file

@ -1,5 +1,10 @@
2010-05-27 Peter Stephenson <p.w.stephenson@ntlworld.com> 2010-05-27 Peter Stephenson <p.w.stephenson@ntlworld.com>
* 27965 plus as per 27966: Src/builtin.c, Src/subst.c,
Src/utils.c, Src/zsh.h: Use $'\n' quoting instead of literal
newline for ${(q)...} to avoid lines getting split unexpectedly.
Quote empty strings as ''.
* 27976: Doc/Zsh/expn.yo: add yet more to the my-brain-hurts * 27976: Doc/Zsh/expn.yo: add yet more to the my-brain-hurts
description of how parameter expansion is ordered. description of how parameter expansion is ordered.
@ -13164,5 +13169,5 @@
***************************************************** *****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL * This is used by the shell to define $ZSH_PATCHLEVEL
* $Revision: 1.4983 $ * $Revision: 1.4984 $
***************************************************** *****************************************************

View file

@ -4233,7 +4233,7 @@ bin_print(char *name, char **args, Options ops, int func)
break; break;
case 'q': case 'q':
stringval = curarg ? stringval = curarg ?
quotestring(curarg, NULL, QT_BACKSLASH) : &nullstr; quotestring(curarg, NULL, QT_BACKSLASH_SHOWNULL) : &nullstr;
*d = 's'; *d = 's';
print_val(stringval); print_val(stringval);
break; break;

View file

@ -2896,7 +2896,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
} }
} else } else
for (; *ap; ap++) for (; *ap; ap++)
*ap = quotestring(*ap, NULL, QT_BACKSLASH); *ap = quotestring(*ap, NULL, QT_BACKSLASH_SHOWNULL);
} else { } else {
int one = noerrs, oef = errflag, haserr = 0; int one = noerrs, oef = errflag, haserr = 0;
@ -2933,7 +2933,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
if (quotetype == QT_DOLLARS) if (quotetype == QT_DOLLARS)
val[0] = '$'; val[0] = '$';
} else } else
val = quotestring(val, NULL, QT_BACKSLASH); val = quotestring(val, NULL, QT_BACKSLASH_SHOWNULL);
} else { } else {
int one = noerrs, oef = errflag, haserr; int one = noerrs, oef = errflag, haserr;
@ -3490,7 +3490,7 @@ modify(char **str, char **ptr)
subst(&copy, hsubl, hsubr, gbal); subst(&copy, hsubl, hsubr, gbal);
break; break;
case 'q': case 'q':
copy = quotestring(copy, NULL, QT_BACKSLASH); copy = quotestring(copy, NULL, QT_BACKSLASH_SHOWNULL);
break; break;
case 'Q': case 'Q':
{ {

View file

@ -4576,7 +4576,7 @@ quotestring(const char *s, char **e, int instring)
char *v; char *v;
int alloclen; int alloclen;
char *buf; char *buf;
int sf = 0; int sf = 0, shownull;
/* /*
* quotesub is used with QT_SINGLE_OPTIONAL. * quotesub is used with QT_SINGLE_OPTIONAL.
* quotesub = 0: mechanism not active * quotesub = 0: mechanism not active
@ -4585,11 +4585,18 @@ quotestring(const char *s, char **e, int instring)
* quotesub = 2: mechanism active, added opening "'"; need * quotesub = 2: mechanism active, added opening "'"; need
* closing "'". * closing "'".
*/ */
int quotesub = 0; int quotesub = 0, slen;
char *quotestart; char *quotestart;
convchar_t cc; convchar_t cc;
const char *uend; const char *uend;
slen = strlen(s);
if (instring == QT_BACKSLASH_SHOWNULL) {
shownull = 1;
instring = QT_BACKSLASH;
} else {
shownull = 0;
}
switch (instring) switch (instring)
{ {
case QT_BACKSLASH: case QT_BACKSLASH:
@ -4598,21 +4605,24 @@ quotestring(const char *s, char **e, int instring)
* Keep memory usage within limits by allocating temporary * Keep memory usage within limits by allocating temporary
* storage and using heap for correct size at end. * storage and using heap for correct size at end.
*/ */
alloclen = strlen(s) * 7 + 1; alloclen = slen * 7 + 1;
if (!*s && shownull)
alloclen += 2; /* for '' */
break; break;
case QT_SINGLE_OPTIONAL: case QT_SINGLE_OPTIONAL:
/* /*
* Here, we may need to add single quotes. * Here, we may need to add single quotes.
*/ */
alloclen = strlen(s) * 4 + 3; alloclen = slen * 4 + 3;
quotesub = 1; quotesub = 1;
break; break;
default: default:
alloclen = strlen(s) * 4 + 1; alloclen = slen * 4 + 1;
break; break;
} }
tt = quotestart = v = buf = zshcalloc(alloclen); tt = quotestart = v = buf = zshcalloc(alloclen);
DPUTS(instring < QT_BACKSLASH || instring == QT_BACKTICK || DPUTS(instring < QT_BACKSLASH || instring == QT_BACKTICK ||
@ -4659,6 +4669,13 @@ quotestring(const char *s, char **e, int instring)
} }
else else
{ {
if (shownull) {
/* We can't show an empty string with just backslash quoting. */
if (!*u) {
*v++ = '\'';
*v++ = '\'';
}
}
/* /*
* Here there are syntactic special characters, so * Here there are syntactic special characters, so
* we start by going through bytewise. * we start by going through bytewise.
@ -4771,15 +4788,19 @@ quotestring(const char *s, char **e, int instring)
continue; continue;
} else if (*u == '\n' || } else if (*u == '\n' ||
(instring == QT_SINGLE && *u == '\'')) { (instring == QT_SINGLE && *u == '\'')) {
if (unset(RCQUOTES)) { if (*u == '\n') {
*v++ = '$';
*v++ = '\'';
*v++ = '\\';
*v++ = 'n';
*v++ = '\'';
} else if (unset(RCQUOTES)) {
*v++ = '\''; *v++ = '\'';
if (*u == '\'') if (*u == '\'')
*v++ = '\\'; *v++ = '\\';
*v++ = *u; *v++ = *u;
*v++ = '\''; *v++ = '\'';
} else if (*u == '\n') } else
*v++ = '"', *v++ = '\n', *v++ = '"';
else
*v++ = '\'', *v++ = '\''; *v++ = '\'', *v++ = '\'';
u++; u++;
continue; continue;

View file

@ -218,7 +218,11 @@ enum {
* Single quotes, but the default is not to quote unless necessary. * Single quotes, but the default is not to quote unless necessary.
* This is only useful as an argument to quotestring(). * This is only useful as an argument to quotestring().
*/ */
QT_SINGLE_OPTIONAL QT_SINGLE_OPTIONAL,
/*
* As QT_BACKSLASH, but a NULL string is shown as ''.
*/
QT_BACKSLASH_SHOWNULL
}; };
#define QT_IS_SINGLE(x) ((x) == QT_SINGLE || (x) == QT_SINGLE_OPTIONAL) #define QT_IS_SINGLE(x) ((x) == QT_SINGLE || (x) == QT_SINGLE_OPTIONAL)