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