docs/cut

view code/cut.c__system_iii.1980-04-11 @ 40:e294684cf338

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