xref: /titanic_51/usr/src/lib/libast/common/regex/regclass.c (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*3e14f97fSRoger A. Faulkner *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6da2e3ebdSchin *                  Common Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10da2e3ebdSchin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11da2e3ebdSchin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12da2e3ebdSchin *                                                                      *
13da2e3ebdSchin *              Information and Software Systems Research               *
14da2e3ebdSchin *                            AT&T Research                             *
15da2e3ebdSchin *                           Florham Park NJ                            *
16da2e3ebdSchin *                                                                      *
17da2e3ebdSchin *                 Glenn Fowler <gsf@research.att.com>                  *
18da2e3ebdSchin *                  David Korn <dgk@research.att.com>                   *
19da2e3ebdSchin *                   Phong Vo <kpv@research.att.com>                    *
20da2e3ebdSchin *                                                                      *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #pragma prototyped
23da2e3ebdSchin /*
24da2e3ebdSchin  * RE character class support
25da2e3ebdSchin  */
26da2e3ebdSchin 
27da2e3ebdSchin #include "reglib.h"
28da2e3ebdSchin 
29da2e3ebdSchin struct Ctype_s; typedef struct Ctype_s Ctype_t;
30da2e3ebdSchin 
31da2e3ebdSchin struct Ctype_s
32da2e3ebdSchin {
33da2e3ebdSchin 	const char*	name;
34da2e3ebdSchin 	size_t		size;
35da2e3ebdSchin 	regclass_t	ctype;
36da2e3ebdSchin 	Ctype_t*	next;
37da2e3ebdSchin #if _lib_wctype
38da2e3ebdSchin 	wctype_t	wtype;
39da2e3ebdSchin #endif
40da2e3ebdSchin };
41da2e3ebdSchin 
42da2e3ebdSchin static Ctype_t*		ctypes;
43da2e3ebdSchin 
44da2e3ebdSchin #define CTYPES		12
45da2e3ebdSchin #if _lib_wctype
46da2e3ebdSchin #define WTYPES		8
47da2e3ebdSchin #else
48da2e3ebdSchin #define WTYPES		0
49da2e3ebdSchin #endif
50da2e3ebdSchin 
51da2e3ebdSchin /*
52da2e3ebdSchin  * this stuff gets around posix failure to define isblank,
53da2e3ebdSchin  * and the fact that ctype functions are macros
54da2e3ebdSchin  * and any local extensions that may not even have functions or macros
55da2e3ebdSchin  */
56da2e3ebdSchin 
57da2e3ebdSchin #if _need_iswblank
58da2e3ebdSchin 
59da2e3ebdSchin int
_reg_iswblank(wint_t wc)60da2e3ebdSchin _reg_iswblank(wint_t wc)
61da2e3ebdSchin {
62da2e3ebdSchin 	static int	initialized;
63da2e3ebdSchin 	static wctype_t	wt;
64da2e3ebdSchin 
65da2e3ebdSchin 	if (!initialized)
66da2e3ebdSchin 	{
67da2e3ebdSchin 		initialized = 1;
68da2e3ebdSchin 		wt = wctype("blank");
69da2e3ebdSchin 	}
70da2e3ebdSchin 	return iswctype(wc, wt);
71da2e3ebdSchin }
72da2e3ebdSchin 
73da2e3ebdSchin #endif
74da2e3ebdSchin 
Isalnum(int c)75da2e3ebdSchin static int  Isalnum(int c) { return  iswalnum(c); }
Isalpha(int c)76da2e3ebdSchin static int  Isalpha(int c) { return  iswalpha(c); }
Isblank(int c)77da2e3ebdSchin static int  Isblank(int c) { return  iswblank(c); }
Iscntrl(int c)78da2e3ebdSchin static int  Iscntrl(int c) { return  iswcntrl(c); }
Isdigit(int c)79da2e3ebdSchin static int  Isdigit(int c) { return  iswdigit(c); }
Notdigit(int c)80da2e3ebdSchin static int Notdigit(int c) { return !iswdigit(c); }
Isgraph(int c)81da2e3ebdSchin static int  Isgraph(int c) { return  iswgraph(c); }
Islower(int c)82da2e3ebdSchin static int  Islower(int c) { return  iswlower(c); }
Isprint(int c)83da2e3ebdSchin static int  Isprint(int c) { return  iswprint(c); }
Ispunct(int c)84da2e3ebdSchin static int  Ispunct(int c) { return  iswpunct(c); }
Isspace(int c)85da2e3ebdSchin static int  Isspace(int c) { return  iswspace(c); }
Notspace(int c)86da2e3ebdSchin static int Notspace(int c) { return !iswspace(c); }
Isupper(int c)87da2e3ebdSchin static int  Isupper(int c) { return  iswupper(c); }
Isword(int c)88da2e3ebdSchin static int   Isword(int c) { return  iswalnum(c) || c == '_'; }
Notword(int c)89da2e3ebdSchin static int  Notword(int c) { return !iswalnum(c) && c != '_'; }
Isxdigit(int c)90da2e3ebdSchin static int Isxdigit(int c) { return  iswxdigit(c);}
91da2e3ebdSchin 
92da2e3ebdSchin #if _lib_wctype
93da2e3ebdSchin 
94da2e3ebdSchin static int Is_wc_1(int);
95da2e3ebdSchin static int Is_wc_2(int);
96da2e3ebdSchin static int Is_wc_3(int);
97da2e3ebdSchin static int Is_wc_4(int);
98da2e3ebdSchin static int Is_wc_5(int);
99da2e3ebdSchin static int Is_wc_6(int);
100da2e3ebdSchin static int Is_wc_7(int);
101da2e3ebdSchin static int Is_wc_8(int);
102da2e3ebdSchin 
103da2e3ebdSchin #endif
104da2e3ebdSchin 
105da2e3ebdSchin #define SZ(s)		s,(sizeof(s)-1)
106da2e3ebdSchin 
107da2e3ebdSchin static Ctype_t ctype[] =
108da2e3ebdSchin {
109da2e3ebdSchin 	{ SZ("alnum"), Isalnum },
110da2e3ebdSchin 	{ SZ("alpha"), Isalpha },
111da2e3ebdSchin 	{ SZ("blank"), Isblank },
112da2e3ebdSchin 	{ SZ("cntrl"), Iscntrl },
113da2e3ebdSchin 	{ SZ("digit"), Isdigit },
114da2e3ebdSchin 	{ SZ("graph"), Isgraph },
115da2e3ebdSchin 	{ SZ("lower"), Islower },
116da2e3ebdSchin 	{ SZ("print"), Isprint },
117da2e3ebdSchin 	{ SZ("punct"), Ispunct },
118da2e3ebdSchin 	{ SZ("space"), Isspace },
119da2e3ebdSchin 	{ SZ("upper"), Isupper },
120da2e3ebdSchin 	{ SZ("word"),  Isword  },
121da2e3ebdSchin 	{ SZ("xdigit"),Isxdigit},
122da2e3ebdSchin #if _lib_wctype
123da2e3ebdSchin 	{ 0, 0,        Is_wc_1 },
124da2e3ebdSchin 	{ 0, 0,        Is_wc_2 },
125da2e3ebdSchin 	{ 0, 0,        Is_wc_3 },
126da2e3ebdSchin 	{ 0, 0,        Is_wc_4 },
127da2e3ebdSchin 	{ 0, 0,        Is_wc_5 },
128da2e3ebdSchin 	{ 0, 0,        Is_wc_6 },
129da2e3ebdSchin 	{ 0, 0,        Is_wc_7 },
130da2e3ebdSchin 	{ 0, 0,        Is_wc_8 },
131da2e3ebdSchin #endif
132da2e3ebdSchin };
133da2e3ebdSchin 
134da2e3ebdSchin #if _lib_wctype
135da2e3ebdSchin 
Is_wc_1(int c)136da2e3ebdSchin static int Is_wc_1(int c) { return iswctype(c, ctype[CTYPES+0].wtype); }
Is_wc_2(int c)137da2e3ebdSchin static int Is_wc_2(int c) { return iswctype(c, ctype[CTYPES+1].wtype); }
Is_wc_3(int c)138da2e3ebdSchin static int Is_wc_3(int c) { return iswctype(c, ctype[CTYPES+2].wtype); }
Is_wc_4(int c)139da2e3ebdSchin static int Is_wc_4(int c) { return iswctype(c, ctype[CTYPES+3].wtype); }
Is_wc_5(int c)140da2e3ebdSchin static int Is_wc_5(int c) { return iswctype(c, ctype[CTYPES+4].wtype); }
Is_wc_6(int c)141da2e3ebdSchin static int Is_wc_6(int c) { return iswctype(c, ctype[CTYPES+5].wtype); }
Is_wc_7(int c)142da2e3ebdSchin static int Is_wc_7(int c) { return iswctype(c, ctype[CTYPES+6].wtype); }
Is_wc_8(int c)143da2e3ebdSchin static int Is_wc_8(int c) { return iswctype(c, ctype[CTYPES+7].wtype); }
144da2e3ebdSchin 
145da2e3ebdSchin #endif
146da2e3ebdSchin 
147da2e3ebdSchin /*
148da2e3ebdSchin  * return pointer to ctype function for :class:] in s
149da2e3ebdSchin  * s points to the first char after the initial [
150da2e3ebdSchin  * if e!=0 it points to next char in s
151da2e3ebdSchin  * 0 returned on error
152da2e3ebdSchin  */
153da2e3ebdSchin 
154da2e3ebdSchin regclass_t
regclass(const char * s,char ** e)155da2e3ebdSchin regclass(const char* s, char** e)
156da2e3ebdSchin {
157da2e3ebdSchin 	register Ctype_t*	cp;
158da2e3ebdSchin 	register int		c;
159da2e3ebdSchin 	register size_t		n;
160da2e3ebdSchin 	register const char*	t;
161da2e3ebdSchin 
162da2e3ebdSchin 	if (c = *s++)
163da2e3ebdSchin 	{
164da2e3ebdSchin 		for (t = s; *t && (*t != c || *(t + 1) != ']'); t++);
165da2e3ebdSchin 		if (*t != c)
166da2e3ebdSchin 			return 0;
167da2e3ebdSchin 		n = t - s;
168da2e3ebdSchin 		for (cp = ctypes; cp; cp = cp->next)
169da2e3ebdSchin 			if (n == cp->size && strneq(s, cp->name, n))
170da2e3ebdSchin 				goto found;
171da2e3ebdSchin 		for (cp = ctype; cp < &ctype[elementsof(ctype)]; cp++)
172da2e3ebdSchin 		{
173da2e3ebdSchin #if _lib_wctype
174da2e3ebdSchin 			if (!cp->size && (cp->name = (const char*)memdup(s, n + 1)))
175da2e3ebdSchin 			{
176da2e3ebdSchin 				*((char*)cp->name + n) = 0;
177da2e3ebdSchin 				/* mvs.390 needs the (char*) cast -- barf */
178da2e3ebdSchin 				if (!(cp->wtype = wctype((char*)cp->name)))
179da2e3ebdSchin 				{
180da2e3ebdSchin 					free((char*)cp->name);
181da2e3ebdSchin 					return 0;
182da2e3ebdSchin 				}
183da2e3ebdSchin 				cp->size = n;
184da2e3ebdSchin 				goto found;
185da2e3ebdSchin 			}
186da2e3ebdSchin #endif
187da2e3ebdSchin 			if (n == cp->size && strneq(s, cp->name, n))
188da2e3ebdSchin 				goto found;
189da2e3ebdSchin 		}
190da2e3ebdSchin 	}
191da2e3ebdSchin 	return 0;
192da2e3ebdSchin  found:
193da2e3ebdSchin 	if (e)
194da2e3ebdSchin 		*e = (char*)t + 2;
195da2e3ebdSchin 	return cp->ctype;
196da2e3ebdSchin }
197da2e3ebdSchin 
198da2e3ebdSchin /*
199da2e3ebdSchin  * associate the ctype function fun with name
200da2e3ebdSchin  */
201da2e3ebdSchin 
202da2e3ebdSchin int
regaddclass(const char * name,regclass_t fun)203da2e3ebdSchin regaddclass(const char* name, regclass_t fun)
204da2e3ebdSchin {
205da2e3ebdSchin 	register Ctype_t*	cp;
206da2e3ebdSchin 	register Ctype_t*	np;
207da2e3ebdSchin 	register size_t		n;
208da2e3ebdSchin 
209da2e3ebdSchin 	n = strlen(name);
210da2e3ebdSchin 	for (cp = ctypes; cp; cp = cp->next)
211da2e3ebdSchin 		if (cp->size == n && strneq(name, cp->name, n))
212da2e3ebdSchin 		{
213da2e3ebdSchin 			cp->ctype = fun;
214da2e3ebdSchin 			return 0;
215da2e3ebdSchin 		}
216da2e3ebdSchin 	if (!(np = newof(0, Ctype_t, 1, n + 1)))
217da2e3ebdSchin 		return REG_ESPACE;
218da2e3ebdSchin 	np->size = n;
219da2e3ebdSchin 	np->name = strcpy((char*)(np + 1), name);
220da2e3ebdSchin 	np->ctype = fun;
221da2e3ebdSchin 	np->next = ctypes;
222da2e3ebdSchin 	ctypes = np;
223da2e3ebdSchin 	return 0;
224da2e3ebdSchin }
225da2e3ebdSchin 
226da2e3ebdSchin /*
227da2e3ebdSchin  * return pointer to ctype function for token
228da2e3ebdSchin  */
229da2e3ebdSchin 
230da2e3ebdSchin regclass_t
classfun(int type)231da2e3ebdSchin classfun(int type)
232da2e3ebdSchin {
233da2e3ebdSchin 	switch (type)
234da2e3ebdSchin 	{
235da2e3ebdSchin 	case T_ALNUM:		return  Isword;
236da2e3ebdSchin 	case T_ALNUM_NOT:	return Notword;
237da2e3ebdSchin 	case T_DIGIT:		return  Isdigit;
238da2e3ebdSchin 	case T_DIGIT_NOT:	return Notdigit;
239da2e3ebdSchin 	case T_SPACE:		return  Isspace;
240da2e3ebdSchin 	case T_SPACE_NOT:	return Notspace;
241da2e3ebdSchin 	}
242da2e3ebdSchin 	return 0;
243da2e3ebdSchin }
244