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