|
|
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.