lint fix; fprintf missing an argument
[unix-history] / usr / src / usr.bin / sort / sort.c
CommitLineData
aaed0657
KB
1static char *sccsid = "@(#)sort.c 4.13 (Berkeley) %G%";
2#include <sys/param.h>
88ab53e6
BJ
3#include <stdio.h>
4#include <ctype.h>
5#include <signal.h>
88ab53e6
BJ
6#include <sys/stat.h>
7
4e315262 8#define L 2048
88ab53e6
BJ
9#define N 7
10#define C 20
8e1d70b8 11#ifndef pdp11
8ec451a2 12#define MEM (128*2048)
2f164ac0 13#else
88ab53e6 14#define MEM (16*2048)
2f164ac0 15#endif
88ab53e6
BJ
16#define NF 10
17
8ec451a2
DS
18#define rline(mp) (fgets((mp)->l, L, (mp)->b) == NULL)
19
88ab53e6
BJ
20FILE *is, *os;
21char *dirtry[] = {"/usr/tmp", "/tmp", NULL};
22char **dirs;
aaed0657 23char file1[MAXPATHLEN];
88ab53e6
BJ
24char *file = file1;
25char *filep;
26int nfiles;
27unsigned nlines;
28unsigned ntext;
29int *lspace;
30char *tspace;
31int cmp(), cmpa();
32int (*compare)() = cmpa;
33char *eol();
34int term();
35int mflg;
36int cflg;
37int uflg;
38char *outfil;
39int unsafeout; /*kludge to assure -m -o works*/
40char tabchar;
41int eargc;
42char **eargv;
43
44char zero[256];
45
46char fold[256] = {
47 0200,0201,0202,0203,0204,0205,0206,0207,
48 0210,0211,0212,0213,0214,0215,0216,0217,
49 0220,0221,0222,0223,0224,0225,0226,0227,
50 0230,0231,0232,0233,0234,0235,0236,0237,
51 0240,0241,0242,0243,0244,0245,0246,0247,
52 0250,0251,0252,0253,0254,0255,0256,0257,
53 0260,0261,0262,0263,0264,0265,0266,0267,
54 0270,0271,0272,0273,0274,0275,0276,0277,
55 0300,0301,0302,0303,0304,0305,0306,0307,
56 0310,0311,0312,0313,0314,0315,0316,0317,
57 0320,0321,0322,0323,0324,0325,0326,0327,
58 0330,0331,0332,0333,0334,0335,0336,0337,
59 0340,0341,0342,0343,0344,0345,0346,0347,
60 0350,0351,0352,0353,0354,0355,0356,0357,
61 0360,0361,0362,0363,0364,0365,0366,0367,
62 0370,0371,0372,0373,0374,0375,0376,0377,
63 0000,0001,0002,0003,0004,0005,0006,0007,
64 0010,0011,0012,0013,0014,0015,0016,0017,
65 0020,0021,0022,0023,0024,0025,0026,0027,
66 0030,0031,0032,0033,0034,0035,0036,0037,
67 0040,0041,0042,0043,0044,0045,0046,0047,
68 0050,0051,0052,0053,0054,0055,0056,0057,
69 0060,0061,0062,0063,0064,0065,0066,0067,
70 0070,0071,0072,0073,0074,0075,0076,0077,
71 0100,0101,0102,0103,0104,0105,0106,0107,
72 0110,0111,0112,0113,0114,0115,0116,0117,
73 0120,0121,0122,0123,0124,0125,0126,0127,
97be3be5 74 0130,0131,0132,0133,0134,0135,0136,0137,
88ab53e6
BJ
75 0140,0101,0102,0103,0104,0105,0106,0107,
76 0110,0111,0112,0113,0114,0115,0116,0117,
77 0120,0121,0122,0123,0124,0125,0126,0127,
78 0130,0131,0132,0173,0174,0175,0176,0177
79};
80char nofold[256] = {
81 0200,0201,0202,0203,0204,0205,0206,0207,
82 0210,0211,0212,0213,0214,0215,0216,0217,
83 0220,0221,0222,0223,0224,0225,0226,0227,
84 0230,0231,0232,0233,0234,0235,0236,0237,
85 0240,0241,0242,0243,0244,0245,0246,0247,
86 0250,0251,0252,0253,0254,0255,0256,0257,
87 0260,0261,0262,0263,0264,0265,0266,0267,
88 0270,0271,0272,0273,0274,0275,0276,0277,
89 0300,0301,0302,0303,0304,0305,0306,0307,
90 0310,0311,0312,0313,0314,0315,0316,0317,
91 0320,0321,0322,0323,0324,0325,0326,0327,
92 0330,0331,0332,0333,0334,0335,0336,0337,
93 0340,0341,0342,0343,0344,0345,0346,0347,
94 0350,0351,0352,0353,0354,0355,0356,0357,
95 0360,0361,0362,0363,0364,0365,0366,0367,
96 0370,0371,0372,0373,0374,0375,0376,0377,
97 0000,0001,0002,0003,0004,0005,0006,0007,
98 0010,0011,0012,0013,0014,0015,0016,0017,
99 0020,0021,0022,0023,0024,0025,0026,0027,
100 0030,0031,0032,0033,0034,0035,0036,0037,
101 0040,0041,0042,0043,0044,0045,0046,0047,
102 0050,0051,0052,0053,0054,0055,0056,0057,
103 0060,0061,0062,0063,0064,0065,0066,0067,
104 0070,0071,0072,0073,0074,0075,0076,0077,
105 0100,0101,0102,0103,0104,0105,0106,0107,
106 0110,0111,0112,0113,0114,0115,0116,0117,
107 0120,0121,0122,0123,0124,0125,0126,0127,
108 0130,0131,0132,0133,0134,0135,0136,0137,
109 0140,0141,0142,0143,0144,0145,0146,0147,
110 0150,0151,0152,0153,0154,0155,0156,0157,
111 0160,0161,0162,0163,0164,0165,0166,0167,
112 0170,0171,0172,0173,0174,0175,0176,0177
113};
114
115char nonprint[256] = {
116 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
117 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
118 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
119 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
120 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
121 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
122 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
123 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
124 1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,
125 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
126 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
127 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
128 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
129 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
130 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
131 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
132};
133
134char dict[256] = {
135 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
136 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
137 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
138 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
139 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
140 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
141 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
142 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
143 1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,
144 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
145 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
146 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
147 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
148 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
149 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
150 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
151};
152
153struct field {
154 char *code;
155 char *ignore;
156 int nflg;
157 int rflg;
158 int bflg[2];
159 int m[2];
160 int n[2];
161} fields[NF];
162struct field proto = {
163 nofold+128,
164 zero+128,
165 0,
166 1,
167 0,0,
168 0,-1,
169 0,0
170};
171int nfields;
172int error = 1;
173char *setfil();
174char *sbrk();
175char *brk();
176
2f164ac0
RE
177#define blank(c) ((c) == ' ' || (c) == '\t')
178
88ab53e6
BJ
179main(argc, argv)
180char **argv;
181{
182 register a;
183 extern char end[1];
184 char *ep;
185 char *arg;
186 struct field *p, *q;
187 int i;
88ab53e6 188
88ab53e6
BJ
189 copyproto();
190 eargv = argv;
191 while (--argc > 0) {
192 if(**++argv == '-') for(arg = *argv;;) {
193 switch(*++arg) {
194 case '\0':
195 if(arg[-1] == '-')
196 eargv[eargc++] = "-";
197 break;
198
199 case 'o':
200 if(--argc > 0)
201 outfil = *++argv;
202 continue;
203
204 case 'T':
205 if (--argc > 0)
206 dirtry[0] = *++argv;
207 continue;
208
209 default:
210 field(++*argv,nfields>0);
211 break;
212 }
213 break;
214 } else if (**argv == '+') {
215 if(++nfields>=NF) {
216 diag("too many keys","");
217 exit(1);
218 }
219 copyproto();
220 field(++*argv,0);
221 } else
222 eargv[eargc++] = *argv;
223 }
224 q = &fields[0];
225 for(a=1; a<=nfields; a++) {
226 p = &fields[a];
227 if(p->code != proto.code) continue;
228 if(p->ignore != proto.ignore) continue;
229 if(p->nflg != proto.nflg) continue;
230 if(p->rflg != proto.rflg) continue;
231 if(p->bflg[0] != proto.bflg[0]) continue;
232 if(p->bflg[1] != proto.bflg[1]) continue;
233 p->code = q->code;
234 p->ignore = q->ignore;
235 p->nflg = q->nflg;
236 p->rflg = q->rflg;
237 p->bflg[0] = p->bflg[1] = q->bflg[0];
238 }
239 if(eargc == 0)
240 eargv[eargc++] = "-";
241 if(cflg && eargc>1) {
242 diag("can check only 1 file","");
243 exit(1);
244 }
245 safeoutfil();
246
247 ep = end + MEM;
248 lspace = (int *)sbrk(0);
249 while((int)brk(ep) == -1)
250 ep -= 512;
2f164ac0 251#ifndef vax
88ab53e6 252 brk(ep -= 512); /* for recursion */
2f164ac0 253#endif
88ab53e6
BJ
254 a = ep - (char*)lspace;
255 nlines = (a-L);
256 nlines /= (5*(sizeof(char *)/sizeof(char)));
2f164ac0 257 ntext = nlines * 4 * (sizeof(char *)/sizeof(char));
88ab53e6
BJ
258 tspace = (char *)(lspace + nlines);
259 a = -1;
260 for(dirs=dirtry; *dirs; dirs++) {
261 sprintf(filep=file1, "%s/stm%05uaa", *dirs, getpid());
262 while (*filep)
263 filep++;
264 filep -= 2;
265 if ( (a=creat(file, 0600)) >=0)
266 break;
267 }
268 if(a < 0) {
269 diag("can't locate temp","");
270 exit(1);
271 }
272 close(a);
3acd6e45
BJ
273 unlink(file);
274 if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
275 signal(SIGHUP, term);
88ab53e6
BJ
276 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
277 signal(SIGINT, term);
278 signal(SIGPIPE,term);
3acd6e45
BJ
279 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
280 signal(SIGTERM,term);
88ab53e6
BJ
281 nfiles = eargc;
282 if(!mflg && !cflg) {
283 sort();
284 fclose(stdin);
285 }
286 for(a = mflg|cflg?0:eargc; a+N<nfiles || unsafeout&&a<eargc; a=i) {
287 i = a+N;
288 if(i>=nfiles)
289 i = nfiles;
290 newfile();
291 merge(a, i);
292 }
293 if(a != nfiles) {
294 oldfile();
295 merge(a, nfiles);
296 }
297 error = 0;
298 term();
299}
300
301sort()
302{
303 register char *cp;
304 register char **lp;
8ec451a2
DS
305 register lines, text, len;
306 int done = 0;
307 int i = 0;
88ab53e6 308 char *f;
4a2665d5 309 char c;
88ab53e6 310
8ec451a2
DS
311 if((f = setfil(i++)) == NULL)
312 is = stdin;
313 else if((is = fopen(f, "r")) == NULL)
314 cant(f);
315
88ab53e6
BJ
316 do {
317 cp = tspace;
318 lp = (char **)lspace;
8ec451a2
DS
319 lines = nlines;
320 text = ntext;
321 while(lines > 0 && text > 0) {
322 if(fgets(cp, L, is) == NULL) {
323 if(i >= eargc) {
324 ++done;
88ab53e6 325 break;
8ec451a2
DS
326 }
327 fclose(is);
328 if((f = setfil(i++)) == NULL)
329 is = stdin;
330 else if((is = fopen(f, "r")) == NULL)
331 cant(f);
332 continue;
88ab53e6 333 }
8ec451a2
DS
334 *lp++ = cp;
335 len = strlen(cp) + 1; /* null terminate */
17126de9
DS
336 if(cp[len - 2] != '\n')
337 if (len == L) {
338 diag("line too long (skipped): ", cp);
339 while((c=getc(is)) != EOF && c != '\n')
340 /* throw it away */;
341 --lp;
342 continue;
343 } else {
344 diag("missing newline before EOF in ",
345 f ? f : "standard input");
346 /* be friendly, append a newline */
347 ++len;
348 cp[len - 2] = '\n';
349 cp[len - 1] = '\0';
350 }
8ec451a2
DS
351 cp += len;
352 --lines;
353 text -= len;
88ab53e6
BJ
354 }
355 qsort((char **)lspace, lp);
356 if(done == 0 || nfiles != eargc)
357 newfile();
358 else
359 oldfile();
e22f8104 360 clearerr(os);
88ab53e6
BJ
361 while(lp > (char **)lspace) {
362 cp = *--lp;
363 if(*cp)
8ec451a2 364 fputs(cp, os);
e22f8104
KM
365 if (ferror(os)) {
366 error = 1;
367 term();
368 }
88ab53e6
BJ
369 }
370 fclose(os);
371 } while(done == 0);
372}
373
374struct merg
375{
376 char l[L];
377 FILE *b;
378} *ibuf[256];
379
380merge(a,b)
381{
382 struct merg *p;
383 register char *cp, *dp;
384 register i;
385 struct merg **ip, *jp;
386 char *f;
387 int j;
388 int k, l;
389 int muflg;
390
391 p = (struct merg *)lspace;
392 j = 0;
393 for(i=a; i < b; i++) {
394 f = setfil(i);
395 if(f == 0)
396 p->b = stdin;
397 else if((p->b = fopen(f, "r")) == NULL)
398 cant(f);
399 ibuf[j] = p;
400 if(!rline(p)) j++;
401 p++;
402 }
403
404 do {
405 i = j;
406 qsort((char **)ibuf, (char **)(ibuf+i));
407 l = 0;
408 while(i--) {
409 cp = ibuf[i]->l;
410 if(*cp == '\0') {
411 l = 1;
412 if(rline(ibuf[i])) {
413 k = i;
414 while(++k < j)
415 ibuf[k-1] = ibuf[k];
416 j--;
417 }
418 }
419 }
420 } while(l);
421
e22f8104 422 clearerr(os);
88ab53e6
BJ
423 muflg = mflg & uflg | cflg;
424 i = j;
425 while(i > 0) {
426 cp = ibuf[i-1]->l;
8e1d70b8 427 if (!cflg && (uflg == 0 || muflg || i == 1 ||
e22f8104 428 (*compare)(ibuf[i-1]->l,ibuf[i-2]->l))) {
8ec451a2 429 fputs(cp, os);
e22f8104
KM
430 if (ferror(os)) {
431 error = 1;
432 term();
433 }
434 }
88ab53e6
BJ
435 if(muflg){
436 cp = ibuf[i-1]->l;
437 dp = p->l;
438 do {
439 } while((*dp++ = *cp++) != '\n');
440 }
441 for(;;) {
442 if(rline(ibuf[i-1])) {
443 i--;
444 if(i == 0)
445 break;
446 if(i == 1)
447 muflg = uflg;
448 }
449 ip = &ibuf[i];
450 while(--ip>ibuf&&(*compare)(ip[0]->l,ip[-1]->l)<0){
451 jp = *ip;
452 *ip = *(ip-1);
453 *(ip-1) = jp;
454 }
455 if(!muflg)
456 break;
457 j = (*compare)(ibuf[i-1]->l,p->l);
458 if(cflg) {
459 if(j > 0)
460 disorder("disorder:",ibuf[i-1]->l);
461 else if(uflg && j==0)
462 disorder("nonunique:",ibuf[i-1]->l);
463 } else if(j == 0)
464 continue;
465 break;
466 }
467 }
468 p = (struct merg *)lspace;
469 for(i=a; i<b; i++) {
470 fclose(p->b);
471 p++;
472 if(i >= eargc)
473 unlink(setfil(i));
474 }
475 fclose(os);
476}
477
88ab53e6
BJ
478disorder(s,t)
479char *s, *t;
480{
481 register char *u;
482 for(u=t; *u!='\n';u++) ;
483 *u = 0;
484 diag(s,t);
485 term();
486}
487
488newfile()
489{
490 register char *f;
491
492 f = setfil(nfiles);
493 if((os=fopen(f, "w")) == NULL) {
494 diag("can't create ",f);
495 term();
496 }
497 nfiles++;
498}
499
500char *
501setfil(i)
502{
503
504 if(i < eargc)
505 if(eargv[i][0] == '-' && eargv[i][1] == '\0')
506 return(0);
507 else
508 return(eargv[i]);
509 i -= eargc;
510 filep[0] = i/26 + 'a';
511 filep[1] = i%26 + 'a';
512 return(file);
513}
514
515oldfile()
516{
517
518 if(outfil) {
519 if((os=fopen(outfil, "w")) == NULL) {
520 diag("can't create ",outfil);
521 term();
522 }
523 } else
524 os = stdout;
525}
526
527safeoutfil()
528{
529 register int i;
530 struct stat obuf,ibuf;
531
532 if(!mflg||outfil==0)
533 return;
534 if(stat(outfil,&obuf)==-1)
535 return;
536 for(i=eargc-N;i<eargc;i++) { /*-N is suff., not nec.*/
537 if(stat(eargv[i],&ibuf)==-1)
538 continue;
539 if(obuf.st_dev==ibuf.st_dev&&
540 obuf.st_ino==ibuf.st_ino)
541 unsafeout++;
542 }
543}
544
545cant(f)
546char *f;
547{
548
78d90aa3 549 perror(f);
88ab53e6
BJ
550 term();
551}
552
553diag(s,t)
554char *s, *t;
555{
556 fputs("sort: ",stderr);
557 fputs(s,stderr);
558 fputs(t,stderr);
559 fputs("\n",stderr);
560}
561
562term()
563{
564 register i;
565
566 signal(SIGINT, SIG_IGN);
567 signal(SIGHUP, SIG_IGN);
568 signal(SIGTERM, SIG_IGN);
569 if(nfiles == eargc)
570 nfiles++;
571 for(i=eargc; i<=nfiles; i++) { /*<= in case of interrupt*/
572 unlink(setfil(i)); /*with nfiles not updated*/
573 }
3acd6e45 574 _exit(error);
88ab53e6
BJ
575}
576
577cmp(i, j)
578char *i, *j;
579{
580 register char *pa, *pb;
581 char *skip();
582 char *code, *ignore;
583 int a, b;
584 int k;
585 char *la, *lb;
586 register int sa;
587 int sb;
588 char *ipa, *ipb, *jpa, *jpb;
589 struct field *fp;
590
591 for(k = nfields>0; k<=nfields; k++) {
592 fp = &fields[k];
593 pa = i;
594 pb = j;
595 if(k) {
596 la = skip(pa, fp, 1);
597 pa = skip(pa, fp, 0);
598 lb = skip(pb, fp, 1);
599 pb = skip(pb, fp, 0);
600 } else {
601 la = eol(pa);
602 lb = eol(pb);
603 }
604 if(fp->nflg) {
3acd6e45
BJ
605 if(tabchar) {
606 if(pa<la&&*pa==tabchar)
607 pa++;
608 if(pb<lb&&*pb==tabchar)
609 pb++;
610 }
88ab53e6
BJ
611 while(blank(*pa))
612 pa++;
613 while(blank(*pb))
614 pb++;
615 sa = sb = fp->rflg;
616 if(*pa == '-') {
617 pa++;
618 sa = -sa;
619 }
620 if(*pb == '-') {
621 pb++;
622 sb = -sb;
623 }
624 for(ipa = pa; ipa<la&&isdigit(*ipa); ipa++) ;
625 for(ipb = pb; ipb<lb&&isdigit(*ipb); ipb++) ;
626 jpa = ipa;
627 jpb = ipb;
628 a = 0;
629 if(sa==sb)
630 while(ipa > pa && ipb > pb)
631 if(b = *--ipb - *--ipa)
632 a = b;
633 while(ipa > pa)
634 if(*--ipa != '0')
635 return(-sa);
636 while(ipb > pb)
637 if(*--ipb != '0')
638 return(sb);
639 if(a) return(a*sa);
640 if(*(pa=jpa) == '.')
641 pa++;
642 if(*(pb=jpb) == '.')
643 pb++;
644 if(sa==sb)
645 while(pa<la && isdigit(*pa)
646 && pb<lb && isdigit(*pb))
647 if(a = *pb++ - *pa++)
648 return(a*sa);
649 while(pa<la && isdigit(*pa))
650 if(*pa++ != '0')
651 return(-sa);
652 while(pb<lb && isdigit(*pb))
653 if(*pb++ != '0')
654 return(sb);
655 continue;
656 }
657 code = fp->code;
658 ignore = fp->ignore;
659loop:
660 while(ignore[*pa])
661 pa++;
662 while(ignore[*pb])
663 pb++;
664 if(pa>=la || *pa=='\n')
665 if(pb<lb && *pb!='\n')
666 return(fp->rflg);
667 else continue;
668 if(pb>=lb || *pb=='\n')
669 return(-fp->rflg);
670 if((sa = code[*pb++]-code[*pa++]) == 0)
671 goto loop;
672 return(sa*fp->rflg);
673 }
674 if(uflg)
675 return(0);
676 return(cmpa(i, j));
677}
678
679cmpa(pa, pb)
680register char *pa, *pb;
681{
682 while(*pa == *pb) {
683 if(*pa++ == '\n')
684 return(0);
685 pb++;
686 }
687 return(
688 *pa == '\n' ? fields[0].rflg:
689 *pb == '\n' ?-fields[0].rflg:
690 *pb > *pa ? fields[0].rflg:
691 -fields[0].rflg
692 );
693}
694
695char *
696skip(pp, fp, j)
697struct field *fp;
698char *pp;
699{
700 register i;
701 register char *p;
702
703 p = pp;
704 if( (i=fp->m[j]) < 0)
705 return(eol(p));
706 while(i-- > 0) {
707 if(tabchar != 0) {
708 while(*p != tabchar)
709 if(*p != '\n')
710 p++;
711 else goto ret;
3acd6e45
BJ
712 if(i>0||j==0)
713 p++;
88ab53e6
BJ
714 } else {
715 while(blank(*p))
716 p++;
717 while(!blank(*p))
718 if(*p != '\n')
719 p++;
720 else goto ret;
721 }
722 }
f26f60ad 723 if(tabchar==0||fp->bflg[j])
88ab53e6
BJ
724 while(blank(*p))
725 p++;
726 i = fp->n[j];
727 while(i-- > 0) {
728 if(*p != '\n')
729 p++;
730 else goto ret;
731 }
732ret:
733 return(p);
734}
735
736char *
737eol(p)
738register char *p;
739{
740 while(*p != '\n') p++;
741 return(p);
742}
743
744copyproto()
745{
746 register i;
747 register int *p, *q;
748
749 p = (int *)&proto;
750 q = (int *)&fields[nfields];
751 for(i=0; i<sizeof(proto)/sizeof(*p); i++)
752 *q++ = *p++;
753}
754
755field(s,k)
756char *s;
757{
758 register struct field *p;
759 register d;
760 p = &fields[nfields];
761 d = 0;
762 for(; *s!=0; s++) {
763 switch(*s) {
764 case '\0':
765 return;
766
767 case 'b':
768 p->bflg[k]++;
769 break;
770
771 case 'd':
772 p->ignore = dict+128;
773 break;
774
775 case 'f':
776 p->code = fold+128;
777 break;
778 case 'i':
779 p->ignore = nonprint+128;
780 break;
781
782 case 'c':
783 cflg = 1;
784 continue;
785
786 case 'm':
787 mflg = 1;
788 continue;
789
790 case 'n':
791 p->nflg++;
792 break;
793 case 't':
794 tabchar = *++s;
795 if(tabchar == 0) s--;
796 continue;
797
798 case 'r':
799 p->rflg = -1;
800 continue;
801 case 'u':
802 uflg = 1;
803 break;
804
805 case '.':
806 if(p->m[k] == -1) /* -m.n with m missing */
807 p->m[k] = 0;
808 d = &fields[0].n[0]-&fields[0].m[0];
809
810 default:
811 p->m[k+d] = number(&s);
812 }
813 compare = cmp;
814 }
815}
816
817number(ppa)
818char **ppa;
819{
820 int n;
821 register char *pa;
822 pa = *ppa;
823 n = 0;
824 while(isdigit(*pa)) {
825 n = n*10 + *pa - '0';
826 *ppa = pa++;
827 }
828 return(n);
829}
830
88ab53e6
BJ
831#define qsexc(p,q) t= *p;*p= *q;*q=t
832#define qstexc(p,q,r) t= *p;*p= *r;*r= *q;*q=t
833
834qsort(a,l)
835char **a, **l;
836{
837 register char **i, **j;
838 char **k;
839 char **lp, **hp;
840 int c;
841 char *t;
842 unsigned n;
843
844
845
846start:
847 if((n=l-a) <= 1)
848 return;
849
850
851 n /= 2;
852 hp = lp = a+n;
853 i = a;
854 j = l-1;
855
856
857 for(;;) {
858 if(i < lp) {
859 if((c = (*compare)(*i, *lp)) == 0) {
860 --lp;
861 qsexc(i, lp);
862 continue;
863 }
864 if(c < 0) {
865 ++i;
866 continue;
867 }
868 }
869
870loop:
871 if(j > hp) {
872 if((c = (*compare)(*hp, *j)) == 0) {
873 ++hp;
874 qsexc(hp, j);
875 goto loop;
876 }
877 if(c > 0) {
878 if(i == lp) {
879 ++hp;
880 qstexc(i, hp, j);
881 i = ++lp;
882 goto loop;
883 }
884 qsexc(i, j);
885 --j;
886 ++i;
887 continue;
888 }
889 --j;
890 goto loop;
891 }
892
893
894 if(i == lp) {
895 if(uflg)
896 for(k=lp+1; k<=hp;) **k++ = '\0';
897 if(lp-a >= l-hp) {
898 qsort(hp+1, l);
899 l = lp;
900 } else {
901 qsort(a, lp);
902 a = hp+1;
903 }
904 goto start;
905 }
906
907
908 --lp;
909 qstexc(j, lp, i);
910 j = --hp;
911 }
912}
913