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