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>
* 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
description of how parameter expansion is ordered.
@ -13164,5 +13169,5 @@
*****************************************************
* 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;
case 'q':
stringval = curarg ?
quotestring(curarg, NULL, QT_BACKSLASH) : &nullstr;
quotestring(curarg, NULL, QT_BACKSLASH_SHOWNULL) : &nullstr;
*d = 's';
print_val(stringval);
break;

View file

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

View file

@ -4576,7 +4576,7 @@ quotestring(const char *s, char **e, int instring)
char *v;
int alloclen;
char *buf;
int sf = 0;
int sf = 0, shownull;
/*
* quotesub is used with QT_SINGLE_OPTIONAL.
* quotesub = 0: mechanism not active
@ -4585,11 +4585,18 @@ quotestring(const char *s, char **e, int instring)
* quotesub = 2: mechanism active, added opening "'"; need
* closing "'".
*/
int quotesub = 0;
int quotesub = 0, slen;
char *quotestart;
convchar_t cc;
const char *uend;
slen = strlen(s);
if (instring == QT_BACKSLASH_SHOWNULL) {
shownull = 1;
instring = QT_BACKSLASH;
} else {
shownull = 0;
}
switch (instring)
{
case QT_BACKSLASH:
@ -4598,21 +4605,24 @@ quotestring(const char *s, char **e, int instring)
* Keep memory usage within limits by allocating temporary
* 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;
case QT_SINGLE_OPTIONAL:
/*
* Here, we may need to add single quotes.
*/
alloclen = strlen(s) * 4 + 3;
alloclen = slen * 4 + 3;
quotesub = 1;
break;
default:
alloclen = strlen(s) * 4 + 1;
alloclen = slen * 4 + 1;
break;
}
tt = quotestart = v = buf = zshcalloc(alloclen);
DPUTS(instring < QT_BACKSLASH || instring == QT_BACKTICK ||
@ -4659,6 +4669,13 @@ quotestring(const char *s, char **e, int instring)
}
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
* we start by going through bytewise.
@ -4771,15 +4788,19 @@ quotestring(const char *s, char **e, int instring)
continue;
} else if (*u == '\n' ||
(instring == QT_SINGLE && *u == '\'')) {
if (unset(RCQUOTES)) {
if (*u == '\n') {
*v++ = '$';
*v++ = '\'';
*v++ = '\\';
*v++ = 'n';
*v++ = '\'';
} else if (unset(RCQUOTES)) {
*v++ = '\'';
if (*u == '\'')
*v++ = '\\';
*v++ = *u;
*v++ = '\'';
} else if (*u == '\n')
*v++ = '"', *v++ = '\n', *v++ = '"';
else
} else
*v++ = '\'', *v++ = '\'';
u++;
continue;

View file

@ -218,7 +218,11 @@ enum {
* Single quotes, but the default is not to quote unless necessary.
* 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)