|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.