1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
29 * match shell file patterns
30 * this interface is a wrapper on regex
32 * sh pattern egrep RE description
33 * ---------- -------- -----------
34 * * .* 0 or more chars
37 * [!.] [^.] negated char class
38 * [[:.:]] [[:.:]] ctype class
39 * [[=.=]] [[=.=]] equivalence class
40 * [[...]] [[...]] collation element
41 * *(.) (.)* 0 or more of
42 * +(.) (.)+ 1 or more of
47 * \# () subgroup back reference [1-9]
51 * \ used to escape metacharacters
53 * *, ?, (, |, &, ), [, \ must be \'d outside of [...]
54 * only ] must be \'d inside [...]
69 * 0 returned if no match
70 * otherwise number of subgroups matched returned
71 * match group begin offsets are even elements of sub
72 * match group end offsets are odd elements of sub
73 * the matched string is from s+sub[0] up to but not
78 strgrpmatch(const char* b
, const char* p
, int* sub
, int n
, register int flags
)
83 register regflags_t reflags
;
86 * 0 and empty patterns are special
92 regcache(NiL
, 0, NiL
);
106 if (flags
& REG_ADVANCE
)
107 reflags
= flags
& ~REG_ADVANCE
;
110 reflags
= REG_SHELL
|REG_AUGMENTED
;
111 if (!(flags
& STR_MAXIMAL
))
112 reflags
|= REG_MINIMAL
;
113 if (flags
& STR_GROUP
)
114 reflags
|= REG_SHELL_GROUP
;
115 if (flags
& STR_LEFT
)
117 if (flags
& STR_RIGHT
)
118 reflags
|= REG_RIGHT
;
119 if (flags
& STR_ICASE
)
120 reflags
|= REG_ICASE
;
123 reflags
|= REG_NOSUB
;
124 if (!(re
= regcache(p
, reflags
, NiL
)))
126 if (n
> matchstate
.nmatch
)
128 if (!(matchstate
.match
= newof(matchstate
.match
, regmatch_t
, n
, 0)))
130 matchstate
.nmatch
= n
;
132 if (regexec(re
, b
, n
, matchstate
.match
, reflags
& ~(REG_MINIMAL
|REG_SHELL_GROUP
|REG_LEFT
|REG_RIGHT
|REG_ICASE
)))
138 for (n
= 0; sub
< end
&& n
<= i
; n
++)
140 *sub
++ = matchstate
.match
[n
].rm_so
;
141 *sub
++ = matchstate
.match
[n
].rm_eo
;
147 * compare the string s with the shell pattern p
148 * returns 1 for match 0 otherwise
152 strmatch(const char* s
, const char* p
)
154 return strgrpmatch(s
, p
, NiL
, 0, STR_MAXIMAL
|STR_LEFT
|STR_RIGHT
);
158 * leading substring match
159 * first char after end of substring returned
160 * 0 returned if no match
162 * OBSOLETE: use strgrpmatch()
166 strsubmatch(const char* s
, const char* p
, int flags
)
170 return strgrpmatch(s
, p
, match
, 1, (flags
? STR_MAXIMAL
: 0)|STR_LEFT
) ? (char*)s
+ match
[1] : (char*)0;