Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/string/fmtre.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
24
/*
25
* Glenn Fowler
26
* AT&T Research
27
*
28
* return RE expression given strmatch() pattern
29
* 0 returned for invalid RE
30
*/
31
32
#include <ast.h>
33
34
typedef struct Stack_s
35
{
36
char* beg;
37
short len;
38
short min;
39
} Stack_t;
40
41
char*
42
fmtre(const char* as)
43
{
44
register char* s = (char*)as;
45
register int c;
46
register char* t;
47
register Stack_t* p;
48
char* x;
49
int n;
50
int end;
51
char* buf;
52
Stack_t stack[32];
53
54
end = 1;
55
c = 2 * strlen(s) + 1;
56
t = buf = fmtbuf(c);
57
p = stack;
58
if (*s != '*' || *(s + 1) == '(' || *(s + 1) == '-' && *(s + 2) == '(')
59
*t++ = '^';
60
else
61
s++;
62
for (;;)
63
{
64
switch (c = *s++)
65
{
66
case 0:
67
break;
68
case '\\':
69
if (!(c = *s++) || c == '{' || c == '}')
70
return 0;
71
*t++ = '\\';
72
if ((*t++ = c) == '(' && *s == '|')
73
{
74
*t++ = *s++;
75
goto logical;
76
}
77
continue;
78
case '[':
79
*t++ = c;
80
n = 0;
81
if ((c = *s++) == '!')
82
{
83
*t++ = '^';
84
c = *s++;
85
}
86
else if (c == '^')
87
{
88
if ((c = *s++) == ']')
89
{
90
*(t - 1) = '\\';
91
*t++ = '^';
92
continue;
93
}
94
n = '^';
95
}
96
for (;;)
97
{
98
if (!(*t++ = c))
99
return 0;
100
if ((c = *s++) == ']')
101
{
102
if (n)
103
*t++ = n;
104
*t++ = c;
105
break;
106
}
107
}
108
continue;
109
case '{':
110
for (x = s; *x && *x != '}'; x++);
111
if (*x++ && (*x == '(' || *x == '-' && *(x + 1) == '('))
112
{
113
if (p >= &stack[elementsof(stack)])
114
return 0;
115
p->beg = s - 1;
116
s = x;
117
p->len = s - p->beg;
118
if (p->min = *s == '-')
119
s++;
120
p++;
121
*t++ = *s++;
122
}
123
else
124
*t++ = c;
125
continue;
126
case '*':
127
if (!*s)
128
{
129
end = 0;
130
break;
131
}
132
/*FALLTHROUGH*/
133
case '?':
134
case '+':
135
case '@':
136
case '!':
137
case '~':
138
if (*s == '(' || c != '~' && *s == '-' && *(s + 1) == '(')
139
{
140
if (p >= &stack[elementsof(stack)])
141
return 0;
142
p->beg = s - 1;
143
if (c == '~')
144
{
145
if (*(s + 1) == 'E' && *(s + 2) == ')')
146
{
147
for (s += 3; *t = *s; t++, s++);
148
continue;
149
}
150
p->len = 0;
151
p->min = 0;
152
*t++ = *s++;
153
*t++ = '?';
154
}
155
else
156
{
157
p->len = c != '@';
158
if (p->min = *s == '-')
159
s++;
160
*t++ = *s++;
161
}
162
p++;
163
}
164
else
165
{
166
switch (c)
167
{
168
case '*':
169
*t++ = '.';
170
break;
171
case '?':
172
c = '.';
173
break;
174
case '+':
175
case '!':
176
*t++ = '\\';
177
break;
178
}
179
*t++ = c;
180
}
181
continue;
182
case '(':
183
if (p >= &stack[elementsof(stack)])
184
return 0;
185
p->beg = s - 1;
186
p->len = 0;
187
p->min = 0;
188
p++;
189
*t++ = c;
190
continue;
191
case ')':
192
if (p == stack)
193
return 0;
194
*t++ = c;
195
p--;
196
for (c = 0; c < p->len; c++)
197
*t++ = p->beg[c];
198
if (p->min)
199
*t++ = '?';
200
continue;
201
case '^':
202
case '.':
203
case '$':
204
*t++ = '\\';
205
*t++ = c;
206
continue;
207
case '|':
208
if (t == buf || *(t - 1) == '(')
209
return 0;
210
logical:
211
if (!*s || *s == ')')
212
return 0;
213
/*FALLTHROUGH*/
214
default:
215
*t++ = c;
216
continue;
217
}
218
break;
219
}
220
if (p != stack)
221
return 0;
222
if (end)
223
*t++ = '$';
224
*t = 0;
225
return buf;
226
}
227
228