From: Michael D. Lowis Date: Fri, 14 Dec 2018 21:21:23 +0000 (-0500) Subject: minor refactoring and commenting X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=75900b7bc7769a2e5049856cd5ca5993c11ee318;p=proto%2Flibregexp.git minor refactoring and commenting --- 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 0000000..c6242ef Binary files /dev/null and b/test differ 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 0000000..169325c Binary files /dev/null and b/test.o differ diff --git a/utf.c b/utf.c index 5a27b68..5ff4a3c 100644 --- a/utf.c +++ b/utf.c @@ -30,19 +30,19 @@ enum T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */ T5 = ((1<<(Bit5+1))-1) ^ 0xFF, /* 1111 1000 */ - Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0000 0000 0111 1111 */ - Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0000 0000 0111 1111 1111 */ - Rune3 = (1<<(Bit3+2*Bitx))-1, /* 0000 0000 1111 1111 1111 1111 */ - Rune4 = (1<<(Bit4+3*Bitx))-1, /* 0011 1111 1111 1111 1111 1111 */ + int1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0000 0000 0111 1111 */ + int2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0000 0000 0111 1111 1111 */ + int3 = (1<<(Bit3+2*Bitx))-1, /* 0000 0000 1111 1111 1111 1111 */ + int4 = (1<<(Bit4+3*Bitx))-1, /* 0011 1111 1111 1111 1111 1111 */ Maskx = (1< 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