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