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