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

unix.superglobalmegacorp.com

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