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>
|
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 $
|
||||||
*****************************************************
|
*****************************************************
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(©, hsubl, hsubr, gbal);
|
subst(©, 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':
|
||||||
{
|
{
|
||||||
|
|
39
Src/utils.c
39
Src/utils.c
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue