docs/cut

annotate code/cut.c__4.3bsd-uwisc.1986-11-07 @ 20:c0e589b92c52

Vorgeschichte von cut in PWB/UNIX behandelt
author markus schnalke <meillo@marmaro.de>
date Thu, 28 May 2015 06:34:21 +0200
parents
children
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 }