Annotation of researchv10no/cmd/sort/fsort.c, revision 1.1.1.1

1.1       root        1: /* Copyright 1990, AT&T Bell Labs */
                      2: #include <stdlib.h>
                      3: #include <string.h>
                      4: #include <ctype.h>
                      5: #include "fsort.h"
                      6: 
                      7: int mflag = 0;
                      8: int cflag = 0;
                      9: int keyed = 0;
                     10: 
                     11: extern void readin(void);
                     12: extern void dumptotemp(void);
                     13: extern void sealstack(struct rec *p);
                     14: extern void filelist(int, char**);
                     15: extern int getopt(int, char*const*, const char*);
                     16: extern char *optarg;
                     17: extern int optind;
                     18: 
                     19: FILE *input;
                     20: char *oname = "-";
                     21: char *tname[] = { "/usr/tmp"/*substitutable*/, "/usr/tmp", "/tmp", 0 };
                     22: 
                     23: char **files;
                     24: int nfiles;
                     25: char *nofiles[] = { "-", 0 };
                     26: 
                     27: main(int argc, char **argv)
                     28: {
                     29:        int c, n;
                     30:        static char s[3] = { '-' };
                     31:        for(;;) {
                     32:                if(optind<argc && argv[optind][0]=='+' &&
                     33:                   isdigit(argv[optind][1])) {
                     34:                        optind += fieldarg(argv[optind],
                     35:                                           argv[optind+1]);
                     36:                        continue;
                     37:                }
                     38:                n = optind;     /* for sake of case '?' */
                     39:                c = getopt(argc,argv,"a:bcdfgik:mno:rst:uw:y:MT:");
                     40:                switch(c) {
                     41:                case '?':
                     42:                        fatal("bad option", argv[n], 0);
                     43:                default:
                     44:                        fatal("implementation error 1","",0);
                     45:                case 'b':
                     46:                case 'd':
                     47:                case 'f':
                     48:                case 'g':
                     49:                case 'i':
                     50:                case 'n':
                     51:                case 'M':
                     52:                case 'r':
                     53:                        s[1] = c;
                     54:                        fieldarg(s, 0);
                     55:                        continue;
                     56:                case 'c':
                     57:                        cflag++;
                     58:                        continue;
                     59:                case 'm':
                     60:                        mflag++;
                     61:                        continue;
                     62:                case 's':
                     63:                        sflag++;
                     64:                        continue;
                     65:                case 'u':
                     66:                        uflag++;
                     67:                        sflag++;
                     68:                        continue;
                     69:                case 'a':
                     70:                        aflag++;
                     71:                        uflag++;
                     72:                        sflag++;
                     73:                        optionk(optarg, accum, &naccum);
                     74:                        continue;
                     75:                case 'k':
                     76:                        optionk(optarg, fields, &nfields);
                     77:                        continue;
                     78:                case 'o':
                     79:                        oname = optarg;
                     80:                        continue;
                     81:                case 'T':
                     82:                        tname[0] = optarg;
                     83:                        continue;
                     84:                case 'w':
                     85:                        nmerge = atoi(optarg);
                     86:                        if(nmerge < 2)
                     87:                                fatal("-w too small","",0);
                     88:                        continue;
                     89:                case 'y':
                     90:                        optiony(optarg);
                     91:                        continue;
                     92:                case 't':
                     93:                        if(strlen(optarg) != 1)
                     94:                                fatal("bad argument for -t", "", 0);
                     95:                        tab = optarg[0];
                     96:                        continue;
                     97:                case 'z':
                     98:                        warn("nonstandard option -z ignored","",0);
                     99:                case -1:
                    100:                        break;
                    101:                }
                    102:                break;
                    103:        }
                    104:        filelist(argc, argv);
                    105:        if(cflag)
                    106:                aflag = 0;
                    107:        fieldwrapup();
                    108:        tabinit();
                    109:        setsigs(cleanup);
                    110: 
                    111:        if(cflag) {
                    112:                if(nfiles > 1)
                    113:                        fatal("-c takes just one file", "", 0);
                    114:                check(files[0]);
                    115:                return 0;
                    116:        }
                    117:        if(mflag) {
                    118:                merge(0);
                    119:                return 0;
                    120:        }
                    121:        for(n=0; n<nfiles; n++) {
                    122:                input = fileopen(files[n], "r");
                    123:                readin();
                    124:                fileclose(input, files[n]);
                    125:        }
                    126:        if(stack->head==0 && nextfile==0) {     /* empty input */
                    127:                if(strcmp(oname,"-") != 0) 
                    128:                        fileclose(fileopen(oname, "w"), oname);
                    129:                return 0;
                    130:        }
                    131:        if(stack->head && stack->head->next)
                    132:                sort(stack, 0);
                    133:        if(nextfile > 0) {
                    134:                if(stack->head)
                    135:                        dumptotemp();
                    136:                tabfree();
                    137:                merge(1);
                    138:        } else {
                    139:                FILE *f;
                    140:                f = fileopen(oname, "w");
                    141:                printout(stack->head, f, oname);
                    142:                fileclose(f, oname);
                    143:        }
                    144:        return 0;
                    145: }
                    146: 
                    147: void
                    148: filelist(int argc, char **argv)
                    149: {
                    150:        int i, j;
                    151:        files = nofiles;
                    152:        nfiles = argc - optind;
                    153:        if(nfiles != 0)
                    154:                files = argv + optind;
                    155:        else
                    156:                nfiles = 1;
                    157:        if(strcmp(argv[optind-1], "--") == 0)
                    158:                return;
                    159:        for(i=j=0; i<nfiles; i++) {
                    160:                if(strncmp(files[i], "-o", 2) == 0) {
                    161:                        if(files[i][2] != 0)
                    162:                                oname = files[i] + 2;
                    163:                        else if(i < argc-1)
                    164:                                oname = files[++i];
                    165:                        else
                    166:                                fatal("incomplete -o", "", 0);
                    167:                } else
                    168:                        files[j++] = files[i];
                    169:        }
                    170:        files[j] = 0;
                    171:        nfiles = j;
                    172: }
                    173: 
                    174: void
                    175: readin(void)
                    176: {
                    177:        int n;
                    178:        struct rec *new;
                    179:        struct rec *p = stack->tail;
                    180:        struct rec *r = p? succ(p): buffer;
                    181: 
                    182:        for(;;) {
                    183:                if(bufmax-(uchar*)r < MINREC) {
                    184:                        sealstack(p);
                    185:                        dumptotemp();
                    186:                        p = 0;
                    187:                        r = buffer;
                    188:                }
                    189:                r->next = (struct rec*)bufmax;
                    190:                new = getline(r, input);
                    191:        recenter:
                    192:                if(new == 0) {
                    193:                        r->next = 0;
                    194:                        if(p)
                    195:                                p->next = r;
                    196:                        p = r;
                    197:                        r = succ(r);
                    198:                } else if(new == ENDFILE) {
                    199:                        sealstack(p);
                    200:                        return;
                    201:                } else {
                    202:                        sealstack(p);
                    203:                        dumptotemp();
                    204:                        p = 0;
                    205:                        r = buffer;
                    206:                        n = data(new)-(uchar*)new+new->dlen+new->klen;
                    207:                        if((uchar*)r+n > bufmax)
                    208:                                fatal("monster record", "", 0);
                    209:                        memmove(r, new, n);
                    210:                        free(new);
                    211:                        new = 0;
                    212:                        goto recenter;
                    213:                }
                    214:        }
                    215: }
                    216: 
                    217: void
                    218: sealstack(struct rec *p)
                    219: {
                    220:        if(p == 0)
                    221:                return;
                    222:        p->next = 0;
                    223:        if(stack->head == 0)
                    224:                stack->head = buffer;
                    225:        stack->tail = p;
                    226: }
                    227: 
                    228: void
                    229: printout(struct rec *r, FILE *f, char *name)
                    230: {
                    231:        int c, n;
                    232:        uchar *dp, *ep;
                    233:        for( ; r; r=r->next) {
                    234:                dp = data(r);
                    235:                n = r->dlen;
                    236:                ep = dp + n++;
                    237:                c = *ep;
                    238:                *ep = '\n';
                    239:                if(fwrite((char*)dp, 1, n, f) != n)
                    240:                        fatal("error writing", name, 0);
                    241:                *ep = c;
                    242:        }
                    243: }
                    244: 
                    245: void
                    246: dumptotemp()
                    247: {
                    248:        char *tempfile = filename(nextfile++);
                    249:        FILE *temp = fileopen(tempfile,"w");
                    250: 
                    251:        if(stack->head == 0)
                    252:                fatal("monster record", "", 0);
                    253:        stack->tail->next = 0;          /* for good measure */
                    254:        sort(stack, 0);
                    255:        printout(stack->head, temp, tempfile);
                    256:        fileclose(temp, tempfile);
                    257:        free(tempfile);
                    258:        stack->head = stack->tail = 0;
                    259:        return;
                    260: }

unix.superglobalmegacorp.com

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