Annotation of researchv8dc/cmd/split.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * split -- break up a file on specified boundaries
                      3:  *
                      4:  *     status returns:
                      5:  *             0 - ok, and some matches
                      6:  *             1 - ok, but no matches
                      7:  *             2 - some error
                      8:  */
                      9: 
                     10: #include <stdio.h>
                     11: #include <ctype.h>
                     12: #include <sys/param.h>
                     13: 
                     14: #define        CBRA    1
                     15: #define        CCHR    2
                     16: #define        CDOT    4
                     17: #define        CCL     6
                     18: #define        NCCL    8
                     19: #define        CDOL    10
                     20: #define        CEOF    11
                     21: #define        CKET    12
                     22: #define        CBACK   18
                     23: 
                     24: #define        STAR    01
                     25: 
                     26: #define        LBSIZE  512
                     27: #define        ESIZE   256
                     28: #define        NBRA    9
                     29: 
                     30: char   bracket[NBRA];
                     31: char   numbra;
                     32: char   nbra;
                     33: char   linebuf[LBSIZE+1];
                     34: char   filebuf[LBSIZE+1];
                     35: char   ybuf[ESIZE];
                     36: char   *fflag="x";
                     37: char   *sflag="";
                     38: unsigned       nfile;
                     39: unsigned       nline;
                     40: int    nflag=1000;
                     41: int    xflag;
                     42: int    yflag;
                     43: int    retcode = 0;
                     44: int    circf;
                     45: int    nsucc;
                     46: char   *braslist[NBRA];
                     47: char   *braelist[NBRA];
                     48: char   bittab[] = {
                     49:        1,
                     50:        2,
                     51:        4,
                     52:        8,
                     53:        16,
                     54:        32,
                     55:        64,
                     56:        128
                     57: };
                     58: struct exp{
                     59:        char expbuf[ESIZE];
                     60:        struct exp *next;
                     61: }*firstexp, *lastexp, *expp, *malloc();
                     62: 
                     63: main(argc, argv)
                     64: char **argv;
                     65: {
                     66:        while (--argc > 0 && (++argv)[0][0]=='-')
                     67:                switch (argv[0][1]) {
                     68:                case '1': case '2': case '3': case '4': case '5':
                     69:                case '6': case '7': case '8': case '9': 
                     70:                        nflag=atoi(&argv[0][1]);
                     71:                        if(nflag<=0)
                     72:                                errexit("split: invalid numeric interval %s\n", argv[0]);
                     73:                        continue;
                     74: 
                     75:                case 'f':
                     76:                        --argc; ++argv;
                     77:                        if(argc<=0)
                     78:                                errexit("split: too few args for -f\n", (char *)NULL);
                     79:                        fflag= *argv;
                     80:                        if(fflag[0]=='\0')
                     81:                                errexit("split: null file name specified for -f\n", (char *)NULL);
                     82:                        continue;
                     83: 
                     84:                case 's':
                     85:                        --argc; ++argv;
                     86:                        if(argc<=0)
                     87:                                errexit("split: too few args for -s\n", (char *)NULL);
                     88:                        sflag= *argv;
                     89:                        continue;
                     90: 
                     91:                case 'x':
                     92:                        xflag++;
                     93:                        continue;
                     94: 
                     95:                case 'y':
                     96:                        yflag++;
                     97:                        continue;
                     98: 
                     99:                case 'e':
                    100:                        --argc;
                    101:                        ++argv;
                    102:                        if(*argv==0 || **argv=='\0')
                    103:                                errexit("split: null expression for -e\n", (char *)NULL);
                    104:                        if (yflag) {
                    105:                                register char *p, *s;
                    106:                                for (s = ybuf, p = *argv; *p; ) {
                    107:                                        if (*p == '\\') {
                    108:                                                *s++ = *p++;
                    109:                                                if (*p)
                    110:                                                        *s++ = *p++;
                    111:                                        } else if (*p == '[') {
                    112:                                                while (*p != '\0' && *p != ']')
                    113:                                                        *s++ = *p++;
                    114:                                        } else if (islower(*p)) {
                    115:                                                *s++ = '[';
                    116:                                                *s++ = toupper(*p);
                    117:                                                *s++ = *p++;
                    118:                                                *s++ = ']';
                    119:                                        } else
                    120:                                                *s++ = *p++;
                    121:                                        if (s >= ybuf+ESIZE-5)
                    122:                                                errexit("split: argument too long\n", (char *)NULL);
                    123:                                }
                    124:                                *s = '\0';
                    125:                                *argv = ybuf;
                    126:                        }
                    127:                        compile(*argv);
                    128:                        nflag=0;
                    129:                        continue;
                    130: 
                    131:                default:
                    132:                        errexit("split: unknown flag\n", (char *)NULL);
                    133:                        continue;
                    134:                }
                    135:        if(nflag)
                    136:                succeed(1);     /* Create first file */
                    137:        if (argc<=0)
                    138:                execute((char *)NULL);
                    139:        else
                    140:                execute(*argv);
                    141:        return (retcode != 0 ? retcode : nsucc == 0);
                    142: }
                    143: 
                    144: compile(astr)
                    145: char *astr;
                    146: {
                    147:        register c;
                    148:        register char *ep, *sp;
                    149:        char *cstart;
                    150:        char *lastep;
                    151:        char *bracketp;
                    152:        int cclcnt;
                    153:        int closed;
                    154:        char neg;
                    155: 
                    156:        expp=malloc(sizeof *expp);
                    157:        if(expp==NULL)
                    158:                errexit("split: too many expressions; can't malloc\n", (char *)NULL);
                    159:        if(firstexp==0) {
                    160:                firstexp=expp;
                    161:                lastexp=expp;
                    162:        } else {
                    163:                lastexp->next = expp;
                    164:                lastexp = expp;
                    165:        }
                    166:        expp->next=0;
                    167:        ep = expp->expbuf;
                    168:        sp = astr;
                    169:        lastep = 0;
                    170:        bracketp = bracket;
                    171:        closed = numbra = 0;
                    172:        if (*sp == '^') {
                    173:                circf++;
                    174:                sp++;
                    175:        }
                    176:        for (;;) {
                    177:                if (ep >= &expp->expbuf[ESIZE])
                    178:                        goto cerror;
                    179:                if ((c = *sp++) != '*')
                    180:                        lastep = ep;
                    181:                switch (c) {
                    182: 
                    183:                case '\0':
                    184:                        *ep++ = CEOF;
                    185:                        if(expp==firstexp)
                    186:                                nbra=numbra;
                    187:                        else if(nbra!=numbra)
                    188:                                errexit("split: inconsistent parentheses in expression %s\n", astr);
                    189:                        return;
                    190: 
                    191:                case '.':
                    192:                        *ep++ = CDOT;
                    193:                        continue;
                    194: 
                    195:                case '*':
                    196:                        if (lastep==0 || *lastep==CBRA || *lastep==CKET)
                    197:                                goto defchar;
                    198:                        *lastep |= STAR;
                    199:                        continue;
                    200: 
                    201:                case '$':
                    202:                        if (*sp != '\0')
                    203:                                goto defchar;
                    204:                        *ep++ = CDOL;
                    205:                        continue;
                    206: 
                    207:                case '[':
                    208:                        if(&ep[17] >= &expp->expbuf[ESIZE])
                    209:                                goto cerror;
                    210:                        *ep++ = CCL;
                    211:                        neg = 0;
                    212:                        if((c = *sp++) == '^') {
                    213:                                neg = 1;
                    214:                                c = *sp++;
                    215:                        }
                    216:                        cstart = sp;
                    217:                        do {
                    218:                                if (c=='\0')
                    219:                                        goto cerror;
                    220:                                if (c=='-' && sp>cstart && *sp!=']') {
                    221:                                        for (c = sp[-2]; c<*sp; c++)
                    222:                                                ep[c>>3] |= bittab[c&07];
                    223:                                        sp++;
                    224:                                }
                    225:                                ep[c>>3] |= bittab[c&07];
                    226:                        } while((c = *sp++) != ']');
                    227:                        if(neg) {
                    228:                                for(cclcnt = 0; cclcnt < 16; cclcnt++)
                    229:                                        ep[cclcnt] ^= -1;
                    230:                                ep[0] &= 0376;
                    231:                        }
                    232: 
                    233:                        ep += 16;
                    234: 
                    235:                        continue;
                    236: 
                    237:                case '\\':
                    238:                        if((c = *sp++) == '(') {
                    239:                                if(numbra >= NBRA) {
                    240:                                        goto cerror;
                    241:                                }
                    242:                                *bracketp++ = numbra;
                    243:                                *ep++ = CBRA;
                    244:                                *ep++ = numbra++;
                    245:                                continue;
                    246:                        }
                    247:                        if(c == ')') {
                    248:                                if(bracketp <= bracket) {
                    249:                                        goto cerror;
                    250:                                }
                    251:                                *ep++ = CKET;
                    252:                                *ep++ = *--bracketp;
                    253:                                closed++;
                    254:                                continue;
                    255:                        }
                    256: 
                    257:                        if(c >= '1' && c <= '9') {
                    258:                                if((c -= '1') >= closed)
                    259:                                        goto cerror;
                    260:                                *ep++ = CBACK;
                    261:                                *ep++ = c;
                    262:                                continue;
                    263:                        }
                    264: 
                    265:                defchar:
                    266:                default:
                    267:                        *ep++ = CCHR;
                    268:                        *ep++ = c;
                    269:                }
                    270:        }
                    271:     cerror:
                    272:        errexit("split: RE error\n", (char *)NULL);
                    273: }
                    274: 
                    275: execute(file)
                    276: char *file;
                    277: {
                    278:        register char *p1, *p2;
                    279:        register c;
                    280: 
                    281:        if (file) {
                    282:                if (freopen(file, "r", stdin) == NULL) {
                    283:                        fprintf(stderr, "split: can't open %s\n", file);
                    284:                        retcode = 2;
                    285:                        return;
                    286:                }
                    287:        }
                    288:        expp=firstexp;
                    289:        for (;;) {
                    290:                p1 = linebuf;
                    291:                if(expp==firstexp){
                    292:                        while ((c = getchar()) != '\n') {
                    293:                                if (c == EOF)
                    294:                                        return;
                    295:                                *p1++ = c;
                    296:                                if (p1 >= &linebuf[LBSIZE-2])
                    297:                                        break;
                    298:                        }
                    299:                        *p1++ = '\0';
                    300:                        p1 = linebuf;
                    301:                        if(nflag){
                    302:                                printf("%s\n", linebuf);
                    303:                                if(++nline>=nflag){
                    304:                                        succeed(1);
                    305:                                        nline=0;
                    306:                                }
                    307:                                continue;
                    308:                        }
                    309:                }
                    310:                p2 = expp->expbuf;
                    311:                if (circf) {
                    312:                        if (advance(p1, p2))
                    313:                                goto found;
                    314:                        goto nfound;
                    315:                }
                    316:                /* fast check for first character */
                    317:                if (*p2==CCHR) {
                    318:                        c = p2[1];
                    319:                        do {
                    320:                                if (*p1!=c)
                    321:                                        continue;
                    322:                                if (advance(p1, p2))
                    323:                                        goto found;
                    324:                        } while (*p1++);
                    325:                        goto nfound;
                    326:                }
                    327:                /* regular algorithm */
                    328:                do {
                    329:                        if (advance(p1, p2))
                    330:                                goto found;
                    331:                } while (*p1++);
                    332:        nfound:
                    333:                if((expp=expp->next)==0){
                    334:                        expp=firstexp;
                    335:                        printf("%s\n", linebuf);
                    336:                }
                    337:                continue;
                    338:        found:
                    339:                succeed(xflag);
                    340:                expp=firstexp;
                    341:        }
                    342: }
                    343: 
                    344: advance(lp, ep)
                    345: register char *lp, *ep;
                    346: {
                    347:        register char *curlp;
                    348:        char c;
                    349:        char *bbeg;
                    350:        int ct;
                    351: 
                    352:        for (;;) switch (*ep++) {
                    353: 
                    354:        case CCHR:
                    355:                if (*ep++ == *lp++)
                    356:                        continue;
                    357:                return(0);
                    358: 
                    359:        case CDOT:
                    360:                if (*lp++)
                    361:                        continue;
                    362:                return(0);
                    363: 
                    364:        case CDOL:
                    365:                if (*lp==0)
                    366:                        continue;
                    367:                return(0);
                    368: 
                    369:        case CEOF:
                    370:                return(1);
                    371: 
                    372:        case CCL:
                    373:                c = *lp++ & 0177;
                    374:                if(ep[c>>3] & bittab[c & 07]) {
                    375:                        ep += 16;
                    376:                        continue;
                    377:                }
                    378:                return(0);
                    379:        case CBRA:
                    380:                braslist[*ep++] = lp;
                    381:                continue;
                    382: 
                    383:        case CKET:
                    384:                braelist[*ep++] = lp;
                    385:                continue;
                    386: 
                    387:        case CBACK:
                    388:                bbeg = braslist[*ep];
                    389:                if (braelist[*ep]==0)
                    390:                        return(0);
                    391:                ct = braelist[*ep++] - bbeg;
                    392:                if(ecmp(bbeg, lp, ct)) {
                    393:                        lp += ct;
                    394:                        continue;
                    395:                }
                    396:                return(0);
                    397: 
                    398:        case CBACK|STAR:
                    399:                bbeg = braslist[*ep];
                    400:                if (braelist[*ep]==0)
                    401:                        return(0);
                    402:                ct = braelist[*ep++] - bbeg;
                    403:                curlp = lp;
                    404:                while(ecmp(bbeg, lp, ct))
                    405:                        lp += ct;
                    406:                while(lp >= curlp) {
                    407:                        if(advance(lp, ep))     return(1);
                    408:                        lp -= ct;
                    409:                }
                    410:                return(0);
                    411: 
                    412: 
                    413:        case CDOT|STAR:
                    414:                curlp = lp;
                    415:                while (*lp++);
                    416:                goto star;
                    417: 
                    418:        case CCHR|STAR:
                    419:                curlp = lp;
                    420:                while (*lp++ == *ep);
                    421:                ep++;
                    422:                goto star;
                    423: 
                    424:        case CCL|STAR:
                    425:                curlp = lp;
                    426:                do {
                    427:                        c = *lp++ & 0177;
                    428:                } while(ep[c>>3] & bittab[c & 07]);
                    429:                ep += 16;
                    430:                goto star;
                    431: 
                    432:        star:
                    433:                if(--lp == curlp) {
                    434:                        continue;
                    435:                }
                    436: 
                    437:                if(*ep == CCHR) {
                    438:                        c = ep[1];
                    439:                        do {
                    440:                                if(*lp != c)
                    441:                                        continue;
                    442:                                if(advance(lp, ep))
                    443:                                        return(1);
                    444:                        } while(lp-- > curlp);
                    445:                        return(0);
                    446:                }
                    447: 
                    448:                do {
                    449:                        if (advance(lp, ep))
                    450:                                return(1);
                    451:                } while (lp-- > curlp);
                    452:                return(0);
                    453: 
                    454:        default:
                    455:                errexit("split RE botch\n", (char *)NULL);
                    456:        }
                    457: }
                    458: 
                    459: char *
                    460: suffix()
                    461: {
                    462:        static char s[3];
                    463:        if(nfile>26*26)
                    464:                errexit("split: too many files (max 26*26)\n", (char *)NULL);
                    465:        s[0]='a'+nfile/26;
                    466:        s[1]='a'+nfile%26;
                    467:        s[2]='\0';
                    468:        nfile++;
                    469:        return(s);
                    470: }
                    471: 
                    472: char *
                    473: filename()
                    474: {
                    475:        extern char *strcat(), *strcpy();
                    476:        if(numbra==0)
                    477:                return(strcat(strcpy(filebuf, fflag), suffix()));
                    478:        if(braslist[0]>=braelist[0])
                    479:                errexit("split: null file name match; line:\n%s\n", linebuf);
                    480:        (void) strncpy(filebuf, braslist[0], braelist[0]-braslist[0]);
                    481:        if(yflag)
                    482:                lowercase(filebuf);
                    483:        (void) strcpy(&filebuf[braelist[0]-braslist[0]], sflag);
                    484:        return(filebuf);
                    485: }
                    486: 
                    487: lowercase(s)
                    488:        register char *s;
                    489: {
                    490:        do
                    491:                if(isupper(*s))
                    492:                        *s=tolower(*s);
                    493:        while(*s++);
                    494: }
                    495: 
                    496: succeed(xflag)
                    497: {
                    498:        long ftell();
                    499:        nsucc = 1;
                    500:        if(freopen(filename(), "w", stdout)==NULL)
                    501:                errexit("split: can't open %s\n", filebuf);
                    502:        if(!xflag)
                    503:                printf("%s\n", linebuf);
                    504: }
                    505: 
                    506: ecmp(a, b, count)
                    507: char   *a, *b;
                    508: {
                    509:        register cc = count;
                    510:        while(cc--)
                    511:                if(*a++ != *b++)        return(0);
                    512:        return(1);
                    513: }
                    514: 
                    515: errexit(s, f)
                    516: char *s, *f;
                    517: {
                    518:        fprintf(stderr, s, f);
                    519:        exit(2);
                    520: }

unix.superglobalmegacorp.com

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