|
|
1.1 ! root 1: static char sccsid[] = "@(#)cut.c 1.2"; ! 2: # ! 3: /* cut : cut and paste columns of a table (projection of a relation) (GWRL) */ ! 4: /* Release 1.5; handles single backspaces as produced by nroff */ ! 5: # include <stdio.h> /* make: cc cut.c */ ! 6: #include <errno.h> ! 7: # define NFIELDS 512 /* max no of fields or resulting line length */ ! 8: # define BACKSPACE 8 ! 9: main(argc, argv) ! 10: int argc; ! 11: char **argv; ! 12: { ! 13: int del = '\t'; ! 14: int i, j, count, poscnt, r, s, t; ! 15: int endflag, supflag, cflag, fflag, backflag, filenr; ! 16: int sel[NFIELDS]; ! 17: register int c; ! 18: register char *p1; ! 19: char *p2, outbuf[NFIELDS]; ! 20: FILE *inptr; ! 21: endflag = supflag = cflag = fflag = 0; ! 22: ! 23: ! 24: for (i=0; i<NFIELDS; i++) ! 25: sel[i] = 0; ! 26: while (argc > 1 && argv[1][0] == '-'){ ! 27: for (i = 1; (c = argv[1][i]) != '\0'; i++) { ! 28: switch(c) { ! 29: case 'd' : ! 30: del = argv[1][++i]; ! 31: if (del == '\0') diag("no delimiter\n"); ! 32: break; ! 33: case 's': ! 34: supflag++ ; ! 35: break; ! 36: case 'c': ! 37: cflag++ ; ! 38: break; ! 39: case 'f': ! 40: fflag++ ; ! 41: break; ! 42: default : ! 43: diag("Usage: cut [-s] [-d<char>] {-c<list> | -f<list>} file ...\n"); ! 44: break; ! 45: } ! 46: if (!endflag && (cflag || fflag)) { ! 47: endflag = 1; ! 48: r = s = t = 0; ! 49: do { ! 50: c = argv[1][++i]; ! 51: switch(c) { ! 52: case '-' : ! 53: if (r) diagl(); ! 54: r = 1; ! 55: if (t == 0) s = 1; ! 56: else { ! 57: s = t; ! 58: t = 0; ! 59: } ! 60: continue; ! 61: case '\0' : ! 62: case ',' : ! 63: if (t >= NFIELDS) diagl(); ! 64: if (r) { ! 65: if (t == 0) t = NFIELDS - 1; ! 66: if (t<s) diagl(); ! 67: for(j = s; j <= t; j++) sel[j] = 1; ! 68: } ! 69: else sel[t] = (t > 0 ? 1 : 0); ! 70: r = s = t = 0; ! 71: if (c == '\0') { ! 72: i--; ! 73: break; ! 74: } ! 75: continue; ! 76: default : ! 77: if (c< '0' || c> '9') diagl(); ! 78: t = 10*t + c - '0'; ! 79: continue; ! 80: } ! 81: for (j = t = 0; j < NFIELDS; j++) t += sel[j]; ! 82: if (t == 0) diag("no fields\n"); ! 83: } while (c != '\0'); ! 84: } ! 85: } ! 86: --argc; ! 87: ++argv; ! 88: } /* end options */ ! 89: if (!(cflag || fflag)) diagl(); ! 90: ! 91: --argc; ! 92: filenr = 1; ! 93: do { /* for all input files */ ! 94: if (argc > 0) inptr = fopen(argv[filenr], "r"); ! 95: else inptr = stdin; ! 96: ! 97: if (inptr == NULL) ! 98: diag(argv[filenr]); ! 99: endflag = 0; ! 100: do { /* for all lines of a file */ ! 101: count = poscnt = backflag = 0; ! 102: p1 = &outbuf[0] - 1 ; ! 103: p2 = p1; ! 104: do { /* for all char of the line */ ! 105: c = fgetc(inptr); ! 106: if (c == EOF) { ! 107: endflag = 1; ! 108: break; ! 109: } ! 110: if (count == NFIELDS - 1) diag("line too long\n"); ! 111: if (c != '\n') *++p1 = c; ! 112: if (cflag && (c == BACKSPACE)) backflag++ ; ! 113: else ! 114: { ! 115: if ( !backflag ) poscnt += 1 ; ! 116: else backflag-- ; ! 117: } ! 118: if ( backflag > 1 ) diag("cannot handle multiple adjacent backspaces\n"); ! 119: if ( ((c == '\n') && count > 0) || c == del || cflag) { ! 120: count += 1; ! 121: if (fflag) poscnt = count ; ! 122: if (sel[poscnt]) p2 = p1; ! 123: else p1 = p2; ! 124: } ! 125: }while (c != '\n'); ! 126: if ( !endflag && (count > 0 || !supflag)) { ! 127: if (*p1 == del) *p1 = '\0'; ! 128: else *++p1 = '\0'; /*suppress trailing delimiter*/ ! 129: puts(outbuf); ! 130: } ! 131: } while (!endflag) ; ! 132: fclose(inptr); ! 133: } while(++filenr <= argc); ! 134: } ! 135: ! 136: diag(s) ! 137: char *s; ! 138: { ! 139: write(2, "cut: ", 5); ! 140: if(errno) ! 141: perror(s); ! 142: else ! 143: write(2,s,strlen(s)); ! 144: exit(2); ! 145: } ! 146: diagl() ! 147: { ! 148: diag("bad list for c/f option\n"); ! 149: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.