~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/lib/slre.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
 
3
 * All rights reserved
 
4
 *
 
5
 * "THE BEER-WARE LICENSE" (Revision 42):
 
6
 * Sergey Lyubka wrote this file.  As long as you retain this notice you
 
7
 * can do whatever you want with this stuff. If we meet some day, and you think
 
8
 * this stuff is worth it, you can buy me a beer in return.
 
9
 */
 
10
 
 
11
/*
 
12
 * Downloaded Sat Nov  5 17:43:06 CET 2011 at
 
13
 * http://slre.sourceforge.net/1.0/slre.c
 
14
 */
 
15
 
 
16
#ifdef SLRE_TEST
 
17
#include <stdio.h>
 
18
#include <assert.h>
 
19
#include <ctype.h>
 
20
#include <stdlib.h>
 
21
#include <string.h>
 
22
#else
 
23
#include <common.h>
 
24
#include <linux/ctype.h>
 
25
#endif /* SLRE_TEST */
 
26
 
 
27
#include <errno.h>
 
28
 
 
29
#include <slre.h>
 
30
 
 
31
enum {END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL,
 
32
        STAR, PLUS, STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT};
 
33
 
 
34
#ifdef SLRE_TEST
 
35
static struct {
 
36
        const char      *name;
 
37
        int             narg;
 
38
        const char      *flags;
 
39
} opcodes[] = {
 
40
        {"END",         0, ""},         /* End of code block or program */
 
41
        {"BRANCH",      2, "oo"},       /* Alternative operator, "|"    */
 
42
        {"ANY",         0, ""},         /* Match any character, "."     */
 
43
        {"EXACT",       2, "d"},        /* Match exact string           */
 
44
        {"ANYOF",       2, "D"},        /* Match any from set, "[]"     */
 
45
        {"ANYBUT",      2, "D"},        /* Match any but from set, "[^]"*/
 
46
        {"OPEN ",       1, "i"},        /* Capture start, "("           */
 
47
        {"CLOSE",       1, "i"},        /* Capture end, ")"             */
 
48
        {"BOL",         0, ""},         /* Beginning of string, "^"     */
 
49
        {"EOL",         0, ""},         /* End of string, "$"           */
 
50
        {"STAR",        1, "o"},        /* Match zero or more times "*" */
 
51
        {"PLUS",        1, "o"},        /* Match one or more times, "+" */
 
52
        {"STARQ",       1, "o"},        /* Non-greedy STAR,  "*?"       */
 
53
        {"PLUSQ",       1, "o"},        /* Non-greedy PLUS, "+?"        */
 
54
        {"QUEST",       1, "o"},        /* Match zero or one time, "?"  */
 
55
        {"SPACE",       0, ""},         /* Match whitespace, "\s"       */
 
56
        {"NONSPACE",    0, ""},         /* Match non-space, "\S"        */
 
57
        {"DIGIT",       0, ""}          /* Match digit, "\d"            */
 
58
};
 
59
#endif /* SLRE_TEST */
 
60
 
 
61
/*
 
62
 * Commands and operands are all unsigned char (1 byte long). All code offsets
 
63
 * are relative to current address, and positive (always point forward). Data
 
64
 * offsets are absolute. Commands with operands:
 
65
 *
 
66
 * BRANCH offset1 offset2
 
67
 *      Try to match the code block that follows the BRANCH instruction
 
68
 *      (code block ends with END). If no match, try to match code block that
 
69
 *      starts at offset1. If either of these match, jump to offset2.
 
70
 *
 
71
 * EXACT data_offset data_length
 
72
 *      Try to match exact string. String is recorded in data section from
 
73
 *      data_offset, and has length data_length.
 
74
 *
 
75
 * OPEN capture_number
 
76
 * CLOSE capture_number
 
77
 *      If the user have passed 'struct cap' array for captures, OPEN
 
78
 *      records the beginning of the matched substring (cap->ptr), CLOSE
 
79
 *      sets the length (cap->len) for respective capture_number.
 
80
 *
 
81
 * STAR code_offset
 
82
 * PLUS code_offset
 
83
 * QUEST code_offset
 
84
 *      *, +, ?, respectively. Try to gobble as much as possible from the
 
85
 *      matched buffer, until code block that follows these instructions
 
86
 *      matches. When the longest possible string is matched,
 
87
 *      jump to code_offset
 
88
 *
 
89
 * STARQ, PLUSQ are non-greedy versions of STAR and PLUS.
 
90
 */
 
91
 
 
92
static const char *meta_chars = "|.^$*+?()[\\";
 
93
 
 
94
#ifdef SLRE_TEST
 
95
 
 
96
static void
 
97
print_character_set(FILE *fp, const unsigned char *p, int len)
 
98
{
 
99
        int     i;
 
100
 
 
101
        for (i = 0; i < len; i++) {
 
102
                if (i > 0)
 
103
                        (void) fputc(',', fp);
 
104
                if (p[i] == 0) {
 
105
                        i++;
 
106
                        if (p[i] == 0)
 
107
                                (void) fprintf(fp, "\\x%02x", p[i]);
 
108
                        else
 
109
                                (void) fprintf(fp, "%s", opcodes[p[i]].name);
 
110
                } else if (isprint(p[i])) {
 
111
                        (void) fputc(p[i], fp);
 
112
                } else {
 
113
                        (void) fprintf(fp, "\\x%02x", p[i]);
 
114
                }
 
115
        }
 
116
}
 
117
 
 
118
void
 
119
slre_dump(const struct slre *r, FILE *fp)
 
120
{
 
121
        int     i, j, ch, op, pc;
 
122
 
 
123
        for (pc = 0; pc < r->code_size; pc++) {
 
124
 
 
125
                op = r->code[pc];
 
126
                (void) fprintf(fp, "%3d %s ", pc, opcodes[op].name);
 
127
 
 
128
                for (i = 0; opcodes[op].flags[i] != '\0'; i++)
 
129
                        switch (opcodes[op].flags[i]) {
 
130
                        case 'i':
 
131
                                (void) fprintf(fp, "%d ", r->code[pc + 1]);
 
132
                                pc++;
 
133
                                break;
 
134
                        case 'o':
 
135
                                (void) fprintf(fp, "%d ",
 
136
                                    pc + r->code[pc + 1] - i);
 
137
                                pc++;
 
138
                                break;
 
139
                        case 'D':
 
140
                                print_character_set(fp, r->data +
 
141
                                    r->code[pc + 1], r->code[pc + 2]);
 
142
                                pc += 2;
 
143
                                break;
 
144
                        case 'd':
 
145
                                (void) fputc('"', fp);
 
146
                                for (j = 0; j < r->code[pc + 2]; j++) {
 
147
                                        ch = r->data[r->code[pc + 1] + j];
 
148
                                        if (isprint(ch)) {
 
149
                                                (void) fputc(ch, fp);
 
150
                                        } else {
 
151
                                                (void) fprintf(fp,
 
152
                                                        "\\x%02x", ch);
 
153
                                        }
 
154
                                }
 
155
                                (void) fputc('"', fp);
 
156
                                pc += 2;
 
157
                                break;
 
158
                        }
 
159
 
 
160
                (void) fputc('\n', fp);
 
161
        }
 
162
}
 
163
#endif /* SLRE_TEST */
 
164
 
 
165
static void
 
166
set_jump_offset(struct slre *r, int pc, int offset)
 
167
{
 
168
        assert(offset < r->code_size);
 
169
 
 
170
        if (r->code_size - offset > 0xff)
 
171
                r->err_str = "Jump offset is too big";
 
172
        else
 
173
                r->code[pc] = (unsigned char) (r->code_size - offset);
 
174
}
 
175
 
 
176
static void
 
177
emit(struct slre *r, int code)
 
178
{
 
179
        if (r->code_size >= (int) (sizeof(r->code) / sizeof(r->code[0])))
 
180
                r->err_str = "RE is too long (code overflow)";
 
181
        else
 
182
                r->code[r->code_size++] = (unsigned char) code;
 
183
}
 
184
 
 
185
static void
 
186
store_char_in_data(struct slre *r, int ch)
 
187
{
 
188
        if (r->data_size >= (int) sizeof(r->data))
 
189
                r->err_str = "RE is too long (data overflow)";
 
190
        else
 
191
                r->data[r->data_size++] = ch;
 
192
}
 
193
 
 
194
static void
 
195
exact(struct slre *r, const char **re)
 
196
{
 
197
        int     old_data_size = r->data_size;
 
198
 
 
199
        while (**re != '\0' && (strchr(meta_chars, **re)) == NULL)
 
200
                store_char_in_data(r, *(*re)++);
 
201
 
 
202
        emit(r, EXACT);
 
203
        emit(r, old_data_size);
 
204
        emit(r, r->data_size - old_data_size);
 
205
}
 
206
 
 
207
static int
 
208
get_escape_char(const char **re)
 
209
{
 
210
        int     res;
 
211
 
 
212
        switch (*(*re)++) {
 
213
        case 'n':
 
214
                res = '\n';
 
215
                break;
 
216
        case 'r':
 
217
                res = '\r';
 
218
                break;
 
219
        case 't':
 
220
                res = '\t';
 
221
                break;
 
222
        case '0':
 
223
                res = 0;
 
224
                break;
 
225
        case 'S':
 
226
                res = NONSPACE << 8;
 
227
                break;
 
228
        case 's':
 
229
                res = SPACE << 8;
 
230
                break;
 
231
        case 'd':
 
232
                res = DIGIT << 8;
 
233
                break;
 
234
        default:
 
235
                res = (*re)[-1];
 
236
                break;
 
237
        }
 
238
 
 
239
        return res;
 
240
}
 
241
 
 
242
static void
 
243
anyof(struct slre *r, const char **re)
 
244
{
 
245
        int     esc, old_data_size = r->data_size, op = ANYOF;
 
246
 
 
247
        if (**re == '^') {
 
248
                op = ANYBUT;
 
249
                (*re)++;
 
250
        }
 
251
 
 
252
        while (**re != '\0')
 
253
 
 
254
                switch (*(*re)++) {
 
255
                case ']':
 
256
                        emit(r, op);
 
257
                        emit(r, old_data_size);
 
258
                        emit(r, r->data_size - old_data_size);
 
259
                        return;
 
260
                        /* NOTREACHED */
 
261
                        break;
 
262
                case '\\':
 
263
                        esc = get_escape_char(re);
 
264
                        if ((esc & 0xff) == 0) {
 
265
                                store_char_in_data(r, 0);
 
266
                                store_char_in_data(r, esc >> 8);
 
267
                        } else {
 
268
                                store_char_in_data(r, esc);
 
269
                        }
 
270
                        break;
 
271
                default:
 
272
                        store_char_in_data(r, (*re)[-1]);
 
273
                        break;
 
274
                }
 
275
 
 
276
        r->err_str = "No closing ']' bracket";
 
277
}
 
278
 
 
279
static void
 
280
relocate(struct slre *r, int begin, int shift)
 
281
{
 
282
        emit(r, END);
 
283
        memmove(r->code + begin + shift, r->code + begin, r->code_size - begin);
 
284
        r->code_size += shift;
 
285
}
 
286
 
 
287
static void
 
288
quantifier(struct slre *r, int prev, int op)
 
289
{
 
290
        if (r->code[prev] == EXACT && r->code[prev + 2] > 1) {
 
291
                r->code[prev + 2]--;
 
292
                emit(r, EXACT);
 
293
                emit(r, r->code[prev + 1] + r->code[prev + 2]);
 
294
                emit(r, 1);
 
295
                prev = r->code_size - 3;
 
296
        }
 
297
        relocate(r, prev, 2);
 
298
        r->code[prev] = op;
 
299
        set_jump_offset(r, prev + 1, prev);
 
300
}
 
301
 
 
302
static void
 
303
exact_one_char(struct slre *r, int ch)
 
304
{
 
305
        emit(r, EXACT);
 
306
        emit(r, r->data_size);
 
307
        emit(r, 1);
 
308
        store_char_in_data(r, ch);
 
309
}
 
310
 
 
311
static void
 
312
fixup_branch(struct slre *r, int fixup)
 
313
{
 
314
        if (fixup > 0) {
 
315
                emit(r, END);
 
316
                set_jump_offset(r, fixup, fixup - 2);
 
317
        }
 
318
}
 
319
 
 
320
static void
 
321
compile(struct slre *r, const char **re)
 
322
{
 
323
        int     op, esc, branch_start, last_op, fixup, cap_no, level;
 
324
 
 
325
        fixup = 0;
 
326
        level = r->num_caps;
 
327
        branch_start = last_op = r->code_size;
 
328
 
 
329
        for (;;)
 
330
                switch (*(*re)++) {
 
331
                case '\0':
 
332
                        (*re)--;
 
333
                        return;
 
334
                        /* NOTREACHED */
 
335
                        break;
 
336
                case '^':
 
337
                        emit(r, BOL);
 
338
                        break;
 
339
                case '$':
 
340
                        emit(r, EOL);
 
341
                        break;
 
342
                case '.':
 
343
                        last_op = r->code_size;
 
344
                        emit(r, ANY);
 
345
                        break;
 
346
                case '[':
 
347
                        last_op = r->code_size;
 
348
                        anyof(r, re);
 
349
                        break;
 
350
                case '\\':
 
351
                        last_op = r->code_size;
 
352
                        esc = get_escape_char(re);
 
353
                        if (esc & 0xff00)
 
354
                                emit(r, esc >> 8);
 
355
                        else
 
356
                                exact_one_char(r, esc);
 
357
                        break;
 
358
                case '(':
 
359
                        last_op = r->code_size;
 
360
                        cap_no = ++r->num_caps;
 
361
                        emit(r, OPEN);
 
362
                        emit(r, cap_no);
 
363
 
 
364
                        compile(r, re);
 
365
                        if (*(*re)++ != ')') {
 
366
                                r->err_str = "No closing bracket";
 
367
                                return;
 
368
                        }
 
369
 
 
370
                        emit(r, CLOSE);
 
371
                        emit(r, cap_no);
 
372
                        break;
 
373
                case ')':
 
374
                        (*re)--;
 
375
                        fixup_branch(r, fixup);
 
376
                        if (level == 0) {
 
377
                                r->err_str = "Unbalanced brackets";
 
378
                                return;
 
379
                        }
 
380
                        return;
 
381
                        /* NOTREACHED */
 
382
                        break;
 
383
                case '+':
 
384
                case '*':
 
385
                        op = (*re)[-1] == '*' ? STAR : PLUS;
 
386
                        if (**re == '?') {
 
387
                                (*re)++;
 
388
                                op = op == STAR ? STARQ : PLUSQ;
 
389
                        }
 
390
                        quantifier(r, last_op, op);
 
391
                        break;
 
392
                case '?':
 
393
                        quantifier(r, last_op, QUEST);
 
394
                        break;
 
395
                case '|':
 
396
                        fixup_branch(r, fixup);
 
397
                        relocate(r, branch_start, 3);
 
398
                        r->code[branch_start] = BRANCH;
 
399
                        set_jump_offset(r, branch_start + 1, branch_start);
 
400
                        fixup = branch_start + 2;
 
401
                        r->code[fixup] = 0xff;
 
402
                        break;
 
403
                default:
 
404
                        (*re)--;
 
405
                        last_op = r->code_size;
 
406
                        exact(r, re);
 
407
                        break;
 
408
                }
 
409
}
 
410
 
 
411
int
 
412
slre_compile(struct slre *r, const char *re)
 
413
{
 
414
        r->err_str = NULL;
 
415
        r->code_size = r->data_size = r->num_caps = r->anchored = 0;
 
416
 
 
417
        if (*re == '^')
 
418
                r->anchored++;
 
419
 
 
420
        emit(r, OPEN);  /* This will capture what matches full RE */
 
421
        emit(r, 0);
 
422
 
 
423
        while (*re != '\0')
 
424
                compile(r, &re);
 
425
 
 
426
        if (r->code[2] == BRANCH)
 
427
                fixup_branch(r, 4);
 
428
 
 
429
        emit(r, CLOSE);
 
430
        emit(r, 0);
 
431
        emit(r, END);
 
432
 
 
433
        return (r->err_str == NULL ? 1 : 0);
 
434
}
 
435
 
 
436
static int match(const struct slre *, int,
 
437
                const char *, int, int *, struct cap *);
 
438
 
 
439
static void
 
440
loop_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs)
 
441
{
 
442
        int     saved_offset, matched_offset;
 
443
 
 
444
        saved_offset = matched_offset = *ofs;
 
445
 
 
446
        while (match(r, pc + 2, s, len, ofs, NULL)) {
 
447
                saved_offset = *ofs;
 
448
                if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL))
 
449
                        matched_offset = saved_offset;
 
450
                *ofs = saved_offset;
 
451
        }
 
452
 
 
453
        *ofs = matched_offset;
 
454
}
 
455
 
 
456
static void
 
457
loop_non_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs)
 
458
{
 
459
        int     saved_offset = *ofs;
 
460
 
 
461
        while (match(r, pc + 2, s, len, ofs, NULL)) {
 
462
                saved_offset = *ofs;
 
463
                if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL))
 
464
                        break;
 
465
        }
 
466
 
 
467
        *ofs = saved_offset;
 
468
}
 
469
 
 
470
static int
 
471
is_any_of(const unsigned char *p, int len, const char *s, int *ofs)
 
472
{
 
473
        int     i, ch;
 
474
 
 
475
        ch = s[*ofs];
 
476
 
 
477
        for (i = 0; i < len; i++)
 
478
                if (p[i] == ch) {
 
479
                        (*ofs)++;
 
480
                        return 1;
 
481
                }
 
482
 
 
483
        return 0;
 
484
}
 
485
 
 
486
static int
 
487
is_any_but(const unsigned char *p, int len, const char *s, int *ofs)
 
488
{
 
489
        int     i, ch;
 
490
 
 
491
        ch = s[*ofs];
 
492
 
 
493
        for (i = 0; i < len; i++) {
 
494
                if (p[i] == ch)
 
495
                        return 0;
 
496
        }
 
497
 
 
498
        (*ofs)++;
 
499
        return 1;
 
500
}
 
501
 
 
502
static int
 
503
match(const struct slre *r, int pc, const char *s, int len,
 
504
                int *ofs, struct cap *caps)
 
505
{
 
506
        int     n, saved_offset, res = 1;
 
507
 
 
508
        while (res && r->code[pc] != END) {
 
509
 
 
510
                assert(pc < r->code_size);
 
511
                assert(pc < (int) (sizeof(r->code) / sizeof(r->code[0])));
 
512
 
 
513
                switch (r->code[pc]) {
 
514
                case BRANCH:
 
515
                        saved_offset = *ofs;
 
516
                        res = match(r, pc + 3, s, len, ofs, caps);
 
517
                        if (res == 0) {
 
518
                                *ofs = saved_offset;
 
519
                                res = match(r, pc + r->code[pc + 1],
 
520
                                    s, len, ofs, caps);
 
521
                        }
 
522
                        pc += r->code[pc + 2];
 
523
                        break;
 
524
                case EXACT:
 
525
                        res = 0;
 
526
                        n = r->code[pc + 2];    /* String length */
 
527
                        if (n <= len - *ofs && !memcmp(s + *ofs, r->data +
 
528
                            r->code[pc + 1], n)) {
 
529
                                (*ofs) += n;
 
530
                                res = 1;
 
531
                        }
 
532
                        pc += 3;
 
533
                        break;
 
534
                case QUEST:
 
535
                        res = 1;
 
536
                        saved_offset = *ofs;
 
537
                        if (!match(r, pc + 2, s, len, ofs, caps))
 
538
                                *ofs = saved_offset;
 
539
                        pc += r->code[pc + 1];
 
540
                        break;
 
541
                case STAR:
 
542
                        res = 1;
 
543
                        loop_greedy(r, pc, s, len, ofs);
 
544
                        pc += r->code[pc + 1];
 
545
                        break;
 
546
                case STARQ:
 
547
                        res = 1;
 
548
                        loop_non_greedy(r, pc, s, len, ofs);
 
549
                        pc += r->code[pc + 1];
 
550
                        break;
 
551
                case PLUS:
 
552
                        res = match(r, pc + 2, s, len, ofs, caps);
 
553
                        if (res == 0)
 
554
                                break;
 
555
 
 
556
                        loop_greedy(r, pc, s, len, ofs);
 
557
                        pc += r->code[pc + 1];
 
558
                        break;
 
559
                case PLUSQ:
 
560
                        res = match(r, pc + 2, s, len, ofs, caps);
 
561
                        if (res == 0)
 
562
                                break;
 
563
 
 
564
                        loop_non_greedy(r, pc, s, len, ofs);
 
565
                        pc += r->code[pc + 1];
 
566
                        break;
 
567
                case SPACE:
 
568
                        res = 0;
 
569
                        if (*ofs < len && isspace(((unsigned char *)s)[*ofs])) {
 
570
                                (*ofs)++;
 
571
                                res = 1;
 
572
                        }
 
573
                        pc++;
 
574
                        break;
 
575
                case NONSPACE:
 
576
                        res = 0;
 
577
                        if (*ofs < len &&
 
578
                                        !isspace(((unsigned char *)s)[*ofs])) {
 
579
                                (*ofs)++;
 
580
                                res = 1;
 
581
                        }
 
582
                        pc++;
 
583
                        break;
 
584
                case DIGIT:
 
585
                        res = 0;
 
586
                        if (*ofs < len && isdigit(((unsigned char *)s)[*ofs])) {
 
587
                                (*ofs)++;
 
588
                                res = 1;
 
589
                        }
 
590
                        pc++;
 
591
                        break;
 
592
                case ANY:
 
593
                        res = 0;
 
594
                        if (*ofs < len) {
 
595
                                (*ofs)++;
 
596
                                res = 1;
 
597
                        }
 
598
                        pc++;
 
599
                        break;
 
600
                case ANYOF:
 
601
                        res = 0;
 
602
                        if (*ofs < len)
 
603
                                res = is_any_of(r->data + r->code[pc + 1],
 
604
                                        r->code[pc + 2], s, ofs);
 
605
                        pc += 3;
 
606
                        break;
 
607
                case ANYBUT:
 
608
                        res = 0;
 
609
                        if (*ofs < len)
 
610
                                res = is_any_but(r->data + r->code[pc + 1],
 
611
                                        r->code[pc + 2], s, ofs);
 
612
                        pc += 3;
 
613
                        break;
 
614
                case BOL:
 
615
                        res = *ofs == 0 ? 1 : 0;
 
616
                        pc++;
 
617
                        break;
 
618
                case EOL:
 
619
                        res = *ofs == len ? 1 : 0;
 
620
                        pc++;
 
621
                        break;
 
622
                case OPEN:
 
623
                        if (caps != NULL)
 
624
                                caps[r->code[pc + 1]].ptr = s + *ofs;
 
625
                        pc += 2;
 
626
                        break;
 
627
                case CLOSE:
 
628
                        if (caps != NULL)
 
629
                                caps[r->code[pc + 1]].len = (s + *ofs) -
 
630
                                    caps[r->code[pc + 1]].ptr;
 
631
                        pc += 2;
 
632
                        break;
 
633
                case END:
 
634
                        pc++;
 
635
                        break;
 
636
                default:
 
637
                        printf("unknown cmd (%d) at %d\n", r->code[pc], pc);
 
638
                        assert(0);
 
639
                        break;
 
640
                }
 
641
        }
 
642
 
 
643
        return res;
 
644
}
 
645
 
 
646
int
 
647
slre_match(const struct slre *r, const char *buf, int len,
 
648
                struct cap *caps)
 
649
{
 
650
        int     i, ofs = 0, res = 0;
 
651
 
 
652
        if (r->anchored) {
 
653
                res = match(r, 0, buf, len, &ofs, caps);
 
654
        } else {
 
655
                for (i = 0; i < len && res == 0; i++) {
 
656
                        ofs = i;
 
657
                        res = match(r, 0, buf, len, &ofs, caps);
 
658
                }
 
659
        }
 
660
 
 
661
        return res;
 
662
}
 
663
 
 
664
#ifdef SLRE_TEST
 
665
#define N_CAPS  5
 
666
 
 
667
int main(int argc, char *argv[])
 
668
{
 
669
        struct slre     slre;
 
670
        struct cap      caps[N_CAPS];
 
671
        unsigned char   data[1 * 1024 * 1024];
 
672
        FILE            *fp;
 
673
        int             i, res, len;
 
674
 
 
675
        if (argc < 2) {
 
676
                fprintf(stderr, "Usage: %s 'slre' <file>\n", argv[0]);
 
677
                return 1;
 
678
        }
 
679
 
 
680
        fp = fopen(argv[2], "rb");
 
681
        if (fp == NULL) {
 
682
                fprintf(stderr, "Error: cannot open %s:%s\n",
 
683
                        argv[2], strerror(errno));
 
684
                return 1;
 
685
        }
 
686
 
 
687
        if (!slre_compile(&slre, argv[1])) {
 
688
                fprintf(stderr, "Error compiling slre: %s\n", slre.err_str);
 
689
                return 1;
 
690
        }
 
691
 
 
692
        slre_dump(&slre, stderr);
 
693
 
 
694
        while (fgets(data, sizeof(data), fp) != NULL) {
 
695
                len = strlen(data);
 
696
 
 
697
                if ((len > 0) && (data[len-1] == '\n')) {
 
698
                        data[len-1] = '\0';
 
699
                        --len;
 
700
                }
 
701
 
 
702
                printf("Data = \"%s\"\n", data);
 
703
 
 
704
                (void) memset(caps, 0, sizeof(caps));
 
705
 
 
706
                res = 0;
 
707
 
 
708
                res = slre_match(&slre, data, len, caps);
 
709
                printf("Result [%d]: %d\n", i, res);
 
710
 
 
711
                for (i = 0; i < N_CAPS; i++) {
 
712
                        if (caps[i].len > 0) {
 
713
                                printf("Substring %d: len=%d  [%.*s]\n", i,
 
714
                                        caps[i].len,
 
715
                                        caps[i].len, caps[i].ptr);
 
716
                        }
 
717
                }
 
718
                printf("----------------------------------------------------\n");
 
719
        }
 
720
        (void) fclose(fp);
 
721
 
 
722
        return 0;
 
723
}
 
724
#endif /* SLRE_TEST */