mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-18 00:51:07 +02:00
zsh-workers/8042
This commit is contained in:
parent
0b6eb90163
commit
9b85146a08
3 changed files with 96 additions and 18 deletions
|
@ -581,12 +581,14 @@ Capitalize the resulting words. `Words' in this case refers to sequences
|
|||
of alphanumeric characters separated by non-alphanumerics, em(not) to words
|
||||
that result from field splitting.
|
||||
)
|
||||
item(tt(V))(
|
||||
Make any special characters in the resulting words visible.
|
||||
)
|
||||
item(tt(q))(
|
||||
Quote the resulting words with backslashes. If this flag is given
|
||||
twice, the resulting words are quoted in single quotes and if it is
|
||||
given three times, the words are quoted in double quotes. If it is
|
||||
given four times, no real quoting is done, but any special characters
|
||||
in the resulting words will be in a human-readable form.
|
||||
given four times, the words are quoted in single quotes preceded a tt($).
|
||||
)
|
||||
item(tt(Q))(
|
||||
Remove one level of quotes from the resulting words.
|
||||
|
|
49
Src/subst.c
49
Src/subst.c
|
@ -723,6 +723,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
int sortit = 0, casind = 0;
|
||||
int casmod = 0;
|
||||
int quotemod = 0, quotetype = 0, quoteerr = 0;
|
||||
int visiblemod = 0;
|
||||
char *sep = NULL, *spsep = NULL;
|
||||
char *premul = NULL, *postmul = NULL, *preone = NULL, *postone = NULL;
|
||||
char *replstr = NULL; /* replacement string for /orig/repl */
|
||||
|
@ -826,6 +827,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
casind = 1;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
visiblemod++;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
quotemod++, quotetype++;
|
||||
break;
|
||||
|
@ -1628,20 +1633,20 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
ap = aval;
|
||||
|
||||
if (quotemod > 0) {
|
||||
if (quotetype == 3)
|
||||
for (; *ap; ap++)
|
||||
*ap = nicedupstring(*ap);
|
||||
else if (quotetype) {
|
||||
if (quotetype) {
|
||||
int sl;
|
||||
char *tmp;
|
||||
|
||||
for (; *ap; ap++) {
|
||||
int pre = quotetype != 3 ? 1 : 2;
|
||||
tmp = bslashquote(*ap, NULL, quotetype);
|
||||
sl = strlen(tmp);
|
||||
*ap = (char *) zhalloc(sl + 3);
|
||||
strcpy((*ap) + 1, tmp);
|
||||
ap[0][0] = ap[0][sl + 1] = (quotetype == 1 ? '\'' : '"');
|
||||
ap[0][sl + 2] = '\0';
|
||||
*ap = (char *) zhalloc(pre + sl + 2);
|
||||
strcpy((*ap) + pre, tmp);
|
||||
ap[0][pre - 1] = ap[0][pre + sl] = (quotetype != 2 ? '\'' : '"');
|
||||
ap[0][pre + sl + 1] = '\0';
|
||||
if (quotetype == 3)
|
||||
ap[0][0] = '$';
|
||||
}
|
||||
} else
|
||||
for (; *ap; ap++)
|
||||
|
@ -1668,18 +1673,19 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
if (!copied)
|
||||
val = dupstring(val), copied = 1;
|
||||
if (quotemod > 0) {
|
||||
if (quotetype == 3)
|
||||
val = nicedupstring(val);
|
||||
else if (quotetype) {
|
||||
if (quotetype) {
|
||||
int pre = quotetype != 3 ? 1 : 2;
|
||||
int sl;
|
||||
char *tmp;
|
||||
|
||||
tmp = bslashquote(val, NULL, quotetype);
|
||||
sl = strlen(tmp);
|
||||
val = (char *) zhalloc(sl + 3);
|
||||
strcpy(val + 1, tmp);
|
||||
val[0] = val[sl + 1] = (quotetype == 1 ? '\'' : '"');
|
||||
val[sl + 2] = '\0';
|
||||
val = (char *) zhalloc(pre + sl + 2);
|
||||
strcpy(val + pre, tmp);
|
||||
val[pre - 1] = val[pre + sl] = (quotetype != 2 ? '\'' : '"');
|
||||
val[pre + sl + 1] = '\0';
|
||||
if (quotetype == 3)
|
||||
val[0] = '$';
|
||||
} else
|
||||
val = bslashquote(val, NULL, 0);
|
||||
} else {
|
||||
|
@ -1700,6 +1706,19 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (visiblemod) {
|
||||
if (isarr) {
|
||||
char **ap;
|
||||
if (!copied)
|
||||
aval = arrdup(aval), copied = 1;
|
||||
for (ap = aval; *ap; ap++)
|
||||
*ap = nicedupstring(*ap);
|
||||
} else {
|
||||
if (!copied)
|
||||
val = dupstring(val), copied = 1;
|
||||
val = nicedupstring(val);
|
||||
}
|
||||
}
|
||||
if (isarr) {
|
||||
char *x;
|
||||
char *y;
|
||||
|
|
59
Src/utils.c
59
Src/utils.c
|
@ -2984,7 +2984,64 @@ bslashquote(const char *s, char **e, int instring)
|
|||
for (; *u; u++) {
|
||||
if (e && *e == u)
|
||||
*e = v, sf = 1;
|
||||
if (ispecial(*u) &&
|
||||
if (instring == 3) {
|
||||
int c = *u;
|
||||
if (c == Meta) {
|
||||
c = *++u ^ 32;
|
||||
}
|
||||
c &= 0xff;
|
||||
if(isprint(c)) {
|
||||
switch (c) {
|
||||
case '\\':
|
||||
case '\'':
|
||||
*v++ = '\\';
|
||||
*v++ = c;
|
||||
break;
|
||||
|
||||
default:
|
||||
if(imeta(c)) {
|
||||
*v++ = Meta;
|
||||
*v++ = c ^ 32;
|
||||
}
|
||||
else {
|
||||
if (isset(BANGHIST) && c == bangchar) {
|
||||
*v++ = '\\';
|
||||
}
|
||||
*v++ = c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (c) {
|
||||
case '\0':
|
||||
*v++ = '\\';
|
||||
*v++ = '0';
|
||||
if ('0' <= u[1] && u[1] <= '7') {
|
||||
*v++ = '0';
|
||||
*v++ = '0';
|
||||
}
|
||||
break;
|
||||
|
||||
case '\007': *v++ = '\\'; *v++ = 'a'; break;
|
||||
case '\b': *v++ = '\\'; *v++ = 'b'; break;
|
||||
case '\f': *v++ = '\\'; *v++ = 'f'; break;
|
||||
case '\n': *v++ = '\\'; *v++ = 'n'; break;
|
||||
case '\r': *v++ = '\\'; *v++ = 'r'; break;
|
||||
case '\t': *v++ = '\\'; *v++ = 't'; break;
|
||||
case '\v': *v++ = '\\'; *v++ = 'v'; break;
|
||||
|
||||
default:
|
||||
*v++ = '\\';
|
||||
*v++ = '0' + ((c >> 6) & 7);
|
||||
*v++ = '0' + ((c >> 3) & 7);
|
||||
*v++ = '0' + (c & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (ispecial(*u) &&
|
||||
(!instring ||
|
||||
(isset(BANGHIST) && *u == (char)bangchar) ||
|
||||
(instring == 2 &&
|
||||
|
|
Loading…
Reference in a new issue