Annotation of researchv9/cmd/cut.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.