From 75900b7bc7769a2e5049856cd5ca5993c11ee318 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Fri, 14 Dec 2018 16:21:23 -0500 Subject: [PATCH] minor refactoring and commenting --- regaux.c | 2 +- regcomp.c | 346 +++++++++++++++++++----------------------------------- regcomp.h | 14 +-- regexec.c | 11 +- regexp9.h | 14 +-- test | Bin 0 -> 69712 bytes test.c | 2 + test.o | Bin 0 -> 11592 bytes utf.c | 44 +++---- utf.h | 25 ++-- 10 files changed, 171 insertions(+), 287 deletions(-) create mode 100755 test create mode 100644 test.o diff --git a/regaux.c b/regaux.c index 0d73b29..a550543 100644 --- a/regaux.c +++ b/regaux.c @@ -89,7 +89,7 @@ extern Relist* _rrenewemptythread(Relist *lp, /* _relist to add to */ Reinst *ip, /* instruction to add */ int ms, - Rune *rsp) /* pointers to subexpressions */ + int *rsp) /* pointers to subexpressions */ { Relist *p; diff --git a/regcomp.c b/regcomp.c index cb15d17..4adc7ef 100644 --- a/regcomp.c +++ b/regcomp.c @@ -2,21 +2,16 @@ #include #include #include +#include + #include "regexp9.h" #include "regcomp.h" -#define TRUE 1 -#define FALSE 0 - -/* - * Parser Information - */ -typedef -struct Node -{ - Reinst* first; - Reinst* last; -}Node; +/* Parser Information */ +typedef struct Node { + Reinst* first; + Reinst* last; +} Node; /* max character classes per program is nelem(reprog->class) */ static Reprog *reprog; @@ -24,24 +19,26 @@ static Reprog *reprog; /* max rune ranges per character class is nelem(classp->spans)/2 */ #define NCCRUNE nelem(classp->spans) +static char* SrcExpr; /* pointer to next character in source expression */ + #define NSTACK 20 -static Node andstack[NSTACK]; -static Node *andp; -static int atorstack[NSTACK]; -static int* atorp; +static Node andstack[NSTACK]; /* Stack of operands */ +static Node* andp; /* Pointer to the top of the operand stack */ +static int atorstack[NSTACK]; /* Stack of operators */ +static int* atorp; /* Pointer to the top of the operator stack */ + static int cursubid; /* id of current subexpression */ static int subidstack[NSTACK]; /* parallel to atorstack */ static int* subidp; -static int lastwasand; /* Last token was operand */ -static int nbra; -static char* exprp; /* pointer to next character in source expression */ +static bool lastwasand; /* Last token was operand */ +static int nparens; static int lexdone; static unsigned int nclass; static Reclass*classp; static Reinst* freep; static int errors; -static Rune yyrune; /* last lex'd rune */ -static Reclass*yyclassp; /* last lex'd class */ +static int yyrune; /* last lex'd rune */ +static Reclass* yyclassp; /* last lex'd class */ /* predeclared crap */ static void operator(int); @@ -52,26 +49,81 @@ static int bldcclass(void); static jmp_buf regkaboom; -static void -rcerror(char *s) -{ +/******************************************************************************/ + +static int nextc(int* p_rune) { + if (lexdone) { + *p_rune = 0; + return 1; + } + SrcExpr += chartorune(p_rune, SrcExpr); + if(*p_rune == '\\'){ + SrcExpr += chartorune(p_rune, SrcExpr); + return 1; + } + lexdone = (*p_rune == 0); + return 0; +} + +static int lex(int literal, int dot_type) { + int quoted = nextc(&yyrune); + if (literal || quoted) { + if (yyrune == 0) + return END; + return RUNE; + } + + switch (yyrune) { + case 0: return END; + case '*': return STAR; + case '?': return QUEST; + case '+': return PLUS; + case '|': return OR; + case '.': return dot_type; + case '(': return LPAREN; + case ')': return RPAREN; + case '^': return BOL; + case '$': return EOL; + case '[': return bldcclass(); + } + return RUNE; +} + +/******************************************************************************/ + +static void rcerror(char *s) { errors++; regerror(s); longjmp(regkaboom, 1); } -static Reinst* -newinst(int t) -{ +static void regerr2(char *s, int c) { + char buf[100]; + char *cp = buf; + while(*s) + *cp++ = *s++; + *cp++ = c; + *cp = '\0'; + rcerror(buf); +} + +static void cant(char *s) { + char buf[100]; + strncpy(buf, "can't happen: ", sizeof(buf)); + strncat(buf, s, sizeof(buf)-1); + rcerror(buf); +} + +/******************************************************************************/ + +static Reinst* newinst(int t) { freep->type = t; freep->l.left = 0; freep->r.right = 0; return freep++; } -static void -operand(int t) -{ +static void operand(int t) { Reinst *i; if(lastwasand) @@ -84,53 +136,28 @@ operand(int t) i->r.r = yyrune; pushand(i, i); - lastwasand = TRUE; + lastwasand = true; } -static void -operator(int t) -{ - if(t==RBRA && --nbra<0) +static void operator(int t) { + if(t==RPAREN && --nparens<0) rcerror("unmatched right paren"); - if(t==LBRA){ + if(t==LPAREN){ if(++cursubid >= NSUBEXP) rcerror("too many subexpressions"); - nbra++; + nparens++; if(lastwasand) operator(CAT); }else evaluntil(t); - if(t != RBRA) + if(t != RPAREN) pushator(t); - lastwasand = FALSE; - if(t==STAR || t==QUEST || t==PLUS || t==RBRA) - lastwasand = TRUE; /* these look like operands */ + lastwasand = false; + if(t==STAR || t==QUEST || t==PLUS || t==RPAREN) + lastwasand = true; /* these look like operands */ } -static void -regerr2(char *s, int c) -{ - char buf[100]; - char *cp = buf; - while(*s) - *cp++ = *s++; - *cp++ = c; - *cp = '\0'; - rcerror(buf); -} - -static void -cant(char *s) -{ - char buf[100]; - strncpy(buf, "can't happen: ", sizeof(buf)); - strncat(buf, s, sizeof(buf)-1); - rcerror(buf); -} - -static void -pushand(Reinst *f, Reinst *l) -{ +static void pushand(Reinst *f, Reinst *l) { if(andp >= &andstack[NSTACK]) cant("operand stack overflow"); andp->first = f; @@ -138,18 +165,14 @@ pushand(Reinst *f, Reinst *l) andp++; } -static void -pushator(int t) -{ +static void pushator(int t) { if(atorp >= &atorstack[NSTACK]) cant("operator stack overflow"); *atorp++ = t; *subidp++ = cursubid; } -static Node* -popand(int op) -{ +static Node* popand(int op) { Reinst *inst; if(andp <= &andstack[0]){ @@ -160,32 +183,28 @@ popand(int op) return --andp; } -static int -popator(void) -{ +static int popator(void) { if(atorp <= &atorstack[0]) cant("operator stack underflow"); --subidp; return *--atorp; } -static void -evaluntil(int pri) -{ +static void evaluntil(int pri) { Node *op1, *op2; Reinst *inst1, *inst2; - while(pri==RBRA || atorp[-1]>=pri){ + while(pri==RPAREN || atorp[-1]>=pri){ switch(popator()){ default: rcerror("unknown operator in evaluntil"); break; - case LBRA: /* must have been RBRA */ + case LPAREN: /* must have been RPAREN */ op1 = popand('('); - inst2 = newinst(RBRA); + inst2 = newinst(RPAREN); inst2->r.subid = *subidp; op1->last->l.next = inst2; - inst1 = newinst(LBRA); + inst1 = newinst(LPAREN); inst1->r.subid = *subidp; inst1->l.next = op1->first; pushand(inst1, inst2); @@ -234,9 +253,7 @@ evaluntil(int pri) } } -static Reprog* -optimize(Reprog *pp) -{ +static Reprog* optimize(Reprog *pp) { Reinst *inst, *target; int size; Reprog *npp; @@ -246,7 +263,7 @@ optimize(Reprog *pp) /* * get rid of NOOP chains */ - for(inst=pp->firstinst; inst->type!=END; inst++){ + for(inst = pp->firstinst; inst->type != END; inst++){ target = inst->l.next; while(target->type == NOP) target = target->l.next; @@ -285,119 +302,17 @@ optimize(Reprog *pp) return npp; } -#ifdef DEBUG -static void -dumpstack(void){ - Node *stk; - int *ip; - - printf("operators\n"); - for(ip=atorstack; ipfirst->type, stk->last->type); -} - -static void -dump(Reprog *pp) -{ - Reinst *l; - Rune *p; - - l = pp->firstinst; - do{ - printf("%d:\t0%o\t%d\t%d", (int)(l-pp->firstinst), l->type, - (int)(l->l.left-pp->firstinst), (int)(l->r.right-pp->firstinst)); - if(l->type == RUNE) - printf("\t%C\n", l->r.r); - else if(l->type == CCLASS || l->type == NCCLASS){ - printf("\t["); - if(l->type == NCCLASS) - printf("^"); - for(p = l->r.cp->spans; p < l->r.cp->end; p += 2) - if(p[0] == p[1]) - printf("%C", p[0]); - else - printf("%C-%C", p[0], p[1]); - printf("]\n"); - } else - printf("\n"); - }while(l++->type); -} -#endif - -static Reclass* -newclass(void) -{ +static Reclass* newclass(void) { if(nclass >= nelem(reprog->class)) rcerror("too many character classes; increase Reprog.class size"); return &(classp[nclass++]); } -static int -nextc(Rune *rp) -{ - if(lexdone){ - *rp = 0; - return 1; - } - exprp += chartorune(rp, exprp); - if(*rp == '\\'){ - exprp += chartorune(rp, exprp); - return 1; - } - if(*rp == 0) - lexdone = 1; - return 0; -} - -static int -lex(int literal, int dot_type) -{ - int quoted; - - quoted = nextc(&yyrune); - if(literal || quoted){ - if(yyrune == 0) - return END; - return RUNE; - } - - switch(yyrune){ - case 0: - return END; - case '*': - return STAR; - case '?': - return QUEST; - case '+': - return PLUS; - case '|': - return OR; - case '.': - return dot_type; - case '(': - return LBRA; - case ')': - return RBRA; - case '^': - return BOL; - case '$': - return EOL; - case '[': - return bldcclass(); - } - return RUNE; -} - -static int -bldcclass(void) -{ +static int bldcclass(void) { int type; - Rune r[NCCRUNE]; - Rune *p, *ep, *np; - Rune rune; + int r[NCCRUNE]; + int *p, *ep, *np; + int rune; int quoted; /* we have already seen the '[' */ @@ -482,15 +397,12 @@ bldcclass(void) return type; } -static Reprog* -regcomp1(char *s, int literal, int dot_type) -{ +static Reprog* regcomp1(char *s, int literal, int dot_type) { int token; - Reprog *volatile pp; /* get memory for the program */ - pp = malloc(sizeof(Reprog) + 6*sizeof(Reinst)*strlen(s)); - if(pp == 0){ + Reprog* volatile pp = malloc(sizeof(Reprog) + 6*sizeof(Reinst)*strlen(s)); + if (pp == 0) { regerror("out of memory"); return 0; } @@ -498,18 +410,19 @@ regcomp1(char *s, int literal, int dot_type) classp = pp->class; errors = 0; + /* setup landing pad for fatal errors */ if(setjmp(regkaboom)) - goto out; + return (free(pp), NULL); /* go compile the sucker */ lexdone = 0; - exprp = s; + SrcExpr = s; nclass = 0; - nbra = 0; + nparens = 0; atorp = atorstack; andp = andstack; subidp = subidstack; - lastwasand = FALSE; + lastwasand = false; cursubid = 0; /* Start with a low priority operator to prime parser */ @@ -527,43 +440,22 @@ regcomp1(char *s, int literal, int dot_type) /* Force END */ operand(END); evaluntil(START); -#ifdef DEBUG - dumpstack(); -#endif - if(nbra) + if(nparens) rcerror("unmatched left paren"); --andp; /* points to first and only operand */ pp->startinst = andp->first; -#ifdef DEBUG - dump(pp); -#endif pp = optimize(pp); -#ifdef DEBUG - printf("start: %d\n", (int)(andp->first-pp->firstinst)); - dump(pp); -#endif -out: - if(errors){ - free(pp); - pp = 0; - } return pp; } -extern Reprog* -regcomp(char *s) -{ +Reprog* regcomp(char *s) { return regcomp1(s, 0, ANY); } -extern Reprog* -regcomplit(char *s) -{ +Reprog* regcomplit(char *s) { return regcomp1(s, 1, ANY); } -extern Reprog* -regcompnl(char *s) -{ +Reprog* regcompnl(char *s) { return regcomp1(s, 0, ANYNL); } diff --git a/regcomp.h b/regcomp.h index a98e5be..c21d21e 100644 --- a/regcomp.h +++ b/regcomp.h @@ -19,8 +19,8 @@ struct Resublist #define RUNE 0177 #define OPERATOR 0200 /* Bitmask of all operators */ #define START 0200 /* Start, used for marker on stack */ -#define RBRA 0201 /* Right bracket, ) */ -#define LBRA 0202 /* Left bracket, ( */ +#define RPAREN 0201 /* Right bracket, ) */ +#define LPAREN 0202 /* Left bracket, ( */ #define OR 0203 /* Alternation, | */ #define CAT 0204 /* Concatentation, implicit operator */ #define STAR 0205 /* Closure, * */ @@ -32,7 +32,7 @@ struct Resublist #define BOL 0303 /* Beginning of line, ^ */ #define EOL 0304 /* End of line, $ */ #define CCLASS 0305 /* Character class, [] */ -#define NCCLASS 0306 /* Negated character class, [] */ +#define NCCLASS 0306 /* Negated character class, [] */ #define END 0377 /* Terminate: match found */ /* @@ -52,14 +52,14 @@ struct Reljunk Relist* relist[2]; Relist* reliste[2]; int starttype; - Rune startchar; + int startchar; char* starts; char* eol; - Rune* rstarts; - Rune* reol; + int* rstarts; + int* reol; }; extern Relist* _renewthread(Relist*, Reinst*, int, Resublist*); extern void _renewmatch(Resub*, int, Resublist*); extern Relist* _renewemptythread(Relist*, Reinst*, int, char*); -extern Relist* _rrenewemptythread(Relist*, Reinst*, int, Rune*); +extern Relist* _rrenewemptythread(Relist*, Reinst*, int, int*); diff --git a/regexec.c b/regexec.c index 4d0124b..0dbdb27 100644 --- a/regexec.c +++ b/regexec.c @@ -2,7 +2,6 @@ #include "regexp9.h" #include "regcomp.h" - /* * return 0 if no match * >0 if a match @@ -21,7 +20,7 @@ regexec1(Reprog *progp, /* program to run */ Relist *tlp; char *s; int i, checkstart; - Rune r, *rp, *ep; + int r, *rp, *ep; int n; Relist* tl; /* This list, next list */ Relist* nl; @@ -63,7 +62,7 @@ regexec1(Reprog *progp, /* program to run */ } } r = *(unsigned char*)s; - if(r < Runeself) + if(r < intself) n = 1; else n = chartorune(&r, s); @@ -89,10 +88,10 @@ regexec1(Reprog *progp, /* program to run */ return -1; } break; - case LBRA: + case LPAREN: tlp->se.m[inst->r.subid].s.sp = s; continue; - case RBRA: + case RPAREN: tlp->se.m[inst->r.subid].e.ep = s; continue; case ANY: @@ -208,7 +207,7 @@ regexec(Reprog *progp, /* program to run */ } j.starttype = 0; j.startchar = 0; - if(progp->startinst->type == RUNE && progp->startinst->r.r < Runeself) { + if(progp->startinst->type == RUNE && progp->startinst->r.r < intself) { j.starttype = RUNE; j.startchar = progp->startinst->r.r; } diff --git a/regexp9.h b/regexp9.h index 962f693..9b52e66 100644 --- a/regexp9.h +++ b/regexp9.h @@ -12,12 +12,12 @@ typedef struct Resub { union { char *sp; - Rune *rsp; + int *rsp; }s; union { char *ep; - Rune *rep; + int *rep; }e; } Resub; @@ -25,8 +25,8 @@ typedef struct Resub { * character class, each pair of rune's defines a range */ typedef struct Reclass { - Rune *end; - Rune spans[64]; + int *end; + int spans[64]; } Reclass; /* @@ -36,7 +36,7 @@ struct Reinst { int type; union { Reclass *cp; /* class pointer */ - Rune r; /* character */ + int r; /* character */ int subid; /* sub-expression id for RBRA and LBRA */ Reinst *right; /* right child of OR */ }r; @@ -62,8 +62,8 @@ extern void regerror9(char*); extern int regexec9(Reprog*, char*, Resub*, int); extern void regsub9(char*, char*, int, Resub*, int); -extern int rregexec9(Reprog*, Rune*, Resub*, int); -extern void rregsub9(Rune*, Rune*, int, Resub*, int); +extern int rregexec9(Reprog*, int*, Resub*, int); +extern void rregsub9(int*, int*, int, Resub*, int); /* * Darwin simply cannot handle having routines that diff --git a/test b/test new file mode 100755 index 0000000000000000000000000000000000000000..c6242ef2da8371e358600e8e47610dfd65d4d6bd GIT binary patch literal 69712 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 literal 0 HcmV?d00001 diff --git a/test.c b/test.c index 11f728a..4e697f2 100644 --- a/test.c +++ b/test.c @@ -21,6 +21,8 @@ struct x t[] = { { "^\xE2\x98\xBA$", "smiley", 0 }, { "^(coma|research|pipe|pyxis|inet|hunny|gauss)!(.*)$", "/mail/lib/qmail '\\s' 'net!\\1' '\\2'", 0 }, { "^.*$", "/mail/lib/qmail '\\s' 'net!research' '&'", 0 }, +// { "^(((((((((((((((((((((a)))))))))))))))))))))$", "/mail/lib/qmail '\\s' 'net!research' '&'", 0 }, + { "^((((((((((((((((((a)))))))))))))))))))))$", "/mail/lib/qmail '\\s' 'net!research' '&'", 0 }, { 0, 0, 0 }, }; diff --git a/test.o b/test.o new file mode 100644 index 0000000000000000000000000000000000000000..169325ca95e4610f7ac9a03cf7b6f85c158a9d48 GIT binary patch literal 11592 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 Runemax) + if(l > intmax) goto bad; *rune = l; return 4; @@ -116,11 +116,11 @@ bad: return 1; } -Rune* -runestrchr(Rune *s, Rune c) +int* +runestrchr(int *s, int c) { - Rune c0 = c; - Rune c1; + int c0 = c; + int c1; if(c == 0) { while(*s++) @@ -135,18 +135,18 @@ runestrchr(Rune *s, Rune c) } char* -utfrune(char *s, Rune c) +utfrune(char *s, int c) { - Rune c1; - Rune r; + int c1; + int r; int n; - if(c < Runesync) /* not part of utf sequence */ + if(c < intsync) /* not part of utf sequence */ return strchr(s, c); for(;;) { c1 = *(unsigned char*)s; - if(c1 < Runeself) { /* one byte rune */ + if(c1 < intself) { /* one byte rune */ if(c1 == 0) return 0; if(c1 == c) diff --git a/utf.h b/utf.h index 7429bb9..b2fa3a0 100644 --- a/utf.h +++ b/utf.h @@ -1,25 +1,16 @@ #ifndef _UTF_H_ #define _UTF_H_ 1 -#if defined(__cplusplus) -extern "C" { -#endif - -typedef unsigned int Rune; /* 32 bits */ -enum -{ +enum { UTFmax = 4, /* maximum bytes per rune */ - Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ - Runeself = 0x80, /* rune and UTF sequences are the same (<) */ - Runeerror = 0xFFFD, /* decoding error in UTF */ - Runemax = 0x10FFFF /* maximum rune value */ + intsync = 0x80, /* cannot represent part of a UTF sequence (<) */ + intself = 0x80, /* rune and UTF sequences are the same (<) */ + interror = 0xFFFD, /* decoding error in UTF */ + intmax = 0x10FFFF /* maximum rune value */ }; -int chartorune(Rune *rune, char *str); -Rune* runestrchr(Rune *s, Rune c); -char* utfrune(char *s, Rune c); +int chartorune(int *rune, char *str); +int* runestrchr(int *s, int c); +char* utfrune(char *s, int c); -#if defined(__cplusplus) -} -#endif #endif -- 2.52.0