Annotation of researchv9/libc/gen/regexec.c, revision 1.1.1.1

1.1       root        1: #include "regprog.h"
                      2: 
                      3: /*
                      4:  *     Machine state
                      5:  */
                      6: #define LISTINCREMENT 8
                      7: typedef struct List{
                      8:        Inst    *inst;          /* Instruction of the thread */
                      9:        Subexp  se;             /* matched subexpressions in this thread */
                     10: }List;
                     11: static List    *tl, *nl;       /* This list, next list */
                     12: static List    *tle, *nle;     /* ends of this and next list */
                     13: static List    *list[2];
                     14: static List    *liste[2];
                     15: static int     listsize = LISTINCREMENT;
                     16: 
                     17: static Subexp sempty;          /* empty set of matches */
                     18: static int match;              /* true if match is found */
                     19: 
                     20: /*
                     21:  * Note optimization in addinst:
                     22:  *     *lp must be pending when addinst called; if *l has been looked
                     23:  *             at already, the optimization is a bug.
                     24:  */
                     25: static List *
                     26: newthread(lp, ip, sep)
                     27:        List *lp;       /* list to add to */
                     28:        Inst *ip;       /* instruction to add */
                     29:        register Subexp *sep;   /* pointers to subexpressions */
                     30: {
                     31:        register List *p;
                     32: 
                     33:        for(p=lp; p->inst != NULL; p++){
                     34:                if(p->inst==ip){
                     35:                        if((sep)->m[0].sp < p->se.m[0].sp)
                     36:                                p->se = *sep;
                     37:                        return NULL;
                     38:                }
                     39:        }
                     40:        p->inst = ip;
                     41:        p->se = *sep;
                     42:        (++p)->inst = NULL;
                     43:        return p;
                     44: }
                     45: 
                     46: static void
                     47: newmatch(mp, ms, sp)
                     48:        regsubexp *mp;
                     49:        int ms; 
                     50:        register Subexp *sp;
                     51: {
                     52:        register int i;
                     53: 
                     54:        if (mp==NULL || ms <=0)
                     55:                return;
                     56:        if(mp[0].sp==0 || sp->m[0].sp<mp[0].sp ||
                     57:           (sp->m[0].sp==mp[0].sp && sp->m[0].ep>mp[0].ep)) {
                     58:                for (i=0; i<ms && i<NSUBEXP; i++)
                     59:                        mp[i] = sp->m[i];
                     60:                for (; i<ms; i++)
                     61:                        mp[i].sp = mp[i].ep = NULL;
                     62:        }
                     63: }
                     64: 
                     65: extern int
                     66: regexec(progp, starts, mp, ms)
                     67:        Prog *progp;    /* program to run */
                     68:        char *starts;   /* string to run machine on */
                     69:        regsubexp *mp;  /* subexpression elements */
                     70:        int ms;         /* number of elements pointed to by mp */
                     71: {
                     72:        register flag=0;
                     73:        register Inst *inst;
                     74:        register List *tlp;
                     75:        register char *s;
                     76:        int startchar=progp->startinst->type<OPERATOR? progp->startinst->type : 0;
                     77:        int i, checkstart;
                     78: 
                     79: restart:
                     80:        match = 0;
                     81:        checkstart = startchar;
                     82:        sempty.m[0].sp = NULL;
                     83:        if (mp!=NULL && ms >0)
                     84:                mp[0].sp = mp[0].ep = NULL;
                     85:        if (list[0] == NULL) {
                     86:                list[0] = (List *)malloc(2*listsize*sizeof(List));
                     87:                list[1] = list[0] + listsize;
                     88:                liste[0] = list[0] + listsize - 1;
                     89:                liste[1] = list[1] + listsize - 1;
                     90:                if (list[0] == NULL)
                     91:                        regerror("list overflow");
                     92:        }
                     93:        list[0][0].inst = list[1][0].inst = NULL;
                     94: 
                     95:        /* Execute machine once for each character, including terminal NUL */
                     96:        s=starts;
                     97:        do{
                     98:                /* fast check for first char */
                     99:                if(checkstart && *s!=startchar)
                    100:                        continue;
                    101:                tl=list[flag];
                    102:                tle=liste[flag];
                    103:                nl=list[flag^=1];
                    104:                nle=liste[flag];
                    105:                nl->inst=0;
                    106:                /* Add first instruction to this list */
                    107:                sempty.m[0].sp = s;
                    108:                (void)newthread(tl, progp->startinst, &sempty);
                    109:                /* Execute machine until this list is empty */
                    110:                for(tlp=tl; inst=tlp->inst; tlp++){     /* assignment = */
                    111:        Switchstmt:
                    112:                        switch(inst->type){
                    113:                        default:        /* regular character */
                    114:                                if(inst->type == *s){
                    115:        Addinst:
                    116:                                        if(newthread(nl, inst->next, &tlp->se)==nle)
                    117:                                                goto realloc;
                    118:                                }
                    119:                                break;
                    120:                        case LBRA:
                    121:                                tlp->se.m[inst->subid].sp = s;
                    122:                                inst=inst->next;
                    123:                                goto Switchstmt;
                    124:                        case RBRA:
                    125:                                tlp->se.m[inst->subid].ep = s;
                    126:                                inst=inst->next;
                    127:                                goto Switchstmt;
                    128:                        case ANY:
                    129:                                goto Addinst;
                    130:                        case BOL:
                    131:                                if(s == starts){
                    132:                                        inst=inst->next;
                    133:                                        goto Switchstmt;
                    134:                                }
                    135:                                break;
                    136:                        case EOL:
                    137:                                if(*s=='\0'){
                    138:                                        inst=inst->next;
                    139:                                        goto Switchstmt;
                    140:                                }
                    141:                                break;
                    142:                        case CCLASS:
                    143:                                if(((char *)inst->right)[*s/8]&(1<<(*s&07)))
                    144:                                        goto Addinst;
                    145:                                break;
                    146:                        case OR:
                    147:                                /* evaluate right choice later */
                    148:                                if (newthread(tlp, inst->right, &tlp->se) == tle)
                    149:                                        goto realloc;
                    150:                                /* efficiency: advance and re-evaluate */
                    151:                                inst=inst->left;
                    152:                                goto Switchstmt;
                    153:                        case END:       /* Match! */
                    154:                                match = 1;
                    155:                                tlp->se.m[0].ep = s;
                    156:                                if (mp != NULL && ms > 0)                                                                       newmatch(mp, ms, &tlp->se);
                    157:                                break;
                    158:                        }
                    159:                }
                    160:                checkstart = startchar && nl->inst==NULL;
                    161:        }while(*s++);
                    162:        return match;
                    163: realloc:
                    164:        free(list[0]);
                    165:        list[0] = NULL;
                    166:        listsize += LISTINCREMENT;
                    167:        goto restart;
                    168: }
                    169: 

unix.superglobalmegacorp.com

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