docs/cut

annotate 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
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 }