Annotation of researchv8dc/cmd/split.c, revision 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.