|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.