Annotation of researchv10no/cmd/mk/export/libc/new.mk, revision 1.1

1.1     ! root        1: #ifdef DEBUG
        !             2: #include <stdio.h>
        !             3: #endif
        !             4: #include <libc.h>
        !             5: #include "regprog.h"
        !             6: 
        !             7: /*
        !             8:  * Parser Information
        !             9:  */
        !            10: typedef struct Node{
        !            11:        Inst    *first;
        !            12:        Inst    *last;
        !            13: }Node;
        !            14: #define        NSTACK  20
        !            15: static Node    andstack[NSTACK];
        !            16: static Node    *andp;
        !            17: static int     atorstack[NSTACK];
        !            18: static int     *atorp;
        !            19: static int     cursubid;               /* id of current subexpression */
        !            20: static int     subidstack[NSTACK];     /* parallel to atorstack */
        !            21: static int     *subidp;
        !            22: static int     lastwasand;     /* Last token was operand */
        !            23: static int     nbra;
        !            24: static char    *exprp;         /* pointer to next character in source expression */
        !            25: static int     nclass;
        !            26: static Class   *classp;
        !            27: static Inst    *freep;
        !            28: static int     errors;
        !            29: 
        !            30: /* predeclared crap */
        !            31: static void operator();
        !            32: static void pushand();
        !            33: static void pushator();
        !            34: static void evaluntil();
        !            35: static void bldcclass();
        !            36: 
        !            37: static void
        !            38: rcerror(s)
        !            39:        char *s;
        !            40: {
        !            41:        errors++;
        !            42:        regerror(s);
        !            43: }
        !            44: 
        !            45: static Inst *
        !            46: newinst(t)
        !            47:        int t;
        !            48: {
        !            49:        freep->type=t;
        !            50:        freep->left=0;
        !            51:        freep->right=0;
        !            52:        return freep++;
        !            53: }
        !            54: 
        !            55: static void
        !            56: operand(t)
        !            57:        int t;
        !            58: {
        !            59:        register Inst *i;
        !            60:        if(lastwasand)
        !            61:                operator(CAT);  /* catenate is implicit */
        !            62:        i=newinst(t);
        !            63:        if(t==CCLASS)   /* ugh */
        !            64:                i->right=(Inst *)&(classp[nclass-1]);   /* UGH! */
        !            65:        pushand(i, i);
        !            66:        lastwasand=TRUE;
        !            67: }
        !            68: 
        !            69: static void
        !            70: operator(t)
        !            71:        int t;
        !            72: {
        !            73:        if(t==RBRA && --nbra<0)
        !            74:                rcerror("unmatched right paren");
        !            75:        if(t==LBRA) {
        !            76:                if (++cursubid >= NSUBEXP)
        !            77:                        rcerror ("too many subexpressions");
        !            78:                nbra++;
        !            79:                if (lastwasand)
        !            80:                        operator(CAT);
        !            81:        } else
        !            82:                evaluntil(t);
        !            83:        if(t!=RBRA)
        !            84:                pushator(t);
        !            85:        lastwasand=FALSE;
        !            86:        if(t==STAR || t==QUEST || t==PLUS || t==RBRA)
        !            87:                lastwasand=TRUE;        /* these look like operands */
        !            88: }
        !            89: 
        !            90: static void
        !            91: regerr2(s, c)
        !            92:        char *s;
        !            93: {
        !            94:        char buf[100];
        !            95:        char *cp = buf;
        !            96:        while(*s)
        !            97:                *cp++ = *s++;
        !            98:        *cp++ = c;
        !            99:        *cp = '\0'; 
        !           100:        rcerror(buf);
        !           101: }
        !           102: 
        !           103: static void
        !           104: cant(s)
        !           105:        char *s;
        !           106: {
        !           107:        char buf[100];
        !           108:        strcpy(buf, "can't happen: ");
        !           109:        strcat(buf, s);
        !           110:        rcerror(buf);
        !           111: }
        !           112: 
        !           113: static void
        !           114: pushand(f, l)
        !           115:        Inst *f, *l;
        !           116: {
        !           117:        if(andp >= &andstack[NSTACK])
        !           118:                cant("operand stack overflow");
        !           119:        andp->first=f;
        !           120:        andp->last=l;
        !           121:        andp++;
        !           122: }
        !           123: 
        !           124: static void
        !           125: pushator(t)
        !           126:        int t;
        !           127: {
        !           128:        if(atorp >= &atorstack[NSTACK])
        !           129:                cant("operator stack overflow");
        !           130:        *atorp++=t;
        !           131:        *subidp++=cursubid;
        !           132: }
        !           133: 
        !           134: static Node *
        !           135: popand(op)
        !           136: {
        !           137:        register Inst *inst;
        !           138: 
        !           139:        if(andp <= &andstack[0]) {
        !           140:                regerr2("missing operand for ", op);
        !           141:                inst=newinst(NOP);
        !           142:                pushand(inst,inst);
        !           143:        }
        !           144:        return --andp;
        !           145: }
        !           146: 
        !           147: static int
        !           148: popator()
        !           149: {
        !           150:        if(atorp <= &atorstack[0])
        !           151:                cant("operator stack underflow");
        !           152:        --subidp;
        !           153:        return *--atorp;
        !           154: }
        !           155: 
        !           156: static void
        !           157: evaluntil(pri)
        !           158:        register pri;
        !           159: {
        !           160:        register Node *op1, *op2;
        !           161:        register Inst *inst1, *inst2;
        !           162: 
        !           163:        while(pri==RBRA || atorp[-1]>=pri){
        !           164:                switch(popator()){
        !           165:                default:
        !           166:                        rcerror("unknown operator in evaluntil");
        !           167:                        break;
        !           168:                case LBRA:              /* must have been RBRA */
        !           169:                        op1=popand('(');
        !           170:                        inst2=newinst(RBRA);
        !           171:                        inst2->subid = *subidp;
        !           172:                        op1->last->next = inst2;
        !           173:                        inst1=newinst(LBRA);
        !           174:                        inst1->subid = *subidp;
        !           175:                        inst1->next=op1->first;
        !           176:                        pushand(inst1, inst2);
        !           177:                        return;
        !           178:                case OR:
        !           179:                        op2=popand('|');
        !           180:                        op1=popand('|');
        !           181:                        inst2=newinst(NOP);
        !           182:                        op2->last->next=inst2;
        !           183:                        op1->last->next=inst2;
        !           184:                        inst1=newinst(OR);
        !           185:                        inst1->right=op1->first;
        !           186:                        inst1->left=op2->first;
        !           187:                        pushand(inst1, inst2);
        !           188:                        break;
        !           189:                case CAT:
        !           190:                        op2=popand(0);
        !           191:                        op1=popand(0);
        !           192:                        op1->last->next=op2->first;
        !           193:                        pushand(op1->first, op2->last);
        !           194:                        break;
        !           195:                case STAR:
        !           196:                        op2=popand('*');
        !           197:                        inst1=newinst(OR);
        !           198:                        op2->last->next=inst1;
        !           199:                        inst1->right=op2->first;
        !           200:                        pushand(inst1, inst1);
        !           201:                        break;
        !           202:                case PLUS:
        !           203:                        op2=popand('+');
        !           204:                        inst1=newinst(OR);
        !           205:                        op2->last->next=inst1;
        !           206:                        inst1->right=op2->first;
        !           207:                        pushand(op2->first, inst1);
        !           208:                        break;
        !           209:                case QUEST:
        !           210:                        op2=popand('?');
        !           211:                        inst1=newinst(OR);
        !           212:                        inst2=newinst(NOP);
        !           213:                        inst1->left=inst2;
        !           214:                        inst1->right=op2->first;
        !           215:                        op2->last->next=inst2;
        !           216:                        pushand(inst1, inst2);
        !           217:                        break;
        !           218:                }
        !           219:        }
        !           220: }
        !           221: 
        !           222: static Prog *
        !           223: optimize(pp)
        !           224:        Prog *pp;
        !           225: {
        !           226:        register Inst *inst, *target;
        !           227:        int size;
        !           228:        Prog *npp;
        !           229: 
        !           230:        /*
        !           231:         *  get rid of NOOP chains
        !           232:         */
        !           233:        for(inst=pp->firstinst; inst->type!=END; inst++){
        !           234:                target=inst->next;
        !           235:                while(target->type == NOP)
        !           236:                        target=target->next;
        !           237:                inst->next=target;
        !           238:        }
        !           239: 
        !           240:        /*
        !           241:         *  The original allocation is for an area larger than
        !           242:         *  necessary.  Reallocate to the actual space used
        !           243:         *  and then relocate the code.
        !           244:         */
        !           245:        size = sizeof(Prog) + (freep - pp->firstinst)*sizeof(Inst);
        !           246:        npp = (Prog *)realloc((char *)pp, size);
        !           247:        if(npp==NULL || npp==pp)
        !           248:                return(pp);
        !           249:        freep = &npp->firstinst[freep - pp->firstinst];
        !           250:        npp->startinst = &npp->firstinst[pp->startinst - pp->firstinst];
        !           251:        for(inst=npp->firstinst; inst<freep; inst++){
        !           252:                switch(inst->type){
        !           253:                case OR:
        !           254:                case STAR:
        !           255:                case PLUS:
        !           256:                case QUEST:
        !           257:                        inst->right = &npp->firstinst[inst->right - pp->firstinst];
        !           258:                        break;
        !           259:                case CCLASS:
        !           260:                        inst->right = (Inst *) &npp->class[(Class*)inst->right - pp->class];
        !           261:                        break;
        !           262:                }
        !           263:                inst->left = &npp->firstinst[inst->left - pp->firstinst];
        !           264:        }
        !           265:        return(npp);
        !           266: }
        !           267: 
        !           268: #ifdef DEBUG
        !           269: static char *
        !           270: dumptype(t){
        !           271:        static char ordinary[4] = "'.'";
        !           272: 
        !           273:        switch(t){
        !           274:        case START:     return "START";
        !           275:        case RBRA:      return "RBRA";
        !           276:        case LBRA:      return "LBRA";
        !           277:        case OR:        return "OR";
        !           278:        case CAT:       return "CAT";
        !           279:        case STAR:      return "STAR";
        !           280:        case PLUS:      return "PLUS";
        !           281:        case QUEST:     return "QUEST";
        !           282:        case ANY:       return "ANY";
        !           283:        case NOP:       return "NOP";
        !           284:        case BOL:       return "BOL";
        !           285:        case EOL:       return "EOL";
        !           286:        case CCLASS:    return "CCLASS";
        !           287:        case END:       return "END";
        !           288:        default:
        !           289:                ordinary[1] = t;
        !           290:                return ordinary;
        !           291:        }
        !           292: }
        !           293: 
        !           294: static void
        !           295: dumpstack(){
        !           296:        Node *stk;
        !           297:        int *ip;
        !           298: 
        !           299:        printf("operators\n");
        !           300:        for(ip=atorstack; ip<atorp; ip++)
        !           301:                printf("0%o\n", *ip);
        !           302:        printf("operands\n");
        !           303:        for(stk=andstack; stk<andp; stk++){
        !           304:                printf("%s\t", dumptype(stk->first->type));
        !           305:                printf("%s\n", dumptype(stk->last->type));
        !           306:        }
        !           307: }
        !           308: 
        !           309: static void
        !           310: putC(c)
        !           311: {
        !           312:        if(c < ' ' || '~' < c){
        !           313:                switch(c){
        !           314:                default:
        !           315:                        putchar('^');
        !           316:                        putchar((c + '@') & 0x7f);
        !           317:                        return;
        !           318:                case '\b':
        !           319:                        c = 'b';
        !           320:                        break;
        !           321:                case '\t':
        !           322:                        c = 't';
        !           323:                        break;
        !           324:                case '\n':
        !           325:                        c = 'n';
        !           326:                        break;
        !           327:                case '\v':
        !           328:                        c = 'v';
        !           329:                        break;
        !           330:                case '\f':
        !           331:                        c = 'f';
        !           332:                        break;
        !           333:                case '\r':
        !           334:                        c = 'r';
        !           335:                        break;
        !           336:                }
        !           337:                putchar('\\');
        !           338:        }
        !           339:        putchar(c);
        !           340: }
        !           341: 
        !           342: static void
        !           343: putCHAR(from, to)
        !           344: {
        !           345:        if(from != 0)
        !           346:                if(from == to)
        !           347:                        putC(from);
        !           348:                else{
        !           349:                        putC(from);
        !           350:                        putchar('-');
        !           351:                        putC(to);
        !           352:                }
        !           353: }
        !           354: 
        !           355: static void
        !           356: dump(pp)
        !           357:        Prog *pp;
        !           358: {
        !           359:        int c, from;
        !           360:        Inst *l;
        !           361:        Class *classp;
        !           362: 
        !           363:        l=pp->firstinst;
        !           364:        do{
        !           365:                printf("%d:\t%s\t%d\t", l-pp->firstinst, dumptype(l->type),
        !           366:                        l->left-pp->firstinst);
        !           367:                if(l->type == CCLASS){
        !           368:                        classp = (Class*) l->right;
        !           369:                        putchar('[');
        !           370:                        if(classp->map[0] & 02){        /* ^A? */
        !           371:                                putchar('^');           /* assume negation */
        !           372:                                for(from=0, c=1; c < 128; ++c){
        !           373:                                        if(classp->map[c/8] & (1<<(c&07))){
        !           374:                                                putCHAR(from, c-1);
        !           375:                                                from = 0;
        !           376:                                        } else {
        !           377:                                                if(from == 0)
        !           378:                                                        from = c;
        !           379:                                        }
        !           380:                                }
        !           381:                                putCHAR(from, c-1);
        !           382:                        } else {
        !           383:                                for(from=0, c=1; c < 128; ++c){
        !           384:                                        if(classp->map[c/8] & (1<<(c&07))){
        !           385:                                                if(from == 0)
        !           386:                                                        from = c;
        !           387:                                        } else {
        !           388:                                                putCHAR(from, c-1);
        !           389:                                                from = 0;
        !           390:                                        }
        !           391:                                }
        !           392:                                putCHAR(from, c-1);
        !           393:                        }
        !           394:                        putchar(']');
        !           395:                } else
        !           396:                        printf("%d", l->right-pp->firstinst);
        !           397:                putchar('\n');
        !           398:        }while(l++->type);
        !           399: }
        !           400: #endif
        !           401: 
        !           402: static void
        !           403: startlex(s)
        !           404:        char *s;
        !           405: {
        !           406:        exprp=s;
        !           407:        nclass=0;
        !           408:        nbra=0;
        !           409: }
        !           410: 
        !           411: static Class *
        !           412: newclass(){
        !           413:        register Class *p;
        !           414:        register n;
        !           415: 
        !           416:        if(nclass >= NCLASS)
        !           417:                regerr2("too many character classes; limit", NCLASS+'0');
        !           418:        p = &(classp[nclass++]);
        !           419:        for(n=0; n<16; n++)
        !           420:                p->map[n]=0;
        !           421:        return p;
        !           422: }
        !           423: 
        !           424: static int
        !           425: lex(){
        !           426:        register c= *exprp++;
        !           427: 
        !           428:        switch(c){
        !           429:        case '\\':
        !           430:                if(*exprp)
        !           431:                        c= *exprp++;
        !           432:                break;
        !           433:        case 0:
        !           434:                c=END;
        !           435:                --exprp;        /* In case we come here again */
        !           436:                break;
        !           437:        case '*':
        !           438:                c=STAR;
        !           439:                break;
        !           440:        case '?':
        !           441:                c=QUEST;
        !           442:                break;
        !           443:        case '+':
        !           444:                c=PLUS;
        !           445:                break;
        !           446:        case '|':
        !           447:                c=OR;
        !           448:                break;
        !           449:        case '.':
        !           450:                c=ANY;
        !           451:                break;
        !           452:        case '(':
        !           453:                c=LBRA;
        !           454:                break;
        !           455:        case ')':
        !           456:                c=RBRA;
        !           457:                break;
        !           458:        case '^':
        !           459:                c=BOL;
        !           460:                break;
        !           461:        case '$':
        !           462:                c=EOL;
        !           463:                break;
        !           464:        case '[':
        !           465:                c=CCLASS;
        !           466:                bldcclass();
        !           467:                break;
        !           468:        }
        !           469:        return c;
        !           470: }
        !           471: 
        !           472: static int
        !           473: nextc(){
        !           474:        if(exprp[0]==0 || (exprp[0]=='\\' && exprp[1]==0))
        !           475:                rcerror("malformed '[]'");
        !           476:        if(exprp[0]=='\\'){
        !           477:                exprp++;
        !           478:                return *exprp++|0200;
        !           479:        }
        !           480:        return *exprp++;
        !           481: }
        !           482: 
        !           483: static void
        !           484: bldcclass(){
        !           485:        register c1, c2;
        !           486:        register Class *classp;
        !           487:        register negate=FALSE;
        !           488: 
        !           489:        classp=newclass();
        !           490:        /* we have already seen the '[' */
        !           491:        if(*exprp=='^'){
        !           492:                negate=TRUE;
        !           493:                exprp++;
        !           494:        }
        !           495:        while((c1=c2=nextc()) != ']'){
        !           496:                if(*exprp=='-'){
        !           497:                        exprp++;        /* eat '-' */
        !           498:                        if((c2=nextc()) == ']')
        !           499:                                rcerror("malformed '[]'");
        !           500:                }
        !           501:                for((c1&=0177), (c2&=0177); c1<=c2; c1++)
        !           502:                        classp->map[c1/8] |= 1<<(c1&07);
        !           503:        }
        !           504:        if(negate)
        !           505:                for(c1=0; c1<16; c1++)
        !           506:                        classp->map[c1]^=0377;
        !           507:        classp->map[0] &= 0376;         /* exclude NUL */
        !           508: }
        !           509: 
        !           510: extern regexp *
        !           511: regcomp(s)
        !           512:        char *s;
        !           513: {
        !           514:        register token;
        !           515:        Prog *pp;
        !           516: 
        !           517:        /* get memory for the program */
        !           518:        pp = (Prog *)malloc(sizeof(Prog) + 3*sizeof(Inst)*strlen(s));
        !           519:        if (pp == NULL) {
        !           520:                rcerror("out of memory");
        !           521:                return NULL;
        !           522:        }
        !           523:        freep = pp->firstinst;
        !           524:        classp = pp->class;
        !           525:        errors = 0;
        !           526: 
        !           527:        /* go compile the sucker */
        !           528:        startlex(s);
        !           529:        atorp=atorstack;
        !           530:        andp=andstack;
        !           531:        subidp=subidstack;
        !           532:        lastwasand=FALSE;
        !           533:        cursubid=0;
        !           534: 
        !           535:        /* Start with a low priority operator to prime parser */
        !           536:        pushator(START-1);
        !           537:        while((token=lex()) != END){
        !           538:                if((token&0300) == OPERATOR)
        !           539:                        operator(token);
        !           540:                else
        !           541:                        operand(token);
        !           542:        }
        !           543: 
        !           544:        /* Close with a low priority operator */
        !           545:        evaluntil(START);
        !           546: 
        !           547:        /* Force END */
        !           548:        operand(END);
        !           549:        evaluntil(START);
        !           550: #ifdef DEBUG
        !           551:        dumpstack();
        !           552: #endif
        !           553:        if(nbra)
        !           554:                rcerror("unmatched left paren");
        !           555:        --andp; /* points to first and only operand */
        !           556:        pp->startinst=andp->first;
        !           557: #ifdef DEBUG
        !           558:        dump(pp);
        !           559: #endif
        !           560:        pp = optimize(pp);
        !           561: #ifdef DEBUG
        !           562:        printf("start: %d\n", pp->startinst-pp->firstinst);
        !           563:        dump(pp);
        !           564:        fflush(stdout);
        !           565: #endif
        !           566:        if (errors) {
        !           567:                free((char *)pp);
        !           568:                pp = NULL;
        !           569:        }
        !           570:        return (regexp *)pp;
        !           571: }
        !           572: 
        !           573: #ifdef DEBUG
        !           574: #include <setjmp.h>
        !           575: 
        !           576: jmp_buf        jmpbuf;
        !           577: 
        !           578: main( argc, argv )
        !           579:        char **argv;
        !           580: {
        !           581:        regexp *prog = NULL;
        !           582:        regsubexp match[NSUBEXP];
        !           583:        char line[256];
        !           584:        int i;
        !           585: 
        !           586:        while( TRUE ) {
        !           587:                setjmp( jmpbuf );
        !           588: 
        !           589:                if(prog)
        !           590:                        free( prog );
        !           591: 
        !           592:                do {
        !           593:                        fputs( "Enter re: ", stdout );
        !           594:                        if ( gets(line) == NULL )
        !           595:                                exit(0);
        !           596:                } while( (prog = regcomp(line)) == NULL );
        !           597: 
        !           598:                fputs( "Enter string: ", stdout );
        !           599:                while( gets(line) != NULL ) {
        !           600:                        if ( !regexec(prog,line,match,NSUBEXP) )
        !           601:                                puts( "*** NO MATCH ***" );
        !           602:                        else
        !           603:                                for( i = 0; i < NSUBEXP; ++i )
        !           604:                                        if ( match[i].sp )
        !           605:                                                printf( "match[%d] = \"%.*s\"\n", i, match[i].ep - match[i].sp, match[i].sp );
        !           606:                }
        !           607:        }
        !           608: }
        !           609: 
        !           610: regerror( s )
        !           611:        char *s;
        !           612: {
        !           613:        puts( s );
        !           614:        longjmp( jmpbuf );
        !           615: }
        !           616: 
        !           617: #endif

unix.superglobalmegacorp.com

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