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:
parent
43ee0cd4fd
commit
147cedfb6f
5 changed files with 45 additions and 15 deletions
|
@ -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 $
|
||||
*****************************************************
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(©, hsubl, hsubr, gbal);
|
||||
break;
|
||||
case 'q':
|
||||
copy = quotestring(copy, NULL, QT_BACKSLASH);
|
||||
copy = quotestring(copy, NULL, QT_BACKSLASH_SHOWNULL);
|
||||
break;
|
||||
case 'Q':
|
||||
{
|
||||
|
|
39
Src/utils.c
39
Src/utils.c
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue