Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/ip_t/ire.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2000-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
* Phong Vo <[email protected]> *
19
* *
20
***********************************************************************/
21
#pragma prototyped
22
/*
23
* ire re implementation
24
*
25
* Glenn Fowler
26
* AT&T Research
27
*/
28
29
#include <ast.h>
30
#include <vmalloc.h>
31
32
struct Ire_s;
33
34
typedef int (*Ireexec_f)(struct Ire_s*, void*, size_t);
35
36
#define _IRE_PRIVATE_ \
37
Iredisc_t* disc; \
38
Vmalloc_t* vm; \
39
struct Re_s* re; \
40
int left; \
41
int right; \
42
int must; \
43
int keepvm; \
44
int type; \
45
Ireexec_f execf;
46
47
#include "ire.h"
48
49
#include <error.h>
50
51
typedef uint8_t Ireint1_t;
52
typedef uint16_t Ireint2_t;
53
typedef uint32_t Ireint4_t;
54
55
typedef struct Re_s
56
{
57
struct Re_s* next;
58
int invert;
59
int lo;
60
int hi;
61
int n;
62
Ireint_t id[1];
63
} Re_t;
64
65
#define irenewof(b,p,t,s,x) (t*)irealloc(b, p, sizeof(t) * s + x)
66
67
static void*
68
irealloc(Ire_t* ire, void* p, size_t n)
69
{
70
void* r;
71
72
if (ire->vm)
73
r = vmnewof(ire->vm, p, char, n, 0);
74
else
75
r = (*ire->disc->resizef)(ire->disc->resizehandle, p, n);
76
if (r)
77
((Re_t*)r)->lo = ((Re_t*)r)->hi = 1;
78
else if (ire->disc->errorf)
79
(*ire->disc->errorf)(ire, ire->disc, ERROR_SYSTEM|2, "out of space");
80
return r;
81
}
82
83
#define IREINT Ireint1_t
84
#define IRENEXT irenext1
85
#define IREEXEC ireexec1
86
87
#include "ireexec.h"
88
89
#define IREINT Ireint2_t
90
#define IRENEXT irenext2
91
#define IREEXEC ireexec2
92
93
#include "ireexec.h"
94
95
#define IREINT Ireint4_t
96
#define IRENEXT irenext4
97
#define IREEXEC ireexec4
98
99
#include "ireexec.h"
100
101
/*
102
* convert tuple number string
103
*/
104
105
Ireint_t
106
irenum(const char* s, char** e)
107
{
108
register Ireint_t n;
109
char* p;
110
111
n = strton(s, &p, NiL, 0);
112
for (;;)
113
{
114
s = (char*)p;
115
if (*s != '.')
116
break;
117
n = (n << 8) | (strtol(s, &p, 0) & 0xff);
118
}
119
if (e)
120
*e = p;
121
return n;
122
}
123
124
/*
125
* compile and return ire re handle
126
*/
127
128
Ire_t*
129
irecomp(const char* pattern, int element, int dots, int tuple, int group, Iredisc_t* disc)
130
{
131
register char* s;
132
char* e;
133
int m;
134
int mem;
135
Ire_t* ire;
136
Vmalloc_t* vm;
137
Re_t* re;
138
Re_t* pe;
139
140
switch (element)
141
{
142
case 1:
143
case 2:
144
case 4:
145
break;
146
default:
147
if (disc->errorf)
148
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "%d: element size must be one of { 1 2 4 }", element);
149
return 0;
150
}
151
if (tuple <= 0)
152
{
153
if (disc->errorf)
154
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "%d: tuple size must > 0", tuple);
155
return 0;
156
}
157
if (disc->resizef)
158
{
159
if (!disc->resizehandle)
160
disc->resizehandle = (*disc->resizef)(NiL, NiL, 0);
161
if (!(ire = (Ire_t*)(*disc->resizef)(disc->resizehandle, NiL, sizeof(Ire_t))))
162
{
163
if (disc->errorf)
164
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
165
if (disc->resizehandle)
166
(*disc->resizef)(disc->resizehandle, NiL, 0);
167
return 0;
168
}
169
vm = 0;
170
}
171
else if (!(vm = vmopen(Vmdcheap, Vmlast, 0)))
172
{
173
if (disc->errorf)
174
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
175
return 0;
176
}
177
else if (!(ire = vmnewof(vm, 0, Ire_t, 1, 0)))
178
{
179
if (disc->errorf)
180
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
181
vmclose(vm);
182
return 0;
183
}
184
ire->id = "ire";
185
ire->disc = disc;
186
ire->vm = vm;
187
ire->element = element;
188
ire->dots = dots;
189
ire->tuple = tuple;
190
s = (char*)pattern;
191
pe = 0;
192
mem = 0;
193
for (;;)
194
{
195
if (++mem > tuple)
196
mem = 1;
197
if (!(re = irenewof(ire, 0, Re_t, 1, 0)))
198
goto nospace;
199
for (;;)
200
{
201
switch (*s++)
202
{
203
case 0:
204
if (mem != 1)
205
{
206
s--;
207
goto append;
208
}
209
if (!ire->left)
210
{
211
pe = 0;
212
mem = 0;
213
for (re = ire->re; re; re = re->next)
214
{
215
if (re->lo)
216
break;
217
if (++mem == tuple)
218
{
219
mem = 0;
220
pe = re;
221
}
222
}
223
if (pe)
224
ire->re = pe;
225
}
226
switch (element)
227
{
228
case 1:
229
ire->execf = (Ireexec_f)ireexec1;
230
ire->group = 0xff;
231
break;
232
case 2:
233
ire->execf = (Ireexec_f)ireexec2;
234
ire->group = 0xffff;
235
break;
236
case 4:
237
ire->execf = (Ireexec_f)ireexec4;
238
ire->group = 0xffffffff;
239
break;
240
}
241
#if 0
242
sfprintf(sfstderr, "ire: element=%d tuple=%d group=%d left=%d right=%d must=%d type=%d\n", ire->element, ire->tuple, ire->group, ire->left, ire->right, ire->must, ire->type);
243
for (re = ire->re; re; re = re->next)
244
sfprintf(sfstderr, " id=%05u n=%d invert=%d lo=%d hi=%d\n", re->id[0], re->n, re->invert, re->lo, re->hi);
245
#endif
246
return ire;
247
case ':':
248
s--;
249
goto append;
250
case ' ':
251
case '\t':
252
case '_':
253
case ',':
254
case '/':
255
if (mem != 1)
256
{
257
s--;
258
goto append;
259
}
260
continue;
261
case '^':
262
if (pe)
263
goto syntax;
264
ire->left = 1;
265
continue;
266
case '$':
267
ire->right = 1;
268
for (; *s == ' ' || *s == '\t'; s++);
269
if (*s)
270
goto syntax;
271
continue;
272
case '.':
273
break;
274
case '-':
275
goto append;
276
case '0': case '1': case '2': case '3': case '4':
277
case '5': case '6': case '7': case '8': case '9':
278
re->n = 1;
279
re->id[0] = irenum(s - 1, &e);
280
s = e;
281
break;
282
case '[':
283
m = 1;
284
for (;;)
285
{
286
switch (*s++)
287
{
288
case 0:
289
goto syntax;
290
case ' ':
291
case '\t':
292
case '_':
293
case ',':
294
continue;
295
case '!':
296
case '^':
297
if (re->n || re->invert)
298
goto syntax;
299
re->invert = 1;
300
continue;
301
case ']':
302
break;
303
case '0': case '1': case '2': case '3': case '4':
304
case '5': case '6': case '7': case '8': case '9':
305
if (re->n >= m)
306
{
307
if (m == 1)
308
m = 8;
309
else
310
m *= 2;
311
if (!(re = irenewof(ire, re, Re_t, 1, (m - 1) * sizeof(re->id[0]))))
312
goto nospace;
313
}
314
re->id[re->n++] = irenum(s - 1, &e);
315
s = e;
316
continue;
317
}
318
if (re->n < m && !(re = irenewof(ire, re, Re_t, 1, (re->n - 1) * sizeof(re->id[0]))))
319
goto nospace;
320
break;
321
}
322
if (!re->n)
323
goto syntax;
324
break;
325
default:
326
goto syntax;
327
}
328
break;
329
}
330
for (;;)
331
{
332
switch (*s++)
333
{
334
case '*':
335
re->lo = 0;
336
re->hi = 0;
337
break;
338
case '+':
339
re->hi = 0;
340
break;
341
case '{':
342
if (!group)
343
goto syntax;
344
re->lo = (int)irenum(s, &e);
345
for (s = e; *s == ' ' || *s == '\t'; s++);
346
if (*s == ',')
347
{
348
re->hi = (int)irenum(s + 1, &e);
349
for (s = e; *s == ' ' || *s == '\t'; s++);
350
}
351
else
352
re->hi = re->lo;
353
if (*s != '}' || re->lo > re->hi && re->hi)
354
goto syntax;
355
s++;
356
break;
357
default:
358
s--;
359
break;
360
}
361
break;
362
}
363
append:
364
if (pe)
365
pe->next = re;
366
else
367
ire->re = re;
368
pe = re;
369
ire->must += re->lo;
370
if (*s == ':')
371
{
372
if (mem >= tuple)
373
goto syntax;
374
s++;
375
if (*s != ' ' && *s != '\t')
376
continue;
377
}
378
if (mem < tuple)
379
{
380
mem++;
381
if (!(re = irenewof(ire, 0, Re_t, 1, 0)))
382
goto nospace;
383
goto append;
384
}
385
}
386
syntax:
387
if (disc->errorf)
388
(*disc->errorf)(NiL, disc, 2, "%-.*s<<<: invalid regular expression", s - (char*)pattern + 1, pattern);
389
nospace:
390
if (ire->vm)
391
vmclose(ire->vm);
392
return 0;
393
}
394
395
/*
396
* match compiled ire re against data with size elements
397
* return 1:match 0:no-match
398
*/
399
400
int
401
ireexec(Ire_t* ire, void* data, size_t size)
402
{
403
if (!ire->re)
404
return !ire->left || !ire->right || !size;
405
return (*ire->execf)(ire, data, size);
406
}
407
408
/*
409
* free ire re handle
410
*/
411
412
int
413
irefree(Ire_t* ire)
414
{
415
if (!ire)
416
return -1;
417
if (ire->vm)
418
vmclose(ire->vm);
419
else if (ire->disc->resizehandle)
420
(*ire->disc->resizef)(ire->disc->resizehandle, NiL, 0);
421
return 0;
422
}
423
424