Deleted Added
full compact
b.c (90902) b.c (107806)
1/****************************************************************
2Copyright (C) Lucent Technologies 1997
3All Rights Reserved
4
5Permission to use, copy, modify, and distribute this software and
6its documentation for any purpose and without fee is hereby
7granted, provided that the above copyright notice appear in all
8copies and that both that the copyright notice and this

--- 61 unchanged lines hidden (view full) ---

70
71char *patbeg;
72int patlen;
73
74#define NFA 20 /* cache this many dynamic fa's */
75fa *fatab[NFA];
76int nfatab = 0; /* entries in fatab */
77
1/****************************************************************
2Copyright (C) Lucent Technologies 1997
3All Rights Reserved
4
5Permission to use, copy, modify, and distribute this software and
6its documentation for any purpose and without fee is hereby
7granted, provided that the above copyright notice appear in all
8copies and that both that the copyright notice and this

--- 61 unchanged lines hidden (view full) ---

70
71char *patbeg;
72int patlen;
73
74#define NFA 20 /* cache this many dynamic fa's */
75fa *fatab[NFA];
76int nfatab = 0; /* entries in fatab */
77
78fa *makedfa(char *s, int anchor) /* returns dfa for reg expr s */
78fa *makedfa(const char *s, int anchor) /* returns dfa for reg expr s */
79{
80 int i, use, nuse;
81 fa *pfa;
82 static int now = 1;
83
84 if (setvec == 0) { /* first time through any RE */
85 maxsetvec = MAXLIN;
86 setvec = (int *) malloc(maxsetvec * sizeof(int));

--- 25 unchanged lines hidden (view full) ---

112 nuse = i;
113 }
114 freefa(fatab[nuse]);
115 fatab[nuse] = pfa;
116 pfa->use = now++;
117 return pfa;
118}
119
79{
80 int i, use, nuse;
81 fa *pfa;
82 static int now = 1;
83
84 if (setvec == 0) { /* first time through any RE */
85 maxsetvec = MAXLIN;
86 setvec = (int *) malloc(maxsetvec * sizeof(int));

--- 25 unchanged lines hidden (view full) ---

112 nuse = i;
113 }
114 freefa(fatab[nuse]);
115 fatab[nuse] = pfa;
116 pfa->use = now++;
117 return pfa;
118}
119
120fa *mkdfa(char *s, int anchor) /* does the real work of making a dfa */
120fa *mkdfa(const char *s, int anchor) /* does the real work of making a dfa */
121 /* anchor = 1 for anchored matches, else 0 */
122{
123 Node *p, *p1;
124 fa *f;
125
126 p = reparse(s);
127 p1 = op2(CAT, op2(STAR, op2(ALL, NIL, NIL), NIL), p);
128 /* put ALL STAR in front of reg. exp. */

--- 148 unchanged lines hidden (view full) ---

277 }
278 c = n;
279 } /* else */
280 /* c = c; */
281 *pp = p;
282 return c;
283}
284
121 /* anchor = 1 for anchored matches, else 0 */
122{
123 Node *p, *p1;
124 fa *f;
125
126 p = reparse(s);
127 p1 = op2(CAT, op2(STAR, op2(ALL, NIL, NIL), NIL), p);
128 /* put ALL STAR in front of reg. exp. */

--- 148 unchanged lines hidden (view full) ---

277 }
278 c = n;
279 } /* else */
280 /* c = c; */
281 *pp = p;
282 return c;
283}
284
285char *cclenter(char *argp) /* add a character class */
285static int collate_range_cmp(int a, int b)
286{
286{
287 int r;
288 static char s[2][2];
289
290 if ((uschar)a == (uschar)b)
291 return 0;
292 s[0][0] = a;
293 s[1][0] = b;
294 if ((r = strcoll(s[0], s[1])) == 0)
295 r = (uschar)a - (uschar)b;
296 return r;
297}
298
299char *cclenter(const char *argp) /* add a character class */
300{
287 int i, c, c2;
301 int i, c, c2;
302 int j;
288 uschar *p = (uschar *) argp;
289 uschar *op, *bp;
290 static uschar *buf = 0;
291 static int bufsz = 100;
292
293 op = p;
294 if (buf == 0 && (buf = (uschar *) malloc(bufsz)) == NULL)
295 FATAL("out of space for character class [%.10s...] 1", p);
296 bp = buf;
297 for (i = 0; (c = *p++) != 0; ) {
298 if (c == '\\') {
299 c = quoted((char **) &p);
300 } else if (c == '-' && i > 0 && bp[-1] != 0) {
301 if (*p != 0) {
302 c = bp[-1];
303 c2 = *p++;
304 if (c2 == '\\')
305 c2 = quoted((char **) &p);
303 uschar *p = (uschar *) argp;
304 uschar *op, *bp;
305 static uschar *buf = 0;
306 static int bufsz = 100;
307
308 op = p;
309 if (buf == 0 && (buf = (uschar *) malloc(bufsz)) == NULL)
310 FATAL("out of space for character class [%.10s...] 1", p);
311 bp = buf;
312 for (i = 0; (c = *p++) != 0; ) {
313 if (c == '\\') {
314 c = quoted((char **) &p);
315 } else if (c == '-' && i > 0 && bp[-1] != 0) {
316 if (*p != 0) {
317 c = bp[-1];
318 c2 = *p++;
319 if (c2 == '\\')
320 c2 = quoted((char **) &p);
306 if (c > c2) { /* empty; ignore */
321 if (collate_range_cmp(c, c2) > 0) { /* empty; ignore */
307 bp--;
308 i--;
309 continue;
310 }
322 bp--;
323 i--;
324 continue;
325 }
311 while (c < c2) {
326 for (j = 0; j < NCHARS; j++) {
327 if ((collate_range_cmp(c, j) > 0) ||
328 collate_range_cmp(j, c2) > 0)
329 continue;
312 if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, 0))
313 FATAL("out of space for character class [%.10s...] 2", p);
330 if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, 0))
331 FATAL("out of space for character class [%.10s...] 2", p);
314 *bp++ = ++c;
332 *bp++ = j;
315 i++;
316 }
317 continue;
318 }
319 }
320 if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, 0))
321 FATAL("out of space for character class [%.10s...] 3", p);
322 *bp++ = c;
323 i++;
324 }
325 *bp = 0;
326 dprintf( ("cclenter: in = |%s|, out = |%s|\n", op, buf) );
327 xfree(op);
328 return (char *) tostring((char *) buf);
329}
330
333 i++;
334 }
335 continue;
336 }
337 }
338 if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, 0))
339 FATAL("out of space for character class [%.10s...] 3", p);
340 *bp++ = c;
341 i++;
342 }
343 *bp = 0;
344 dprintf( ("cclenter: in = |%s|, out = |%s|\n", op, buf) );
345 xfree(op);
346 return (char *) tostring((char *) buf);
347}
348
331void overflo(char *s)
349void overflo(const char *s)
332{
333 FATAL("regular expression too big: %.30s...", s);
334}
335
336void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfollow[leaf] */
337{
338 int i;
339 int *p;

--- 101 unchanged lines hidden (view full) ---

441 return;
442 }
443 } else /* v is right child */
444 follow(p);
445 return;
446 }
447}
448
350{
351 FATAL("regular expression too big: %.30s...", s);
352}
353
354void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfollow[leaf] */
355{
356 int i;
357 int *p;

--- 101 unchanged lines hidden (view full) ---

459 return;
460 }
461 } else /* v is right child */
462 follow(p);
463 return;
464 }
465}
466
449int member(int c, char *sarg) /* is c in s? */
467int member(int c, const char *sarg) /* is c in s? */
450{
451 uschar *s = (uschar *) sarg;
452
453 while (*s)
454 if (c == *s++)
455 return(1);
456 return(0);
457}
458
468{
469 uschar *s = (uschar *) sarg;
470
471 while (*s)
472 if (c == *s++)
473 return(1);
474 return(0);
475}
476
459int match(fa *f, char *p0) /* shortest match ? */
477int match(fa *f, const char *p0) /* shortest match ? */
460{
461 int s, ns;
462 uschar *p = (uschar *) p0;
463
464 s = f->reset ? makeinit(f,0) : f->initstat;
465 if (f->out[s])
466 return(1);
467 do {
468 if ((ns = f->gototab[s][*p]) != 0)
469 s = ns;
470 else
471 s = cgoto(f, s, *p);
472 if (f->out[s])
473 return(1);
474 } while (*p++ != 0);
475 return(0);
476}
477
478{
479 int s, ns;
480 uschar *p = (uschar *) p0;
481
482 s = f->reset ? makeinit(f,0) : f->initstat;
483 if (f->out[s])
484 return(1);
485 do {
486 if ((ns = f->gototab[s][*p]) != 0)
487 s = ns;
488 else
489 s = cgoto(f, s, *p);
490 if (f->out[s])
491 return(1);
492 } while (*p++ != 0);
493 return(0);
494}
495
478int pmatch(fa *f, char *p0) /* longest match, for sub */
496int pmatch(fa *f, const char *p0) /* longest match, for sub */
479{
480 int s, ns;
481 uschar *p = (uschar *) p0;
482 uschar *q;
483 int i, k;
484
485 s = f->reset ? makeinit(f,1) : f->initstat;
486 patbeg = (char *) p;

--- 36 unchanged lines hidden (view full) ---

523 f->out[2] = f->out[0];
524 for (i = 0; i < NCHARS; i++)
525 f->gototab[2][i] = 0;
526 }
527 } while (*p++ != 0);
528 return (0);
529}
530
497{
498 int s, ns;
499 uschar *p = (uschar *) p0;
500 uschar *q;
501 int i, k;
502
503 s = f->reset ? makeinit(f,1) : f->initstat;
504 patbeg = (char *) p;

--- 36 unchanged lines hidden (view full) ---

541 f->out[2] = f->out[0];
542 for (i = 0; i < NCHARS; i++)
543 f->gototab[2][i] = 0;
544 }
545 } while (*p++ != 0);
546 return (0);
547}
548
531int nematch(fa *f, char *p0) /* non-empty match, for sub */
549int nematch(fa *f, const char *p0) /* non-empty match, for sub */
532{
533 int s, ns;
534 uschar *p = (uschar *) p0;
535 uschar *q;
536 int i, k;
537
538 s = f->reset ? makeinit(f,1) : f->initstat;
539 patlen = -1;

--- 35 unchanged lines hidden (view full) ---

575 for (i = 0; i < NCHARS; i++)
576 f->gototab[2][i] = 0;
577 }
578 p++;
579 }
580 return (0);
581}
582
550{
551 int s, ns;
552 uschar *p = (uschar *) p0;
553 uschar *q;
554 int i, k;
555
556 s = f->reset ? makeinit(f,1) : f->initstat;
557 patlen = -1;

--- 35 unchanged lines hidden (view full) ---

593 for (i = 0; i < NCHARS; i++)
594 f->gototab[2][i] = 0;
595 }
596 p++;
597 }
598 return (0);
599}
600
583Node *reparse(char *p) /* parses regular expression pointed to by p */
601Node *reparse(const char *p) /* parses regular expression pointed to by p */
584{ /* uses relex() to scan regular expression */
585 Node *np;
586
587 dprintf( ("reparse <%s>\n", p) );
588 lastre = prestr = (uschar *) p; /* prestr points to string to be parsed */
589 rtok = relex();
602{ /* uses relex() to scan regular expression */
603 Node *np;
604
605 dprintf( ("reparse <%s>\n", p) );
606 lastre = prestr = (uschar *) p; /* prestr points to string to be parsed */
607 rtok = relex();
608 /* GNU compatibility: an empty regexp matches anything */
590 if (rtok == '\0')
609 if (rtok == '\0')
591 FATAL("empty regular expression");
610 /* FATAL("empty regular expression"); previous */
611 return(op2(ALL, NIL, NIL));
592 np = regexp();
593 if (rtok != '\0')
594 FATAL("syntax error in regular expression %s at %s", lastre, prestr);
595 return(np);
596}
597
598Node *regexp(void) /* top-level parse of reg expr */
599{

--- 88 unchanged lines hidden (view full) ---

688 * defined in IEEE P1003.1 draft 7 of June 2001, assuming the source
689 * and operating character sets are both ASCII (ISO646) or supersets
690 * thereof.
691 *
692 * Note that to avoid overflowing the temporary buffer used in
693 * relex(), the expanded character class (prior to range expansion)
694 * must be less than twice the size of their full name.
695 */
612 np = regexp();
613 if (rtok != '\0')
614 FATAL("syntax error in regular expression %s at %s", lastre, prestr);
615 return(np);
616}
617
618Node *regexp(void) /* top-level parse of reg expr */
619{

--- 88 unchanged lines hidden (view full) ---

708 * defined in IEEE P1003.1 draft 7 of June 2001, assuming the source
709 * and operating character sets are both ASCII (ISO646) or supersets
710 * thereof.
711 *
712 * Note that to avoid overflowing the temporary buffer used in
713 * relex(), the expanded character class (prior to range expansion)
714 * must be less than twice the size of their full name.
715 */
716
696struct charclass {
697 const char *cc_name;
698 int cc_namelen;
717struct charclass {
718 const char *cc_name;
719 int cc_namelen;
699 const char *cc_expand;
720 int (*cc_func)(int);
700} charclasses[] = {
721} charclasses[] = {
701 { "alnum", 5, "0-9A-Za-z" },
702 { "alpha", 5, "A-Za-z" },
703 { "blank", 5, " \t" },
704 { "cntrl", 5, "\000-\037\177" },
705 { "digit", 5, "0-9" },
706 { "graph", 5, "\041-\176" },
707 { "lower", 5, "a-z" },
708 { "print", 5, " \041-\176" },
709 { "punct", 5, "\041-\057\072-\100\133-\140\173-\176" },
710 { "space", 5, " \f\n\r\t\v" },
711 { "upper", 5, "A-Z" },
712 { "xdigit", 6, "0-9A-Fa-f" },
722 { "alnum", 5, isalnum },
723 { "alpha", 5, isalpha },
724 { "blank", 5, isblank },
725 { "cntrl", 5, iscntrl },
726 { "digit", 5, isdigit },
727 { "graph", 5, isgraph },
728 { "lower", 5, islower },
729 { "print", 5, isprint },
730 { "punct", 5, ispunct },
731 { "space", 5, isspace },
732 { "upper", 5, isupper },
733 { "xdigit", 6, isxdigit },
713 { NULL, 0, NULL },
714};
715
716
717int relex(void) /* lexical analyzer for reparse */
718{
719 int c, n;
720 int cflag;
721 static uschar *buf = 0;
722 static int bufsz = 100;
723 uschar *bp;
724 struct charclass *cc;
734 { NULL, 0, NULL },
735};
736
737
738int relex(void) /* lexical analyzer for reparse */
739{
740 int c, n;
741 int cflag;
742 static uschar *buf = 0;
743 static int bufsz = 100;
744 uschar *bp;
745 struct charclass *cc;
725 const uschar *p;
746 int i;
726
727 switch (c = *prestr++) {
728 case '|': return OR;
729 case '*': return STAR;
730 case '+': return PLUS;
731 case '?': return QUEST;
732 case '.': return DOT;
733 case '\0': prestr--; return '\0';

--- 32 unchanged lines hidden (view full) ---

766 } else if (c == '[' && *prestr == ':') {
767 /* POSIX char class names, Dag-Erling Smorgrav, des@ofug.org */
768 for (cc = charclasses; cc->cc_name; cc++)
769 if (strncmp((const char *) prestr + 1, (const char *) cc->cc_name, cc->cc_namelen) == 0)
770 break;
771 if (cc->cc_name != NULL && prestr[1 + cc->cc_namelen] == ':' &&
772 prestr[2 + cc->cc_namelen] == ']') {
773 prestr += cc->cc_namelen + 3;
747
748 switch (c = *prestr++) {
749 case '|': return OR;
750 case '*': return STAR;
751 case '+': return PLUS;
752 case '?': return QUEST;
753 case '.': return DOT;
754 case '\0': prestr--; return '\0';

--- 32 unchanged lines hidden (view full) ---

787 } else if (c == '[' && *prestr == ':') {
788 /* POSIX char class names, Dag-Erling Smorgrav, des@ofug.org */
789 for (cc = charclasses; cc->cc_name; cc++)
790 if (strncmp((const char *) prestr + 1, (const char *) cc->cc_name, cc->cc_namelen) == 0)
791 break;
792 if (cc->cc_name != NULL && prestr[1 + cc->cc_namelen] == ':' &&
793 prestr[2 + cc->cc_namelen] == ']') {
794 prestr += cc->cc_namelen + 3;
774 for (p = (const uschar *) cc->cc_expand; *p; p++)
775 *bp++ = *p;
795 for (i = 0; i < NCHARS; i++) {
796 if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, 0))
797 FATAL("out of space for reg expr %.10s...", lastre);
798 if (cc->cc_func(i)) {
799 *bp++ = i;
800 n++;
801 }
802 }
776 } else
777 *bp++ = c;
778 } else if (c == '\0') {
779 FATAL("nonterminated character class %.20s", lastre);
780 } else if (bp == buf) { /* 1st char is special */
781 *bp++ = c;
782 } else if (c == ']') {
783 *bp++ = 0;

--- 117 unchanged lines hidden ---
803 } else
804 *bp++ = c;
805 } else if (c == '\0') {
806 FATAL("nonterminated character class %.20s", lastre);
807 } else if (bp == buf) { /* 1st char is special */
808 *bp++ = c;
809 } else if (c == ']') {
810 *bp++ = 0;

--- 117 unchanged lines hidden ---