Mercurial > docs > cut
comparison code/cut.c__system_iii.1980-04-11 @ 14:21ad1c1548c4
Code ausgewaehlter Implementierungen eingefuegt
Das Datum entspricht dem Dateiaenderungsdatum.
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Tue, 12 May 2015 06:46:59 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
13:bf5e41260f89 | 14:21ad1c1548c4 |
---|---|
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; | |
18 | |
19 | |
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(); | |
69 | |
70 --argc; | |
71 filenr = 1; | |
72 do { /* for all input files */ | |
73 if (argc > 0) inptr = fopen(argv[filenr], "r"); | |
74 else inptr = stdin; | |
75 | |
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 } | |
111 | |
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 } |