Annotation of researchv10no/cmd/gre/cw.c, revision 1.1.1.1

1.1       root        1: #include       "re.h"
                      2: #include       "lre.h"
                      3: #include       "hdr.h"
                      4: 
                      5: typedef struct Link
                      6: {
                      7:        unsigned char l;
                      8:        struct Node *node;
                      9:        struct Link *next;
                     10: } Link;
                     11: static Link *froot;
                     12: 
                     13: #define        NEW(N)  (froot?(t = froot, froot = froot->next, t->next = 0, t->node = N, t): newlink(c, 0, N))
                     14: #define        ADD(N)  if(qtail) qtail = qtail->next = NEW(N);\
                     15:                        else qtail = qhead = NEW(N)
                     16: #define        DEL()   { Link *tmp = qhead;if((qhead = qhead->next) == 0)\
                     17:                        qtail = 0; tmp->next = froot; froot = tmp;}
                     18: 
                     19: typedef struct Node
                     20: {
                     21:        short out;
                     22:        short d;
                     23:        short shift1;
                     24:        short shift2;
                     25:        long id;
                     26:        struct Node **tab;
                     27:        Link *alts;
                     28:        struct Node *fail;
                     29: } Node;
                     30: 
                     31: static Link *newlink(re_cw*, int, Node*);
                     32: static Node *newnode(re_cw*, int);
                     33: static void zeroroot(Node*, Node*);
                     34: static void shifttab(Node*);
                     35: static void shiftprop(re_cw*,Node*);
                     36: #ifdef DEBUG
                     37: static void cwpr(register Node *n);
                     38: #endif
                     39: 
                     40: re_cw *
                     41: re_cwinit(unsigned char *cmap)
                     42: {
                     43:        register i;
                     44:        register re_cw *c;
                     45: 
                     46:        if((c = (re_cw *)egmalloc(sizeof *c, "malloc failed in re_cwinit")) == 0)
                     47:                return((re_cw *)0);
                     48:        c->nodeid = 0;
                     49:        c->maxdepth = 0;
                     50:        c->mindepth = 10000;
                     51:        c->seenerror = 0;
                     52:        c->root = newnode(c, 0);
                     53:        if(cmap)
                     54:                memmove((char *)c->map, (char *)cmap, sizeof c->map);
                     55:        else
                     56:                for(i = 0; i < sizeof c->map; i++)
                     57:                        c->map[i] = i;
                     58:        return(c);
                     59: }
                     60: 
                     61: void
                     62: re_cwadd(register re_cw *c, register unsigned char *s, register unsigned char *e)
                     63: {
                     64:        register Node *p, *state;
                     65:        register Link *l;
                     66:        int depth;
                     67: 
                     68:        for(state = c->root; s <= --e;){
                     69:                for(l = state->alts; l; l = l->next)
                     70:                        if(l->l == c->map[*e]) break;
                     71:                if(l == 0)
                     72:                        break;
                     73:                else
                     74:                        state = l->node;
                     75:        }
                     76:        if(s <= e){
                     77:                depth = state->d+1;
                     78:                l = newlink(c, *e--, p = newnode(c, depth++));
                     79:                if((l == 0) || (p == 0)){
                     80:                        c->seenerror = 1;
                     81:                        return;
                     82:                }
                     83:                l->next = state->alts;
                     84:                state->alts = l;
                     85:                state = p;
                     86:                while(s <= e){
                     87:                        state->alts = newlink(c, *e--, p = newnode(c, depth++));
                     88:                        if((state->alts == 0) || (p == 0)){
                     89:                                c->seenerror = 1;
                     90:                                return;
                     91:                        }
                     92:                        state = p;
                     93:                }
                     94:        }
                     95:        if(c->mindepth > state->d)
                     96:                c->mindepth = state->d;
                     97:        state->out = 1;
                     98: }
                     99: 
                    100: #ifdef DEBUG
                    101: static void
                    102: cwpr(register Node *n)
                    103: {
                    104:        register Link *l;
                    105: 
                    106:        Fprint(1, "%d[%d,%d]: ", n->id, n->shift1, n->shift2);
                    107:        for(l = n->alts; l; l = l->next){
                    108:                Fprint(1, "edge from \"%d\" to \"%d\" label {\"%c\"};",
                    109:                        n->id, l->node->id, l->l);
                    110:                if(l->node->out) Fprint(1, " draw \"%d\" as Doublecircle;", l->node->id);
                    111:                if(l->node->fail)
                    112:                        Fprint(1, " edge from \"%d\" to \"%d\" dashed;", l->node->id, l->node->fail->id);
                    113:                Fprint(1, "\n");
                    114:                cwpr(l->node);
                    115:        }
                    116: }
                    117: #endif
                    118: 
                    119: static void
                    120: fail(re_cw *c, Node *root)
                    121: {
                    122:        Link *qhead = 0, *qtail = 0;
                    123:        register Link *l, *ll;
                    124:        register Link *t;
                    125:        register Node *state, *r, *s;
                    126:        int a;
                    127: 
                    128:        for(l = root->alts; l; l = l->next){
                    129:                ADD(l->node);
                    130:                l->node->fail = root;
                    131:        }
                    132:        while(qhead){
                    133:                r = qhead->node;
                    134:                DEL();
                    135:                for(l = r->alts; l; l = l->next){
                    136:                        s = l->node;
                    137:                        a = l->l;
                    138:                        ADD(s);
                    139:                        for(state = r->fail; state;){
                    140:                                for(ll = state->alts; ll; ll = ll->next)
                    141:                                        if(ll->l == a)
                    142:                                                break;
                    143:                                if(ll || (state == root)){
                    144:                                        if(ll)
                    145:                                                state = ll->node;
                    146:                                        /*
                    147:                                                do it here as only other exit is
                    148:                                                state 0
                    149:                                        */
                    150:                                        if(state->out){
                    151:                                                s->out = 1;
                    152:                                        }
                    153:                                        break;
                    154:                                } else
                    155:                                        state = state->fail;
                    156:                        }
                    157:                        s->fail = state;
                    158:                }
                    159:        }
                    160:        zeroroot(root, root);
                    161: }
                    162: 
                    163: static void
                    164: zeroroot(register Node *root, register Node *n)
                    165: {
                    166:        register Link *l;
                    167: 
                    168:        if(n->fail == root)
                    169:                n->fail = 0;
                    170:        for(l = n->alts; l; l = l->next)
                    171:                zeroroot(root, l->node);
                    172: }
                    173: 
                    174: static void
                    175: shift(re_cw *c)
                    176: {
                    177:        Link *qhead = 0, *qtail = 0;
                    178:        register Link *l;
                    179:        register Link *t;
                    180:        register Node *state, *r, *s;
                    181:        int k;
                    182: 
                    183:        for(k = 0; k < 256; k++)
                    184:                c->step[k] = c->mindepth+1;
                    185:        c->root->shift1 = 1;
                    186:        c->root->shift2 = c->mindepth;
                    187:        for(l = c->root->alts; l; l = l->next){
                    188: /*             l->node->shift2 = c->root->shift2;/**/
                    189:                ADD(l->node);
                    190:                l->node->fail = 0;
                    191:        }
                    192:        while(qhead){
                    193:                r = qhead->node;
                    194:                DEL();
                    195:                r->shift1 = c->mindepth;
                    196:                r->shift2 = c->mindepth;
                    197:                if(state = r->fail){
                    198:                        do {
                    199:                                k = r->d - state->d;
                    200:                                if(k < state->shift1){
                    201:                                        state->shift1 = k;
                    202:                                }
                    203:                                if(r->out && (k < state->shift2)){
                    204:                                        state->shift2 = k;
                    205:                                }
                    206:                        } while(state = state->fail);
                    207:                }
                    208:                for(l = r->alts; l; l = l->next){
                    209:                        s = l->node;
                    210:                        ADD(s);
                    211:                }
                    212:        }
                    213:        shiftprop(c, c->root);
                    214:        shifttab(c->root);
                    215:        c->step[0] = 1;
                    216: }
                    217: 
                    218: static void
                    219: shifttab(register Node *n)
                    220: {
                    221:        register Link *l;
                    222:        register Node **nn;
                    223: 
                    224:        n->tab = nn = (Node **)calloc(256, sizeof(Node *));
                    225:        for(l = n->alts; l; l = l->next)
                    226:                nn[l->l] = l->node;
                    227: }
                    228: 
                    229: static void
                    230: shiftprop(register re_cw *c, register Node *n)
                    231: {
                    232:        register Link *l;
                    233:        register Node *nn;
                    234: 
                    235:        for(l = n->alts; l; l = l->next){
                    236:                if(c->step[l->l] > l->node->d)
                    237:                        c->step[l->l] = l->node->d;
                    238:                nn = l->node;
                    239:                if(n->shift2 < nn->shift2)
                    240:                        nn->shift2 = n->shift2;
                    241:                shiftprop(c, nn);
                    242:        }
                    243: }
                    244: 
                    245: void
                    246: re_cwcomp(re_cw *c)
                    247: {
                    248:        if(c->seenerror)
                    249:                return;
                    250:        fail(c, c->root);
                    251:        shift(c);
                    252: #ifdef DEBUG
                    253:        cwpr(c->root);
                    254: #endif
                    255: }
                    256: 
                    257: re_cwexec(void *re_c, RDFN rdfn, MATCHFN matchfn)
                    258: {
                    259:        re_cw *c = (re_cw*)re_c;
                    260:        register Node *state;
                    261:        register Link *l;
                    262:        register unsigned char *sp;
                    263:        register unsigned char *e, *s;
                    264:        register Node *ostate;
                    265:        register k;
                    266:        unsigned char *rs, *re;
                    267:        unsigned char fake[1];
                    268:        unsigned char mappedsp;
                    269: 
                    270:        if(c->seenerror)
                    271:                return(-1);
                    272:        fake[0] = 0;
                    273:        state = c->root;
                    274:        for(rs = 0; (k = (*rdfn)((char**)&rs,(char**) &re)) > 0;){
                    275: doneline:
                    276:                s = rs+c->mindepth-1;
                    277:                e = re;
                    278:                while(s < e){
                    279:                        /* scan */
                    280:                        for(sp = s; ostate = state;){
                    281:                                if(state->tab){
                    282:                                        if((state = state->tab[c->map[*sp]]) == 0)
                    283:                                                goto nomatch;
                    284:                                } else {
                    285:                                        mappedsp = c->map[*sp];
                    286:                                        for(l = state->alts; ; l = l->next){
                    287:                                                if(l == 0)
                    288:                                                        goto nomatch;
                    289:                                                if(l->l == mappedsp){
                    290:                                                        state = l->node;
                    291:                                                        break;
                    292:                                                }
                    293:                                        }
                    294:                                }
                    295: #ifdef DEBUG
                    296: print("state %d -0x%x-> state %d (out=%d)\n", ostate->id, *sp&0xFF, state->id, state->out);
                    297: #endif
                    298:                                if(state->out){
                    299:                                        unsigned char *bm = sp, *em = s+1;
                    300:                                        if((k = (*matchfn)((char**)&bm, (char**)&em)) <= 0)
                    301:                                                return(k);
                    302:                                        rs = bm;
                    303:                                        re = em;
                    304:                                        state = c->root;
                    305:                                        goto doneline;
                    306:                                }
                    307:                                if(--sp < rs){
                    308:                                        sp = fake;
                    309:                                        break;
                    310:                                }
                    311:                        }
                    312:                nomatch:
                    313:                        k = c->step[c->map[*sp]]-ostate->d-1;
                    314:                        if(k < ostate->shift1)
                    315:                                k = ostate->shift1;
                    316:                        if(k > ostate->shift2)
                    317:                                k = ostate->shift2;
                    318:                        s += k;
                    319:                        state = c->root;
                    320:                }
                    321: #ifdef DEBUG
                    322: print("end of s<e loop: s=%d e=%d, rs=%d, re=%d\n", s, e, rs, re);
                    323: #endif
                    324:                rs = re;        /* we have analysed evrything up to here */
                    325:        }
                    326:        return(k? -1:0);
                    327: }
                    328: 
                    329: static void
                    330: freenode(Node *n)
                    331: {
                    332:        register Link *l, *ll;
                    333: 
                    334:        if(n->tab)
                    335:                free((char *)n->tab);
                    336:        for(l = n->alts; l; l = ll){
                    337:                ll = l->next;
                    338:                freenode(l->node);
                    339:        }
                    340:        free((char *)n);
                    341: }
                    342: 
                    343: void
                    344: re_cwfree(re_cw *cw)
                    345: {
                    346:        register Link *l;
                    347: 
                    348:        while(froot){
                    349:                l = froot->next;
                    350:                free((char *)froot);
                    351:                froot = l;
                    352:        }
                    353:        freenode(cw->root);
                    354:        free((char *)cw);
                    355: }
                    356: 
                    357: static Node *
                    358: newnode(re_cw *c, int d)
                    359: {
                    360:        static Node *next = 0, *lim = 0;
                    361:        static incr = 1000;
                    362: 
                    363:        if(next == lim){
                    364:                next = (Node *)malloc(incr*sizeof(Node));
                    365:                if(next == 0){
                    366:                        re_error("node malloc fail");
                    367:                        return 0;
                    368:                }
                    369:                lim = next+incr;
                    370:        }
                    371:        next->d = d;
                    372:        if(d > c->maxdepth) c->maxdepth = d;
                    373:        next->id = c->nodeid++;
                    374:        next->alts = 0;
                    375:        next->tab = 0;
                    376:        next->out = 0;
                    377:        return(next++);
                    378: }
                    379: 
                    380: static Link *
                    381: newlink(re_cw *c, int l, Node *n)
                    382: {
                    383:        static Link *next = 0, *lim = 0;
                    384:        static incr = 1000;
                    385: 
                    386:        if(next == lim){
                    387:                next = (Link *)malloc(incr*sizeof(Node));
                    388:                if(next == 0){
                    389:                        re_error("link malloc fail");
                    390:                        return 0;
                    391:                }
                    392:                lim = next+incr;
                    393:        }
                    394:        next->l = c->map[l];
                    395:        next->node = n;
                    396:        next->next = 0;
                    397:        return(next++);
                    398: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.