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