mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-01 05:16:05 +01:00
35067: Add (b) parameter flag for pattern char backslashing.
Doc tweak from Daniel in 35071. Includes test.
This commit is contained in:
parent
bb2362e2c0
commit
6269db883a
7 changed files with 72 additions and 6 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2015-05-10 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||||
|
|
||||||
|
* 35067 (doc tweak from Daniel, 35071): Doc/Zsh/expn.yo,
|
||||||
|
Src/subst.c, Src/utils.c, Src/zsh.h, Src/ztype.h,
|
||||||
|
Test/D04parameter.ztst: add ${(b)foo} for backslash
|
||||||
|
quoting of patterns.
|
||||||
|
|
||||||
2015-05-10 Mikael Magnusson <mikachu@gmail.com>
|
2015-05-10 Mikael Magnusson <mikachu@gmail.com>
|
||||||
|
|
||||||
* 35065: Src/zsh.h: Don't treat NUL as a combining character
|
* 35065: Src/zsh.h: Don't treat NUL as a combining character
|
||||||
|
|
|
@ -1014,6 +1014,25 @@ form of single quoting is used that only quotes the string if needed to
|
||||||
protect special characters. Typically this form gives the most readable
|
protect special characters. Typically this form gives the most readable
|
||||||
output.
|
output.
|
||||||
)
|
)
|
||||||
|
item(tt(b))(
|
||||||
|
Quote with backslashes only characters that are special to pattern
|
||||||
|
matching. This is useful when the contents of the variable are to be
|
||||||
|
tested using tt(GLOB_SUBST), including the tt(${~)var(...)tt(}) switch.
|
||||||
|
|
||||||
|
Quoting using one of the tt(q) family of flags does not work
|
||||||
|
for this purpose since quotes are not stripped from non-pattern
|
||||||
|
characters by tt(GLOB_SUBST). In other words,
|
||||||
|
|
||||||
|
example(pattern=${(q)str}
|
||||||
|
[[ $str = ${~pattern} ]])
|
||||||
|
|
||||||
|
works if tt($str) is tt('a*b') but not if it is tt('a b'), whereas
|
||||||
|
|
||||||
|
example(pattern=${(b)str}
|
||||||
|
[[ $str = ${~pattern} ]])
|
||||||
|
|
||||||
|
is always true for any possible value of tt($str).
|
||||||
|
)
|
||||||
item(tt(Q))(
|
item(tt(Q))(
|
||||||
Remove one level of quotes from the resulting words.
|
Remove one level of quotes from the resulting words.
|
||||||
)
|
)
|
||||||
|
|
13
Src/subst.c
13
Src/subst.c
|
@ -1592,7 +1592,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
/* combination of (L), (U) and (C) flags. */
|
/* combination of (L), (U) and (C) flags. */
|
||||||
int casmod = CASMOD_NONE;
|
int casmod = CASMOD_NONE;
|
||||||
/*
|
/*
|
||||||
* quotemod says we are doing either (q) (positive), (Q) (negative)
|
* quotemod says we are doing either (q/b) (positive), (Q) (negative)
|
||||||
* or not (0). quotetype counts the q's for the first case.
|
* or not (0). quotetype counts the q's for the first case.
|
||||||
* quoterr is simply (X) but gets passed around a lot because the
|
* quoterr is simply (X) but gets passed around a lot because the
|
||||||
* combination (eX) needs it.
|
* combination (eX) needs it.
|
||||||
|
@ -1861,6 +1861,12 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
quotemod++, quotetype++;
|
quotemod++, quotetype++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'b':
|
||||||
|
if (quotemod || quotetype != QT_NONE)
|
||||||
|
goto flagerr;
|
||||||
|
quotemod = 1;
|
||||||
|
quotetype = QT_BACKSLASH_PATTERN;
|
||||||
|
break;
|
||||||
case 'Q':
|
case 'Q':
|
||||||
quotemod--;
|
quotemod--;
|
||||||
break;
|
break;
|
||||||
|
@ -3460,7 +3466,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
if (quotemod) {
|
if (quotemod) {
|
||||||
int pre = 0, post = 0;
|
int pre = 0, post = 0;
|
||||||
|
|
||||||
if (quotemod > 0 && quotetype > QT_BACKSLASH) {
|
if (quotemod > 0) {
|
||||||
switch (quotetype)
|
switch (quotetype)
|
||||||
{
|
{
|
||||||
case QT_DOLLARS:
|
case QT_DOLLARS:
|
||||||
|
@ -3471,6 +3477,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
|
|
||||||
case QT_SINGLE_OPTIONAL:
|
case QT_SINGLE_OPTIONAL:
|
||||||
/* quotes will be added for us */
|
/* quotes will be added for us */
|
||||||
|
case QT_BACKSLASH:
|
||||||
|
case QT_BACKSLASH_PATTERN:
|
||||||
|
/* no quotes */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
23
Src/utils.c
23
Src/utils.c
|
@ -3694,6 +3694,8 @@ inittyptab(void)
|
||||||
typtab[bangchar] |= ISPECIAL;
|
typtab[bangchar] |= ISPECIAL;
|
||||||
} else
|
} else
|
||||||
typtab_flags &= ~ZTF_BANGCHAR;
|
typtab_flags &= ~ZTF_BANGCHAR;
|
||||||
|
for (s = PATCHARS; *s; s++)
|
||||||
|
typtab[STOUC(*s)] |= IPATTERN;
|
||||||
|
|
||||||
unqueue_signals();
|
unqueue_signals();
|
||||||
}
|
}
|
||||||
|
@ -5075,6 +5077,10 @@ quotestring(const char *s, char **e, int instring)
|
||||||
alloclen = slen * 7 + 1;
|
alloclen = slen * 7 + 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case QT_BACKSLASH_PATTERN:
|
||||||
|
alloclen = slen * 2 + 1;
|
||||||
|
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.
|
||||||
|
@ -5094,7 +5100,7 @@ quotestring(const char *s, char **e, int instring)
|
||||||
quotestart = v = buf = zshcalloc(alloclen);
|
quotestart = v = buf = zshcalloc(alloclen);
|
||||||
|
|
||||||
DPUTS(instring < QT_BACKSLASH || instring == QT_BACKTICK ||
|
DPUTS(instring < QT_BACKSLASH || instring == QT_BACKTICK ||
|
||||||
instring > QT_SINGLE_OPTIONAL,
|
instring > QT_BACKSLASH_PATTERN,
|
||||||
"BUG: bad quote type in quotestring");
|
"BUG: bad quote type in quotestring");
|
||||||
u = s;
|
u = s;
|
||||||
if (instring == QT_DOLLARS) {
|
if (instring == QT_DOLLARS) {
|
||||||
|
@ -5134,9 +5140,18 @@ quotestring(const char *s, char **e, int instring)
|
||||||
u = uend;
|
u = uend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (instring == QT_BACKSLASH_PATTERN) {
|
||||||
else
|
while (*u) {
|
||||||
{
|
if (e && !sf && *e == u) {
|
||||||
|
*e = v;
|
||||||
|
sf = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipattern(*u))
|
||||||
|
*v++ = '\\';
|
||||||
|
*v++ = *u++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (shownull) {
|
if (shownull) {
|
||||||
/* We can't show an empty string with just backslash quoting. */
|
/* We can't show an empty string with just backslash quoting. */
|
||||||
if (!*u) {
|
if (!*u) {
|
||||||
|
|
10
Src/zsh.h
10
Src/zsh.h
|
@ -215,6 +215,10 @@ struct mathfunc {
|
||||||
|
|
||||||
#define SPECCHARS "#$^*()=|{}[]`<>?~;&\n\t \\\'\""
|
#define SPECCHARS "#$^*()=|{}[]`<>?~;&\n\t \\\'\""
|
||||||
|
|
||||||
|
/* chars that need to be quoted for pattern matching */
|
||||||
|
|
||||||
|
#define PATCHARS "#^*()|[]<>?~"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Types of quote. This is used in various places, so care needs
|
* Types of quote. This is used in various places, so care needs
|
||||||
* to be taken when changing them. (Oooh, don't you look surprised.)
|
* to be taken when changing them. (Oooh, don't you look surprised.)
|
||||||
|
@ -248,6 +252,12 @@ enum {
|
||||||
* This is only useful as an argument to quotestring().
|
* This is only useful as an argument to quotestring().
|
||||||
*/
|
*/
|
||||||
QT_SINGLE_OPTIONAL,
|
QT_SINGLE_OPTIONAL,
|
||||||
|
/*
|
||||||
|
* Only quote pattern characters.
|
||||||
|
* ${(b)foo} guarantees that ${~foo} matches the string
|
||||||
|
* contained in foo.
|
||||||
|
*/
|
||||||
|
QT_BACKSLASH_PATTERN,
|
||||||
/*
|
/*
|
||||||
* As QT_BACKSLASH, but a NULL string is shown as ''.
|
* As QT_BACKSLASH, but a NULL string is shown as ''.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#define IMETA (1 << 12)
|
#define IMETA (1 << 12)
|
||||||
#define IWSEP (1 << 13)
|
#define IWSEP (1 << 13)
|
||||||
#define INULL (1 << 14)
|
#define INULL (1 << 14)
|
||||||
|
#define IPATTERN (1 << 15)
|
||||||
#define zistype(X,Y) (typtab[STOUC(X)] & Y)
|
#define zistype(X,Y) (typtab[STOUC(X)] & Y)
|
||||||
#define idigit(X) zistype(X,IDIGIT)
|
#define idigit(X) zistype(X,IDIGIT)
|
||||||
#define ialnum(X) zistype(X,IALNUM)
|
#define ialnum(X) zistype(X,IALNUM)
|
||||||
|
@ -58,6 +59,7 @@
|
||||||
#define imeta(X) zistype(X,IMETA)
|
#define imeta(X) zistype(X,IMETA)
|
||||||
#define iwsep(X) zistype(X,IWSEP)
|
#define iwsep(X) zistype(X,IWSEP)
|
||||||
#define inull(X) zistype(X,INULL)
|
#define inull(X) zistype(X,INULL)
|
||||||
|
#define ipattern(X) zistype(X,IPATTERN)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bit flags for typtab_flags --- preserved after
|
* Bit flags for typtab_flags --- preserved after
|
||||||
|
|
|
@ -1699,3 +1699,7 @@
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
>Four
|
>Four
|
||||||
|
|
||||||
|
funnychars='The qu*nk br!wan f@x j/mps o[]r the la~# ^"&;'
|
||||||
|
[[ $funnychars = ${~${(b)funnychars}} ]]
|
||||||
|
0:${(b)...} quoting protects from GLOB_SUBST
|
||||||
|
|
Loading…
Reference in a new issue