1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-27 16:50:58 +01:00

27304: add ${(q-)..} flag

This commit is contained in:
Peter Stephenson 2009-06-05 11:15:48 +00:00
parent 96eb8faa7c
commit 72529e4fa6
6 changed files with 182 additions and 29 deletions

View file

@ -4408,6 +4408,11 @@ addunprintable(char *v, const char *u, const char *uend)
*
* The last argument is a QT_ value defined in zsh.h other than QT_NONE.
*
* Most quote styles other than backslash assume the quotes are to
* be added outside quotestring(). QT_SINGLE_OPTIONAL is different:
* the single quotes are only added where necessary, so the
* whole expression is handled here.
*
* The string may be metafied and contain tokens.
*/
@ -4417,20 +4422,50 @@ quotestring(const char *s, char **e, int instring)
{
const char *u, *tt;
char *v;
/*
* With QT_BACKSLASH we may need to use $'\300' stuff.
* Keep memory usage within limits by allocating temporary
* storage and using heap for correct size at end.
*/
int alloclen = (instring == QT_BACKSLASH ? 7 : 4) * strlen(s) + 1;
char *buf = zshcalloc(alloclen);
int alloclen;
char *buf;
int sf = 0;
/*
* quotesub is used with QT_SINGLE_OPTIONAL.
* quotesub = 0: mechanism not active
* quotesub = 1: mechanism pending, no "'" yet;
* needs adding at quotestart.
* quotesub = 2: mechanism active, added opening "'"; need
* closing "'".
*/
int quotesub = 0;
char *quotestart;
convchar_t cc;
const char *uend;
DPUTS(instring < QT_BACKSLASH || instring > QT_DOLLARS,
switch (instring)
{
case QT_BACKSLASH:
/*
* With QT_BACKSLASH we may need to use $'\300' stuff.
* Keep memory usage within limits by allocating temporary
* storage and using heap for correct size at end.
*/
alloclen = strlen(s) * 7 + 1;
break;
case QT_SINGLE_OPTIONAL:
/*
* Here, we may need to add single quotes.
*/
alloclen = strlen(s) * 4 + 3;
quotesub = 1;
break;
default:
alloclen = strlen(s) * 4 + 1;
break;
}
tt = quotestart = v = buf = zshcalloc(alloclen);
DPUTS(instring < QT_BACKSLASH || instring == QT_BACKTICK ||
instring > QT_SINGLE_OPTIONAL,
"BUG: bad quote type in quotestring");
tt = v = buf;
u = s;
if (instring == QT_DOLLARS) {
/*
@ -4526,12 +4561,64 @@ quotestring(const char *s, char **e, int instring)
(u[-1] == '=' || u[-1] == ':')) ||
(*u == '~' && isset(EXTENDEDGLOB))) &&
(instring == QT_BACKSLASH ||
instring == QT_SINGLE_OPTIONAL ||
(isset(BANGHIST) && *u == (char)bangchar &&
instring != QT_SINGLE) ||
(instring == QT_DOUBLE &&
(*u == '$' || *u == '`' || *u == '\"' || *u == '\\')) ||
(instring == QT_SINGLE && *u == '\''))) {
if (*u == '\n' || (instring == QT_SINGLE && *u == '\'')) {
if (instring == QT_SINGLE_OPTIONAL) {
if (quotesub == 1) {
/*
* We haven't yet had to quote at the start.
*/
if (*u == '\'') {
/*
* We don't need to.
*/
*v++ = '\\';
} else {
/*
* It's now time to add quotes.
*/
if (v > quotestart)
{
char *addq;
for (addq = v; addq > quotestart; addq--)
*addq = addq[-1];
}
*quotestart = '\'';
v++;
quotesub = 2;
}
*v++ = *u++;
/*
* Next place to start quotes is here.
*/
quotestart = v;
} else if (*u == '\'') {
if (unset(RCQUOTES)) {
*v++ = '\'';
*v++ = '\\';
*v++ = '\'';
/* Don't restart quotes unless we need them */
quotesub = 1;
quotestart = v;
} else {
/* simplest just to use '' always */
*v++ = '\'';
*v++ = '\'';
}
/* dealt with */
u++;
} else {
/* else already quoting, just add */
*v++ = *u++;
}
continue;
} else if (*u == '\n' ||
(instring == QT_SINGLE && *u == '\'')) {
if (unset(RCQUOTES)) {
*v++ = '\'';
if (*u == '\'')
@ -4589,6 +4676,8 @@ quotestring(const char *s, char **e, int instring)
}
}
}
if (quotesub == 2)
*v++ = '\'';
*v = '\0';
if (e && *e == u)