|
|
1.1 root 1: mkdir math fio libc
2: # To unbundle, sh this file
3: echo ./libc/README 1>&2
4: sed 's/.//' >./libc/README <<'//GO.SYSIN DD ./libc/README'
5: -here (as in ../fio) you have to add whatever commands
6: -you need to set up an archive in the shell file `gen'.
7: //GO.SYSIN DD ./libc/README
8: echo ./libc/doprint.c 1>&2
9: sed 's/.//' >./libc/doprint.c <<'//GO.SYSIN DD ./libc/doprint.c'
10: -#include <varargs.h>
11: -
12: -#define SIZE 1024
13: -#define FUNSIGN 4
14: -#define FSHORT 2
15: -#define FLONG 1
16: -#define PTR sizeof (char *)
17: -#define SHORT sizeof (int)
18: -#define INT sizeof (int)
19: -#define LONG sizeof (long)
20: -#define FLOAT sizeof (double)
21: -#define FDIGIT 30
22: -#define FDEFLT 8
23: -#define IDIGIT 40
24: -#define MAXCONV 30
25: -
26: -static char *out, *eout;
27: -static convcount = { 13 };
28: -
29: -static noconv();
30: -static cconv(), dconv(), hconv(), lconv();
31: -static oconv(), sconv(), uconv(), xconv();
32: -
33: -static econv(), fconv(), gconv(), percent();
34: -int printcol;
35: -static
36: -int (*fmtconv[MAXCONV])() =
37: -{
38: - noconv,
39: - cconv, dconv, hconv, lconv,
40: - oconv, sconv, uconv, xconv,
41: - econv, fconv, gconv, percent,
42: -};
43: -static
44: -char fmtindex[128] =
45: -{
46: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48: - 0, 0, 0, 0, 0,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52: - 0, 0, 0, 1, 2, 9,10,11, 3, 0, 0, 0, 4, 0, 0, 5,
53: - 0, 0, 0, 6, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
54: -};
55: -
56: -fmtinstall(c, f)
57: -char c;
58: -int (*f)();
59: -{
60: -
61: - c &= 0177;
62: - if(fmtindex[c] == 0) {
63: - if(convcount >= MAXCONV)
64: - return 1;
65: - fmtindex[c] = convcount++;
66: - }
67: - fmtconv[fmtindex[c]] = f;
68: - return 0;
69: -}
70: -
71: -char*
72: -donprint(s, es, fmt, argpp)
73: -char *s, *es;
74: -register char *fmt;
75: -va_list *argpp;
76: -{
77: - register int f1, f2, f3, sf1, c;
78: - char *sout, *seout;
79: -
80: - sout = out;
81: - seout = eout;
82: - out = s;
83: - eout = es-1;
84: -loop:
85: - c = *fmt++;
86: - if(c != '%') {
87: - if(c == 0) {
88: - *out = 0;
89: - s = out;
90: - out = sout;
91: - eout = seout;
92: - return s;
93: - }
94: - if(out < eout)
95: - *out++ = c;
96: - printcol++;
97: - if(c == '\n')
98: - printcol = 0; else
99: - if(c == '\t')
100: - printcol = (printcol+7) & ~7;
101: - goto loop;
102: - }
103: - f1 = 0;
104: - f2 = -1;
105: - f3 = 0;
106: - c = *fmt++;
107: - sf1 = 0;
108: - if(c == '-') {
109: - sf1 = 1;
110: - c = *fmt++;
111: - }
112: - while(c >= '0' && c <= '9') {
113: - f1 = f1*10 + c-'0';
114: - c = *fmt++;
115: - }
116: - if(sf1)
117: - f1 = -f1;
118: - if(c != '.')
119: - goto l1;
120: - c = *fmt++;
121: - while(c >= '0' && c <= '9') {
122: - if(f2 < 0)
123: - f2 = 0;
124: - f2 = f2*10 + c-'0';
125: - c = *fmt++;
126: - }
127: -l1:
128: - if(c == 0)
129: - fmt--;
130: - /* NB: first arg is now a (va_list *) */
131: - c = (*fmtconv[fmtindex[c&0177]])(argpp, f1, f2, f3);
132: - if(c < 0) {
133: - f3 |= -c;
134: - c = *fmt++;
135: - goto l1;
136: - }
137: -#ifdef notdef
138: - argp += c; /* increment is now done in called routine by va_arg() */
139: -#endif
140: - goto loop;
141: -}
142: -
143: -numbconv(o, f1, f2, f3, b)
144: -va_list *o;
145: -{
146: - char s[IDIGIT];
147: - register long v;
148: - register int i, f, n, r;
149: -
150: - switch(f3 & (FLONG|FSHORT|FUNSIGN)) {
151: - case FLONG:
152: - v = va_arg(*o, long);
153: - r = LONG;
154: - break;
155: -
156: - case FUNSIGN|FLONG:
157: - v = va_arg(*o, unsigned long);
158: - r = LONG;
159: - break;
160: -
161: - /* NB: a (unsigned) short argument is promoted to an (unsigned) int arg. */
162: - case FSHORT:
163: - v = (short)va_arg(*o, int);
164: - r = SHORT;
165: - break;
166: -
167: - case FUNSIGN|FSHORT:
168: - v = (unsigned short)va_arg(*o, unsigned);
169: - r = SHORT;
170: - break;
171: -
172: - default:
173: - v = va_arg(*o, int);
174: - r = INT;
175: - break;
176: -
177: - case FUNSIGN:
178: - v = va_arg(*o, unsigned);
179: - r = INT;
180: - break;
181: - }
182: - f = 0;
183: - if(!(f3 & FUNSIGN) && v < 0) {
184: - v = -v;
185: - f = 1;
186: - }
187: - s[IDIGIT-1] = 0;
188: - for(i = IDIGIT-2; i >= 1; i--) {
189: - n = (unsigned long)v % b;
190: - n += '0';
191: - if(n > '9')
192: - n += 'a' - ('9'+1);
193: - s[i] = n;
194: - v = (unsigned long)v / b;
195: - if(f2 >= 0 && i >= IDIGIT-f2)
196: - continue;
197: - if(v <= 0)
198: - break;
199: - }
200: - if(f)
201: - s[--i] = '-';
202: - strconv(s+i, f1, -1);
203: - return r;
204: -}
205: -
206: -char*
207: -doprint(s, fmt, argp)
208: -char *s, *fmt;
209: -va_list *argp;
210: -{
211: -
212: - return donprint(s, s+SIZE, fmt, argp);
213: -}
214: -
215: -/*
216: - if you change this, change chconv
217: -*/
218: -
219: -strconv(o, f1, f2)
220: -char *o;
221: -{
222: - register int n, c;
223: - register char *s;
224: -
225: - n = 0;
226: - for(s = o; *s++;)
227: - n++;
228: - if(f1 >= 0)
229: - while(n < f1) {
230: - if(out < eout)
231: - *out++ = ' ';
232: - printcol++;
233: - n++;
234: - }
235: - for(s=o; c = *s++;)
236: - if(f2 != 0) {
237: - if(out < eout)
238: - *out++ = c;
239: - printcol++;
240: - if(c == '\n')
241: - printcol = 0; else
242: - if(c == '\t')
243: - printcol = (printcol+7) & ~7;
244: - f2--;
245: - }
246: - if(f1 < 0) {
247: - f1 = -f1;
248: - while(n < f1) {
249: - if(out < eout)
250: - *out++ = ' ';
251: - printcol++;
252: - n++;
253: - }
254: - }
255: -}
256: -
257: -chconv(o, f1)
258: -char o;
259: -{
260: - register int n;
261: -
262: - n = 1;
263: - if(f1 >= 0)
264: - while(n < f1) {
265: - if(out < eout)
266: - *out++ = ' ';
267: - printcol++;
268: - n++;
269: - }
270: - if(out < eout)
271: - *out++ = o;
272: - printcol++;
273: - if(o == '\n')
274: - printcol = 0; else
275: - if(o == '\t')
276: - printcol = (printcol+7) & ~7;
277: - if(f1 < 0) {
278: - f1 = -f1;
279: - while(n < f1) {
280: - if(out < eout)
281: - *out++ = ' ';
282: - printcol++;
283: - n++;
284: - }
285: - }
286: -}
287: -
288: -/* ARGSUSED */
289: -static
290: -noconv(o, f1, f2, f3)
291: -char *o;
292: -{
293: -
294: - strconv("***", 0, -1);
295: - return 0;
296: -}
297: -
298: -/* ARGSUSED */
299: -static
300: -cconv(o, f1, f2, f3)
301: -va_list *o;
302: -{
303: - chconv((char)va_arg(*o, int), f1);
304: - return INT;
305: -}
306: -
307: -static
308: -dconv(o, f1, f2, f3)
309: -va_list *o;
310: -{
311: - int r;
312: -
313: - r = numbconv(o, f1, f2, f3, 10);
314: - return r;
315: -}
316: -
317: -/* ARGSUSED */
318: -static
319: -hconv(o, f1, f2, f3)
320: -{
321: - return -FSHORT;
322: -}
323: -
324: -/* ARGSUSED */
325: -static
326: -lconv(o, f1, f2, f3)
327: -{
328: -
329: - return -FLONG;
330: -}
331: -
332: -static
333: -oconv(o, f1, f2, f3)
334: -va_list *o;
335: -{
336: - int r;
337: -
338: - r = numbconv(o, f1, f2, f3, 8);
339: - return r;
340: -}
341: -
342: -/* ARGSUSED */
343: -static
344: -sconv(o, f1, f2, f3)
345: -va_list *o;
346: -{
347: -
348: - strconv(va_arg(*o, char *), f1, f2);
349: - return PTR;
350: -}
351: -
352: -/* ARGSUSED */
353: -static
354: -uconv(o, f1, f2, f3)
355: -{
356: - return -FUNSIGN;
357: -}
358: -
359: -static
360: -xconv(o, f1, f2, f3)
361: -va_list *o;
362: -{
363: - int r;
364: -
365: - r = numbconv(o, f1, f2, f3, 16);
366: - return r;
367: -}
368: -
369: -double pow10(), frexp();
370: -/* ARGSUSED */
371: -fltconv(f, f1, f2, f3, c)
372: -register double f;
373: -{
374: - char s1[FDIGIT+10], s2[FDIGIT+10];
375: - register double g;
376: - register int d, i, n, s;
377: - double h;
378: - int e;
379: - int c1, c2, c3;
380: -
381: - s = 0;
382: - if(f < 0) {
383: - f = -f;
384: - s++;
385: - }
386: -
387: -loop:
388: - e = 0;
389: - g = 0;
390: - if(f != 0) {
391: - g = frexp(f, &e);
392: - e = e * .30103;
393: - d = e/2;
394: - h = f * pow10(-d); /* 10**-e in 2 parts */
395: - g = h * pow10(d-e);
396: - while(g < 1) {
397: - e--;
398: - g = h * pow10(d-e);
399: - }
400: - while(g >= 10) {
401: - e++;
402: - g = h * pow10(d-e);
403: - }
404: - }
405: - if(f2 < 0)
406: - f2 = FDEFLT;
407: - if(c == 'g' && f2 > 0)
408: - f2--;
409: - if(f2 > FDIGIT)
410: - f2 = FDIGIT;
411: - /*
412: - * n is number of digits to convert
413: - * 1 before, f2 after, 1 extra for rounding
414: - */
415: - n = f2 + 2;
416: - if(c == 'f') {
417: - /*
418: - * e+1 before, f2 after, 1 extra
419: - */
420: - n += e;
421: - if(n <= 0) {
422: - n = 1;
423: - g = 0;
424: - }
425: - }
426: - if(n >= FDIGIT+2) {
427: - if(c == 'e')
428: - f2 = -1;
429: - c = 'e';
430: - goto loop;
431: - }
432: - /*
433: - * convert n digits
434: - */
435: - for(i=0; i<n; i++) {
436: - d = g;
437: - if(d > g)
438: - d--;
439: - g -= d;
440: - s1[i+1] = d + '0';
441: - g *= 10;
442: - }
443: - /*
444: - * round by adding .5 into extra digit
445: - */
446: - d = 5;
447: - for(i=n-1; i>=0; i--) {
448: - s1[i+1] += d;
449: - d = 0;
450: - if(s1[i+1] > '9') {
451: - s1[i+1] -= 10;
452: - d++;
453: - }
454: - }
455: - i = 1;
456: - if(d) {
457: - s1[0] = '1';
458: - e++;
459: - i = 0;
460: - }
461: - /*
462: - * copy into final place
463: - * c1 digits of leading '0'
464: - * c2 digits from conversion
465: - * c3 digits after '.'
466: - */
467: - d = 0;
468: - if(s)
469: - s2[d++] = '-';
470: - c1 = 0;
471: - c2 = f2 + 1;
472: - c3 = f2;
473: - if(c == 'g')
474: - if(e >= -5 && e <= f2) {
475: - c1 = -e - 1;
476: - c3 = c1;
477: - if(c1 < 0)
478: - c1 = 0;
479: - c3 = f2 - e;
480: - c = 'h';
481: - }
482: - if(c == 'f') {
483: - c1 = -e;
484: - if(c1 < 0)
485: - c1 = 0;
486: - if(c1 > f2)
487: - c1 = c2;
488: - c2 += e;
489: - if(c2 < 0)
490: - c2 = 0;
491: - }
492: - while(c1 > 0) {
493: - if(c1+c2 == c3)
494: - s2[d++] = '.';
495: - s2[d++] = '0';
496: - c1--;
497: - }
498: - while(c2 > 0) {
499: - if(c1+c2 == c3)
500: - s2[d++] = '.';
501: - s2[d++] = s1[i++];
502: - c2--;
503: - }
504: - /*
505: - * strip trailing '0' on g conv
506: - */
507: - if(c == 'g' || c == 'h') {
508: - for(n=d-1; n>=0; n--)
509: - if(s2[n] != '0')
510: - break;
511: - for(i=n; i>=0; i--)
512: - if(s2[i] == '.') {
513: - d = n;
514: - if(i != n)
515: - d++;
516: - break;
517: - }
518: - }
519: - if(c == 'e' || c == 'g') {
520: - s2[d++] = 'e';
521: - s2[d++] = '+';
522: - c1 = e;
523: - if(c1 < 0) {
524: - s2[d-1] = '-';
525: - c1 = -c1;
526: - }
527: - if(c1 >= 100) {
528: - s2[d++] = c1/100 + '0';
529: - c1 %= 100;
530: - }
531: - s2[d++] = c1/10 + '0';
532: - s2[d++] = c1%10 + '0';
533: - }
534: - s2[d] = 0;
535: - strconv(s2, f1, -1);
536: - return FLOAT;
537: -}
538: -
539: -static
540: -econv(o, f1, f2, f3)
541: -va_list *o;
542: -{
543: -
544: - return fltconv(va_arg(*o, double), f1, f2, f3, 'e');
545: -}
546: -
547: -static
548: -fconv(o, f1, f2, f3)
549: -va_list *o;
550: -{
551: -
552: - return fltconv(va_arg(*o, double), f1, f2, f3, 'f');
553: -}
554: -
555: -static
556: -gconv(o, f1, f2, f3)
557: -va_list *o;
558: -{
559: -
560: - return fltconv(va_arg(*o, double), f1, f2, f3, 'g');
561: -}
562: -
563: -static
564: -percent()
565: -{
566: -
567: - if(out < eout)
568: - *out++ = '%';
569: - return 0;
570: -}
571: //GO.SYSIN DD ./libc/doprint.c
572: echo ./libc/exit.c 1>&2
573: sed 's/.//' >./libc/exit.c <<'//GO.SYSIN DD ./libc/exit.c'
574: -#include <libc.h>
575: -
576: -extern int (*_onexitfns[])();
577: -
578: -void
579: -exit(status)
580: -{
581: - int i, (*f)();
582: -
583: - for(i = NONEXIT-1; i >= 0; i--)
584: - if(_onexitfns[i]){
585: - f = _onexitfns[i];
586: - _onexitfns[i] = 0; /* self defense against bozos */
587: - (*f)();
588: - }
589: - _exit(status);
590: -}
591: //GO.SYSIN DD ./libc/exit.c
592: echo ./libc/regcomp.c 1>&2
593: sed 's/.//' >./libc/regcomp.c <<'//GO.SYSIN DD ./libc/regcomp.c'
594: -#include <libc.h>
595: -#include "regprog.h"
596: -
597: -/*
598: - * Parser Information
599: - */
600: -typedef struct Node{
601: - Inst *first;
602: - Inst *last;
603: -}Node;
604: -#define NSTACK 20
605: -static Node andstack[NSTACK];
606: -static Node *andp;
607: -static int atorstack[NSTACK];
608: -static int *atorp;
609: -static int cursubid; /* id of current subexpression */
610: -static int subidstack[NSTACK]; /* parallel to atorstack */
611: -static int *subidp;
612: -static int lastwasand; /* Last token was operand */
613: -static int nbra;
614: -static char *exprp; /* pointer to next character in source expression */
615: -static int nclass;
616: -static Class *classp;
617: -static Inst *freep;
618: -static int errors;
619: -
620: -/* predeclared crap */
621: -static void operator();
622: -static void pushand();
623: -static void pushator();
624: -static void evaluntil();
625: -static void bldcclass();
626: -
627: -static void
628: -rcerror(s)
629: - char *s;
630: -{
631: - errors++;
632: - regerror(s);
633: -}
634: -
635: -static Inst *
636: -newinst(t)
637: - int t;
638: -{
639: - freep->type=t;
640: - freep->left=0;
641: - freep->right=0;
642: - return freep++;
643: -}
644: -
645: -static void
646: -operand(t)
647: - int t;
648: -{
649: - register Inst *i;
650: - if(lastwasand)
651: - operator(CAT); /* catenate is implicit */
652: - i=newinst(t);
653: - if(t==CCLASS) /* ugh */
654: - i->right=(Inst *)&(classp[nclass-1]); /* UGH! */
655: - pushand(i, i);
656: - lastwasand=TRUE;
657: -}
658: -
659: -static void
660: -operator(t)
661: - int t;
662: -{
663: - if(t==RBRA && --nbra<0)
664: - rcerror("unmatched right paren");
665: - if(t==LBRA) {
666: - if (++cursubid >= NSUBEXP)
667: - rcerror ("too many subexpressions");
668: - nbra++;
669: - if (lastwasand)
670: - operator(CAT);
671: - } else
672: - evaluntil(t);
673: - if(t!=RBRA)
674: - pushator(t);
675: - lastwasand=FALSE;
676: - if(t==STAR || t==QUEST || t==PLUS || t==RBRA)
677: - lastwasand=TRUE; /* these look like operands */
678: -}
679: -
680: -static void
681: -regerr2(s, c)
682: - char *s;
683: -{
684: - char buf[100];
685: - char *cp = buf;
686: - while(*s)
687: - *cp++ = *s++;
688: - *cp++ = c;
689: - *cp = '\0';
690: - rcerror(buf);
691: -}
692: -
693: -static void
694: -cant(s)
695: - char *s;
696: -{
697: - char buf[100];
698: - strcpy(buf, "can't happen: ");
699: - strcat(buf, s);
700: - rcerror(buf);
701: -}
702: -
703: -static void
704: -pushand(f, l)
705: - Inst *f, *l;
706: -{
707: - if(andp >= &andstack[NSTACK])
708: - cant("operand stack overflow");
709: - andp->first=f;
710: - andp->last=l;
711: - andp++;
712: -}
713: -
714: -static void
715: -pushator(t)
716: - int t;
717: -{
718: - if(atorp >= &atorstack[NSTACK])
719: - cant("operator stack overflow");
720: - *atorp++=t;
721: - *subidp++=cursubid;
722: -}
723: -
724: -static Node *
725: -popand(op)
726: -{
727: - register Inst *inst;
728: -
729: - if(andp <= &andstack[0]) {
730: - regerr2("missing operand for ", op);
731: - inst=newinst(NOP);
732: - pushand(inst,inst);
733: - }
734: - return --andp;
735: -}
736: -
737: -static int
738: -popator()
739: -{
740: - if(atorp <= &atorstack[0])
741: - cant("operator stack underflow");
742: - --subidp;
743: - return *--atorp;
744: -}
745: -
746: -static void
747: -evaluntil(pri)
748: - register pri;
749: -{
750: - register Node *op1, *op2;
751: - register Inst *inst1, *inst2;
752: -
753: - while(pri==RBRA || atorp[-1]>=pri){
754: - switch(popator()){
755: - default:
756: - rcerror("unknown operator in evaluntil");
757: - break;
758: - case LBRA: /* must have been RBRA */
759: - op1=popand('(');
760: - inst2=newinst(RBRA);
761: - inst2->subid = *subidp;
762: - op1->last->next = inst2;
763: - inst1=newinst(LBRA);
764: - inst1->subid = *subidp;
765: - inst1->next=op1->first;
766: - pushand(inst1, inst2);
767: - return;
768: - case OR:
769: - op2=popand('|');
770: - op1=popand('|');
771: - inst2=newinst(NOP);
772: - op2->last->next=inst2;
773: - op1->last->next=inst2;
774: - inst1=newinst(OR);
775: - inst1->right=op1->first;
776: - inst1->left=op2->first;
777: - pushand(inst1, inst2);
778: - break;
779: - case CAT:
780: - op2=popand(0);
781: - op1=popand(0);
782: - op1->last->next=op2->first;
783: - pushand(op1->first, op2->last);
784: - break;
785: - case STAR:
786: - op2=popand('*');
787: - inst1=newinst(OR);
788: - op2->last->next=inst1;
789: - inst1->right=op2->first;
790: - pushand(inst1, inst1);
791: - break;
792: - case PLUS:
793: - op2=popand('+');
794: - inst1=newinst(OR);
795: - op2->last->next=inst1;
796: - inst1->right=op2->first;
797: - pushand(op2->first, inst1);
798: - break;
799: - case QUEST:
800: - op2=popand('?');
801: - inst1=newinst(OR);
802: - inst2=newinst(NOP);
803: - inst1->left=inst2;
804: - inst1->right=op2->first;
805: - op2->last->next=inst2;
806: - pushand(inst1, inst2);
807: - break;
808: - }
809: - }
810: -}
811: -
812: -static Prog *
813: -optimize(pp)
814: - Prog *pp;
815: -{
816: - register Inst *inst, *target;
817: - int size;
818: - Prog *npp;
819: - int diff;
820: -
821: - /*
822: - * get rid of NOOP chains
823: - */
824: - for(inst=pp->firstinst; inst->type!=END; inst++){
825: - target=inst->next;
826: - while(target->type == NOP)
827: - target=target->next;
828: - inst->next=target;
829: - }
830: -
831: - /*
832: - * The original allocation is for an area larger than
833: - * necessary. Reallocate to the actual space used
834: - * and then relocate the code.
835: - */
836: - size = sizeof(Prog) + (freep - pp->firstinst)*sizeof(Inst);
837: - npp = (Prog *)realloc((char *)pp, size);
838: - if(npp==NULL || npp==pp)
839: - return(pp);
840: - diff = (char *)npp - (char *)pp;
841: - freep = (Inst *)((char *)freep + diff);
842: - for(inst=npp->firstinst; inst<freep; inst++){
843: - switch(inst->type){
844: - case OR:
845: - case STAR:
846: - case PLUS:
847: - case QUEST:
848: - case CCLASS:
849: - *(char **)&inst->right += diff;
850: - break;
851: - }
852: - *(char **)&inst->left += diff;
853: - }
854: - *(char **)&npp->startinst += diff;
855: - return(npp);
856: -}
857: -
858: -#ifdef DEBUG
859: -static void
860: -dumpstack(){
861: - Node *stk;
862: - int *ip;
863: -
864: - printf("operators\n");
865: - for(ip=atorstack; ip<atorp; ip++)
866: - printf("0%o\n", *ip);
867: - printf("operands\n");
868: - for(stk=andstack; stk<andp; stk++)
869: - printf("0%o\t0%o\n", stk->first->type, stk->last->type);
870: -}
871: -
872: -static void
873: -dump(pp)
874: - Prog *pp;
875: -{
876: - Inst *l;
877: -
878: - l=pp->firstinst;
879: - do{
880: - printf("%d:\t0%o\t%d\t%d\n", l-pp->firstinst, l->type,
881: - l->left-pp->firstinst, l->right-pp->firstinst);
882: - }while(l++->type);
883: -}
884: -#endif
885: -
886: -static void
887: -startlex(s)
888: - char *s;
889: -{
890: - exprp=s;
891: - nclass=0;
892: - nbra=0;
893: -}
894: -
895: -static Class *
896: -newclass(){
897: - register Class *p;
898: - register n;
899: -
900: - if(nclass >= NCLASS)
901: - regerr2("too many character classes; limit", NCLASS+'0');
902: - p = &(classp[nclass++]);
903: - for(n=0; n<16; n++)
904: - p->map[n]=0;
905: - return p;
906: -}
907: -
908: -static int
909: -lex(){
910: - register c= *exprp++;
911: -
912: - switch(c){
913: - case '\\':
914: - if(*exprp)
915: - c= *exprp++;
916: - break;
917: - case 0:
918: - c=END;
919: - --exprp; /* In case we come here again */
920: - break;
921: - case '*':
922: - c=STAR;
923: - break;
924: - case '?':
925: - c=QUEST;
926: - break;
927: - case '+':
928: - c=PLUS;
929: - break;
930: - case '|':
931: - c=OR;
932: - break;
933: - case '.':
934: - c=ANY;
935: - break;
936: - case '(':
937: - c=LBRA;
938: - break;
939: - case ')':
940: - c=RBRA;
941: - break;
942: - case '^':
943: - c=BOL;
944: - break;
945: - case '$':
946: - c=EOL;
947: - break;
948: - case '[':
949: - c=CCLASS;
950: - bldcclass();
951: - break;
952: - }
953: - return c;
954: -}
955: -
956: -static int
957: -nextc(){
958: - if(exprp[0]==0 || (exprp[0]=='\\' && exprp[1]==0))
959: - rcerror("malformed '[]'");
960: - if(exprp[0]=='\\'){
961: - exprp++;
962: - return *exprp++|0200;
963: - }
964: - return *exprp++;
965: -}
966: -
967: -static void
968: -bldcclass(){
969: - register c1, c2;
970: - register Class *classp;
971: - register negate=FALSE;
972: -
973: - classp=newclass();
974: - /* we have already seen the '[' */
975: - if(*exprp=='^'){
976: - negate=TRUE;
977: - exprp++;
978: - }
979: - while((c1=c2=nextc()) != ']'){
980: - if(*exprp=='-'){
981: - exprp++; /* eat '-' */
982: - if((c2=nextc()) == ']')
983: - rcerror("malformed '[]'");
984: - }
985: - for((c1&=0177), (c2&=0177); c1<=c2; c1++)
986: - classp->map[c1/8] |= 1<<(c1&07);
987: - }
988: - if(negate)
989: - for(c1=0; c1<16; c1++)
990: - classp->map[c1]^=0377;
991: - classp->map[0] &= 0376; /* exclude NUL */
992: -}
993: -
994: -extern regexp *
995: -regcomp(s)
996: - char *s;
997: -{
998: - register token;
999: - Prog *pp;
1000: -
1001: - /* get memory for the program */
1002: - pp = (Prog *)malloc(sizeof(Prog) + 3*sizeof(Inst)*strlen(s));
1003: - if (pp == NULL) {
1004: - rcerror("out of memory");
1005: - return NULL;
1006: - }
1007: - freep = pp->firstinst;
1008: - classp = pp->class;
1009: - errors = 0;
1010: -
1011: - /* go compile the sucker */
1012: - startlex(s);
1013: - atorp=atorstack;
1014: - andp=andstack;
1015: - subidp=subidstack;
1016: - lastwasand=FALSE;
1017: - cursubid=0;
1018: -
1019: - /* Start with a low priority operator to prime parser */
1020: - pushator(START-1);
1021: - while((token=lex()) != END){
1022: - if((token&0300) == OPERATOR)
1023: - operator(token);
1024: - else
1025: - operand(token);
1026: - }
1027: -
1028: - /* Close with a low priority operator */
1029: - evaluntil(START);
1030: -
1031: - /* Force END */
1032: - operand(END);
1033: - evaluntil(START);
1034: -#ifdef DEBUG
1035: - dumpstack();
1036: -#endif
1037: - if(nbra)
1038: - rcerror("unmatched left paren");
1039: - --andp; /* points to first and only operand */
1040: - pp->startinst=andp->first;
1041: -#ifdef DEBUG
1042: - dump(pp);
1043: -#endif
1044: - pp = optimize(pp);
1045: -#ifdef DEBUG
1046: - printf("start: %d\n", andp->first-pp->firstinst);
1047: - dump(pp);
1048: -#endif
1049: - if (errors) {
1050: - free((char *)pp);
1051: - pp = NULL;
1052: - }
1053: - return (regexp *)pp;
1054: -}
1055: //GO.SYSIN DD ./libc/regcomp.c
1056: echo ./libc/getfields.c 1>&2
1057: sed 's/.//' >./libc/getfields.c <<'//GO.SYSIN DD ./libc/getfields.c'
1058: -#include <libc.h>
1059: -
1060: -static char is_sep[256] = {
1061: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1062: - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1063: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1064: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1065: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1066: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1067: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1068: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1069: -};
1070: -static char is_field[256] = {
1071: - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1072: - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1073: - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1074: - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1075: - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1076: - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1077: - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1078: - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1079: -};
1080: -static char last_sep[256];
1081: -
1082: -char *
1083: -setfields(arg)
1084: - char *arg;
1085: -{
1086: - register unsigned char *s;
1087: - register i;
1088: -
1089: - for(i = 1, s = (unsigned char *)last_sep; i < 256; i++)
1090: - if(is_sep[i])
1091: - *s++ = i;
1092: - *s = 0;
1093: - memset(is_sep, 0, sizeof is_sep);
1094: - memset(is_field, 1, sizeof is_field);
1095: - for(s = (unsigned char *)arg; *s;){
1096: - is_sep[*s] = 1;
1097: - is_field[*s++] = 0;
1098: - }
1099: - is_field[0] = 0;
1100: - return(last_sep);
1101: -}
1102: -
1103: -getfields(ss, sp, nptrs)
1104: - char *ss;
1105: - char **sp;
1106: -{
1107: - register unsigned char *s = (unsigned char *)ss;
1108: - register unsigned char **p = (unsigned char **)sp;
1109: - register unsigned c;
1110: -
1111: - for(;;){
1112: - if(--nptrs < 0) break;
1113: - *p++ = s;
1114: - while(is_field[c = *s++])
1115: - ;
1116: - if(c == 0) break;
1117: - s[-1] = 0;
1118: - }
1119: - if(nptrs > 0)
1120: - *p = 0;
1121: - else if(--s >= (unsigned char *)ss)
1122: - *s = c;
1123: - return(p - (unsigned char **)sp);
1124: -}
1125: -
1126: -getmfields(ss, sp, nptrs)
1127: - char *ss;
1128: - char **sp;
1129: -{
1130: - register unsigned char *s = (unsigned char *)ss;
1131: - register unsigned char **p = (unsigned char **)sp;
1132: - register unsigned c;
1133: - register unsigned d;
1134: -
1135: - if(nptrs <= 0)
1136: - return(0);
1137: - goto flushdelim;
1138: - for(;;){
1139: - *p++ = s;
1140: - if(--nptrs == 0) break;
1141: - while(is_field[c = *s++])
1142: - ;
1143: - /*
1144: - * s is now pointing 1 past the delimiter of the last field
1145: - * c is the delimiter
1146: - */
1147: - if(c == 0) break;
1148: - s[-1] = 0;
1149: - flushdelim:
1150: - while(is_sep[c = *s++])
1151: - ;
1152: - /*
1153: - * s is now pointing 1 past the beginning of the next field
1154: - * c is the first letter of the field
1155: - */
1156: - if(c == 0) break;
1157: - s--;
1158: - /*
1159: - * s is now pointing to the beginning of the next field
1160: - * c is the first letter of the field
1161: - */
1162: - }
1163: - if(nptrs > 0)
1164: - *p = 0;
1165: - return(p - (unsigned char **)sp);
1166: -}
1167: -
1168: -#ifdef MAIN
1169: -#include <fio.h>
1170: -
1171: -main()
1172: -{
1173: - char *fields[256];
1174: - char *s;
1175: - int n, i;
1176: - char buf[1024];
1177: -
1178: - print("go:\n");
1179: - while(s = Frdline(0)){
1180: - strcpy(buf, s);
1181: - Fprint(1, "getf:");
1182: - n = getfields(s, fields, 4);
1183: - for(i = 0; i < n; i++)
1184: - Fprint(1, " >%s<", fields[i]);
1185: - Fputc(1, '\n');
1186: - Fprint(1, "getmf:");
1187: - n = getmfields(buf, fields, 4);
1188: - for(i = 0; i < n; i++)
1189: - Fprint(1, " >%s<", fields[i]);
1190: - Fputc(1, '\n');
1191: - Fflush(1);
1192: - }
1193: - exit(0);
1194: -}
1195: -#endif
1196: //GO.SYSIN DD ./libc/getfields.c
1197: echo ./libc/libc.h 1>&2
1198: sed 's/.//' >./libc/libc.h <<'//GO.SYSIN DD ./libc/libc.h'
1199: -/* system calls */
1200: -extern unsigned alarm();
1201: -extern void nap(), pause();
1202: -extern char *sbrk();
1203: -extern void exit(), _exit();
1204: -extern long lseek();
1205: -extern void nice();
1206: -extern void profil();
1207: -extern unsigned long settod();
1208: -extern void sync();
1209: -extern long time();
1210: -
1211: -/* libc et al */
1212: -extern long lcm();
1213: -extern double atof(), strtod();
1214: -extern long atol();
1215: -extern char *crypt();
1216: -extern char *ctime();
1217: -extern char *ecvt(), *fcvt(), *gcvt();
1218: -extern char *galloc();
1219: -extern char *getenv();
1220: -extern char *getlogin();
1221: -extern char *getpass();
1222: -extern char *getwd(), *getcwd();
1223: -extern char *malloc(), *realloc(), *calloc();
1224: -extern char *memcpy(), *memchr(), *memccpy(), *memset();
1225: -extern char *mktemp();
1226: -extern double frand();
1227: -extern char *setfields();
1228: -extern char *strcpy(), *strncpy(), *strcat(), *strncat(), *strchr(), *strrchr();
1229: -extern char *strpbrk(), *strtok(), *strdup();
1230: -extern int atoi();
1231: -extern char *tgetstr(), tgoto();
1232: -extern char *ttyname(), *cttyname();
1233: -
1234: -#define NONEXIT 33
1235: //GO.SYSIN DD ./libc/libc.h
1236: echo ./libc/onexit.c 1>&2
1237: sed 's/.//' >./libc/onexit.c <<'//GO.SYSIN DD ./libc/onexit.c'
1238: -#include <libc.h>
1239: -
1240: -int (*_onexitfns[NONEXIT])();
1241: -
1242: -atexit(f)
1243: -int (*f)();
1244: -{
1245: - onexit(f);
1246: -}
1247: -
1248: -onexit(f)
1249: -int (*f)();
1250: -{
1251: - int i;
1252: -
1253: - for(i=0; i<NONEXIT; i++)
1254: - if(!_onexitfns[i]){
1255: - _onexitfns[i] = f;
1256: - return(1);
1257: - }
1258: - return(0);
1259: -}
1260: //GO.SYSIN DD ./libc/onexit.c
1261: echo ./libc/regexp.h 1>&2
1262: sed 's/.//' >./libc/regexp.h <<'//GO.SYSIN DD ./libc/regexp.h'
1263: -/* the structure describing a sub-expression match */
1264: -typedef struct {
1265: - char *sp;
1266: - char *ep;
1267: -} regsubexp;
1268: -
1269: -/* a compiled regular expression */
1270: -typedef char *regexp;
1271: -
1272: -/* the routines */
1273: -extern regexp *regcomp();
1274: -extern int regexec();
1275: -extern void regsub();
1276: //GO.SYSIN DD ./libc/regexp.h
1277: echo ./libc/print.c 1>&2
1278: sed 's/.//' >./libc/print.c <<'//GO.SYSIN DD ./libc/print.c'
1279: -#include <varargs.h>
1280: -
1281: -#define SIZE 1024
1282: -extern int printcol;
1283: -
1284: -char *doprint();
1285: -
1286: -/* VARARGS 1 */
1287: -print(fmt, va_alist)
1288: -char *fmt;
1289: -va_dcl
1290: -{
1291: - char buf[SIZE], *out;
1292: - va_list ap;
1293: -
1294: - va_start(ap);
1295: - out = doprint(buf, fmt, &ap);
1296: - va_end(ap);
1297: - return write(1, buf, (int)(out-buf));
1298: -}
1299: -
1300: -/* VARARGS 2 */
1301: -fprint(fd, fmt, va_alist)
1302: -char *fmt;
1303: -va_dcl
1304: -{
1305: - char buf[SIZE], *out;
1306: - va_list ap;
1307: -
1308: - va_start(ap);
1309: - out = doprint(buf, fmt, &ap);
1310: - va_end(ap);
1311: - return write(fd, buf, (int)(out-buf));
1312: -}
1313: -
1314: -/* VARARGS 2 */
1315: -sprint(buf, fmt, va_alist)
1316: -char *buf;
1317: -char *fmt;
1318: -va_dcl
1319: -{
1320: - char *out;
1321: - int scol;
1322: - va_list ap;
1323: -
1324: - scol = printcol;
1325: - va_start(ap);
1326: - out = doprint(buf, fmt, &ap);
1327: - va_end(ap);
1328: - printcol = scol;
1329: - return out-buf;
1330: -}
1331: //GO.SYSIN DD ./libc/print.c
1332: echo ./libc/strdup.c 1>&2
1333: sed 's/.//' >./libc/strdup.c <<'//GO.SYSIN DD ./libc/strdup.c'
1334: -/* @(#)strdup.c 1.2 */
1335: -/*LINTLIBRARY*/
1336: -/* string duplication
1337: - returns pointer to a new string which is the duplicate of string
1338: - pointed to by s1
1339: - NULL is returned if new string can't be created
1340: -*/
1341: -
1342: -#include <string.h>
1343: -#ifndef NULL
1344: -#define NULL 0
1345: -#endif
1346: -
1347: -extern int strlen();
1348: -extern char *malloc();
1349: -
1350: -char *
1351: -strdup(s1)
1352: -
1353: - char * s1;
1354: -
1355: -{
1356: - char * s2;
1357: -
1358: - s2 = malloc((unsigned) strlen(s1)+1) ;
1359: - return(s2==NULL ? NULL : strcpy(s2,s1) );
1360: -}
1361: //GO.SYSIN DD ./libc/strdup.c
1362: echo ./libc/Makefile 1>&2
1363: sed 's/.//' >./libc/Makefile <<'//GO.SYSIN DD ./libc/Makefile'
1364: -OBJ=doprint.o exit.o getfields.o onexit.o print.o strdup.o regcomp.o regexec.o regsub.o dup2.o
1365: -
1366: -libc.a: $(OBJ)
1367: - ar r libc.a $(OBJ)
1368: - $(RANLIB) libc.a
1369: -
1370: -cray: libc.o
1371: -
1372: -libc.o: $(OBJ)
1373: - cat $(OBJ) > libc.o
1374: //GO.SYSIN DD ./libc/Makefile
1375: echo ./libc/regexec.c 1>&2
1376: sed 's/.//' >./libc/regexec.c <<'//GO.SYSIN DD ./libc/regexec.c'
1377: -#include "regprog.h"
1378: -
1379: -/*
1380: - * Machine state
1381: - */
1382: -#define LISTINCREMENT 8
1383: -typedef struct List{
1384: - Inst *inst; /* Instruction of the thread */
1385: - Subexp se; /* matched subexpressions in this thread */
1386: -}List;
1387: -static List *tl, *nl; /* This list, next list */
1388: -static List *tle, *nle; /* ends of this and next list */
1389: -static List *list[2];
1390: -static List *liste[2];
1391: -static int listsize = LISTINCREMENT;
1392: -
1393: -static Subexp sempty; /* empty set of matches */
1394: -static int match; /* true if match is found */
1395: -
1396: -/*
1397: - * Note optimization in addinst:
1398: - * *lp must be pending when addinst called; if *l has been looked
1399: - * at already, the optimization is a bug.
1400: - */
1401: -static List *
1402: -newthread(lp, ip, sep)
1403: - List *lp; /* list to add to */
1404: - Inst *ip; /* instruction to add */
1405: - register Subexp *sep; /* pointers to subexpressions */
1406: -{
1407: - register List *p;
1408: -
1409: - for(p=lp; p->inst != NULL; p++){
1410: - if(p->inst==ip){
1411: - if((sep)->m[0].sp < p->se.m[0].sp)
1412: - p->se = *sep;
1413: - return NULL;
1414: - }
1415: - }
1416: - p->inst = ip;
1417: - p->se = *sep;
1418: - (++p)->inst = NULL;
1419: - return p;
1420: -}
1421: -
1422: -static void
1423: -newmatch(mp, ms, sp)
1424: - regsubexp *mp;
1425: - int ms;
1426: - register Subexp *sp;
1427: -{
1428: - register int i;
1429: -
1430: - if (mp==NULL || ms <=0)
1431: - return;
1432: - if(mp[0].sp==0 || sp->m[0].sp<mp[0].sp ||
1433: - (sp->m[0].sp==mp[0].sp && sp->m[0].ep>mp[0].ep)) {
1434: - for (i=0; i<ms && i<NSUBEXP; i++)
1435: - mp[i] = sp->m[i];
1436: - for (; i<ms; i++)
1437: - mp[i].sp = mp[i].ep = NULL;
1438: - }
1439: -}
1440: -
1441: -extern int
1442: -regexec(progp, starts, mp, ms)
1443: - Prog *progp; /* program to run */
1444: - char *starts; /* string to run machine on */
1445: - regsubexp *mp; /* subexpression elements */
1446: - int ms; /* number of elements pointed to by mp */
1447: -{
1448: - register flag=0;
1449: - register Inst *inst;
1450: - register List *tlp;
1451: - register char *s;
1452: - int startchar=progp->startinst->type<OPERATOR? progp->startinst->type : 0;
1453: - int i, checkstart;
1454: -
1455: -restart:
1456: - match = 0;
1457: - checkstart = startchar;
1458: - sempty.m[0].sp = NULL;
1459: - if (mp!=NULL && ms >0)
1460: - mp[0].sp = mp[0].ep = NULL;
1461: - if (list[0] == NULL) {
1462: - list[0] = (List *)malloc(2*listsize*sizeof(List));
1463: - list[1] = list[0] + listsize;
1464: - liste[0] = list[0] + listsize - 1;
1465: - liste[1] = list[1] + listsize - 1;
1466: - if (list[0] == NULL)
1467: - regerror("list overflow");
1468: - }
1469: - list[0][0].inst = list[1][0].inst = NULL;
1470: -
1471: - /* Execute machine once for each character, including terminal NUL */
1472: - s=starts;
1473: - do{
1474: - /* fast check for first char */
1475: - if(checkstart && *s!=startchar)
1476: - continue;
1477: - tl=list[flag];
1478: - tle=liste[flag];
1479: - nl=list[flag^=1];
1480: - nle=liste[flag];
1481: - nl->inst=0;
1482: - /* Add first instruction to this list */
1483: - sempty.m[0].sp = s;
1484: - (void)newthread(tl, progp->startinst, &sempty);
1485: - /* Execute machine until this list is empty */
1486: - for(tlp=tl; inst=tlp->inst; tlp++){ /* assignment = */
1487: - Switchstmt:
1488: - switch(inst->type){
1489: - default: /* regular character */
1490: - if(inst->type == *s){
1491: - Addinst:
1492: - if(newthread(nl, inst->next, &tlp->se)==nle)
1493: - goto realloc;
1494: - }
1495: - break;
1496: - case LBRA:
1497: - tlp->se.m[inst->subid].sp = s;
1498: - inst=inst->next;
1499: - goto Switchstmt;
1500: - case RBRA:
1501: - tlp->se.m[inst->subid].ep = s;
1502: - inst=inst->next;
1503: - goto Switchstmt;
1504: - case ANY:
1505: - goto Addinst;
1506: - case BOL:
1507: - if(s == starts){
1508: - inst=inst->next;
1509: - goto Switchstmt;
1510: - }
1511: - break;
1512: - case EOL:
1513: - if(*s=='\0'){
1514: - inst=inst->next;
1515: - goto Switchstmt;
1516: - }
1517: - break;
1518: - case CCLASS:
1519: - if(((char *)inst->right)[*s/8]&(1<<(*s&07)))
1520: - goto Addinst;
1521: - break;
1522: - case OR:
1523: - /* evaluate right choice later */
1524: - if (newthread(tlp, inst->right, &tlp->se) == tle)
1525: - goto realloc;
1526: - /* efficiency: advance and re-evaluate */
1527: - inst=inst->left;
1528: - goto Switchstmt;
1529: - case END: /* Match! */
1530: - match = 1;
1531: - tlp->se.m[0].ep = s;
1532: - if (mp != NULL && ms > 0) newmatch(mp, ms, &tlp->se);
1533: - break;
1534: - }
1535: - }
1536: - checkstart = startchar && nl->inst==NULL;
1537: - }while(*s++);
1538: - return match;
1539: -realloc:
1540: - free(list[0]);
1541: - list[0] = NULL;
1542: - listsize += LISTINCREMENT;
1543: - goto restart;
1544: -}
1545: -
1546: //GO.SYSIN DD ./libc/regexec.c
1547: echo ./libc/regprog.h 1>&2
1548: sed 's/.//' >./libc/regprog.h <<'//GO.SYSIN DD ./libc/regprog.h'
1549: -#include <regexp.h>
1550: -
1551: -/* useful constants */
1552: -#define NULL 0
1553: -#define TRUE 1
1554: -#define FALSE 0
1555: -#define HAT '\177' /* character to mark real beg. of line */
1556: -
1557: -/*
1558: - * Sub expression matches
1559: - */
1560: -#define NSUBEXP 10
1561: -typedef struct {
1562: - regsubexp m[NSUBEXP];
1563: -}Subexp;
1564: -
1565: -/*
1566: - * character class
1567: - */
1568: -typedef struct {
1569: - char map[16]; /* 16 bytes == 128 bits, one bit per char */
1570: -}Class;
1571: -
1572: -/*
1573: - * Machine instructions
1574: - */
1575: -typedef struct Inst{
1576: - int type; /* < 0200 ==> literal, otherwise action */
1577: - union {
1578: - int sid; /* sub-expression id for RBRA and LBRA */
1579: - struct Inst *other; /* instructions pointer */
1580: - } u;
1581: - struct Inst *left;
1582: -}Inst;
1583: -#define next left /* Left branch is usually just next ptr */
1584: -#define subid u.sid
1585: -#define right u.other
1586: -
1587: -/*
1588: - * Program definition
1589: - */
1590: -#define NCLASS 16
1591: -typedef struct Program{
1592: - Inst *startinst; /* start pc */
1593: - Class class[NCLASS]; /* .data */
1594: - Inst firstinst[5]; /* .text */
1595: -}Prog;
1596: -
1597: -/*
1598: - * Actions and Tokens
1599: - *
1600: - * 02xx are operators, value == precedence
1601: - * 03xx are tokens, i.e. operands for operators
1602: - */
1603: -#define OPERATOR 0200 /* Bitmask of all operators */
1604: -#define START 0200 /* Start, used for marker on stack */
1605: -#define RBRA 0201 /* Right bracket, ) */
1606: -#define LBRA 0202 /* Left bracket, ( */
1607: -#define OR 0203 /* Alternation, | */
1608: -#define CAT 0204 /* Concatentation, implicit operator */
1609: -#define STAR 0205 /* Closure, * */
1610: -#define PLUS 0206 /* a+ == aa* */
1611: -#define QUEST 0207 /* a? == a|nothing, i.e. 0 or 1 a's */
1612: -#define ANY 0300 /* Any character, . */
1613: -#define NOP 0301 /* No operation, internal use only */
1614: -#define BOL 0302 /* Beginning of line, ^ */
1615: -#define EOL 0303 /* End of line, $ */
1616: -#define CCLASS 0304 /* Character class, [] */
1617: -#define END 0377 /* Terminate: match found */
1618: //GO.SYSIN DD ./libc/regprog.h
1619: echo ./libc/regsub.c 1>&2
1620: sed 's/.//' >./libc/regsub.c <<'//GO.SYSIN DD ./libc/regsub.c'
1621: -#include "regprog.h"
1622: -
1623: -/* substitute into one string using the matches from the last regexec() */
1624: -extern void
1625: -regsub (sp, dp, mp, ms)
1626: - char *sp; /* source string */
1627: - char *dp; /* destination string */
1628: - regsubexp *mp; /* subexpression elements */
1629: - int ms; /* number of elements pointed to by mp */
1630: -{
1631: - char *ssp;
1632: - register int i;
1633: -
1634: - while (*sp != '\0') {
1635: - if (*sp == '\\') {
1636: - switch (*++sp) {
1637: - case '0':
1638: - case '1':
1639: - case '2':
1640: - case '3':
1641: - case '4':
1642: - case '5':
1643: - case '6':
1644: - case '7':
1645: - case '8':
1646: - case '9':
1647: - i = *sp-'0';
1648: - if (mp[i].sp != NULL && mp!=NULL && ms>i)
1649: - for (ssp = mp[i].sp;
1650: - ssp < mp[i].ep;
1651: - ssp++)
1652: - *dp++ = *ssp;
1653: - break;
1654: - case '\\':
1655: - *dp++ = '\\';
1656: - break;
1657: - case '\0':
1658: - sp--;
1659: - break;
1660: - default:
1661: - *dp++ = *sp;
1662: - break;
1663: - }
1664: - } else if (*sp == '&') {
1665: - if (mp[0].sp != NULL && mp!=NULL && ms>0)
1666: - if (mp[0].sp != NULL)
1667: - for (ssp = mp[0].sp;
1668: - ssp < mp[0].ep; ssp++)
1669: - *dp++ = *ssp;
1670: - } else
1671: - *dp++ = *sp;
1672: - sp++;
1673: - }
1674: - *dp = '\0';
1675: -}
1676: //GO.SYSIN DD ./libc/regsub.c
1677: echo ./libc/dup2.c 1>&2
1678: sed 's/.//' >./libc/dup2.c <<'//GO.SYSIN DD ./libc/dup2.c'
1679: -#ifdef SYSV
1680: -/*
1681: - dup2(a, b)
1682: -
1683: - dup a as value b
1684: -*/
1685: -
1686: -dup2(a, b)
1687: -{
1688: - int poot[256]; /* greater than NFILES i hope! */
1689: - register i, ret;
1690: -
1691: - close(b);
1692: - for(i = 0; (poot[i] = dup(a)) >= 0; i++)
1693: - if(poot[i] == b) break;
1694: - ret = i;
1695: - while(--i >= 0)
1696: - close(poot[i]); /* don't need 'em anymore */
1697: - return(poot[ret]);
1698: -}
1699: -#endif
1700: //GO.SYSIN DD ./libc/dup2.c
1701: echo ./libc/new.mk 1>&2
1702: sed 's/.//' >./libc/new.mk <<'//GO.SYSIN DD ./libc/new.mk'
1703: -#ifdef DEBUG
1704: -#include <stdio.h>
1705: -#endif
1706: -#include <libc.h>
1707: -#include "regprog.h"
1708: -
1709: -/*
1710: - * Parser Information
1711: - */
1712: -typedef struct Node{
1713: - Inst *first;
1714: - Inst *last;
1715: -}Node;
1716: -#define NSTACK 20
1717: -static Node andstack[NSTACK];
1718: -static Node *andp;
1719: -static int atorstack[NSTACK];
1720: -static int *atorp;
1721: -static int cursubid; /* id of current subexpression */
1722: -static int subidstack[NSTACK]; /* parallel to atorstack */
1723: -static int *subidp;
1724: -static int lastwasand; /* Last token was operand */
1725: -static int nbra;
1726: -static char *exprp; /* pointer to next character in source expression */
1727: -static int nclass;
1728: -static Class *classp;
1729: -static Inst *freep;
1730: -static int errors;
1731: -
1732: -/* predeclared crap */
1733: -static void operator();
1734: -static void pushand();
1735: -static void pushator();
1736: -static void evaluntil();
1737: -static void bldcclass();
1738: -
1739: -static void
1740: -rcerror(s)
1741: - char *s;
1742: -{
1743: - errors++;
1744: - regerror(s);
1745: -}
1746: -
1747: -static Inst *
1748: -newinst(t)
1749: - int t;
1750: -{
1751: - freep->type=t;
1752: - freep->left=0;
1753: - freep->right=0;
1754: - return freep++;
1755: -}
1756: -
1757: -static void
1758: -operand(t)
1759: - int t;
1760: -{
1761: - register Inst *i;
1762: - if(lastwasand)
1763: - operator(CAT); /* catenate is implicit */
1764: - i=newinst(t);
1765: - if(t==CCLASS) /* ugh */
1766: - i->right=(Inst *)&(classp[nclass-1]); /* UGH! */
1767: - pushand(i, i);
1768: - lastwasand=TRUE;
1769: -}
1770: -
1771: -static void
1772: -operator(t)
1773: - int t;
1774: -{
1775: - if(t==RBRA && --nbra<0)
1776: - rcerror("unmatched right paren");
1777: - if(t==LBRA) {
1778: - if (++cursubid >= NSUBEXP)
1779: - rcerror ("too many subexpressions");
1780: - nbra++;
1781: - if (lastwasand)
1782: - operator(CAT);
1783: - } else
1784: - evaluntil(t);
1785: - if(t!=RBRA)
1786: - pushator(t);
1787: - lastwasand=FALSE;
1788: - if(t==STAR || t==QUEST || t==PLUS || t==RBRA)
1789: - lastwasand=TRUE; /* these look like operands */
1790: -}
1791: -
1792: -static void
1793: -regerr2(s, c)
1794: - char *s;
1795: -{
1796: - char buf[100];
1797: - char *cp = buf;
1798: - while(*s)
1799: - *cp++ = *s++;
1800: - *cp++ = c;
1801: - *cp = '\0';
1802: - rcerror(buf);
1803: -}
1804: -
1805: -static void
1806: -cant(s)
1807: - char *s;
1808: -{
1809: - char buf[100];
1810: - strcpy(buf, "can't happen: ");
1811: - strcat(buf, s);
1812: - rcerror(buf);
1813: -}
1814: -
1815: -static void
1816: -pushand(f, l)
1817: - Inst *f, *l;
1818: -{
1819: - if(andp >= &andstack[NSTACK])
1820: - cant("operand stack overflow");
1821: - andp->first=f;
1822: - andp->last=l;
1823: - andp++;
1824: -}
1825: -
1826: -static void
1827: -pushator(t)
1828: - int t;
1829: -{
1830: - if(atorp >= &atorstack[NSTACK])
1831: - cant("operator stack overflow");
1832: - *atorp++=t;
1833: - *subidp++=cursubid;
1834: -}
1835: -
1836: -static Node *
1837: -popand(op)
1838: -{
1839: - register Inst *inst;
1840: -
1841: - if(andp <= &andstack[0]) {
1842: - regerr2("missing operand for ", op);
1843: - inst=newinst(NOP);
1844: - pushand(inst,inst);
1845: - }
1846: - return --andp;
1847: -}
1848: -
1849: -static int
1850: -popator()
1851: -{
1852: - if(atorp <= &atorstack[0])
1853: - cant("operator stack underflow");
1854: - --subidp;
1855: - return *--atorp;
1856: -}
1857: -
1858: -static void
1859: -evaluntil(pri)
1860: - register pri;
1861: -{
1862: - register Node *op1, *op2;
1863: - register Inst *inst1, *inst2;
1864: -
1865: - while(pri==RBRA || atorp[-1]>=pri){
1866: - switch(popator()){
1867: - default:
1868: - rcerror("unknown operator in evaluntil");
1869: - break;
1870: - case LBRA: /* must have been RBRA */
1871: - op1=popand('(');
1872: - inst2=newinst(RBRA);
1873: - inst2->subid = *subidp;
1874: - op1->last->next = inst2;
1875: - inst1=newinst(LBRA);
1876: - inst1->subid = *subidp;
1877: - inst1->next=op1->first;
1878: - pushand(inst1, inst2);
1879: - return;
1880: - case OR:
1881: - op2=popand('|');
1882: - op1=popand('|');
1883: - inst2=newinst(NOP);
1884: - op2->last->next=inst2;
1885: - op1->last->next=inst2;
1886: - inst1=newinst(OR);
1887: - inst1->right=op1->first;
1888: - inst1->left=op2->first;
1889: - pushand(inst1, inst2);
1890: - break;
1891: - case CAT:
1892: - op2=popand(0);
1893: - op1=popand(0);
1894: - op1->last->next=op2->first;
1895: - pushand(op1->first, op2->last);
1896: - break;
1897: - case STAR:
1898: - op2=popand('*');
1899: - inst1=newinst(OR);
1900: - op2->last->next=inst1;
1901: - inst1->right=op2->first;
1902: - pushand(inst1, inst1);
1903: - break;
1904: - case PLUS:
1905: - op2=popand('+');
1906: - inst1=newinst(OR);
1907: - op2->last->next=inst1;
1908: - inst1->right=op2->first;
1909: - pushand(op2->first, inst1);
1910: - break;
1911: - case QUEST:
1912: - op2=popand('?');
1913: - inst1=newinst(OR);
1914: - inst2=newinst(NOP);
1915: - inst1->left=inst2;
1916: - inst1->right=op2->first;
1917: - op2->last->next=inst2;
1918: - pushand(inst1, inst2);
1919: - break;
1920: - }
1921: - }
1922: -}
1923: -
1924: -static Prog *
1925: -optimize(pp)
1926: - Prog *pp;
1927: -{
1928: - register Inst *inst, *target;
1929: - int size;
1930: - Prog *npp;
1931: -
1932: - /*
1933: - * get rid of NOOP chains
1934: - */
1935: - for(inst=pp->firstinst; inst->type!=END; inst++){
1936: - target=inst->next;
1937: - while(target->type == NOP)
1938: - target=target->next;
1939: - inst->next=target;
1940: - }
1941: -
1942: - /*
1943: - * The original allocation is for an area larger than
1944: - * necessary. Reallocate to the actual space used
1945: - * and then relocate the code.
1946: - */
1947: - size = sizeof(Prog) + (freep - pp->firstinst)*sizeof(Inst);
1948: - npp = (Prog *)realloc((char *)pp, size);
1949: - if(npp==NULL || npp==pp)
1950: - return(pp);
1951: - freep = &npp->firstinst[freep - pp->firstinst];
1952: - npp->startinst = &npp->firstinst[pp->startinst - pp->firstinst];
1953: - for(inst=npp->firstinst; inst<freep; inst++){
1954: - switch(inst->type){
1955: - case OR:
1956: - case STAR:
1957: - case PLUS:
1958: - case QUEST:
1959: - inst->right = &npp->firstinst[inst->right - pp->firstinst];
1960: - break;
1961: - case CCLASS:
1962: - inst->right = (Inst *) &npp->class[(Class*)inst->right - pp->class];
1963: - break;
1964: - }
1965: - inst->left = &npp->firstinst[inst->left - pp->firstinst];
1966: - }
1967: - return(npp);
1968: -}
1969: -
1970: -#ifdef DEBUG
1971: -static char *
1972: -dumptype(t){
1973: - static char ordinary[4] = "'.'";
1974: -
1975: - switch(t){
1976: - case START: return "START";
1977: - case RBRA: return "RBRA";
1978: - case LBRA: return "LBRA";
1979: - case OR: return "OR";
1980: - case CAT: return "CAT";
1981: - case STAR: return "STAR";
1982: - case PLUS: return "PLUS";
1983: - case QUEST: return "QUEST";
1984: - case ANY: return "ANY";
1985: - case NOP: return "NOP";
1986: - case BOL: return "BOL";
1987: - case EOL: return "EOL";
1988: - case CCLASS: return "CCLASS";
1989: - case END: return "END";
1990: - default:
1991: - ordinary[1] = t;
1992: - return ordinary;
1993: - }
1994: -}
1995: -
1996: -static void
1997: -dumpstack(){
1998: - Node *stk;
1999: - int *ip;
2000: -
2001: - printf("operators\n");
2002: - for(ip=atorstack; ip<atorp; ip++)
2003: - printf("0%o\n", *ip);
2004: - printf("operands\n");
2005: - for(stk=andstack; stk<andp; stk++){
2006: - printf("%s\t", dumptype(stk->first->type));
2007: - printf("%s\n", dumptype(stk->last->type));
2008: - }
2009: -}
2010: -
2011: -static void
2012: -putC(c)
2013: -{
2014: - if(c < ' ' || '~' < c){
2015: - switch(c){
2016: - default:
2017: - putchar('^');
2018: - putchar((c + '@') & 0x7f);
2019: - return;
2020: - case '\b':
2021: - c = 'b';
2022: - break;
2023: - case '\t':
2024: - c = 't';
2025: - break;
2026: - case '\n':
2027: - c = 'n';
2028: - break;
2029: - case '\v':
2030: - c = 'v';
2031: - break;
2032: - case '\f':
2033: - c = 'f';
2034: - break;
2035: - case '\r':
2036: - c = 'r';
2037: - break;
2038: - }
2039: - putchar('\\');
2040: - }
2041: - putchar(c);
2042: -}
2043: -
2044: -static void
2045: -putCHAR(from, to)
2046: -{
2047: - if(from != 0)
2048: - if(from == to)
2049: - putC(from);
2050: - else{
2051: - putC(from);
2052: - putchar('-');
2053: - putC(to);
2054: - }
2055: -}
2056: -
2057: -static void
2058: -dump(pp)
2059: - Prog *pp;
2060: -{
2061: - int c, from;
2062: - Inst *l;
2063: - Class *classp;
2064: -
2065: - l=pp->firstinst;
2066: - do{
2067: - printf("%d:\t%s\t%d\t", l-pp->firstinst, dumptype(l->type),
2068: - l->left-pp->firstinst);
2069: - if(l->type == CCLASS){
2070: - classp = (Class*) l->right;
2071: - putchar('[');
2072: - if(classp->map[0] & 02){ /* ^A? */
2073: - putchar('^'); /* assume negation */
2074: - for(from=0, c=1; c < 128; ++c){
2075: - if(classp->map[c/8] & (1<<(c&07))){
2076: - putCHAR(from, c-1);
2077: - from = 0;
2078: - } else {
2079: - if(from == 0)
2080: - from = c;
2081: - }
2082: - }
2083: - putCHAR(from, c-1);
2084: - } else {
2085: - for(from=0, c=1; c < 128; ++c){
2086: - if(classp->map[c/8] & (1<<(c&07))){
2087: - if(from == 0)
2088: - from = c;
2089: - } else {
2090: - putCHAR(from, c-1);
2091: - from = 0;
2092: - }
2093: - }
2094: - putCHAR(from, c-1);
2095: - }
2096: - putchar(']');
2097: - } else
2098: - printf("%d", l->right-pp->firstinst);
2099: - putchar('\n');
2100: - }while(l++->type);
2101: -}
2102: -#endif
2103: -
2104: -static void
2105: -startlex(s)
2106: - char *s;
2107: -{
2108: - exprp=s;
2109: - nclass=0;
2110: - nbra=0;
2111: -}
2112: -
2113: -static Class *
2114: -newclass(){
2115: - register Class *p;
2116: - register n;
2117: -
2118: - if(nclass >= NCLASS)
2119: - regerr2("too many character classes; limit", NCLASS+'0');
2120: - p = &(classp[nclass++]);
2121: - for(n=0; n<16; n++)
2122: - p->map[n]=0;
2123: - return p;
2124: -}
2125: -
2126: -static int
2127: -lex(){
2128: - register c= *exprp++;
2129: -
2130: - switch(c){
2131: - case '\\':
2132: - if(*exprp)
2133: - c= *exprp++;
2134: - break;
2135: - case 0:
2136: - c=END;
2137: - --exprp; /* In case we come here again */
2138: - break;
2139: - case '*':
2140: - c=STAR;
2141: - break;
2142: - case '?':
2143: - c=QUEST;
2144: - break;
2145: - case '+':
2146: - c=PLUS;
2147: - break;
2148: - case '|':
2149: - c=OR;
2150: - break;
2151: - case '.':
2152: - c=ANY;
2153: - break;
2154: - case '(':
2155: - c=LBRA;
2156: - break;
2157: - case ')':
2158: - c=RBRA;
2159: - break;
2160: - case '^':
2161: - c=BOL;
2162: - break;
2163: - case '$':
2164: - c=EOL;
2165: - break;
2166: - case '[':
2167: - c=CCLASS;
2168: - bldcclass();
2169: - break;
2170: - }
2171: - return c;
2172: -}
2173: -
2174: -static int
2175: -nextc(){
2176: - if(exprp[0]==0 || (exprp[0]=='\\' && exprp[1]==0))
2177: - rcerror("malformed '[]'");
2178: - if(exprp[0]=='\\'){
2179: - exprp++;
2180: - return *exprp++|0200;
2181: - }
2182: - return *exprp++;
2183: -}
2184: -
2185: -static void
2186: -bldcclass(){
2187: - register c1, c2;
2188: - register Class *classp;
2189: - register negate=FALSE;
2190: -
2191: - classp=newclass();
2192: - /* we have already seen the '[' */
2193: - if(*exprp=='^'){
2194: - negate=TRUE;
2195: - exprp++;
2196: - }
2197: - while((c1=c2=nextc()) != ']'){
2198: - if(*exprp=='-'){
2199: - exprp++; /* eat '-' */
2200: - if((c2=nextc()) == ']')
2201: - rcerror("malformed '[]'");
2202: - }
2203: - for((c1&=0177), (c2&=0177); c1<=c2; c1++)
2204: - classp->map[c1/8] |= 1<<(c1&07);
2205: - }
2206: - if(negate)
2207: - for(c1=0; c1<16; c1++)
2208: - classp->map[c1]^=0377;
2209: - classp->map[0] &= 0376; /* exclude NUL */
2210: -}
2211: -
2212: -extern regexp *
2213: -regcomp(s)
2214: - char *s;
2215: -{
2216: - register token;
2217: - Prog *pp;
2218: -
2219: - /* get memory for the program */
2220: - pp = (Prog *)malloc(sizeof(Prog) + 3*sizeof(Inst)*strlen(s));
2221: - if (pp == NULL) {
2222: - rcerror("out of memory");
2223: - return NULL;
2224: - }
2225: - freep = pp->firstinst;
2226: - classp = pp->class;
2227: - errors = 0;
2228: -
2229: - /* go compile the sucker */
2230: - startlex(s);
2231: - atorp=atorstack;
2232: - andp=andstack;
2233: - subidp=subidstack;
2234: - lastwasand=FALSE;
2235: - cursubid=0;
2236: -
2237: - /* Start with a low priority operator to prime parser */
2238: - pushator(START-1);
2239: - while((token=lex()) != END){
2240: - if((token&0300) == OPERATOR)
2241: - operator(token);
2242: - else
2243: - operand(token);
2244: - }
2245: -
2246: - /* Close with a low priority operator */
2247: - evaluntil(START);
2248: -
2249: - /* Force END */
2250: - operand(END);
2251: - evaluntil(START);
2252: -#ifdef DEBUG
2253: - dumpstack();
2254: -#endif
2255: - if(nbra)
2256: - rcerror("unmatched left paren");
2257: - --andp; /* points to first and only operand */
2258: - pp->startinst=andp->first;
2259: -#ifdef DEBUG
2260: - dump(pp);
2261: -#endif
2262: - pp = optimize(pp);
2263: -#ifdef DEBUG
2264: - printf("start: %d\n", pp->startinst-pp->firstinst);
2265: - dump(pp);
2266: - fflush(stdout);
2267: -#endif
2268: - if (errors) {
2269: - free((char *)pp);
2270: - pp = NULL;
2271: - }
2272: - return (regexp *)pp;
2273: -}
2274: -
2275: -#ifdef DEBUG
2276: -#include <setjmp.h>
2277: -
2278: -jmp_buf jmpbuf;
2279: -
2280: -main( argc, argv )
2281: - char **argv;
2282: -{
2283: - regexp *prog = NULL;
2284: - regsubexp match[NSUBEXP];
2285: - char line[256];
2286: - int i;
2287: -
2288: - while( TRUE ) {
2289: - setjmp( jmpbuf );
2290: -
2291: - if(prog)
2292: - free( prog );
2293: -
2294: - do {
2295: - fputs( "Enter re: ", stdout );
2296: - if ( gets(line) == NULL )
2297: - exit(0);
2298: - } while( (prog = regcomp(line)) == NULL );
2299: -
2300: - fputs( "Enter string: ", stdout );
2301: - while( gets(line) != NULL ) {
2302: - if ( !regexec(prog,line,match,NSUBEXP) )
2303: - puts( "*** NO MATCH ***" );
2304: - else
2305: - for( i = 0; i < NSUBEXP; ++i )
2306: - if ( match[i].sp )
2307: - printf( "match[%d] = \"%.*s\"\n", i, match[i].ep - match[i].sp, match[i].sp );
2308: - }
2309: - }
2310: -}
2311: -
2312: -regerror( s )
2313: - char *s;
2314: -{
2315: - puts( s );
2316: - longjmp( jmpbuf );
2317: -}
2318: -
2319: -#endif
2320: //GO.SYSIN DD ./libc/new.mk
2321: echo ./fio/README 1>&2
2322: sed 's/.//' >./fio/README <<'//GO.SYSIN DD ./fio/README'
2323: -here (as in ../libc) you have to add whatever commands
2324: -you need to set up an archive in the shell file `gen'.
2325: //GO.SYSIN DD ./fio/README
2326: echo ./fio/fio.h 1>&2
2327: sed 's/.//' >./fio/fio.h <<'//GO.SYSIN DD ./fio/fio.h'
2328: -#define FIOBSIZE 4096
2329: -
2330: -typedef struct Fbuffer
2331: -{
2332: - unsigned char *next; /* next char to be used */
2333: - unsigned char *end; /* first invalid char */
2334: - unsigned char *lnext; /* previous value of next */
2335: - unsigned short flags; /* see FIO_.* below */
2336: - short oflush; /* if >= 0 fd to flush on read */
2337: - long offset; /* seek of end */
2338: - unsigned char buf[FIOBSIZE];
2339: -} Fbuffer;
2340: -extern Fbuffer *Ffb[];
2341: -
2342: -#define FIORESET(f) ((f)->next=(f)->lnext=(f)->end=(f)->buf, (f)->flags&= ~FIO_MALLOCED, (f)->oflush= -1)
2343: -#define FIOSET(f, fd) if((f=Ffb[fd&=0x7f]) == 0){Finit(fd,(char *)0);f=Ffb[fd];}
2344: -/* FIOLINELEN is length of last input */
2345: -#define FIOLINELEN(fd) (((int)(Ffb[fd]->next - Ffb[fd]->lnext))-1)
2346: -/* FIOSEEK is lseek of next char to be processed */
2347: -#define FIOSEEK(fd) (Ffb[fd]->offset - (Ffb[fd]->end - Ffb[fd]->next))
2348: -#define FIOFLUSH(fd) if((fd >= 0) && Ffb[fd]) Fflush(fd)
2349: -
2350: -#define FIO_RDLAST 0x0001 /* true if last input was rdline */
2351: -#define FIO_WRITING 0x0002 /* true if last action was write */
2352: -#define FIO_MALLOCED 0x0004 /* set if Finit did the malloc */
2353: -
2354: -extern void Finit();
2355: -extern char *Frdline();
2356: -extern void Fundo();
2357: -extern int Fgetc();
2358: -extern long Fread();
2359: -extern long Fwrite();
2360: -extern long Fseek();
2361: -extern int Fflush();
2362: -
2363: -#ifdef FIO_IMP
2364: -/* COUNT is the type of counts to things like read, write, memcpy etc */
2365: -#ifdef GNOT
2366: -#define COUNT long
2367: -#define FIOMALLOC(n) malloc(n)
2368: -#define SEEK(a,b,c) seek(a,b,c)
2369: -#else
2370: -#define COUNT int
2371: -#define FIOMALLOC(n) malloc(n)
2372: -#define SEEK(a,b,c) lseek(a,b,c)
2373: -#endif
2374: -extern COUNT read(), write();
2375: -#endif
2376: //GO.SYSIN DD ./fio/fio.h
2377: echo ./fio/fiofillbuf.c 1>&2
2378: sed 's/.//' >./fio/fiofillbuf.c <<'//GO.SYSIN DD ./fio/fiofillbuf.c'
2379: -#define FIO_IMP
2380: -#include "fio.h"
2381: -#include <libc.h>
2382: -
2383: -Ffillbuf(fd)
2384: -{
2385: - register COUNT n;
2386: - register Fbuffer *f = Ffb[fd];
2387: -
2388: - if(n = &f->buf[FIOBSIZE]-f->end){
2389: - FIOFLUSH(f->oflush);
2390: - n = read(fd, f->end, n);
2391: - if(n <= 0)
2392: - return(-1);
2393: - f->end += n;
2394: - f->offset += n;
2395: - }
2396: - return(1);
2397: -}
2398: //GO.SYSIN DD ./fio/fiofillbuf.c
2399: echo ./fio/fioflush.c 1>&2
2400: sed 's/.//' >./fio/fioflush.c <<'//GO.SYSIN DD ./fio/fioflush.c'
2401: -#define FIO_IMP
2402: -#include "fio.h"
2403: -#include <libc.h>
2404: -
2405: -Fflush(fd)
2406: -{
2407: - register Fbuffer *f;
2408: -
2409: - FIOSET(f, fd);
2410: - if(f->flags&FIO_WRITING)
2411: - return(F_flush(f, fd));
2412: - else
2413: - return(0);
2414: -}
2415: -
2416: -F_flush(f, fd)
2417: - register Fbuffer *f;
2418: -{
2419: - register COUNT n;
2420: -
2421: - f->flags &= ~FIO_WRITING;
2422: - if(n = f->next - f->buf){
2423: - if(write(fd, f->buf, n) != n)
2424: - return(-1);
2425: - f->next = f->buf;
2426: - }
2427: - return(0);
2428: -}
2429: //GO.SYSIN DD ./fio/fioflush.c
2430: echo ./fio/fiogetc.c 1>&2
2431: sed 's/.//' >./fio/fiogetc.c <<'//GO.SYSIN DD ./fio/fiogetc.c'
2432: -#define FIO_IMP
2433: -#include "fio.h"
2434: -#include <libc.h>
2435: -
2436: -Fgetc(fd)
2437: -{
2438: - register Fbuffer *f;
2439: -
2440: - FIOSET(f, fd);
2441: - if(f->next >= f->end){
2442: - if(f->end >= &f->buf[FIOBSIZE])
2443: - f->end = f->next = f->buf;
2444: - else
2445: - f->next = f->end;
2446: - if(Ffillbuf(fd) <= 0)
2447: - return(-1);
2448: - }
2449: - f->lnext = f->next;
2450: - f->flags &= ~(FIO_RDLAST|FIO_WRITING);
2451: - return(*f->next++);
2452: -}
2453: //GO.SYSIN DD ./fio/fiogetc.c
2454: echo ./fio/fioinit.c 1>&2
2455: sed 's/.//' >./fio/fioinit.c <<'//GO.SYSIN DD ./fio/fioinit.c'
2456: -#define FIO_IMP
2457: -#include "fio.h"
2458: -#include <libc.h>
2459: -
2460: -static Fdie()
2461: -{
2462: - Fexit(0);
2463: -}
2464: -
2465: -void
2466: -Finit(fd, buf)
2467: - char *buf;
2468: -{
2469: - register Fbuffer *f;
2470: - static setfioexit = 1;
2471: -
2472: - if(setfioexit){
2473: - setfioexit = 0;
2474: - atexit(Fdie);
2475: - }
2476: - fd &= 0x7f;
2477: - if(buf){
2478: - Ffb[fd] = (Fbuffer *)buf;
2479: - Ffb[fd]->flags = 0;
2480: - } else if(!Ffb[fd]){
2481: - Ffb[fd] = (Fbuffer *)FIOMALLOC((COUNT)sizeof(Fbuffer));
2482: - Ffb[fd]->flags = FIO_MALLOCED;
2483: - }
2484: - f = Ffb[fd];
2485: - FIORESET(f);
2486: - f->offset = SEEK(fd, 0L, 1);
2487: - if(f->offset < 0)
2488: - f->offset = 0; /* file not been written yet */
2489: -}
2490: -
2491: -#ifdef GNOT
2492: -#define NOFILE 128
2493: -#endif
2494: -#ifndef GNOT
2495: -#include <sys/param.h>
2496: -#endif
2497: -
2498: -Fbuffer *Ffb[NOFILE];
2499: -
2500: -Fexit(type)
2501: -{
2502: - register n;
2503: -
2504: - for(n = 0; n < NOFILE; n++)
2505: - if(Ffb[n])
2506: - if(type == 0)
2507: - Fflush(n);
2508: - else
2509: - Fclose(n);
2510: -}
2511: //GO.SYSIN DD ./fio/fioinit.c
2512: echo ./fio/fioprint.c 1>&2
2513: sed 's/.//' >./fio/fioprint.c <<'//GO.SYSIN DD ./fio/fioprint.c'
2514: -#define FIO_IMP
2515: -#include <varargs.h>
2516: -#include <fio.h>
2517: -
2518: -/* VARARGS 2 */
2519: -Fprint(f, fmt, va_alist)
2520: -int f;
2521: -char *fmt;
2522: -va_dcl
2523: -{
2524: - char buf[FIOBSIZE], *out;
2525: - register long n;
2526: - va_list ap;
2527: - extern char *doprint();
2528: -
2529: - va_start(ap);
2530: - out = doprint(buf, fmt, &ap);
2531: - va_end(ap);
2532: - n = out-buf;
2533: - if(Fwrite(f, buf, n) != n)
2534: - return(-1);
2535: - else
2536: - return((int)n);
2537: -}
2538: //GO.SYSIN DD ./fio/fioprint.c
2539: echo ./fio/fioputc.c 1>&2
2540: sed 's/.//' >./fio/fioputc.c <<'//GO.SYSIN DD ./fio/fioputc.c'
2541: -#define FIO_IMP
2542: -#include "fio.h"
2543: -#include <libc.h>
2544: -
2545: -Fputc(fd, c)
2546: -{
2547: - register Fbuffer *f;
2548: -
2549: - FIOSET(f, fd);
2550: - if(f->next >= &f->buf[FIOBSIZE]){
2551: - if(F_flush(f, fd))
2552: - return(-1);
2553: - }
2554: - *f->next++ = c;
2555: - f->end = f->next;
2556: - f->offset++;
2557: - f->flags |= FIO_WRITING;
2558: - return(0);
2559: -}
2560: //GO.SYSIN DD ./fio/fioputc.c
2561: echo ./fio/fiordline.c 1>&2
2562: sed 's/.//' >./fio/fiordline.c <<'//GO.SYSIN DD ./fio/fiordline.c'
2563: -#define FIO_IMP
2564: -#include "fio.h"
2565: -#include <libc.h>
2566: -
2567: -char *
2568: -Frdline(fd)
2569: -{
2570: - register unsigned char *p;
2571: - register Fbuffer *f;
2572: - register n;
2573: - register char *nextnl;
2574: -
2575: - FIOSET(f, fd);
2576: - while((nextnl = memchr(f->next, '\n', (COUNT)(f->end-f->next))) == 0){
2577: - if(f->next == f->buf){
2578: - if(f->end >= &f->buf[FIOBSIZE])
2579: - f->end = &f->buf[FIOBSIZE-64]; /* full buffer, no newline */
2580: - } else {
2581: - n = f->next-f->buf;
2582: - memcpy(f->buf, f->next, (COUNT)(FIOBSIZE-n));
2583: - f->next -= n;
2584: - f->end -= n;
2585: - }
2586: - if(Ffillbuf(fd) <= 0)
2587: - return((char *)0);
2588: - }
2589: - f->lnext = f->next;
2590: - f->next = (unsigned char *)(nextnl+1);
2591: - *nextnl = 0;
2592: - f->flags = (f->flags|FIO_RDLAST)&~FIO_WRITING;
2593: - return((char *)f->lnext);
2594: -}
2595: //GO.SYSIN DD ./fio/fiordline.c
2596: echo ./fio/fioread.c 1>&2
2597: sed 's/.//' >./fio/fioread.c <<'//GO.SYSIN DD ./fio/fioread.c'
2598: -#define FIO_IMP
2599: -#include "fio.h"
2600: -#include <libc.h>
2601: -
2602: -#define MAXREAD 0xff00 /* 64K - 4K */
2603: -#define FIOSHORT 100
2604: -
2605: -long
2606: -Fread(fd, addr, n)
2607: - char *addr;
2608: - long n;
2609: -{
2610: - register unsigned char *p;
2611: - register Fbuffer *f;
2612: - COUNT k;
2613: - char *oaddr = addr;
2614: - char *goal = addr+n;
2615: -
2616: - FIOSET(f, fd);
2617: -again:
2618: - k = f->end - f->next;
2619: - if(n < k) k = n;
2620: - memcpy(addr, (char *)f->next, k);
2621: - f->next += k;
2622: - f->lnext = f->next; /* effectively disable undo */
2623: - n -= k;
2624: - addr += k;
2625: - if((n > 0) && (n < FIOSHORT)){ /* buffer reads of less than FIOSHORT */
2626: - if(f->next == f->end)
2627: - f->next = f->end = f->buf;
2628: - if(Ffillbuf(fd) < 0)
2629: - return((long)(addr - oaddr));
2630: - goto again;
2631: - }
2632: - if(n > 0)
2633: - FIOFLUSH(f->oflush);
2634: - while(n > 0){ /* buffer is empty so do real reads */
2635: - k = n;
2636: - if(k > MAXREAD) k = MAXREAD;
2637: - if((k = read(fd, addr, k)) < 0)
2638: - return(-1L);
2639: - if(k == 0) break;
2640: - addr += k;
2641: - n -= k;
2642: - f->offset += k;
2643: - }
2644: - return((long)(addr - oaddr));
2645: -}
2646: //GO.SYSIN DD ./fio/fioread.c
2647: echo ./fio/fioseek.c 1>&2
2648: sed 's/.//' >./fio/fioseek.c <<'//GO.SYSIN DD ./fio/fioseek.c'
2649: -#define FIO_IMP
2650: -#include "fio.h"
2651: -#include <libc.h>
2652: -
2653: -long
2654: -Fseek(fd, n, cmd)
2655: - long n;
2656: -{
2657: - register Fbuffer *f;
2658: - register long dest, k;
2659: -
2660: - FIOSET(f, fd);
2661: - switch(cmd)
2662: - {
2663: - case 0:
2664: - dest = n;
2665: - break;
2666: - case 1:
2667: - /* allow for the fact we are beyond where we think we are */
2668: - dest = f->offset + n + f->next-f->end;
2669: - break;
2670: - case 2:
2671: - if(f->flags&FIO_WRITING)
2672: - F_flush(f, fd);
2673: - dest = SEEK(fd, n, cmd);
2674: - FIORESET(f);
2675: - f->offset = dest;
2676: - break;
2677: - }
2678: - if(dest < 0)
2679: - return(dest);
2680: - k = f->end - ((f->flags&FIO_WRITING)? f->buf : f->lnext);
2681: - if((dest >= f->offset) || (dest < f->offset-k)){
2682: - if(f->flags&FIO_WRITING)
2683: - F_flush(f, fd);
2684: - FIORESET(f);
2685: - f->offset = dest;
2686: - SEEK(fd, f->offset, 0);
2687: - } else {
2688: - f->next = f->lnext + (dest-(f->offset-k));
2689: - if(f->flags&FIO_WRITING){
2690: - f->offset -= f->end - f->next;
2691: - f->end = f->next;
2692: - }
2693: - SEEK(fd, f->offset, 0);
2694: - }
2695: - return(dest);
2696: -}
2697: //GO.SYSIN DD ./fio/fioseek.c
2698: echo ./fio/fioundo.c 1>&2
2699: sed 's/.//' >./fio/fioundo.c <<'//GO.SYSIN DD ./fio/fioundo.c'
2700: -#define FIO_IMP
2701: -#include "fio.h"
2702: -#include <libc.h>
2703: -
2704: -void
2705: -Fundo(fd)
2706: -{
2707: - register Fbuffer *f;
2708: -
2709: - FIOSET(f, fd);
2710: - if(f->flags&FIO_WRITING)
2711: - return;
2712: - if(f->flags&FIO_RDLAST)
2713: - f->next[-1] = '\n';
2714: - f->next = f->lnext;
2715: -}
2716: //GO.SYSIN DD ./fio/fioundo.c
2717: echo ./fio/fiowrite.c 1>&2
2718: sed 's/.//' >./fio/fiowrite.c <<'//GO.SYSIN DD ./fio/fiowrite.c'
2719: -#define FIO_IMP
2720: -#include "fio.h"
2721: -#include <libc.h>
2722: -
2723: -long
2724: -Fwrite(fd, addr, nbytes)
2725: - register char *addr;
2726: - register long nbytes;
2727: -{
2728: - register Fbuffer *f;
2729: - register COUNT n;
2730: - long nnbytes = nbytes;
2731: -
2732: - FIOSET(f, fd);
2733: - f->flags |= FIO_WRITING;
2734: - n = &f->buf[FIOBSIZE] - f->next;
2735: - if(nbytes < n) n = nbytes;
2736: - memcpy(f->next, addr, n);
2737: - f->end = (f->next += n);
2738: - f->offset += n;
2739: - nbytes -= n;
2740: - addr += n;
2741: - if(nbytes){
2742: - if(F_flush(f, fd))
2743: - return(-1L);
2744: - while(nbytes >= FIOBSIZE){
2745: - if(write(fd, addr, (COUNT)FIOBSIZE) != FIOBSIZE)
2746: - return(-1L);
2747: - addr += FIOBSIZE;
2748: - nbytes -= FIOBSIZE;
2749: - f->offset += FIOBSIZE;
2750: - }
2751: - memcpy(f->buf, addr, (COUNT)(n = nbytes));
2752: - f->end = f->next = f->buf+n;
2753: - f->offset += n;
2754: - f->flags |= FIO_WRITING;
2755: - }
2756: - return(nnbytes);
2757: -}
2758: //GO.SYSIN DD ./fio/fiowrite.c
2759: echo ./fio/libc.h 1>&2
2760: sed 's/.//' >./fio/libc.h <<'//GO.SYSIN DD ./fio/libc.h'
2761: -/* system calls */
2762: -extern unsigned alarm();
2763: -extern void nap(), pause();
2764: -extern char *sbrk();
2765: -extern void exit(), _exit();
2766: -extern long lseek();
2767: -extern void nice();
2768: -extern void profil();
2769: -extern unsigned long settod();
2770: -extern void sync();
2771: -extern long time();
2772: -
2773: -/* libc et al */
2774: -extern long lcm();
2775: -extern double atof(), strtod();
2776: -extern long atol();
2777: -extern char *crypt();
2778: -extern char *ctime();
2779: -extern char *ecvt(), *fcvt(), *gcvt();
2780: -extern char *galloc();
2781: -extern char *getenv();
2782: -extern char *getlogin();
2783: -extern char *getpass();
2784: -extern char *getwd(), *getcwd();
2785: -extern char *malloc(), *realloc(), *calloc();
2786: -extern char *memcpy(), *memchr(), *memccpy(), *memset();
2787: -extern char *mktemp();
2788: -extern double frand();
2789: -extern char *strcpy(), *strncpy(), *strcat(), *strncat(), *strchr(), *strrchr();
2790: -extern char *strpbrk(), *strtok(), *strdup();
2791: -extern int atoi();
2792: -extern char *tgetstr(), tgoto();
2793: -extern char *ttyname(), *cttyname();
2794: -
2795: -#define NONEXIT 33
2796: //GO.SYSIN DD ./fio/libc.h
2797: echo ./fio/tstrd.c 1>&2
2798: sed 's/.//' >./fio/tstrd.c <<'//GO.SYSIN DD ./fio/tstrd.c'
2799: -#include <fio.h>
2800: -#include <libc.h>
2801: -
2802: -main(argc, argv)
2803: - char **argv;
2804: -{
2805: - register n, c, k;
2806: - int len, fd, cd;
2807: - char *b1, *b2, *p;
2808: -
2809: - if(argc < 2){
2810: - Fprint(2, "Usage: tstrd file\n");
2811: - exit(1);
2812: - }
2813: - len = flen(argv[1]);
2814: - if((fd = open(argv[1], 0)) < 0){
2815: - perror(argv[1]);
2816: - exit(1);
2817: - }
2818: - if((b1 = malloc(len)) == 0){
2819: - Fprint(2, "malloc(%d) failed\n", len);
2820: - exit(1);
2821: - }
2822: - if(read(fd, b1, len) != len){
2823: - perror("read");
2824: - exit(1);
2825: - }
2826: - lseek(fd, 0L, 0);
2827: - if((b2 = malloc(len)) == 0){
2828: - Fprint(2, "malloc(%d) failed\n", len);
2829: - exit(1);
2830: - }
2831: - for(p = b2, cd = 0; cd < len;){
2832: - n = 1000*nrand(6) + nrand(199);
2833: - if(n > len-cd) n = len-cd;
2834: - Fprint(1, "%d getchars\n", n);
2835: - cd += n;
2836: - while(n--)
2837: - *p++ = Fgetc(fd);
2838: - if(cd == len)
2839: - continue;
2840: - n = 1000*nrand(12) + nrand(199);
2841: - if(n > len-cd) n = len-cd;
2842: - cd += n;
2843: - Fprint(1, "%d read\n", n);
2844: - if(Fread(fd, p, (long)n) != (long)n) break;
2845: - p += n;
2846: - }
2847: -done:
2848: - if(memcmp(b1, b2, len)){
2849: - Fprint(2, "memcmp failed!\n");
2850: - exit(1);
2851: - }
2852: - Fprint(2, "tstrd: %d bytes, succeeded\n", len);
2853: - exit(0);
2854: -}
2855: -
2856: -#include <sys/types.h>
2857: -#include <sys/stat.h>
2858: -
2859: -flen(s)
2860: - char *s;
2861: -{
2862: - struct stat sb;
2863: - int n;
2864: -
2865: - if(stat(s, &sb) < 0){
2866: - perror(s);
2867: - exit(1);
2868: - }
2869: - n = sb.st_size;
2870: - if(sizeof(int) == 2)
2871: - n &= 0x7FFF;
2872: - return(n);
2873: -}
2874: //GO.SYSIN DD ./fio/tstrd.c
2875: echo ./fio/tstsk.c 1>&2
2876: sed 's/.//' >./fio/tstsk.c <<'//GO.SYSIN DD ./fio/tstsk.c'
2877: -#include <fio.h>
2878: -#include <libc.h>
2879: -
2880: -#define TMP "/tmp/tstsk"
2881: -#define FN(x) (unsigned char)((x&0xFF)^(x/251))
2882: -
2883: -main(argc, argv)
2884: - char **argv;
2885: -{
2886: - register n, c, k;
2887: - int len, fd, cd;
2888: - char *b1, *b2, *p;
2889: -
2890: - if(argc != 1){
2891: - Fprint(2, "Usage: tstsk\n");
2892: - exit(1);
2893: - }
2894: - len = 1000000;
2895: - if(sizeof(int) == 2)
2896: - len &= 0x7FFF;
2897: - if((fd = creat(TMP, 0666)) < 0){
2898: - perror(TMP);
2899: - exit(1);
2900: - }
2901: - close(fd);
2902: - if((fd = open(TMP, 2)) < 0){
2903: - perror(TMP);
2904: - exit(1);
2905: - }
2906: - unlink(TMP);
2907: - if((b2 = malloc(len)) == 0){
2908: - Fprint(2, "malloc(%d) failed\n", len);
2909: - exit(1);
2910: - }
2911: - for(n = 0, p = b2; n < len; n++)
2912: - *p++ = FN(n);
2913: - if(write(fd, b2, len) != len){
2914: - perror("write");
2915: - exit(1);
2916: - }
2917: - lseek(fd, 0L, 0);
2918: - Finit(fd, (char *)0);
2919: - for(n = 0; n < 500; n++){
2920: - k = nrand(len);
2921: - c = nrand(sizeof(Fbuffer))+100;
2922: - if(k+c > len) c = len-k;
2923: - test(fd, k, c, n);
2924: - }
2925: -done:
2926: - Fprint(2, "tstsk: %d bytes, %d seeks, succeeded\n", len, n);
2927: - exit(0);
2928: -}
2929: -
2930: -test(fd, off, n, count)
2931: -{
2932: - long offset;
2933: - int c;
2934: -
2935: - offset = off;
2936: - if(Fseek(fd, offset, 0) != offset){
2937: - fprint(2, "fseek(%ld) != %ld!!\n", offset, offset);
2938: - exit(1);
2939: - }
2940: - while(n-- > 0){
2941: - if((c = Fgetc(fd)) != FN(offset)){
2942: - fprint(2, "tst %d: char mismatch; %ld: %x, expected %x\n",
2943: - count, offset, c, FN(offset));
2944: - dumpfb(fd);
2945: - exit(1);
2946: - }
2947: - offset++;
2948: - }
2949: -}
2950: -
2951: -dumpfb(fd)
2952: -{
2953: - register Fbuffer *f = Ffb[fd];
2954: - register unsigned char *c;
2955: - register long off;
2956: - int i;
2957: -
2958: - fprint(2, "buf@%ld: next=%ld end=%ld lnext=%ld buf=%ld offset=%ld\n",
2959: - f, f->next, f->end, f->lnext, f->buf, f->offset);
2960: - off = f->offset - (f->end - f->buf);
2961: - for(c = f->buf; c < &f->buf[64]; ){
2962: - fprint(2, "%7ld:", off);
2963: - for(i = 0; i < 16; i++, off++)
2964: - fprint(2, " %2x", *c++);
2965: - fprint(2, "\n");
2966: - }
2967: -}
2968: //GO.SYSIN DD ./fio/tstsk.c
2969: echo ./fio/tstwr.c 1>&2
2970: sed 's/.//' >./fio/tstwr.c <<'//GO.SYSIN DD ./fio/tstwr.c'
2971: -#include <fio.h>
2972: -#include <libc.h>
2973: -
2974: -#define TMP "/tmp/tstwr"
2975: -
2976: -main(argc, argv)
2977: - char **argv;
2978: -{
2979: - register n, c, k;
2980: - int len, fd, cd;
2981: - char *b1, *b2, *p;
2982: -
2983: - if(argc < 2){
2984: - Fprint(2, "Usage: tstwr file\n");
2985: - exit(1);
2986: - }
2987: - len = flen(argv[1]);
2988: - if((fd = open(argv[1], 0)) < 0){
2989: - perror(argv[1]);
2990: - exit(1);
2991: - }
2992: - if((b1 = malloc(len)) == 0){
2993: - Fprint(2, "malloc(%d) failed\n", len);
2994: - exit(1);
2995: - }
2996: - if(read(fd, b1, len) != len){
2997: - perror("read");
2998: - exit(1);
2999: - }
3000: - close(fd);
3001: - if((fd = creat(TMP, 0666)) < 0){
3002: - perror(TMP);
3003: - exit(1);
3004: - }
3005: - close(fd);
3006: - if((fd = open(TMP, 2)) < 0){
3007: - perror(TMP);
3008: - exit(1);
3009: - }
3010: -/* unlink(TMP); /**/
3011: - if((b2 = malloc(len)) == 0){
3012: - Fprint(2, "malloc(%d) failed\n", len);
3013: - exit(1);
3014: - }
3015: - for(p = b1, cd = 0; cd < len;){
3016: - n = 1000*nrand(6) + nrand(199);
3017: - if(n > len-cd) n = len-cd;
3018: - Fprint(1, "%d putc's\n", n);
3019: - cd += n;
3020: - while(n--)
3021: - Fputc(fd, *p++);
3022: - if(len == cd)
3023: - continue;
3024: - n = 1000*nrand(12) + nrand(199);
3025: - if(n > len-cd) n = len-cd;
3026: - cd += n;
3027: - Fprint(1, "%d write\n", n);
3028: - if(Fwrite(fd, p, (long)n) != (long)n) break;
3029: - p += n;
3030: - }
3031: -done:
3032: - Fflush(fd);
3033: - lseek(fd, 0L, 0);
3034: - if((n = read(fd, b2, len)) != len){
3035: - fprint(2, "read %d, len=%d: ", n, len);
3036: - perror("read2");
3037: - exit(1);
3038: - }
3039: - if(memcmp(b1, b2, len)){
3040: - Fprint(2, "memcmp failed!\n");
3041: - exit(1);
3042: - }
3043: - Fprint(2, "tstwr: %d bytes, succeeded\n", len);
3044: - exit(0);
3045: -}
3046: -
3047: -#include <sys/types.h>
3048: -#include <sys/stat.h>
3049: -
3050: -flen(s)
3051: - char *s;
3052: -{
3053: - struct stat sb;
3054: - int n;
3055: -
3056: - if(stat(s, &sb) < 0){
3057: - perror(s);
3058: - exit(1);
3059: - }
3060: - n = sb.st_size;
3061: - if(sizeof(int) == 2)
3062: - n &= 0x7FFF;
3063: - return(n);
3064: -}
3065: //GO.SYSIN DD ./fio/tstwr.c
3066: echo ./fio/Makefile 1>&2
3067: sed 's/.//' >./fio/Makefile <<'//GO.SYSIN DD ./fio/Makefile'
3068: -OBJ=fiofillbuf.o fioflush.o fiogetc.o fioinit.o fioprint.o fioputc.o\
3069: - fiordline.o fioread.o fioseek.o fioundo.o fiowrite.o fiotie.o fioclose.o
3070: -
3071: -fio.a: $(OBJ)
3072: - ar r fio.a $(OBJ)
3073: - $(RANLIB) fio.a
3074: -
3075: -cray: fio.o
3076: -
3077: -fio.o: $(OBJ)
3078: - cat $(OBJ) > fio.o
3079: //GO.SYSIN DD ./fio/Makefile
3080: echo ./fio/fiotie.c 1>&2
3081: sed 's/.//' >./fio/fiotie.c <<'//GO.SYSIN DD ./fio/fiotie.c'
3082: -#define FIO_IMP
3083: -#include "fio.h"
3084: -
3085: -void
3086: -Ftie(ifd, ofd)
3087: -{
3088: - register Fbuffer *f;
3089: -
3090: - FIOSET(f, ifd);
3091: - f->oflush = ofd;
3092: -}
3093: //GO.SYSIN DD ./fio/fiotie.c
3094: echo ./fio/tstagh.c 1>&2
3095: sed 's/.//' >./fio/tstagh.c <<'//GO.SYSIN DD ./fio/tstagh.c'
3096: -#include <fio.h>
3097: -#include <libc.h>
3098: -
3099: -#define TMP "/tmp/tstsk"
3100: -#define FN(x) (unsigned char)((x&0xFF)^(x/251))
3101: -
3102: -main(argc, argv)
3103: - char **argv;
3104: -{
3105: - register n, c, k;
3106: - int len, fd, cd;
3107: - char *b1, *b2, *p;
3108: -
3109: - Fprint(1, "the letter 'c' is 'c'\n");
3110: - dumpfb(1);
3111: - Fseek(1, -3, 1);
3112: - dumpfb(1);
3113: - Fputc(1, '\n');
3114: - dumpfb(1);
3115: - exit(0);
3116: -}
3117: -
3118: -dumpfb(fd)
3119: -{
3120: - register Fbuffer *f = Ffb[fd];
3121: - register unsigned char *c;
3122: - register long off;
3123: - int i;
3124: -
3125: - fprint(2, "buf@%ld: next=%ld end=%ld lnext=%ld buf=%ld offset=%ld\n",
3126: - f, f->next, f->end, f->lnext, f->buf, f->offset);
3127: - off = f->offset - (f->end - f->buf);
3128: - for(c = f->buf; c < &f->buf[64]; ){
3129: - fprint(2, "%7ld:", off);
3130: - for(i = 0; i < 16; i++, off++)
3131: - fprint(2, " %2x", *c++);
3132: - fprint(2, "\n");
3133: - }
3134: -}
3135: //GO.SYSIN DD ./fio/tstagh.c
3136: echo ./fio/fioclose.c 1>&2
3137: sed 's/.//' >./fio/fioclose.c <<'//GO.SYSIN DD ./fio/fioclose.c'
3138: -#define FIO_IMP
3139: -#include "fio.h"
3140: -#include <libc.h>
3141: -
3142: -void
3143: -Fclose(fd)
3144: -{
3145: - register Fbuffer *f;
3146: -
3147: - FIOSET(f, fd);
3148: - Fflush(fd);
3149: - if(f->flags&FIO_MALLOCED)
3150: - free((char *)f);
3151: - Ffb[fd] = 0;
3152: - close(fd);
3153: -}
3154: //GO.SYSIN DD ./fio/fioclose.c
3155: echo ./README 1>&2
3156: sed 's/.//' >./README <<'//GO.SYSIN DD ./README'
3157: -mk runs on Unix V9. To run on other systems requires some help.
3158: -the help takes the form of the fast i/o library (fio) and some
3159: -libc routines. dir.o provides support for the directory routines
3160: -on V7-style filesystems; on most modern systems you should probably
3161: -not use dir.o.
3162: -
3163: - - edit Makefile by setting the initial variables as
3164: -per the instructions.
3165: -
3166: - - type make (unless on the cray, in which case, type make cray).
3167: -
3168: - - everything should now be compiled and you should have a mk.
3169: -
3170: - - edit mkfile to set the system type as in the Makefile
3171: -
3172: -as a first order test that all is well, try
3173: - mk
3174: -which generates a `correctly compiled' mk in the file nmk.
3175: -
3176: -If things go badly, (core dump hell), try not using alloc.c. it may be
3177: -that your hardware needs special alloc treatment. otherwise, mail
3178: -research!andrew (or [email protected]).
3179: -
3180: -the manual page and a tutorial style document are included.
3181: //GO.SYSIN DD ./README
3182: echo ./fio.h 1>&2
3183: sed 's/.//' >./fio.h <<'//GO.SYSIN DD ./fio.h'
3184: -#define FIOBSIZE 4096
3185: -
3186: -typedef struct Fbuffer
3187: -{
3188: - unsigned char *next; /* next char to be used */
3189: - unsigned char *end; /* first invalid char */
3190: - unsigned char *lnext; /* previous value of next */
3191: - unsigned short flags; /* see FIO_.* below */
3192: - short oflush; /* if >= 0 fd to flush on read */
3193: - long offset; /* seek of end */
3194: - unsigned char buf[FIOBSIZE];
3195: -} Fbuffer;
3196: -extern Fbuffer *Ffb[];
3197: -
3198: -#define FIORESET(f) ((f)->next=(f)->lnext=(f)->end=(f)->buf, (f)->flags&= ~FIO_MALLOCED, (f)->oflush= -1)
3199: -#define FIOSET(f, fd) if((f=Ffb[fd&=0x7f]) == 0){Finit(fd,(char *)0);f=Ffb[fd];}
3200: -/* FIOLINELEN is length of last input */
3201: -#define FIOLINELEN(fd) (((int)(Ffb[fd]->next - Ffb[fd]->lnext))-1)
3202: -/* FIOSEEK is lseek of next char to be processed */
3203: -#define FIOSEEK(fd) (Ffb[fd]->offset - (Ffb[fd]->end - Ffb[fd]->next))
3204: -#define FIOFLUSH(fd) if((fd >= 0) && Ffb[fd]) Fflush(fd)
3205: -
3206: -#define FIO_RDLAST 0x0001 /* true if last input was rdline */
3207: -#define FIO_WRITING 0x0002 /* true if last action was write */
3208: -#define FIO_MALLOCED 0x0004 /* set if Finit did the malloc */
3209: -
3210: -extern void Finit();
3211: -extern char *Frdline();
3212: -extern void Fundo();
3213: -extern int Fgetc();
3214: -extern long Fread();
3215: -extern long Fwrite();
3216: -extern long Fseek();
3217: -extern int Fflush();
3218: -
3219: -#ifdef FIO_IMP
3220: -/* COUNT is the type of counts to things like read, write, memcpy etc */
3221: -#ifdef GNOT
3222: -#define COUNT long
3223: -#define FIOMALLOC(n) malloc(n)
3224: -#define SEEK(a,b,c) seek(a,b,c)
3225: -#else
3226: -#define COUNT int
3227: -#define FIOMALLOC(n) malloc(n)
3228: -#define SEEK(a,b,c) lseek(a,b,c)
3229: -#endif
3230: -extern COUNT read(), write();
3231: -#endif
3232: //GO.SYSIN DD ./fio.h
3233: echo ./regexp.h 1>&2
3234: sed 's/.//' >./regexp.h <<'//GO.SYSIN DD ./regexp.h'
3235: -/* the structure describing a sub-expression match */
3236: -typedef struct {
3237: - char *sp;
3238: - char *ep;
3239: -} regsubexp;
3240: -
3241: -/* a compiled regular expression */
3242: -typedef char *regexp;
3243: -
3244: -/* the routines */
3245: -extern regexp *regcomp();
3246: -extern int regexec();
3247: -extern void regsub();
3248: //GO.SYSIN DD ./regexp.h
3249: echo ./libc.h 1>&2
3250: sed 's/.//' >./libc.h <<'//GO.SYSIN DD ./libc.h'
3251: -/* system calls */
3252: -extern unsigned alarm();
3253: -extern void nap(), pause();
3254: -extern char *sbrk();
3255: -extern void exit(), _exit();
3256: -extern long lseek();
3257: -extern void nice();
3258: -extern void profil();
3259: -extern unsigned long settod();
3260: -extern void sync();
3261: -extern long time();
3262: -
3263: -/* libc et al */
3264: -extern long lcm();
3265: -extern double atof(), strtod();
3266: -extern long atol();
3267: -extern char *crypt();
3268: -extern char *ctime();
3269: -extern char *ecvt(), *fcvt(), *gcvt();
3270: -extern char *galloc();
3271: -extern char *getenv();
3272: -extern char *getlogin();
3273: -extern char *getpass();
3274: -extern char *getwd(), *getcwd();
3275: -extern char *malloc(), *realloc(), *calloc();
3276: -extern char *memcpy(), *memchr(), *memccpy(), *memset();
3277: -extern char *mktemp();
3278: -extern double frand();
3279: -extern char *setfields();
3280: -extern char *strcpy(), *strncpy(), *strcat(), *strncat(), *strchr(), *strrchr();
3281: -extern char *strpbrk(), *strtok(), *strdup();
3282: -extern int atoi();
3283: -extern char *tgetstr(), tgoto();
3284: -extern char *ttyname(), *cttyname();
3285: -
3286: -#define NONEXIT 33
3287: //GO.SYSIN DD ./libc.h
3288: echo ./math/pow10.c 1>&2
3289: sed 's/.//' >./math/pow10.c <<'//GO.SYSIN DD ./math/pow10.c'
3290: -static double p[10] =
3291: -{
3292: - 1.0e0,
3293: - 1.0e1,
3294: - 1.0e2,
3295: - 1.0e3,
3296: - 1.0e4,
3297: - 1.0e5,
3298: - 1.0e6,
3299: - 1.0e7,
3300: - 1.0e8,
3301: - 1.0e9,
3302: -};
3303: -
3304: -double
3305: -pow10(e)
3306: -{
3307: - int i;
3308: -
3309: - if(e < 0)
3310: - return 1 / pow10(-e);
3311: - if(e >= 10) {
3312: - i = e/2;
3313: - return pow10(i) * pow10(e-i);
3314: - }
3315: - return p[e];
3316: -}
3317: //GO.SYSIN DD ./math/pow10.c
3318: echo ./math/Makefile 1>&2
3319: sed 's/.//' >./math/Makefile <<'//GO.SYSIN DD ./math/Makefile'
3320: -OBJ=pow10.o
3321: -
3322: -math.a: $(OBJ)
3323: - ar r math.a $(OBJ)
3324: - $(RANLIB) math.a
3325: -
3326: -cray: math.o
3327: -
3328: -math.o: $(OBJ)
3329: - cat $(OBJ) > math.o
3330: //GO.SYSIN DD ./math/Makefile
3331: echo ./Makefile 1>&2
3332: sed 's/.//' >./Makefile <<'//GO.SYSIN DD ./Makefile'
3333: -OBJ=alloc.o arc.o bquote.o builtins.o dir.o expand.o gen.o glob.o graph.o job.o lex.o main.o makefile.o match.o mk.o parse.o quote.o recipe.o regexp.o rule.o run.o shprint.o sig.o symtab.o t_ar.o t_driver.o t_file.o var.o word.o
3334: -# first define the system type from V9, BSD42, SEQUENT, SYSV
3335: -SYSTEM=SYSV
3336: -# second add any special C flags (and -DCRAY and -g if on the cray)
3337: -CFLAGS=-I. -D$(SYSTEM)
3338: -# third, if you don't have a ranlib, set RANLIB=:
3339: -RANLIB=: # ranlib on other systems
3340: -# now, to make everything just type make
3341: -
3342: -mk: nlib $(OBJ)
3343: - $(CC) $(CFLAGS) -o mk $(OBJ) fio/fio.a libc/libc.a math/math.a
3344: -nlib:
3345: - cd math; make CFLAGS="$(CFLAGS)" CC=$(CC) RANLIB=$(RANLIB)
3346: - cd libc; make CFLAGS="$(CFLAGS)" CC=$(CC) RANLIB=$(RANLIB)
3347: - cd fio; make CFLAGS="$(CFLAGS)" CC=$(CC) RANLIB=$(RANLIB)
3348: -
3349: -clean:
3350: - rm -f *.o mk nmk */*.[oa]
3351: -alloc.o arc.o bquote.o builtins.o dir.o expand.o gen.o glob.o graph.o job.o lex.o main.o makefile.o match.o mk.o parse.o quote.o recipe.o regexp.o rule.o run.o shprint.o sig.o symtab.o t_ar.o t_driver.o t_file.o var.o word.o: fio.h libc.h mk.h ndir.h regexp.h
3352: //GO.SYSIN DD ./Makefile
3353: echo ./mkconv 1>&2
3354: sed 's/.//' >./mkconv <<'//GO.SYSIN DD ./mkconv'
3355: -x=/tmp/mk$$
3356: -trap 'rm -f $x' 0 1 2
3357: -tee $x < $1 | sed -e 's/$(\([^)]*\))\([ :\/]\)/$\1\2/g
3358: - s/$(\([^)]*\))$/$\1/g
3359: - s/$(\([^)]*\))/${\1}/g
3360: - s/^ @/ /
3361: - /^ -/,/[^\\]$/{
3362: - /[^\\]$/s/$/; set -e/
3363: - }
3364: - /^ -/s/ -/ set +e; /
3365: - s/:&/:/
3366: - s/$% /$stem /g
3367: - s/$%\./$stem\./g
3368: - s/$%/${stem}/g
3369: - s/$@/${target}/g
3370: - s/$^/${prereq}/g
3371: - s/$?/$newprereq/g'
3372: -if egrep -s 'cd[ ]|make' < $x
3373: -then
3374: - echo "Warning: recipes containing \`cd' or \`make' need attention."
3375: - egrep 'cd[ ]|make' < $x
3376: -fi 1>&2
3377: //GO.SYSIN DD ./mkconv
3378: echo ./membername 1>&2
3379: sed 's/.//' >./membername <<'//GO.SYSIN DD ./membername'
3380: -echo "$@" | tr " " "\012" | sed -e "s/[^(]*(\([^)]*\)).*/\1/" | tr "\012" " "
3381: //GO.SYSIN DD ./membername
3382: echo ./mk.1 1>&2
3383: sed 's/.//' >./mk.1 <<'//GO.SYSIN DD ./mk.1'
3384: -.TH MK 1
3385: -.CT 1 prog_c writing_troff prog_other
3386: -.SH NAME
3387: -mk, mkconv, membername \- maintain (make) related files
3388: -.SH SYNOPSIS
3389: -.B mk
3390: -[
3391: -.B -f
3392: -.I mkfile
3393: -] ...
3394: -[
3395: -.I option ...
3396: -]
3397: -[
3398: -.I name ...
3399: -]
3400: -.PP
3401: -.B mkconv
3402: -.I makefile
3403: -.PP
3404: -.B membername
3405: -.I aggregate ...
3406: -.SH DESCRIPTION
3407: -.I Mk
3408: -is most often used to keep object files current with the
3409: -source they depend on.
3410: -.PP
3411: -.I Mk
3412: -reads
3413: -.I mkfile
3414: -and builds and executes dependency dags (directed acyclic graphs) for the target
3415: -.IR names .
3416: -If no target is specified, the targets of the first non-metarule in
3417: -the first
3418: -.I mkfile
3419: -are used.
3420: -If no
3421: -.B -f
3422: -option is present,
3423: -.L mkfile
3424: -is tried.
3425: -Other options are:
3426: -.TP \w'\fL-d[egp]\ 'u
3427: -.B -a
3428: -Assume all targets to be out of date.
3429: -Thus, everything gets made.
3430: -.PD 0
3431: -.TP
3432: -.BR -d [ egp ]
3433: -Produce debugging output
3434: -.RB ( p
3435: -is for parsing,
3436: -.B g
3437: -for graph building,
3438: -.B e
3439: -for execution).
3440: -.TP
3441: -.B -e
3442: -Explain why each target is made.
3443: -.TP
3444: -.B -i
3445: -Force any missing intermediate targets to be made.
3446: -.TP
3447: -.B -k
3448: -Do as much work as possible in the face of errors.
3449: -.TP
3450: -.B -m
3451: -Generate an equivalent makefile on standard output.
3452: -Recipes are not handled well.
3453: -.TP
3454: -.B -n
3455: -Print, but do not execute, the commands
3456: -needed to update the targets.
3457: -.TP
3458: -.B -t
3459: -Touch (update the modified date of) non-virtual targets, without
3460: -executing any recipes.
3461: -.TP
3462: -.B -u
3463: -Produce a table of clock seconds spent with
3464: -.I n
3465: -recipes running.
3466: -.TP
3467: -.BI -w name1,name2,...
3468: -Set the initial date stamp for each name
3469: -to the current time.
3470: -The names may also be separated by blanks or newlines.
3471: -(Use with
3472: -.B -n
3473: -to find what else would need to change if the named files
3474: -were modified.)
3475: -.PD
3476: -.PP
3477: -.I Mkconv
3478: -attempts to convert a
3479: -.IR make (1)
3480: -.I makefile
3481: -to a
3482: -.IR mkfile
3483: -on standard output.
3484: -The conversion is not likely to be faithful.
3485: -.PP
3486: -The shell script
3487: -.I membername
3488: -extracts member names
3489: -(see `Aggregates' below)
3490: -from its arguments.
3491: -.SS Definitions
3492: -A
3493: -.I mkfile
3494: -consists of
3495: -.I assignments
3496: -(described under `Environment') and
3497: -.IR rules .
3498: -A rule contains
3499: -.I targets
3500: -and a
3501: -.I tail.
3502: -A target is a literal string, or
3503: -.I label,
3504: -and is normally a file name.
3505: -The tail contains zero or more
3506: -.I prerequisites
3507: -and an optional
3508: -.I recipe,
3509: -which is a shell script.
3510: -.PP
3511: -A
3512: -.I metarule
3513: -has a target of the form
3514: -.IB A % B
3515: -where
3516: -.I A
3517: -and
3518: -.I B
3519: -are (possibly empty) strings.
3520: -A metarule applies to any label that matches the target with
3521: -.B %
3522: -replaced by an arbitrary string, called the
3523: -.IR stem .
3524: -In interpreting a metarule,
3525: -the stem is substituted for all occurrences of
3526: -.B %
3527: -in the prerequisite names.
3528: -A metarule may be marked as using regular expressions (described under `Syntax').
3529: -In this case,
3530: -.B %
3531: -has no special meaning;
3532: -the target is interpreted according to
3533: -.IR regexp (3).
3534: -The dependencies may refer to subexpressions in the normal way, using
3535: -.BI \e n.
3536: -The
3537: -.I dependency dag
3538: -for a target consists of
3539: -.I nodes
3540: -connected by directed
3541: -.IR arcs .
3542: -A node consists of a label
3543: -and a set of arcs leading to prerequisite nodes.
3544: -The root
3545: -node is labeled with an original target
3546: -.I name.
3547: -.SS Building the Dependency Dag
3548: -.PP
3549: -Read the
3550: -.I mkfiles
3551: -in command line order and distribute rule tails over targets
3552: -to get single-target rules.
3553: -.PP
3554: -For a node
3555: -.IR n ,
3556: -for every rule
3557: -.I r
3558: -that matches
3559: -.IR n 's
3560: -label generate an arc to a prerequisite node.
3561: -The node
3562: -.I n
3563: -is then marked as done.
3564: -The process is then repeated for each of the prerequisite nodes.
3565: -The process stops if
3566: -.I n
3567: -is already done,
3568: -or if
3569: -.I n
3570: -has no prerequisites,
3571: -or if any rule would be used more than
3572: -.B $NREP
3573: -times on the current path in the dag.
3574: -A probable node is one where the label exists as a file
3575: -or is a target of a non-metarule.
3576: -.PP
3577: -After the graph is built, it is checked for cycles,
3578: -and subdags containing no probable nodes are deleted.
3579: -Also, for any node with arcs generated by a non-metarule with a recipe,
3580: -arcs generated by a metarule with a recipe
3581: -are deleted.
3582: -Disconnected subdags are deleted.
3583: -.SS Execution
3584: -Labels have an associated date stamp.
3585: -A label is
3586: -.I ready
3587: -if it has no prerequisites, or
3588: -all its prerequisites are made.
3589: -A ready label is
3590: -.I trivially uptodate
3591: -if it is not a target and has a nonzero date stamp, or
3592: -it has a nonzero date stamp,
3593: -and all its prerequisites are made and predate the ready label.
3594: -A ready label is marked
3595: -.I made
3596: -(and given a date stamp)
3597: -if it is trivially uptodate or by executing the recipe
3598: -associated with the arcs leading from the node associated with the ready label.
3599: -The
3600: -.B P
3601: -attribute can be used to generalize
3602: -.IR mk 's
3603: -notion of determining if prerequisites predate a label.
3604: -Rather than comparing date stamps, it executes a specified program
3605: -and uses the exit status.
3606: -.PP
3607: -Date stamps are calculated differently for virtual labels,
3608: -for labels that correspond to extant files,
3609: -and for other labels.
3610: -If a label is
3611: -.I virtual
3612: -(target of a rule with the
3613: -.B V
3614: -attribute),
3615: -its date stamp is initially zero and upon being made is set to
3616: -the most recent date stamp of its prerequisites.
3617: -Otherwise, if a label is nonexistent
3618: -(does not exist as a file),
3619: -its date stamp is set to the most recent date stamp of its prerequisites,
3620: -or zero if it has no prerequisites.
3621: -Otherwise, the label is the name of a file and
3622: -the label's date stamp is always that file's modification date.
3623: -.PP
3624: -Nonexistent labels which have prerequisites
3625: -and are prerequisite to other label(s) are treated specially unless the
3626: -.B -i
3627: -flag is used.
3628: -Such a label
3629: -.I l
3630: -is given the date stamp of its most recent prerequisite
3631: -and if this causes all the labels which have
3632: -.I l
3633: -as a prerequisite to be trivially uptodate,
3634: -.I l
3635: -is considered to be trivially uptodate.
3636: -Otherwise,
3637: -.I l
3638: -is made in the normal fashion.
3639: -.PP
3640: -Two recipes are called identical if they arose by distribution
3641: -from a single rule as described above.
3642: -Identical recipes may be executed only when all
3643: -their prerequisite nodes are ready, and then just one instance of
3644: -the identical recipes is executed to make all their target nodes.
3645: -.PP
3646: -Files may be made in any order that respects
3647: -the preceding restrictions.
3648: -.PP
3649: -A recipe is executed by supplying the recipe as standard input to
3650: -the command
3651: -.B
3652: - /bin/sh -e
3653: -.br
3654: -The environment is augmented by the following variables:
3655: -.TP 14
3656: -.B $alltarget
3657: -all the targets of this rule.
3658: -.TP
3659: -.B $newprereq
3660: -the prerequisites that caused this rule to execute.
3661: -.TP
3662: -.B $nproc
3663: -the process slot for this recipe.
3664: -It satisfies
3665: -.RB 0\(<= $nproc < $NPROC ,
3666: -where
3667: -.B $NPROC
3668: -is the maximum number of recipes that may be executing
3669: -simultaneously.
3670: -.TP
3671: -.B $pid
3672: -the process id for the
3673: -.I mk
3674: -forking the recipe.
3675: -.TP
3676: -.B $prereq
3677: -all the prerequisites for this rule.
3678: -.TP
3679: -.B $stem
3680: -if this is a metarule,
3681: -.B $stem
3682: -is the string that matched
3683: -.BR % .
3684: -Otherwise, it is empty.
3685: -For regular expression metarules, the variables
3686: -.LR stem0 ", ...,"
3687: -.L stem9
3688: -are set to the corresponding subexpressions.
3689: -.TP
3690: -.B $target
3691: -the targets for this rule that need to be remade.
3692: -.PP
3693: -Unless the rule has the
3694: -.B Q
3695: -attribute,
3696: -the recipe is printed prior to execution
3697: -with recognizable shell variables expanded.
3698: -To see the commands print as they execute,
3699: -include a
3700: -.L set -x
3701: -in your rule.
3702: -Commands returning nonzero status (see
3703: -.IR intro (1))
3704: -cause
3705: -.I mk
3706: -to terminate.
3707: -.SS Aggregates
3708: -Names of the form
3709: -.IR a ( b )
3710: -refer to member
3711: -.I b
3712: -of the aggregate
3713: -.IR a .
3714: -Currently, the only aggregates supported are
3715: -.IR ar (1)
3716: -archives.
3717: -.SS Environment
3718: -Rules may make use of shell (or environment) variables.
3719: -A legal shell variable reference of the form
3720: -.B $OBJ
3721: -or
3722: -.B ${name}
3723: -is expanded as in
3724: -.IR sh (1).
3725: -A reference of the form
3726: -.BI ${name: A % B = C\fB%\fID\fB}\fR,
3727: -where
3728: -.I A, B, C, D
3729: -are (possibly empty) strings,
3730: -has the value formed by expanding
3731: -.B $name
3732: -and substituting
3733: -.I C
3734: -for
3735: -.I A
3736: -and
3737: -.I D
3738: -for
3739: -.I B
3740: -in each word in
3741: -.B $name
3742: -that matches pattern
3743: -.IB A % B .
3744: -.PP
3745: -Variables can be set by
3746: -assignments of the form
3747: -.I
3748: - var\fB=\fR[\fIattr\fB=\fR]\fItokens\fR
3749: -.br
3750: -where
3751: -.I tokens
3752: -and the optional attributes
3753: -are defined under `Syntax' below.
3754: -The environment is exported to recipe executions.
3755: -Variable values are taken from (in increasing order of precedence)
3756: -the default values below, the environment, the mkfiles,
3757: -and any command line assignment.
3758: -A variable assignment argument overrides the first (but not any subsequent)
3759: -assignment to that variable.
3760: -.br
3761: -.ne 1i
3762: -.EX
3763: -.ta \n(.lu/3u +\n(.lu/3u
3764: -.nf
3765: -AS=as FFLAGS= NPROC=1
3766: -CC=cc LEX=lex NREP=1
3767: -CFLAGS= LFLAGS= YACC=yacc
3768: -FC=f77 LDFLAGS= YFLAGS=
3769: -BUILTINS='
3770: -.ta 8n
3771: -%.o: %.c
3772: - $CC $CFLAGS -c $stem.c
3773: -%.o: %.s
3774: - $AS -o $stem.o $stem.s
3775: -%.o: %.f
3776: - $FC $FFLAGS -c $stem.f
3777: -%.o: %.y
3778: - $YACC $YFLAGS $stem.y &&
3779: - $CC $CFLAGS -c y.tab.c && mv y.tab.o $stem.o; rm y.tab.c
3780: -%.o: %.l
3781: - $LEX $LFLAGS -t $stem.l > $stem.c &&
3782: - $CC $CFLAGS -c $stem.c && rm $stem.c'
3783: -ENVIRON=
3784: -.EE
3785: -.PP
3786: -The builtin rules are obtained from the variable
3787: -.B BUILTINS
3788: -after all input has been processed.
3789: -The
3790: -.B ENVIRON
3791: -variable is split into parts at control-A characters,
3792: -the control-A characters are deleted, and the parts are
3793: -placed in the environment.
3794: -The variable
3795: -.B MKFLAGS
3796: -contains all the option arguments (arguments starting with
3797: -.L -
3798: -or containing
3799: -.LR = )
3800: -and
3801: -.B MKARGS
3802: -contains all the targets in the call to
3803: -.IR mk .
3804: -.SS Syntax
3805: -Leading white space (blank or tab) is ignored.
3806: -Input after an unquoted
3807: -.B #
3808: -(a comment) is ignored as are blank lines.
3809: -Lines can be spread over several physical lines by
3810: -placing a
3811: -.B \e
3812: -before newlines to be elided.
3813: -Non-recipe lines are processed by substituting for
3814: -.BI ` cmd `
3815: -and then substituting for variable references.
3816: -Finally, the filename metacharacters
3817: -.B []*?
3818: -are expanded.
3819: -.tr #"
3820: -Quoting by
3821: -.BR \&'' ,
3822: -.BR ## ,
3823: -and
3824: -.B \e
3825: -is supported.
3826: -The semantics for substitution and quoting are given in
3827: -.IR sh (1).
3828: -.PP
3829: -The contents of files may be included by lines beginning with
3830: -.B <
3831: -followed by a filename.
3832: -.PP
3833: -.tr ##
3834: -Assignments and rule header lines are distinguished by
3835: -the first unquoted occurrence of
3836: -.B :
3837: -(rule header)
3838: -or
3839: -.B =
3840: -(assignment).
3841: -.PP
3842: -A rule definition consists of a header line followed by a recipe.
3843: -The recipe consists of all lines following the header line
3844: -that start with white space.
3845: -The recipe may be empty.
3846: -The first character on every line of the recipe is elided.
3847: -The header line consists of at least one target followed by the rule separator
3848: -and a possibly empty list of prerequisites.
3849: -The rule separator is either a single
3850: -.LR :
3851: -or is a
3852: -.L :
3853: -immediately followed by attributes and another
3854: -.LR : .
3855: -If any prerequisite is more recent than any of the targets,
3856: -the recipe is executed.
3857: -This meaning is modified by the following attributes
3858: -.TP
3859: -.B <
3860: -The standard output of the recipe is read by
3861: -.I mk
3862: -as an additional mkfile.
3863: -Assignments take effect immediately.
3864: -Rule definitions are used when a new dependency dag is constructed.
3865: -.PD 0
3866: -.TP
3867: -.B D
3868: -If the recipe exits with an error status, the target is deleted.
3869: -.TP
3870: -.B N
3871: -If there is no recipe, the target has its time updated.
3872: -.TP
3873: -.B P
3874: -The characters after the
3875: -.B P
3876: -until the terminating
3877: -.B :
3878: -are taken as a program name.
3879: -It will be invoked as
3880: -.B "sh -c prog 'arg1' 'arg2'"
3881: -and should return 0 exit status
3882: -if and only if arg1 is not out of date with respect to arg2.
3883: -Date stamps are still propagated in the normal way.
3884: -.TP
3885: -.B Q
3886: -The recipe is not printed prior to execution.
3887: -.TP
3888: -.B R
3889: -The rule is a metarule using regular expressions.
3890: -.TP
3891: -.B U
3892: -The targets are considered to have been updated
3893: -even if the recipe did not do so.
3894: -.TP
3895: -.B V
3896: -The targets of this rule are marked as virtual.
3897: -They are distinct from files of the same name.
3898: -.PD
3899: -.PP
3900: -Similarly, assignments may have attributes terminated by
3901: -.BR = .
3902: -The only assignment attribute is
3903: -.TP 3
3904: -.B U
3905: -Do not export this variable to recipe executions.
3906: -.SH EXAMPLES
3907: -A simple mkfile to compile a program.
3908: -.IP
3909: -.EX
3910: -prog: a.o b.o c.o
3911: - $CC $CFLAGS -o $target $prereq
3912: -.EE
3913: -.PP
3914: -Override flag settings in the mkfile.
3915: -.IP
3916: -.EX
3917: -$ mk target CFLAGS='-O -s'
3918: -.EE
3919: -.PP
3920: -To get the prerequisites for an aggregate.
3921: -.IP
3922: -.EX
3923: -$ membername 'libc.a(read.o)' 'libc.a(write.o)'
3924: -read.o write.o
3925: -.EE
3926: -.PP
3927: -Maintain a library.
3928: -.IP
3929: -.EX
3930: -libc.a(%.o):N: %.o
3931: -libc.a: libc.a(abs.o) libc.a(access.o) libc.a(alarm.o) ...
3932: - names=`membername $newprereq`
3933: - ar r libc.a $names && rm $names
3934: -.EE
3935: -.PP
3936: -Backquotes used to derive a list from a master list.
3937: -.IP
3938: -.EX
3939: -NAMES=alloc arc bquote builtins expand main match mk var word
3940: -OBJ=`echo $NAMES|sed -e 's/[^ ][^ ]*/&.o/g'`
3941: -.EE
3942: -.PP
3943: -Regular expression metarules.
3944: -The single quotes are needed to protect the
3945: -.BR \e s.
3946: -.IP
3947: -.EX
3948: -\&'([^/]*)/(.*)\e.o':R: '\e1/\e2.c'
3949: - cd $stem1; $CC $CFLAGS -c $stem2.c
3950: -.EE
3951: -.PP
3952: -A correct way to deal with
3953: -.IR yacc (1)
3954: -grammars.
3955: -The file
3956: -.B lex.c
3957: -includes the file
3958: -.B x.tab.h
3959: -rather than
3960: -.B y.tab.h
3961: -in order to reflect changes in content, not just modification time.
3962: -.IP
3963: -.EX
3964: -YFLAGS=-d
3965: -lex.o: x.tab.h
3966: -x.tab.h: y.tab.h
3967: - cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h
3968: -y.tab.c y.tab.h: gram.y
3969: - $YACC $YFLAGS gram.y
3970: -.EE
3971: -.PP
3972: -The above example could also use the
3973: -.B P
3974: -attribute for the
3975: -.B x.tab.h
3976: -rule:
3977: -.IP
3978: -.EX
3979: -x.tab.h:Pcmp -s: y.tab.h
3980: - cp y.tab.h x.tab.h
3981: -.EE
3982: -.SH SEE ALSO
3983: -.IR make (1),
3984: -.IR chdate (1),
3985: -.IR sh (1),
3986: -.IR regexp (3)
3987: -.br
3988: -A. Hume,
3989: -.RI ` Mk :
3990: -a Successor to
3991: -.IR Make ',
3992: -this manual, Volume 2
3993: -.SH BUGS
3994: -Identical recipes for regular expression metarules only have one target.
3995: -.br
3996: -Seemingly appropriate input like
3997: -.B CFLAGS=-DHZ=60
3998: -is parsed as an erroneous attribute; correct it by inserting
3999: -a space after the first
4000: -.LR = .
4001: //GO.SYSIN DD ./mk.1
4002: echo ./alloc.c 1>&2
4003: sed 's/.//' >./alloc.c <<'//GO.SYSIN DD ./alloc.c'
4004: -#include "libc.h"
4005: -
4006: -static int goo; /* so no empty object on cray */
4007: -
4008: -#ifndef CRAY
4009: -
4010: -#define A(x) ((((long)x)+sizeof(long)-1)&~(sizeof(long)-1))
4011: -
4012: -char *next;
4013: -int nleft;
4014: -
4015: -char *
4016: -malloc(n)
4017: -{
4018: - extern char *sbrk();
4019: - char *s;
4020: -
4021: - n = A(n);
4022: - if(n > nleft){
4023: - next = sbrk(nleft = A(32000));
4024: - if(next == (char *)-1){
4025: - perror("mk: sbrk");
4026: - Exit();
4027: - }
4028: - }
4029: - s = next;
4030: - next += n;
4031: - nleft -= n;
4032: - return(s);
4033: -}
4034: -
4035: -free(s)
4036: - char *s;
4037: -{
4038: -}
4039: -
4040: -char *
4041: -realloc(s, n)
4042: - char *s;
4043: - unsigned n;
4044: -{
4045: - char *r;
4046: -
4047: - r = malloc(n);
4048: - memcpy(r, s, n);
4049: - return(r);
4050: -}
4051: -
4052: -#endif
4053: //GO.SYSIN DD ./alloc.c
4054: echo ./arc.c 1>&2
4055: sed 's/.//' >./arc.c <<'//GO.SYSIN DD ./arc.c'
4056: -#include "mk.h"
4057: -
4058: -Arc *
4059: -newarc(n, r, stem, match)
4060: - Node *n;
4061: - Rule *r;
4062: - char *stem;
4063: - regsubexp *match;
4064: -{
4065: - register Arc *a;
4066: -
4067: - a = (Arc *)Malloc(sizeof(Arc));
4068: - a->n = n;
4069: - a->r = r;
4070: - a->stem = strdup(stem);
4071: - memcpy((char *)a->match, (char *)match, sizeof a->match);
4072: - a->next = 0;
4073: - a->flag = 0;
4074: - a->prog = r->prog;
4075: - return(a);
4076: -}
4077: -
4078: -dumpa(s, a)
4079: - char *s;
4080: - register Arc *a;
4081: -{
4082: - char buf[1024];
4083: -
4084: - sprint(buf, "%s ", (*s == ' ')? s:"");
4085: - Fprint(1, "%sArc@%ld: n=%ld r=%ld flag=0x%x stem='%s'",
4086: - s, a, a->n, a->r, a->flag, a->stem);
4087: - if(a->prog)
4088: - Fprint(1, " prog='%s'", a->prog);
4089: - Fprint(1, "\n");
4090: - if(a->n)
4091: - dumpn(buf, a->n);
4092: -}
4093: -
4094: -nrep()
4095: -{
4096: - register Symtab *sym;
4097: -
4098: - if(sym = symlook("NREP", S_VAR, (char *)0))
4099: - nreps = atoi(sym->value);
4100: - if(nreps < 1)
4101: - nreps = 1;
4102: - if(DEBUG(D_GRAPH))
4103: - Fprint(1, "nreps = %d\n", nreps);
4104: -}
4105: //GO.SYSIN DD ./arc.c
4106: echo ./bquote.c 1>&2
4107: sed 's/.//' >./bquote.c <<'//GO.SYSIN DD ./bquote.c'
4108: -#include "mk.h"
4109: -
4110: -bquote(fd, src, dest)
4111: - register char *src, *dest;
4112: -{
4113: - int childin[2], childout[2], pid, i;
4114: - int quotedone = 1;
4115: - char *ldest, *t;
4116: - char *newline = "\n";
4117: - int wearedone = 0;
4118: - int initdone = 0;
4119: - extern char **environ;
4120: -
4121: - while(wearedone == 0)
4122: - switch(*src)
4123: - {
4124: - default:
4125: - *dest++ = *src++;
4126: - break;
4127: - case 0:
4128: - if(quotedone)
4129: - wearedone = 1;
4130: - else {
4131: - if(t = Frdline(fd)){
4132: - inline++;
4133: - *dest++ = '\n'|EBIT;
4134: - strcpy(src, t);
4135: - continue;
4136: - } else {
4137: - SYNERR(-1); Fprint(2, "missing closing `\n");
4138: - break;
4139: - }
4140: - }
4141: - break;
4142: - case '\\':
4143: - if(*src)
4144: - *dest++ = *src++;
4145: - else
4146: - if(t = Frdline(fd)){
4147: - inline++;
4148: - strcpy(src, t);
4149: - }
4150: - break;
4151: - case '`':
4152: - if(quotedone = 1-quotedone){
4153: - if(initdone == 0){
4154: - execinit();
4155: - initdone = 1;
4156: - }
4157: - Fflush(1);
4158: - Fflush(2);
4159: - if(pipe(childin) < 0){
4160: - SYNERR(-1); perror("pipe1");
4161: - Exit();
4162: - }
4163: - if(pipe(childout) < 0){
4164: - SYNERR(-1); perror("pipe2");
4165: - Exit();
4166: - }
4167: - if((pid = fork()) < 0){
4168: - SYNERR(-1); perror("fork");
4169: - Exit();
4170: - }
4171: - if(pid){ /* parent */
4172: - close(childin[0]);
4173: - close(childout[1]);
4174: - if(ldest < dest){
4175: - writeout(childin[1], ldest, dest);
4176: - writeout(childin[1], newline, newline+1);
4177: - }
4178: - close(childin[1]);
4179: - dest = ldest;
4180: - while((i = read(childout[0], dest, 512)) > 0)
4181: - dest += i;
4182: - if((dest > ldest) && (dest[-1] == '\n'))
4183: - dest--;
4184: - close(childout[0]);
4185: - } else {
4186: - dup2(childin[0], 0);
4187: - dup2(childout[1], 1);
4188: - close(childin[0]);
4189: - close(childin[1]);
4190: - close(childout[0]);
4191: - close(childout[1]);
4192: - if(execle(SHELL, "sh", (char *)0, environ) < 0)
4193: - perror("exec");
4194: - _exit(1);
4195: - }
4196: - } else
4197: - ldest = dest;
4198: - src++;
4199: - break;
4200: - }
4201: - *dest = 0;
4202: -}
4203: -
4204: -writeout(fd, b, e)
4205: - register char *b, *e;
4206: -{
4207: - char buf[BIGBLOCK];
4208: - register char *s;
4209: -
4210: - for(s = buf; b < e;){
4211: - if(s >= &buf[BIGBLOCK-1]){
4212: - SYNERR(-1); Fprint(2, "too much text (%d chars) for `expr`\n", s-buf);
4213: - Exit();
4214: - }
4215: - if(*b&EBIT){
4216: - *s++ = '\\';
4217: - *s++ = (~EBIT) & *b++;
4218: - } else
4219: - *s++ = *b++;
4220: - }
4221: - write(fd, buf, s-buf);
4222: -}
4223: //GO.SYSIN DD ./bquote.c
4224: echo ./builtins.c 1>&2
4225: sed 's/.//' >./builtins.c <<'//GO.SYSIN DD ./builtins.c'
4226: -#include "mk.h"
4227: -
4228: -char *bltin[] =
4229: -{
4230: - "AS", "as",
4231: - "CC", "cc",
4232: - "CFLAGS", "",
4233: - "FC", "f77",
4234: - "FFLAGS", "",
4235: - "LDFLAGS", "",
4236: - "LEX", "lex",
4237: - "LFLAGS", "",
4238: - "NPROC", "1",
4239: - "NREP", "1",
4240: - "YACC", "yacc",
4241: - "YFLAGS", "",
4242: - "BUILTINS", "%.o: %.c\n\
4243: - $CC $CFLAGS -c $stem.c\n\
4244: -%.o: %.s\n\
4245: - $AS -o $stem.o $stem.s\n\
4246: -%.o: %.f\n\
4247: - $FC $FFLAGS -c $stem.f\n\
4248: -%.o: %.y\n\
4249: - $YACC $YFLAGS $stem.y && $CC $CFLAGS -c y.tab.c && mv y.tab.o $stem.o; rm y.tab.c\n\
4250: -%.o: %.l\n\
4251: - $LEX $LFLAGS -t $stem.l > /tmp/$$.c && $CC $CFLAGS -c /tmp/$$.c && mv /tmp/$$.o $stem.o; rm /tmp/$$.c\n",
4252: - "ENVIRON", "",
4253: - 0
4254: -};
4255: -
4256: -builtins()
4257: -{
4258: - register char **b;
4259: -
4260: - for(b = bltin; *b; b += 2)
4261: - setvar(b[0], strdup(b[1]));
4262: -}
4263: -
4264: -parsebuiltins()
4265: -{
4266: - char *s, *file;
4267: - int fd;
4268: - int n;
4269: -
4270: - s = symlook("BUILTINS", S_VAR, (char *)0)->value;
4271: - if(*s == 0)
4272: - return;
4273: - file = mktemp("/tmp/mkXXXXXX");
4274: - if((fd = creat(file, 0600)) < 0){
4275: - fprint(2, "mk: builtins in ");
4276: - perror(file);
4277: - Exit();
4278: - }
4279: - if(n = strlen(s)){
4280: - write(fd, s, n);
4281: - if(s[n-1] != '\n')
4282: - write(fd, "\n", 1);
4283: - }
4284: - close(fd);
4285: - parse("BUILTINS", open(file, 0), 0, 0);
4286: - unlink(file);
4287: -}
4288: //GO.SYSIN DD ./builtins.c
4289: echo ./dir.c 1>&2
4290: sed 's/.//' >./dir.c <<'//GO.SYSIN DD ./dir.c'
4291: -#include <sys/types.h>
4292: -#include <sys/stat.h>
4293: -#ifndef SEQUENT
4294: -#include <ndir.h>
4295: -#else
4296: -#include <dir.h>
4297: -#endif
4298: -
4299: -#ifdef SEQUENT
4300: -#define DIRSIZE MAXNAMELEN
4301: -#else
4302: -#define DIRSIZE 14
4303: -#endif
4304: -#ifndef MAXNAMELEN
4305: -#define MAXNAMELEN 255
4306: -#endif
4307: -#ifndef DIRSIZ
4308: -#define DIRSIZ(dp) \
4309: - ((sizeof(struct direct) - MAXNAMLEN + (dp)->d_namlen + sizeof(ino_t) - 1) &\
4310: - ~(sizeof(ino_t) - 1))
4311: -#endif
4312: -
4313: -extern char *strncpy(), *malloc();
4314: -
4315: -DIR *
4316: -opendir(name)
4317: -register char *name;
4318: -{
4319: - DIR dirbuf, *dirp;
4320: - struct stat statb;
4321: - char buf[MAXNAMELEN+1];
4322: - register char *s;
4323: -
4324: - strncpy(buf, name, MAXNAMELEN);
4325: - buf[MAXNAMELEN-1] = 0;
4326: - if ((dirbuf.dd_fd = open(buf, 0)) < 0)
4327: - return((DIR *)0);
4328: - if (fstat(dirbuf.dd_fd, &statb)!=0 || (statb.st_mode & S_IFMT)!=S_IFDIR){
4329: - close(dirbuf.dd_fd);
4330: - return((DIR *)0);
4331: - }
4332: - dirbuf.dd_loc = 0;
4333: - dirp = (DIR *)malloc(sizeof(DIR));
4334: - *dirp = dirbuf;
4335: - return(dirp);
4336: -}
4337: -
4338: -void
4339: -closedir(dirp)
4340: -DIR *dirp;
4341: -{
4342: - close(dirp->dd_fd);
4343: - free((char *)dirp);
4344: -}
4345: -
4346: -/*
4347: - * read an old stlye directory entry and present it as a new one
4348: - */
4349: -#define ODIRSIZ 14
4350: -
4351: -struct olddirect {
4352: - ino_t d_ino;
4353: - char d_name[ODIRSIZ];
4354: -#ifdef CRAY
4355: - char d_pad[10];
4356: -#endif
4357: -};
4358: -
4359: -/*
4360: - * get next entry in a directory.
4361: - */
4362: -struct direct *
4363: -readdir(dirp)
4364: - register DIR *dirp;
4365: -{
4366: - register struct olddirect *dp;
4367: - static struct direct dir;
4368: -
4369: - for (;;) {
4370: - if (dirp->dd_loc == 0) {
4371: - dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
4372: - DIRBLKSIZ);
4373: - if (dirp->dd_size <= 0)
4374: - return((struct direct *)0);
4375: - }
4376: - if (dirp->dd_loc >= dirp->dd_size) {
4377: - dirp->dd_loc = 0;
4378: - continue;
4379: - }
4380: - dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
4381: - dirp->dd_loc += sizeof(struct olddirect);
4382: - if (dp->d_ino == 0)
4383: - continue;
4384: - dir.d_ino = dp->d_ino;
4385: - strncpy(dir.d_name, dp->d_name, ODIRSIZ);
4386: - dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
4387: - dir.d_namlen = strlen(dir.d_name);
4388: - dir.d_reclen = DIRSIZ(&dir);
4389: - return (&dir);
4390: - }
4391: -}
4392: //GO.SYSIN DD ./dir.c
4393: echo ./expand.c 1>&2
4394: sed 's/.//' >./expand.c <<'//GO.SYSIN DD ./expand.c'
4395: -#include "mk.h"
4396: -#include <ctype.h>
4397: -
4398: -static Word *bollard;
4399: -
4400: -static void
4401: -append(s)
4402: - char *s;
4403: -{
4404: - register Word *w;
4405: - register char *p;
4406: -
4407: - if(bollard){
4408: - for(w = bollard; w->next; w = w->next)
4409: - ;
4410: - w = w->next = stow(s);
4411: - } else
4412: - w = bollard = stow(s);
4413: - if(w) /* if we got a word */
4414: - for(p = w->s; *p;)
4415: - *p++ &= ~EBIT;
4416: -}
4417: -
4418: -Word *
4419: -expand(s)
4420: - register char *s;
4421: -{
4422: - char save;
4423: - register char *t;
4424: - Word *head, *w;
4425: -
4426: - w = head = newword("");
4427: - while(*s){
4428: - while(SEP(*s))
4429: - s++;
4430: - if(*s == 0) break;
4431: - for(t = s+1; *t && !SEP(*t); t++)
4432: - ;
4433: - save = *t;
4434: - *t = 0;
4435: - bollard = 0;
4436: - glob(s, append);
4437: - w->next = bollard;
4438: - while(w->next)
4439: - w = w->next;
4440: - *t = save;
4441: - s = t;
4442: - }
4443: - w = head->next;
4444: - delword(head);
4445: - return(w);
4446: -}
4447: //GO.SYSIN DD ./expand.c
4448: echo ./gen.c 1>&2
4449: sed 's/.//' >./gen.c <<'//GO.SYSIN DD ./gen.c'
4450: -#include "mk.h"
4451: -
4452: -#define NMATCH 10
4453: -
4454: -gen(buf)
4455: - char *buf;
4456: -{
4457: - char buf1[BIGBLOCK];
4458: - register char *src, *dest;
4459: - register char *s1, *s2, *s3, *s4;
4460: - regexp *prog;
4461: - regsubexp match[NMATCH];
4462: - char c;
4463: -
4464: - if((s1 = strchr(buf, '@')) == 0)
4465: - return;
4466: - patrule = 0;
4467: - src = buf;
4468: - dest = buf1;
4469: - do {
4470: - while(src != s1)
4471: - *dest++ = *src++;
4472: - if((s2 = strchr(s1+1, '@')) && (s3 = strchr(s2+1, '@'))
4473: - && (s4 = strchr(s3+1, '@')))
4474: - ;
4475: - else {
4476: - SYNERR(-1); Fprint(2, "expected four @\n");
4477: - break;
4478: - }
4479: - src = s4+1;
4480: - *s2++ = *s3++ = *s4 = 0;
4481: - prog = regcomp(s2);
4482: - for(s2 = ++s1; ; s2 = s1){
4483: - while((*s2 == ' ')||(*s2 == '\t'))
4484: - s2++;
4485: - if(s1 != s2) *dest++ = ' ';
4486: - if(*s2 == 0) break;
4487: - for(s1 = s2+1; *s1 && (*s1 != ' ') && (*s1 != '\t');)
4488: - s1++;
4489: - c = *s1;
4490: - *s1 = 0;
4491: - if(regexec(prog, s2, match, NMATCH)){
4492: - regsub(s3, dest, match, NMATCH);
4493: - while(*dest) dest++;
4494: - } else
4495: - while(*dest = *s2++)
4496: - dest++;
4497: - *s1 = c;
4498: - }
4499: - } while(s1 = strchr(src, '@'));
4500: - while(*dest++ = *src++)
4501: - ;
4502: - memcpy(buf, buf1, (int)(dest-buf1));
4503: -}
4504: //GO.SYSIN DD ./gen.c
4505: echo ./glob.c 1>&2
4506: sed 's/.//' >./glob.c <<'//GO.SYSIN DD ./glob.c'
4507: -#include <sys/types.h>
4508: -#include <sys/stat.h>
4509: -#ifndef SEQUENT
4510: -#include <ndir.h>
4511: -#else
4512: -#include <dir.h>
4513: -#endif
4514: -#include <string.h>
4515: -#include "mk.h"
4516: -
4517: -#define MAXPATH BIGBLOCK
4518: -
4519: -static char result[MAXPATH];
4520: -static doit();
4521: -
4522: -/*
4523: - * globals (file name generation)
4524: - *
4525: - * "*" in params matches r.e ".*"
4526: - * "?" in params matches r.e. "."
4527: - * "[...]" in params matches character class
4528: - * "[...a-z...]" in params matches a through z.
4529: - *
4530: - */
4531: -
4532: -static
4533: -gglob(arg, dest, fn)
4534: - char *arg, *dest;
4535: - void (*fn)();
4536: -{
4537: - int meta;
4538: - char *slash, *s;
4539: - DIR *dirf;
4540: -
4541: - /*
4542: - check for meta chars
4543: - */
4544: - for(s = arg, slash = 0, meta = 0; *s && !meta; s++)
4545: - switch(*s)
4546: - {
4547: - case '/':
4548: - slash = s+1;
4549: - break;
4550: - case '\\':
4551: - if(s[1])
4552: - s++;
4553: - break;
4554: - case '[':
4555: - case '*':
4556: - case '?':
4557: - meta = 1;
4558: - break;
4559: - }
4560: - if(meta == 0){
4561: - strcpy(dest, arg);
4562: - (*fn)(result);
4563: - return;
4564: - }
4565: - if(slash){
4566: - memcpy(dest, arg, slash-arg);
4567: - dest += slash-arg;
4568: - *dest = 0;
4569: - } else
4570: - slash = arg;
4571: - s = strchr(slash, '/');
4572: - if(dirf = opendir(result[0] ? result : ".")){
4573: - struct direct *e;
4574: - int found;
4575: -
4576: - found = 0;
4577: - if(s) *s = 0;
4578: - /* slash is null terminated (s) pattern */
4579: - while(e = readdir(dirf)){
4580: - if(e->d_name[0] == '.' && *slash != '.'){
4581: - if (e->d_name[1] == 0)
4582: - continue;
4583: - if (e->d_name[1] == '.' && e->d_name[2] == 0)
4584: - continue;
4585: - }
4586: - if(gmatch(e->d_name, slash)){
4587: - found = 1;
4588: - strcpy(dest, e->d_name);
4589: - doit(s, dest, fn);
4590: - }
4591: - }
4592: - if(!found){
4593: - strcpy(dest, slash);
4594: - doit(s, dest, fn);
4595: - }
4596: - closedir(dirf);
4597: - } else {
4598: - if(s)
4599: - *s = 0;
4600: - strcpy(dest, slash);
4601: - dest = strchr(dest, 0);
4602: - if(s){
4603: - *dest++ = '/';
4604: - *dest = 0;
4605: - gglob(s+1, dest, fn);
4606: - } else
4607: - (*fn)(result);
4608: - }
4609: - if(s) *s = '/';
4610: -}
4611: -
4612: -static
4613: -doit(s, dest, fn)
4614: - char *s, *dest;
4615: - void (*fn)();
4616: -{
4617: - if(s){
4618: - register char *ss;
4619: -
4620: - ss = strchr(dest, 0);
4621: - *ss++ = '/';
4622: - *ss = 0;
4623: - gglob(s+1, ss, fn);
4624: - } else
4625: - (*fn)(result);
4626: -}
4627: -
4628: -gmatch(s, p)
4629: -register char *s, *p;
4630: -{
4631: - register int scc;
4632: - unsigned char c;
4633: -
4634: - scc = *s++&(0xFF&~EBIT);
4635: - switch (c = *p++)
4636: - {
4637: - case '[':
4638: - {
4639: - int ok;
4640: - int lc;
4641: - int notflag = 0;
4642: -
4643: - ok = 0;
4644: - lc = 077777;
4645: - if (*p == '^'){
4646: - notflag = 1;
4647: - p++;
4648: - }
4649: - while (c = *p++){
4650: - if (c == ']')
4651: - return(ok ? gmatch(s, p) : 0);
4652: - else if (c == '-'){
4653: - if (notflag){
4654: - if (scc < lc || scc > *(p++))
4655: - ok++;
4656: - else
4657: - return(0);
4658: - } else {
4659: - if (lc <= scc && scc <= (*p++))
4660: - ok++;
4661: - }
4662: - } else {
4663: - lc = c&~EBIT;
4664: - if (notflag){
4665: - if (scc && scc != lc)
4666: - ok++;
4667: - else
4668: - return(0);
4669: - } else {
4670: - if (scc == lc)
4671: - ok++;
4672: - }
4673: - }
4674: - }
4675: - return(0);
4676: - }
4677: -
4678: - default:
4679: - if ((c&~EBIT) != scc)
4680: - return(0);
4681: -
4682: - case '?':
4683: - return(scc ? gmatch(s, p) : 0);
4684: -
4685: - case '*':
4686: - while (*p == '*')
4687: - p++;
4688: -
4689: - if (*p == 0)
4690: - return(1);
4691: - --s;
4692: - while (*s){
4693: - if (gmatch(s++, p))
4694: - return(1);
4695: - }
4696: - return(0);
4697: -
4698: - case 0:
4699: - return(scc == 0);
4700: - }
4701: -}
4702: -
4703: -glob(s, fn)
4704: - char *s;
4705: - void (*fn)();
4706: -{
4707: - result[0] = 0;
4708: - if(strlen(s) >= MAXPATH){
4709: - SYNERR(inline-1);
4710: - Fprint(2, "too much input for glob expansion; max=%d, given %d\n", MAXPATH, strlen(s));
4711: - Exit();
4712: - }
4713: - gglob(s, result, fn);
4714: -}
4715: -
4716: -#ifdef MAIN
4717: -
4718: -void
4719: -pr(s)
4720: - char *s;
4721: -{
4722: - Fwrite(1, s, strlen(s));
4723: - Fputc(1, '\n');
4724: -}
4725: -
4726: -main(argc, argv)
4727: - char **argv;
4728: -{
4729: - for(argv++; *argv; argv++){
4730: - Fprint(1, "<%s>:\n", *argv);
4731: - glob(*argv, pr);
4732: - Fprint(1, "*******\n");
4733: - }
4734: - exit(0);
4735: -}
4736: -#endif
4737: //GO.SYSIN DD ./glob.c
4738: echo ./graph.c 1>&2
4739: sed 's/.//' >./graph.c <<'//GO.SYSIN DD ./graph.c'
4740: -#include "mk.h"
4741: -
4742: -static Node *newnode(), *applyrules();
4743: -static cyclechk(), vacuous(), ambiguous(), attribute();
4744: -
4745: -Node *
4746: -graph(target)
4747: - char *target;
4748: -{
4749: - Node *node;
4750: - char *cnt;
4751: -
4752: - node = applyrules(target, cnt = rulecnt());
4753: - free(cnt);
4754: - cyclechk(node);
4755: - node->flags |= PROBABLE; /* make sure it doesn't get deleted */
4756: - (void)vacuous(node);
4757: - (void)ambiguous(node);
4758: - (void)attribute(node);
4759: - return(node);
4760: -}
4761: -
4762: -static Node *
4763: -applyrules(target, cnt)
4764: - char *target, *cnt;
4765: -{
4766: - Symtab *sym;
4767: - Node *node;
4768: - Rule *r;
4769: - Arc head, *a = &head;
4770: - Word *w;
4771: - char stem[NAMEBLOCK], buf[NAMEBLOCK];
4772: - regsubexp rmatch[NREGEXP];
4773: -
4774: -/* print("appplyrules(%ld='%s')\n", target, target);/**/
4775: - if(sym = symlook(target, S_NODE, (char *)0)){
4776: - node = (Node *)(sym->value);
4777: - return(node);
4778: - }
4779: - target = strdup(target);
4780: - node = newnode(target);
4781: - head.n = 0;
4782: - head.next = 0;
4783: - sym = symlook(target, S_TARGET, (char *)0);
4784: - for(r = sym? (Rule *)(sym->value):0; r; r = r->chain){
4785: - if(r->attr&META) continue;
4786: - if(strcmp(target, r->target)) continue;
4787: - if(cnt[r->rule] >= nreps) continue;
4788: - cnt[r->rule]++;
4789: - node->flags |= PROBABLE;
4790: - if(r->attr&VIR)
4791: - node->flags |= VIRTUAL;
4792: - if(r->attr&NOREC)
4793: - node->flags |= NORECIPE;
4794: - if(r->attr&DEL)
4795: - node->flags |= DELETE;
4796: - if(r->tail == 0)
4797: - a = a->next = newarc((Node *)0, r, "", rmatch);
4798: - else
4799: - for(w = r->tail; w; w = w->next){
4800: - a = a->next = newarc(applyrules(w->s, cnt), r, "", rmatch);
4801: - }
4802: - cnt[r->rule]--;
4803: - head.n = node;
4804: - }
4805: - for(r = metarules; r; r = r->next){
4806: - if(r->attr®EXP){
4807: - stem[0] = 0;
4808: - patrule = r;
4809: - if(regexec(r->pat, node->name, rmatch, NREGEXP) == 0)
4810: - continue;
4811: - } else {
4812: - if(!match(node->name, r->target, stem)) continue;
4813: - }
4814: - if(cnt[r->rule] >= nreps) continue;
4815: - cnt[r->rule]++;
4816: - if(r->attr&VIR)
4817: - node->flags |= VIRTUAL;
4818: - if(r->attr&NOREC)
4819: - node->flags |= NORECIPE;
4820: - if(r->attr&DEL)
4821: - node->flags |= DELETE;
4822: - if(r->tail == 0)
4823: - a = a->next = newarc((Node *)0, r, strdup(stem), rmatch);
4824: - else
4825: - for(w = r->tail; w; w = w->next){
4826: - if(r->attr®EXP)
4827: - regsub(w->s, buf, rmatch, NREGEXP);
4828: - else
4829: - subst(stem, w->s, buf);
4830: - a = a->next = newarc(applyrules(buf, cnt), r, strdup(stem), rmatch);
4831: - }
4832: - cnt[r->rule]--;
4833: - }
4834: - a->next = node->prereqs;
4835: - node->prereqs = head.next;
4836: - return(node);
4837: -}
4838: -
4839: -static
4840: -togo(node)
4841: - register Node *node;
4842: -{
4843: - register Arc *la, *a;
4844: -
4845: - /* delete them now */
4846: - for(a = node->prereqs; a; la = a, a = a->next)
4847: - if(a->flag&TOGO){
4848: - if(a == node->prereqs)
4849: - node->prereqs = a->next;
4850: - else
4851: - la->next = a->next, a = la;
4852: - }
4853: -}
4854: -
4855: -static
4856: -vacuous(node)
4857: - register Node *node;
4858: -{
4859: - register Arc *la, *a;
4860: - int vac = !(node->flags&PROBABLE);
4861: -
4862: - if(node->flags&READY)
4863: - return(node->flags&VACUOUS);
4864: - node->flags |= READY;
4865: - for(a = node->prereqs; a; a = a->next)
4866: - if(a->n && vacuous(a->n) && (a->r->attr&META))
4867: - a->flag |= TOGO;
4868: - else
4869: - vac = 0;
4870: - /* if a rule generated arcs that DON'T go; no others from that rule go */
4871: - for(a = node->prereqs; a; a = a->next)
4872: - if((a->flag&TOGO) == 0)
4873: - for(la = node->prereqs; la; la = la->next)
4874: - if((la->flag&TOGO) && (la->r == a->r)){
4875: - la->flag &= ~TOGO;
4876: - }
4877: - togo(node);
4878: - if(vac)
4879: - node->flags |= VACUOUS;
4880: - return(vac);
4881: -}
4882: -
4883: -static Node *
4884: -newnode(name)
4885: - char *name;
4886: -{
4887: - register Node *node;
4888: -
4889: - node = (Node *)Malloc(sizeof(Node));
4890: - symlook(name, S_NODE, (char *)node);
4891: - node->name = name;
4892: - node->time = timeof(name, 0);
4893: - node->prereqs = 0;
4894: - node->flags = node->time? PROBABLE : 0;
4895: - node->next = 0;
4896: - return(node);
4897: -}
4898: -
4899: -dumpn(s, n)
4900: - char *s;
4901: - register Node *n;
4902: -{
4903: - char buf[1024];
4904: - register Arc *a;
4905: -
4906: - sprint(buf, "%s ", (*s == ' ')? s:"");
4907: - Fprint(1, "%s%s@%ld: time=%ld flags=0x%x next=%ld\n",
4908: - s, n->name, n, n->time, n->flags, n->next);
4909: - for(a = n->prereqs; a; a = a->next)
4910: - dumpa(buf, a);
4911: -}
4912: -
4913: -static
4914: -trace(s, a)
4915: - char *s;
4916: - register Arc *a;
4917: -{
4918: - Fprint(2, "\t%s", s);
4919: - while(a){
4920: - Fprint(2, " <-(%s:%d)- %s", a->r->file, a->r->line,
4921: - a->n? a->n->name:"");
4922: - if(a->n){
4923: - for(a = a->n->prereqs; a; a = a->next)
4924: - if(*a->r->recipe) break;
4925: - } else
4926: - a = 0;
4927: - }
4928: - Fputc(2, '\n');
4929: -}
4930: -
4931: -static
4932: -cyclechk(n)
4933: - register Node *n;
4934: -{
4935: - register Arc *a;
4936: -
4937: - if((n->flags&CYCLE) && n->prereqs){
4938: - Fprint(2, "mk: cycle in graph detected at target %s\n", n->name);
4939: - Exit();
4940: - }
4941: - n->flags |= CYCLE;
4942: - for(a = n->prereqs; a; a = a->next)
4943: - if(a->n)
4944: - cyclechk(a->n);
4945: - n->flags &= ~CYCLE;
4946: -}
4947: -
4948: -static
4949: -ambiguous(n)
4950: - register Node *n;
4951: -{
4952: - register Arc *a;
4953: - register Rule *r = 0;
4954: - Arc *la;
4955: - int bad = 0;
4956: -
4957: - for(a = n->prereqs; a; a = a->next){
4958: - if(a->n)
4959: - ambiguous(a->n);
4960: - if(*a->r->recipe == 0) continue;
4961: - if(r == 0)
4962: - r = a->r, la = a;
4963: - else{
4964: - if(r->recipe != a->r->recipe){
4965: - if((r->attr&META) && !(a->r->attr&META)){
4966: - la->flag |= TOGO;
4967: - r = a->r, la = a;
4968: - } else if(!(r->attr&META) && (a->r->attr&META)){
4969: - a->flag |= TOGO;
4970: - continue;
4971: - }
4972: - }
4973: - if(r->recipe != a->r->recipe){
4974: - if(bad == 0){
4975: - Fprint(2, "mk: ambiguous recipes for %s:\n", n->name);
4976: - bad = 1;
4977: - trace(n->name, la);
4978: - }
4979: - trace(n->name, a);
4980: - }
4981: - }
4982: - }
4983: - if(bad)
4984: - Exit();
4985: - togo(n);
4986: -}
4987: -
4988: -static
4989: -attribute(n)
4990: - register Node *n;
4991: -{
4992: - register Arc *a;
4993: -
4994: - for(a = n->prereqs; a; a = a->next){
4995: - if(a->r->attr&VIR)
4996: - n->flags |= VIRTUAL;
4997: - if(a->r->attr&NOREC)
4998: - n->flags |= NORECIPE;
4999: - if(a->r->attr&DEL)
5000: - n->flags |= DELETE;
5001: - if(a->n)
5002: - attribute(a->n);
5003: - }
5004: - if(n->flags&VIRTUAL)
5005: - n->time = 0;
5006: -}
5007: //GO.SYSIN DD ./graph.c
5008: echo ./job.c 1>&2
5009: sed 's/.//' >./job.c <<'//GO.SYSIN DD ./job.c'
5010: -#include "mk.h"
5011: -
5012: -Job *
5013: -newjob(r, nlist, stem, match, pre, npre, tar, atar)
5014: - Rule *r;
5015: - Node *nlist;
5016: - char *stem;
5017: - regsubexp *match;
5018: - Word *pre, *npre, *tar, *atar;
5019: -{
5020: - register Job *j;
5021: -
5022: - j = (Job *)Malloc(sizeof(Job));
5023: - j->r = r;
5024: - j->n = nlist;
5025: - j->stem = stem;
5026: - j->match = match;
5027: - j->p = pre;
5028: - j->np = npre;
5029: - j->t = tar;
5030: - j->at = atar;
5031: - j->nproc = -1;
5032: - j->fd = -1;
5033: - j->next = 0;
5034: - return(j);
5035: -}
5036: -
5037: -dumpj(s, j, all)
5038: - char *s;
5039: - Job *j;
5040: -{
5041: - Fprint(1, "%s\n", s);
5042: - while(j){
5043: - Fprint(1, "job@%ld: r=%ld n=%ld stem='%s' nproc=%d\n",
5044: - j, j->r, j->n, j->stem, j->nproc);
5045: - Fprint(1, "\ttarget='%s' alltarget='%s' prereq='%s' nprereq='%s'\n",
5046: - wtos(j->t), wtos(j->at), wtos(j->p), wtos(j->np));
5047: - j = all? j->next : 0;
5048: - }
5049: -}
5050: //GO.SYSIN DD ./job.c
5051: echo ./lex.c 1>&2
5052: sed 's/.//' >./lex.c <<'//GO.SYSIN DD ./lex.c'
5053: -#include "mk.h"
5054: -
5055: -lex(fd, buf)
5056: - char *buf;
5057: -{
5058: - char buf1[BIGBLOCK];
5059: -
5060: - quote1(fd, buf, buf1); /* '..' */
5061: - bquote(fd, buf1, buf); /* `cmd` */
5062: - quote2(fd, buf, buf1); /* ".." and variable expansion */
5063: - strcpy(buf, buf1);
5064: -}
5065: //GO.SYSIN DD ./lex.c
5066: echo ./main.c 1>&2
5067: sed 's/.//' >./main.c <<'//GO.SYSIN DD ./main.c'
5068: -#include "mk.h"
5069: -
5070: -#define MKFILE "mkfile"
5071: -
5072: -static char *version = "@(#)mk general release 3";
5073: -int debug;
5074: -Rule *rules, *metarules;
5075: -int nproclimit;
5076: -int nflag = 0;
5077: -int tflag = 0;
5078: -int iflag = 0;
5079: -int kflag = 0;
5080: -int mflag = 0;
5081: -int aflag = 0;
5082: -int uflag = 0;
5083: -char *explain = 0;
5084: -Word *target1;
5085: -int nreps = 1;
5086: -Job *jobs;
5087: -char *whatif = 0;
5088: -#ifdef PROF
5089: -short buf[10000];
5090: -#endif
5091: -
5092: -main(argc, argv)
5093: - char **argv;
5094: -{
5095: - register Word *w;
5096: - register char *s;
5097: - char *files[256], **f = files, **ff;
5098: - char mkargs[256], *ma = mkargs;
5099: - int i;
5100: - int tfd = -1;
5101: - char *temp = "/tmp/mkargXXXXXX";
5102: -
5103: - *ma = 0;
5104: - for(argv++; *argv && (**argv == '-'); argv++)
5105: - {
5106: - for(s = argv[0]; *s; *ma++ = *s++);
5107: - *ma++ = ' ';
5108: - switch(argv[0][1])
5109: - {
5110: - case 'a':
5111: - aflag = 1;
5112: - break;
5113: - case 'd':
5114: - if(*(s = &argv[0][2]))
5115: - while(*s) switch(*s++)
5116: - {
5117: - case 'p': debug |= D_PARSE; break;
5118: - case 'g': debug |= D_GRAPH; break;
5119: - case 'e': debug |= D_EXEC; break;
5120: - }
5121: - else
5122: - debug = 0xFFFF;
5123: - break;
5124: - case 'e':
5125: - explain = &argv[0][2];
5126: - break;
5127: - case 'f':
5128: - if(*++argv == 0)
5129: - usage();
5130: - *f++ = *argv;
5131: - for(s = argv[0]; *s; *ma++ = *s++);
5132: - *ma++ = ' ';
5133: - break;
5134: - case 'i':
5135: - iflag = 1;
5136: - break;
5137: - case 'k':
5138: - kflag = 1;
5139: - break;
5140: - case 'm':
5141: - mflag = 1;
5142: - aflag = nflag = 1;
5143: - break;
5144: - case 'n':
5145: - nflag = 1;
5146: - break;
5147: - case 't':
5148: - tflag = 1;
5149: - break;
5150: - case 'u':
5151: - uflag = 1;
5152: - break;
5153: - case 'w':
5154: - if(argv[0][2])
5155: - whatif = &argv[0][2];
5156: - else {
5157: - if(*++argv == 0)
5158: - usage();
5159: - whatif = &argv[0][0];
5160: - }
5161: - break;
5162: - default:
5163: - usage();
5164: - }
5165: - }
5166: -#ifdef PROF
5167: - {
5168: - extern etext();
5169: - monitor(main, etext, buf, sizeof buf, 300);
5170: - }
5171: -#endif
5172: -
5173: - if(aflag)
5174: - iflag = 1;
5175: -
5176: - account();
5177: - syminit();
5178: - builtins();
5179: - initenv();
5180: -
5181: - /*
5182: - assignment args become null strings
5183: - */
5184: - for(i = 0; argv[i]; i++) if(strchr(argv[i], '=')){
5185: - for(s = argv[i]; *s; *ma++ = *s++);
5186: - *ma++ = ' ';
5187: - if(tfd < 0){
5188: - mktemp(temp);
5189: - close(creat(temp, 0600));
5190: - if((tfd = open(temp, 2)) < 0){
5191: - perror(temp);
5192: - Exit();
5193: - }
5194: - }
5195: - Fprint(tfd, "%s\n", argv[i]);
5196: - *argv[i] = 0;
5197: - }
5198: - if(tfd >= 0){
5199: - Fflush(tfd);
5200: - lseek(tfd, 0L, 0);
5201: - parse("command line args", tfd, 1, 1);
5202: - unlink(temp);
5203: - }
5204: -
5205: - if(ma != mkargs) ma--;
5206: - *ma = 0;
5207: - symlook("MKFLAGS", S_VAR, strdup(mkargs));
5208: - for(ma = mkargs, i = 0; argv[i]; i++){
5209: - if(*argv[i] == 0) continue;
5210: - if(i) *ma++ = ' ';
5211: - for(s = argv[i]; *s; *ma++ = *s++);
5212: - }
5213: - *ma = 0;
5214: - symlook("MKARGS", S_VAR, strdup(mkargs));
5215: -
5216: - if(f == files){
5217: - if(access(MKFILE, 4) == 0)
5218: - parse(MKFILE, open(MKFILE, 0), 0, 1);
5219: - } else
5220: - for(ff = files; ff < f; ff++)
5221: - parse(*ff, open(*ff, 0), 0, 1);
5222: - parsebuiltins();
5223: - if(DEBUG(D_PARSE)){
5224: - dumpw("default targets", target1);
5225: - dumpr("rules", rules);
5226: - dumpr("metarules", metarules);
5227: - dumpv("variables");
5228: - }
5229: - if(whatif)
5230: - timeinit(whatif);
5231: - execinit();
5232: - /* skip assignment args */
5233: - while(*argv && (**argv == 0))
5234: - argv++;
5235: - sigcatch();
5236: - if(*argv == 0){
5237: - if(target1)
5238: - for(w = target1; w; w = w->next)
5239: - mk(w->s);
5240: - else {
5241: - Fprint(2, "mk: nothing to mk\n");
5242: - Exit();
5243: - }
5244: - } else
5245: - for(; *argv; argv++)
5246: - if(**argv)
5247: - mk(*argv);
5248: - if(uflag)
5249: - praccount();
5250: - if(mflag)
5251: - makefile();
5252: - exit(0);
5253: -}
5254: -
5255: -usage()
5256: -{
5257: -
5258: - Fprint(2, "Usage: mk [-f file] [-n] [-a] [-e] [-t] [-k] [-i] [-d[egp]] [targets ...]\n");
5259: - Exit();
5260: -}
5261: -
5262: -char *
5263: -Malloc(n)
5264: -{
5265: - register char *s;
5266: -
5267: - if(s = malloc(n))
5268: - return(s);
5269: - Fprint(2, "mk: cannot alloc %d bytes\n", n);
5270: - Exit();
5271: - return((char *)0); /* shut cyntax up */
5272: -}
5273: -
5274: -Exit()
5275: -{
5276: - while(wait((int *)0) >= 0)
5277: - ;
5278: - exit(1);
5279: -}
5280: -
5281: -char *
5282: -strndup(s, n)
5283: - char *s;
5284: -{
5285: - register char *goo;
5286: -
5287: - goo = Malloc(n);
5288: - memcpy(goo, s, n);
5289: - return(goo);
5290: -}
5291: -
5292: -initenv()
5293: -{
5294: - extern char **environ;
5295: - register char **p, *s, *ss;
5296: -
5297: - for(p = environ; *p; p++){
5298: - s = shname(*p);
5299: - switch(*s)
5300: - {
5301: - case '=':
5302: - *s = 0;
5303: - ss = strdup(s+1);
5304: - symlook(strdup(*p), S_VAR, ss)->value = ss;
5305: - *s = '=';
5306: - break;
5307: - case 0:
5308: - ss = strdup("");
5309: - symlook(strdup(*p), S_VAR, ss)->value = ss;
5310: - break;
5311: - }
5312: - }
5313: -}
5314: -
5315: -assert(s, n)
5316: - char *s;
5317: -{
5318: - if(!n){
5319: - Fprint(2, "mk: Assertion ``%s'' failed.\n", s);
5320: - Exit();
5321: - }
5322: -}
5323: //GO.SYSIN DD ./main.c
5324: echo ./makefile.c 1>&2
5325: sed 's/.//' >./makefile.c <<'//GO.SYSIN DD ./makefile.c'
5326: -#include "mk.h"
5327: -
5328: -#define FOLD 65
5329: -
5330: -static char *first = 0;
5331: -static didit;
5332: -
5333: -maketarget(s)
5334: - char *s;
5335: -{
5336: - if(first == 0)
5337: - first = s;
5338: -}
5339: -
5340: -addmake(n)
5341: - Node *n;
5342: -{
5343: - symlook(n->name, S_MAKEFILE, (char *)n);
5344: -}
5345: -
5346: -static
5347: -fold(s, sep)
5348: - char *s;
5349: -{
5350: - int i = 0;
5351: -
5352: - while(*s){
5353: - i++;
5354: - if((*s == ' ') && (i > FOLD)){
5355: - Fprint(1, "\\\n%c", sep);
5356: - i = 0;
5357: - } else
5358: - Fputc(1, *s++);
5359: - }
5360: -}
5361: -
5362: -static void
5363: -vd(s)
5364: - register Symtab *s;
5365: -{
5366: - Fprint(1, "%s=", s->name);
5367: - fold(symlook(s->name, S_VAR, (char *)0)->value, ' ');
5368: - Fputc(1, '\n');
5369: -}
5370: -
5371: -#define SUB(s) { register char *ss = s; while(*dest++ = *ss++); dest--; copy = 0; }
5372: -
5373: -static char *
5374: -vexpand(ww, dest, j)
5375: - char **ww, *dest;
5376: - Job *j;
5377: -{
5378: - register char *s, *w = *ww;
5379: - char carry, *q;
5380: - int copy;
5381: -
5382: - assert("vexpand no $", *w == '$');
5383: - if(*++w == '{'){
5384: - for(s = ++w; *s != '}'; s++)
5385: - if(*s == 0) break;
5386: - } else
5387: - s = shname(w);
5388: - carry = *s;
5389: - *s = 0;
5390: - copy = 1;
5391: - if(!symlook(w, S_MAKEVAR, (char *)0)){
5392: - if(strcmp(w, "target") == 0){
5393: - SUB("$?")
5394: - } else if(strcmp(w, "stem") == 0){
5395: - SUB(j->stem)
5396: - } else if(strcmp(w, "prereq") == 0){
5397: - SUB("$@")
5398: - } else if(strcmp(w, "pid") == 0){
5399: - SUB("$$$$")
5400: - } else if(strcmp(w, "newprereq") == 0){
5401: - SUB(wtos(j->np))
5402: - } else if(strcmp(w, "alltarget") == 0){
5403: - SUB(wtos(j->at))
5404: - Fprint(2, "Warning; $alltarget expanded to '%s'\n", wtos(j->at));
5405: - } else if((strncmp(w, "stem", 4) == 0) && (w[4] >= '0') && (w[4] <= '9')){
5406: - int i = w[4] - '0';
5407: - int nb = j->match[i].ep - j->match[i].sp;
5408: -
5409: - memcpy(dest, j->match[i].sp, nb);
5410: - dest += nb;
5411: - } else {
5412: - SUB("1");
5413: - Fprint(2, "Warning; $%s expanded to 1\n", w);
5414: - }
5415: - }
5416: - if(copy){
5417: - *dest++ = '$';
5418: - *dest++ = '{';
5419: - for(q = w; q != s;)
5420: - *dest++ = *q++;
5421: - *dest++ = '}';
5422: - }
5423: - *s = carry;
5424: - if(carry == '}')
5425: - s++;
5426: - *ww = s;
5427: - return(dest);
5428: -}
5429: -
5430: -static
5431: -recipepr(s, j)
5432: - char *s;
5433: - Job *j;
5434: -{
5435: - char buf[BIGBLOCK];
5436: - register char *q = buf;
5437: -
5438: - while(*s)
5439: - switch(*s)
5440: - {
5441: - case '\\':
5442: - *q++ = *s++;
5443: - *q++ = *s++;
5444: - break;
5445: - case '$':
5446: - q = vexpand(&s, q, j);
5447: - break;
5448: - case '\n':
5449: - *q = 0;
5450: - Fprint(1, "\t%s\n", buf);
5451: - q = buf;
5452: - s++;
5453: - break;
5454: - default:
5455: - *q++ = *s++;
5456: - break;
5457: - }
5458: - *q = 0;
5459: - if(q != buf)
5460: - Fprint(1, "\t%s\n", buf);
5461: -}
5462: -
5463: -static void
5464: -nd(s)
5465: - Symtab *s;
5466: -{
5467: - Job *j = (Job *)s->value;
5468: - register Node *n = j->n;
5469: - Arc *a;
5470: - int i;
5471: - char *ss, *s, c;
5472: -
5473: - if(strcmp(n->name, first) == 0){
5474: - if(didit)
5475: - return;
5476: - didit = 1;
5477: - }
5478: - Fprint(1, "\n%s:", n->name);
5479: - fold(wtos(j->p), ' ');
5480: - Fputc(1, '\n');
5481: - recipepr(j->r->recipe, j);
5482: -}
5483: -
5484: -makefile()
5485: -{
5486: - symtraverse(S_MAKEVAR, vd);
5487: - didit = 0;
5488: - nd(symlook(first, S_MAKEFILE, (char *)0));
5489: - symtraverse(S_MAKEFILE, nd);
5490: -}
5491: //GO.SYSIN DD ./makefile.c
5492: echo ./match.c 1>&2
5493: sed 's/.//' >./match.c <<'//GO.SYSIN DD ./match.c'
5494: -#include "mk.h"
5495: -
5496: -mninlist(name, list, stem)
5497: - register char *name, *stem;
5498: - Word *list;
5499: -{
5500: - for(; list; list = list->next){
5501: - if(match(name, list->s, stem))
5502: - return(1);
5503: - }
5504: - return(0);
5505: -}
5506: -
5507: -static
5508: -isatomic(p)
5509: - char *p;
5510: -{
5511: - while(*p){
5512: - if((*p == '.') || (*p == '/'))
5513: - return(0);
5514: - p++;
5515: - }
5516: - return(1);
5517: -}
5518: -
5519: -match(name, template, stem)
5520: - char *name, *template, *stem;
5521: -{
5522: - register char *p, *q;
5523: - char *b;
5524: - char *ostem = stem;
5525: -
5526: - for(p = name, q = template; *p && *q && !PERCENT(*q);)
5527: - if(*p++ != *q++) return(0);
5528: - if(!PERCENT(*q))
5529: - return(0);
5530: - b = p;
5531: - while(*p) p++;
5532: - while(*q) q++;
5533: - for(q--; !PERCENT(*q); q--)
5534: - if(*--p != *q) return(0);
5535: - while(b < p)
5536: - *stem++ = *b++;
5537: - *stem = 0;
5538: - if(*q == '&')
5539: - return(isatomic(ostem));
5540: - return(1);
5541: -}
5542: -
5543: -subst(stem, template, dest)
5544: - register char *stem, *template, *dest;
5545: -{
5546: - while(*template){
5547: - if(PERCENT(*template)){
5548: - template++;
5549: - while(*stem)
5550: - *dest++ = *stem++;
5551: - } else
5552: - *dest++ = *template++;
5553: - }
5554: - *dest = 0;
5555: -}
5556: //GO.SYSIN DD ./match.c
5557: echo ./mk.c 1>&2
5558: sed 's/.//' >./mk.c <<'//GO.SYSIN DD ./mk.c'
5559: -#include "mk.h"
5560: -
5561: -int runerrs;
5562: -
5563: -mk(target)
5564: - char *target;
5565: -{
5566: - Node *node;
5567: - int did = 0;
5568: -
5569: - nproc(); /* it can be updated dynamically */
5570: - nrep(); /* it can be updated dynamically */
5571: - runerrs = 0;
5572: - if(mflag)
5573: - maketarget(target);
5574: - node = graph(target);
5575: - if(DEBUG(D_GRAPH)){
5576: - dumpn("new target\n", node);
5577: - Fflush(1);
5578: - }
5579: - clrmade(node);
5580: - while(node->flags&NOTMADE){
5581: - if(work(node, (Node *)0, (Arc *)0))
5582: - did = 1; /* found something to do */
5583: - else {
5584: - if(waitup(1, (int *)0) > 0){
5585: - if(node->flags&(NOTMADE|BEINGMADE)){
5586: - assert("must be run errors", runerrs);
5587: - break; /* nothing more waiting */
5588: - }
5589: - }
5590: - }
5591: - }
5592: - if(node->flags&BEINGMADE)
5593: - waitup(-1, (int *)0);
5594: - while(jobs)
5595: - waitup(-2, (int *)0);
5596: - assert("target didn't get done", runerrs || (node->flags&MADE));
5597: - if(did == 0)
5598: - Fprint(1, "mk: '%s' is up to date\n", node->name);
5599: -}
5600: -
5601: -clrmade(n)
5602: - register Node *n;
5603: -{
5604: - register Arc *a;
5605: -
5606: - n->flags &= ~(CANPRETEND|PRETENDING);
5607: - n->flags |= CANPRETEND;
5608: - MADESET(n, NOTMADE);
5609: - for(a = n->prereqs; a; a = a->next)
5610: - if(a->n)
5611: - clrmade(a->n);
5612: -}
5613: -
5614: -static void
5615: -unpretend(n)
5616: - register Node *n;
5617: -{
5618: - MADESET(n, NOTMADE);
5619: - n->flags &= ~(CANPRETEND|PRETENDING);
5620: - n->time = 0;
5621: -}
5622: -
5623: -work(node, p, parc)
5624: - Node *node, *p;
5625: - Arc *parc;
5626: -{
5627: - register Arc *a, *ra;
5628: - int weoutofdate;
5629: - int ready;
5630: - int did = 0;
5631: -
5632: -/* print("work(%s) flags=0x%x time=%ld\n", node->name, node->flags, node->time);/**/
5633: - if(node->flags&BEINGMADE)
5634: - return(did);
5635: - if((node->flags&MADE) && (node->flags&PRETENDING) && p && outofdate(p, parc, 0)){
5636: - if(explain)
5637: - fprint(1, "unpretending %s(%ld) because %s is out of date(%ld)\n",
5638: - node->name, node->time, p->name, p->time);
5639: - unpretend(node);
5640: - }
5641: - /*
5642: - have a look if we are pretending in case
5643: - someone has been unpretended out from underneath us
5644: - */
5645: - if(node->flags&MADE){
5646: - if(node->flags&PRETENDING){
5647: - node->time = 0;
5648: - }else
5649: - return(did);
5650: - }
5651: - /* consider no prerequsite case */
5652: - if(node->prereqs == 0){
5653: - if(node->time == 0){
5654: - Fprint(2, "mk: don't know how to make '%s'\n", node->name);
5655: - if(kflag){
5656: - node->flags |= BEINGMADE;
5657: - runerrs++;
5658: - } else
5659: - Exit();
5660: - } else
5661: - MADESET(node, MADE);
5662: - return(did);
5663: - }
5664: - /*
5665: - now see if we are out of date or what
5666: - */
5667: - ready = 1;
5668: - weoutofdate = aflag;
5669: - ra = 0;
5670: - for(a = node->prereqs; a; a = a->next)
5671: - if(a->n){
5672: - did = work(a->n, node, a) || did;
5673: - if(a->n->flags&(NOTMADE|BEINGMADE))
5674: - ready = 0;
5675: - if(outofdate(node, a, 0)){
5676: - weoutofdate = 1;
5677: - if((ra == 0) || (ra->n == 0)
5678: - || (ra->n->time < a->n->time))
5679: - ra = a;
5680: - }
5681: - } else {
5682: - if(node->time == 0){
5683: - if(ra == 0)
5684: - ra = a;
5685: - weoutofdate = 1;
5686: - }
5687: - }
5688: - if(ready == 0) /* can't do anything now */
5689: - return(did);
5690: - if(weoutofdate == 0){
5691: - MADESET(node, MADE);
5692: - return(did);
5693: - }
5694: - /*
5695: - can we pretend to be made?
5696: - */
5697: - if((iflag == 0) && (node->time == 0) && (node->flags&(PRETENDING|CANPRETEND)) && p && ra->n && !outofdate(p, ra, 0)){
5698: - node->flags &= ~CANPRETEND;
5699: - MADESET(node, MADE);
5700: - node->time = ra->n->time;
5701: - if(explain && ((node->flags&PRETENDING) == 0))
5702: - fprint(1, "pretending %s has time %ld\n", node->name, node->time);
5703: - node->flags |= PRETENDING;
5704: - return(did);
5705: - }
5706: - /*
5707: - node is out of date and we REALLY do have to do something.
5708: - quickly rescan for pretenders
5709: - */
5710: - for(a = node->prereqs; a; a = a->next)
5711: - if(a->n && (a->n->flags&PRETENDING)){
5712: - if(explain)
5713: - Fprint(1, "unpretending %s because of %s because of %s\n",
5714: - a->n->name, node->name, ra->n? ra->n->name : "rule with no prerequisites");
5715: -
5716: - unpretend(a->n);
5717: - did = work(a->n, node, a) || did;
5718: - ready = 0;
5719: - }
5720: - if(ready == 0) /* try later unless nothing has happened for -k's sake */
5721: - return(did || work(node, p, parc));
5722: - did = dorecipe(node) || did;
5723: - return(did);
5724: -}
5725: -
5726: -update(fake, node)
5727: - register Node *node;
5728: -{
5729: - register Arc *a;
5730: -
5731: - MADESET(node, fake? BEINGMADE : MADE);
5732: - if(((node->flags&VIRTUAL) == 0) && (access(node->name, 0) == 0)){
5733: - node->time = timeof(node->name, 1);
5734: - node->flags &= ~(CANPRETEND|PRETENDING);
5735: - for(a = node->prereqs; a; a = a->next)
5736: - if(a->prog)
5737: - (void)outofdate(node, a, 1);
5738: - } else {
5739: - node->time = 1;
5740: - for(a = node->prereqs; a; a = a->next)
5741: - if(a->n && outofdate(node, a, 1))
5742: - node->time = a->n->time;
5743: - }
5744: -/* print("----node %s time=%ld flags=0x%x\n", node->name, node->time, node->flags);/**/
5745: -}
5746: -
5747: -static
5748: -pcmp(prog, n1, n2)
5749: - char *prog, *n1, *n2;
5750: -{
5751: - char buf[3*NAMEBLOCK];
5752: - int ret, pid;
5753: -
5754: - pid = fork();
5755: - if(pid < 0){
5756: - fprint(2, "mk: ");
5757: - perror("pcmp fork");
5758: - Exit();
5759: - }
5760: - Fexit(0);
5761: - if(pid == 0){
5762: - sprint(buf, "%s '%s' '%s'", prog, n1, n2);
5763: - execl(SHELL, "sh", "-c", buf, (char *)0);
5764: - sprint(buf, "exec %s", SHELL);
5765: - perror(buf);
5766: - _exit(1);
5767: - } else {
5768: - while(waitup(-3, &pid) >= 0)
5769: - ;
5770: - return(pid? 2:1);
5771: - }
5772: -}
5773: -
5774: -
5775: -outofdate(node, arc, eval)
5776: - register Node *node;
5777: - register Arc *arc;
5778: -{
5779: - char buf[3*NAMEBLOCK], *str;
5780: - Symtab *sym;
5781: - int ret;
5782: -
5783: - if(arc->prog){
5784: - sprint(buf, "%s%c%s", node->name, 0377, arc->n->name);
5785: - if(!(sym = symlook(buf, S_OUTOFDATE, (char *)0)) || eval){
5786: - if(!sym)
5787: - str = strdup(buf);
5788: - ret = pcmp(arc->prog, node->name, arc->n->name);
5789: - if(sym)
5790: - sym->value = (char *)ret;
5791: - else
5792: - symlook(str, S_OUTOFDATE, (char *)ret);
5793: - } else
5794: - ret = (int)sym->value;
5795: - return(ret-1);
5796: - } else
5797: - return(node->time < arc->n->time);
5798: -}
5799: -
5800: //GO.SYSIN DD ./mk.c
5801: echo ./mk.h 1>&2
5802: sed 's/.//' >./mk.h <<'//GO.SYSIN DD ./mk.h'
5803: -#include "libc.h"
5804: -#include "fio.h"
5805: -#include "regexp.h"
5806: -
5807: -typedef struct Word
5808: -{
5809: - char *s;
5810: - struct Word *next;
5811: -} Word;
5812: -extern Word *newword(), *expand(), *wsubst(), *stow();
5813: -
5814: -typedef struct Rule
5815: -{
5816: - char *target; /* one target */
5817: - Word *tail; /* constituents of targets */
5818: - char *recipe; /* do it ! */
5819: - short attr; /* attributes */
5820: - short line; /* source line */
5821: - char *file; /* source file */
5822: - Word *alltargets; /* all the targets */
5823: - int rule; /* rule number */
5824: - regexp *pat; /* reg exp goo */
5825: - char *prog; /* to use in out of date */
5826: - struct Rule *chain; /* hashed per target */
5827: - struct Rule *next;
5828: -} Rule;
5829: -extern Rule *rules, *metarules, *patrule;
5830: -
5831: -#define META 0x0001
5832: -#define SEQ 0x0002
5833: -#define UPD 0x0004
5834: -#define RED 0x0008
5835: -#define QUIET 0x0010
5836: -#define VIR 0x0020
5837: -#define REGEXP 0x0040
5838: -#define NOREC 0x0080
5839: -#define DEL 0x0100
5840: -
5841: -#define NREGEXP 10
5842: -
5843: -typedef struct Arc
5844: -{
5845: - short flag;
5846: - struct Node *n;
5847: - Rule *r;
5848: - char *stem;
5849: - char *prog;
5850: - regsubexp match[NREGEXP];
5851: - struct Arc *next;
5852: -} Arc;
5853: -extern Arc *newarc();
5854: -#define TOGO 1
5855: -
5856: -typedef struct Node
5857: -{
5858: - char *name;
5859: - long time;
5860: - unsigned short flags;
5861: - Arc *prereqs;
5862: - struct Node *next; /* list for a rule */
5863: -} Node;
5864: -extern Node *graph();
5865: -#define VIRTUAL 0x0001
5866: -#define CYCLE 0x0002
5867: -#define READY 0x0004
5868: -#define CANPRETEND 0x0008
5869: -#define PRETENDING 0x0010
5870: -#define NOTMADE 0x0020
5871: -#define BEINGMADE 0x0040
5872: -#define MADE 0x0080
5873: -#define MADESET(n,m) n->flags = (n->flags&~(NOTMADE|BEINGMADE|MADE))|(m)
5874: -#define PROBABLE 0x0100
5875: -#define VACUOUS 0x0200
5876: -#define NORECIPE 0x0400
5877: -#define DELETE 0x0800
5878: -
5879: -typedef struct Job
5880: -{
5881: - Rule *r; /* master rule for job */
5882: - Node *n; /* list of node targets */
5883: - char *stem;
5884: - regsubexp *match;
5885: - Word *p; /* prerequisites */
5886: - Word *np; /* new prerequisites */
5887: - Word *t; /* targets */
5888: - Word *at; /* all targets */
5889: - int nproc; /* slot number */
5890: - int fd; /* if redirecting */
5891: - struct Job *next;
5892: -} Job;
5893: -extern Job *newjob(), *jobs;
5894: -
5895: -typedef struct Symtab
5896: -{
5897: - short space;
5898: - char *name;
5899: - char *value;
5900: - struct Symtab *next;
5901: -} Symtab;
5902: -extern Symtab *symlook();
5903: -enum {
5904: - S_VAR, /* variable -> value */
5905: - S_TARGET, /* target -> rule */
5906: - S_TIME, /* file -> time */
5907: - S_PID, /* pid -> products */
5908: - S_NODE, /* target name -> node */
5909: - S_AGG, /* aggregate -> time */
5910: - S_BITCH, /* bitched about aggregate not there */
5911: - S_NOEXPORT, /* var -> noexport */
5912: - S_OVERRIDE, /* can't override */
5913: - S_OUTOFDATE, /* n1\377n2 -> 2(outofdate) or 1(not outofdate) */
5914: - S_MAKEFILE, /* target -> node */
5915: - S_MAKEVAR, /* dumpable mk variable */
5916: -};
5917: -
5918: -extern int debug;
5919: -extern int nflag, tflag, iflag, kflag, aflag, mflag;
5920: -extern int inline;
5921: -extern char *infile;
5922: -extern char *Malloc(), *strndup();
5923: -extern long timeof();
5924: -extern void touch(), delete();
5925: -extern char *shname(), *vexpand();
5926: -extern int nproclimit;
5927: -extern int nreps;
5928: -extern char *explain;
5929: -extern char *envpr(), *wtos();
5930: -extern char *rulecnt();
5931: -
5932: -#define SYNERR(l) (Fprint(2, "mk: %s:%d: syntax error; ", infile, (((l)>=0)?(l):inline)))
5933: -#define RERR(r) (Fprint(2, "mk: %s:%d: rule error; ", (r)->file, (r)->line))
5934: -#define NAMEBLOCK 1000
5935: -#define BIGBLOCK 20000
5936: -
5937: -#ifndef SHELL
5938: -#define SHELL "/bin/sh" /* should be bourne-like */
5939: -#endif
5940: -
5941: -#define SEP(c) (((c)==' ')||((c)=='\t')||((c)=='\n'))
5942: -
5943: -#define DEBUG(x) (debug&(x))
5944: -#define D_PARSE 0x01
5945: -#define D_GRAPH 0x02
5946: -#define D_EXEC 0x04
5947: -
5948: -#define EBIT 0x80 /* sorry japan */
5949: -
5950: -#define PERCENT(ch) (((ch) == '%') || ((ch) == '&'))
5951: //GO.SYSIN DD ./mk.h
5952: echo ./parse.c 1>&2
5953: sed 's/.//' >./parse.c <<'//GO.SYSIN DD ./parse.c'
5954: -#include "mk.h"
5955: -
5956: -char *infile;
5957: -int inline;
5958: -static longline();
5959: -extern Word *target1;
5960: -
5961: -parse(f, fd, varoverride, ruleoverride)
5962: - char *f;
5963: -{
5964: - int hline;
5965: - char *s, *body;
5966: - Word *head, *tail;
5967: - int attr, set;
5968: - char *prog, *inc;
5969: -
5970: - if(fd < 0){
5971: - perror(f);
5972: - Exit();
5973: - }
5974: - ipush();
5975: - infile = strdup(f);
5976: - inline = 1;
5977: - Finit(fd, (char *)0);
5978: - while(s = Frdline(fd)){
5979: - if((*s == '#') || (*s == 0)){
5980: - inline++;
5981: - continue;
5982: - }
5983: - hline = inline;
5984: - switch(rhead(s, fd, &head, &tail, &attr, &prog))
5985: - {
5986: - case '<':
5987: - if((tail == 0) || ((inc = wtos(tail)) == 0)){
5988: - SYNERR(-1);
5989: - Fprint(2, "missing include file name\n");
5990: - Exit();
5991: - }
5992: - parse(inc, open(inc, 0), 0, 1);
5993: - break;
5994: - case ':':
5995: - rbody(fd, &body);
5996: - addrules(head, tail, body, attr, hline, ruleoverride, prog);
5997: - break;
5998: - case '=':
5999: - if(head->next){
6000: - SYNERR(-1);
6001: - Fprint(2, "multiple vars on left side of assignment\n");
6002: - Exit();
6003: - }
6004: - if(symlook(head->s, S_OVERRIDE, (char *)0)){
6005: - set = varoverride;
6006: - symdel(head->s, S_OVERRIDE);
6007: - } else {
6008: - set = 1;
6009: - if(varoverride)
6010: - symlook(head->s, S_OVERRIDE, "");
6011: - }
6012: - if(set)
6013: - setvar(head->s, wtos(tail));
6014: - if(attr)
6015: - (void)symlook(head->s, S_NOEXPORT, "");
6016: - break;
6017: - default:
6018: - SYNERR(hline);
6019: - Fprint(2, "expected : or =\n");
6020: - Exit();
6021: - break;
6022: - }
6023: - }
6024: - close(fd);
6025: - ipop();
6026: -}
6027: -
6028: -addrules(head, tail, body, attr, hline, override, prog)
6029: - Word *head, *tail;
6030: - char *body, *prog;
6031: -{
6032: - register Word *w;
6033: -
6034: - assert("addrules args", head && body);
6035: - if((target1 == 0) && !(attr®EXP))
6036: - frule(head);
6037: - for(w = head; w; w = w->next)
6038: - addrule(w->s, tail, body, head, attr, hline, override, prog);
6039: -}
6040: -
6041: -rhead(s, fd, h, t, attr, prog)
6042: - char *s;
6043: - Word **h, **t;
6044: - int *attr;
6045: - char **prog;
6046: -{
6047: - char buf[BIGBLOCK];
6048: - register char *p;
6049: - char *pp;
6050: - int sep;
6051: -
6052: - longline(fd, s, buf); /* cover \\n guys */
6053: - lex(fd, buf);
6054: - if(p = strchr(buf, '#')) /* comment ? */
6055: - *p = 0;
6056: - for(p = buf; *p; p++)
6057: - if((*p == ':') || (*p == '=') || (*p == '<')) break;
6058: - if(*p == 0){
6059: - return('?');
6060: - }
6061: - sep = *p;
6062: - *p++ = 0;
6063: - *attr = 0;
6064: - *prog = 0;
6065: - if(sep == '='){
6066: - char *le, *e;
6067: -
6068: - le = strchr(p, ' ');
6069: - if(e = strchr(p, '\t'))
6070: - if((le == 0) || (e < le))
6071: - le = e;
6072: - if((e = strchr(p, '=')) && ((le == 0) || (e < le))){
6073: - while(*p != '='){
6074: - switch(*p++)
6075: - {
6076: - case 0:
6077: - SYNERR(-1);
6078: - Fprint(2, "missing trailing =\n");
6079: - Exit();
6080: - default:
6081: - SYNERR(-1);
6082: - Fprint(2, "unknown attribute '%c'\n", p[-1]);
6083: - Exit();
6084: - case 'U':
6085: - *attr = 1;
6086: - break;
6087: - }
6088: - }
6089: - p++;
6090: - }
6091: - }
6092: - if((sep == ':') && *p && (*p != ' ') && (*p != '\t')){
6093: - while(*p != ':')
6094: - switch(*p++)
6095: - {
6096: - case 0:
6097: - eos:
6098: - SYNERR(-1);
6099: - Fprint(2, "missing trailing :\n");
6100: - Exit();
6101: - default:
6102: - SYNERR(-1);
6103: - Fprint(2, "unknown attribute '%c'\n", p[-1]);
6104: - Exit();
6105: - case '<':
6106: - *attr |= RED;
6107: - break;
6108: - case 'D':
6109: - *attr |= DEL;
6110: - break;
6111: - case 'N':
6112: - *attr |= NOREC;
6113: - break;
6114: - case 'P':
6115: - pp = p;
6116: - while(*p && (*p != ':'))
6117: - p++;
6118: - if(*p == 0)
6119: - goto eos;
6120: - *p = 0;
6121: - *prog = strdup(pp);
6122: - *p = ':';
6123: - break;
6124: - case 'Q':
6125: - *attr |= QUIET;
6126: - break;
6127: - case 'R':
6128: - *attr |= REGEXP;
6129: - break;
6130: - case 'U':
6131: - *attr |= UPD;
6132: - break;
6133: - case 'V':
6134: - *attr |= VIR;
6135: - break;
6136: - }
6137: - p++;
6138: - }
6139: - *h = expand(buf);
6140: - if((*h == 0) && (sep != '<')){
6141: - SYNERR(inline-1);
6142: - Fprint(2, "no var on left side of assignment/rule\n");
6143: - Exit();
6144: - }
6145: - while((*p == ' ') || (*p == '\t'))
6146: - p++;
6147: - *t = expand(p);
6148: - return(sep);
6149: -}
6150: -
6151: -rbody(fd, b)
6152: - char **b;
6153: -{
6154: - char buf[BIGBLOCK];
6155: - char *cp, *s;
6156: - register n;
6157: -
6158: - cp = buf;
6159: - while(s = Frdline(fd)){
6160: - inline++;
6161: - if((*s != '\t') && (*s != ' ')){
6162: - inline--;
6163: - Fundo(fd);
6164: - break;
6165: - }
6166: - memcpy(cp, s+1, n = FIOLINELEN(fd)-1);
6167: - cp += n;
6168: - *cp++ = '\n';
6169: - }
6170: - *cp++ = 0;
6171: - assert("rbody overflow", cp <= &buf[BIGBLOCK]);
6172: - *b = (buf[0])? strndup(buf, (int)(cp-buf)) : strdup("");
6173: -}
6174: -
6175: -static
6176: -longline(fd, line, dest)
6177: - register char *line, *dest;
6178: -{
6179: - for(;;){
6180: - inline++;
6181: - while(*dest++ = *line++);
6182: - dest -= 2;
6183: - if(*dest == '\\'){
6184: - *dest = 0;
6185: - if((line = Frdline(fd)) == 0){
6186: - Fundo(fd);
6187: - break;
6188: - }
6189: - } else
6190: - break;
6191: - }
6192: -}
6193: -
6194: -struct input
6195: -{
6196: - char *file;
6197: - int line;
6198: - struct input *next;
6199: -};
6200: -static struct input *inputs = 0;
6201: -
6202: -ipush()
6203: -{
6204: - register struct input *in, *me;
6205: -
6206: - me = (struct input *)Malloc(sizeof(*me));
6207: - me->file = infile;
6208: - me->line = inline;
6209: - me->next = 0;
6210: - if(inputs == 0)
6211: - inputs = me;
6212: - else {
6213: - for(in = inputs; in->next; )
6214: - in = in->next;
6215: - in->next = me;
6216: - }
6217: -}
6218: -
6219: -ipop()
6220: -{
6221: - register struct input *in, *me;
6222: -
6223: - assert("pop input list", inputs != 0);
6224: - if(inputs->next == 0){
6225: - me = inputs;
6226: - inputs = 0;
6227: - } else {
6228: - for(in = inputs; in->next->next; )
6229: - in = in->next;
6230: - me = in->next;
6231: - in->next = 0;
6232: - }
6233: - infile = me->file;
6234: - inline = me->line;
6235: - free((char *)me);
6236: -}
6237: //GO.SYSIN DD ./parse.c
6238: echo ./quote.c 1>&2
6239: sed 's/.//' >./quote.c <<'//GO.SYSIN DD ./quote.c'
6240: -#include "mk.h"
6241: -
6242: -/*
6243: - quoted stuff gets EBIT
6244: -*/
6245: -
6246: -static
6247: -squote(fd, srcp, destp)
6248: - char **srcp, **destp;
6249: -{
6250: - register char *src = *srcp, *dest = *destp;
6251: -
6252: - while(*src != '\''){
6253: - if(*src == 0){
6254: - char *s;
6255: -
6256: - if(s = Frdline(fd)){
6257: - inline++;
6258: - *dest++ = '\n'|EBIT;
6259: - strcpy(src, s);
6260: - continue;
6261: - } else {
6262: - SYNERR(-1); Fprint(2, "missing closing '\n");
6263: - break;
6264: - }
6265: - }
6266: - *dest++ = *src++|EBIT;
6267: - }
6268: - *dest = 0;
6269: - if(*src)
6270: - src++;
6271: - *srcp = src;
6272: - *destp = dest;
6273: -}
6274: -
6275: -static
6276: -dquote(fd, src, dest)
6277: - char **src, **dest;
6278: -{
6279: - char *p = *src, *s = *dest;
6280: - char *t, carry;
6281: - Symtab *sym;
6282: -
6283: - while(*p != '"'){
6284: - switch(*p)
6285: - {
6286: - case 0:
6287: - if(t = Frdline(fd)){
6288: - inline++;
6289: - *s++ = '\n'|EBIT;
6290: - strcpy(p, t);
6291: - continue;
6292: - } else {
6293: - SYNERR(-1); Fprint(2, "missing closing \"\n");
6294: - break;
6295: - }
6296: - break;
6297: - case '\\':
6298: - switch(*++p)
6299: - {
6300: - default:
6301: - *s++ = '\\'|EBIT;
6302: - case '\\': case '"':
6303: - case '\'': case '$':
6304: - *s++ = *p|EBIT;
6305: - }
6306: - p++;
6307: - break;
6308: - case '$':
6309: - varsub(&p, &s, EBIT);
6310: - break;
6311: - default:
6312: - *s++ = *p++|EBIT;
6313: - }
6314: - }
6315: - *s = 0;
6316: - if(*p)
6317: - p++;
6318: - *src = p;
6319: - *dest = s;
6320: -}
6321: -
6322: -quote1(fd, src, dest)
6323: - char *src, *dest;
6324: -{
6325: - char *t;
6326: -
6327: - while(*src){
6328: - switch(*src)
6329: - {
6330: - case '\'':
6331: - src++;
6332: - squote(fd, &src, &dest);
6333: - break;
6334: - case '\\':
6335: - if(src[1]){
6336: - *dest++ = *++src | EBIT;
6337: - src++;
6338: - } else if(t = Frdline(fd)){
6339: - inline++;
6340: - strcpy(src, t);
6341: - }
6342: - break;
6343: - default:
6344: - *dest++ = *src++;
6345: - }
6346: - }
6347: - *dest = 0;
6348: -}
6349: -
6350: -quote2(fd, src, dest)
6351: - char *src, *dest;
6352: -{
6353: - char *t;
6354: -
6355: - while(*src){
6356: - switch(*src)
6357: - {
6358: - case '"':
6359: - src++;
6360: - dquote(fd, &src, &dest);
6361: - break;
6362: - case '\\':
6363: - if(src[1]){
6364: - *dest++ = *++src;
6365: - src++;
6366: - } else if(t = Frdline(fd)){
6367: - inline++;
6368: - strcpy(src, t);
6369: - }
6370: - break;
6371: - case '$':
6372: - varsub(&src, &dest, 0);
6373: - break;
6374: - default:
6375: - *dest++ = *src++;
6376: - }
6377: - }
6378: - *dest = 0;
6379: -}
6380: -
6381: -static char *
6382: -subsub(val, ext, dest, bit)
6383: - char *val, *ext, *dest;
6384: -{
6385: - register char *s;
6386: - char *a, *b, *c, *d;
6387: - int na, nb, nc, nd, n;
6388: - int destsub = 0;
6389: -
6390: - /* prepare literals */
6391: - a = s = ext;
6392: - for(; *s && (*s != '=') && !PERCENT(*s); s++)
6393: - ;
6394: - na = s-a;
6395: - if(PERCENT(*s)) s++;
6396: - b = s;
6397: - for(; *s && (*s != '='); s++)
6398: - ;
6399: - nb = s-b;
6400: - if(*s == '=') s++;
6401: - c = s;
6402: - for(; *s && !PERCENT(*s); s++)
6403: - ;
6404: - nc = s-c;
6405: - if(PERCENT(*s)) s++, destsub = 1;
6406: - d = s;
6407: - for(; *s; s++)
6408: - ;
6409: - nd = s-d;
6410: - /* break into words, do sub */
6411: - while(*val){
6412: - for(s = val; *s && !SEP(*s); s++)
6413: - ;
6414: - /* substitute in val..s */
6415: - if((memcmp(val, a, na) == 0) && (memcmp(s-nb, b, nb) == 0)){
6416: -#define DEST(s,n) if(n) memcpy(dest,s,n), dest += n
6417: - DEST(c, nc);
6418: - n = (s-nb) - (val+na);
6419: - if(destsub)
6420: - DEST(val+na, n);
6421: - DEST(d, nd);
6422: - } else
6423: - while(val < s)
6424: - *dest++ = (*val++&~EBIT)|bit;
6425: - /* clean up */
6426: - while(*s && SEP(*s))
6427: - *dest++ = (*s++&~EBIT)|bit;
6428: - val = s;
6429: - }
6430: - return(dest);
6431: -}
6432: -
6433: -varsub(psrc, pdest, bit)
6434: - char **psrc, **pdest;
6435: -{
6436: - char *t, carry;
6437: - Symtab *sym;
6438: - char *src = *psrc, *dest = *pdest;
6439: - char *v = 0, vc;
6440: -
6441: - if(*++src == '{'){
6442: - for(t = ++src; *src != '}'; src++)
6443: - if(*src == 0){
6444: - SYNERR(-1);
6445: - Fprint(2, "missing '}'\n");
6446: - Exit();
6447: - }
6448: - v = shname(t);
6449: - if(src == v)
6450: - v = 0;
6451: - else {
6452: - if(*v != ':'){
6453: - SYNERR(-1);
6454: - Fprint(2, "bad variable name\n");
6455: - Exit();
6456: - }
6457: - vc = *v;
6458: - *v = 0;
6459: - }
6460: - *src++ = carry = 0;
6461: - } else {
6462: - src = shname(t = src);
6463: - carry = *src;
6464: - *src = 0;
6465: - }
6466: - if(sym = symlook(t, S_VAR, (char *)0)){
6467: - if(v){
6468: -char buf[BIGBLOCK]; strcpy(buf, v+1); lex(-1, buf);
6469: - dest = subsub(sym->value, buf, dest, bit);
6470: - *v = vc;
6471: - } else
6472: - for(t = sym->value; *t; )
6473: - *dest++ = *t++|bit;
6474: - }
6475: - if(carry)
6476: - *src = carry;
6477: - *psrc = src;
6478: - *pdest = dest;
6479: -}
6480: //GO.SYSIN DD ./quote.c
6481: echo ./recipe.c 1>&2
6482: sed 's/.//' >./recipe.c <<'//GO.SYSIN DD ./recipe.c'
6483: -#include "mk.h"
6484: -
6485: -dorecipe(node)
6486: - Node *node;
6487: -{
6488: - char buf[BIGBLOCK];
6489: - register Node *n;
6490: - Rule *r = 0;
6491: - Arc *a, *aa;
6492: - Word head, ahead, lp, ln, *w, *ww, *aw;
6493: - Symtab *s;
6494: - int did = 0;
6495: - regexp rmatch[NREGEXP];
6496: -
6497: - /*
6498: - pick up the rule
6499: - */
6500: - for(a = node->prereqs; a; a = a->next)
6501: - if(*a->r->recipe)
6502: - r = (aa = a)->r;
6503: - /*
6504: - no recipe? go to buggery!
6505: - */
6506: - if(r == 0){
6507: - if(!(node->flags&VIRTUAL) && !(node->flags&NORECIPE)){
6508: - Fprint(2, "mk: no recipe to make '%s'\n", node->name);
6509: - Exit();
6510: - }
6511: - update(0, node);
6512: - if(tflag){
6513: - if(!(node->flags&VIRTUAL))
6514: - touch(node->name);
6515: - else if(explain)
6516: - Fprint(1, "no touch of virtual '%s'\n", node->name);
6517: - }
6518: - return(did);
6519: - }
6520: - /*
6521: - build the node list
6522: - */
6523: - node->next = 0;
6524: - head.next = 0;
6525: - ww = &head;
6526: - ahead.next = 0;
6527: - aw = &ahead;
6528: - if(r->attr®EXP){
6529: - ww->next = newword(node->name);
6530: - aw->next = newword(node->name);
6531: - } else {
6532: - for(w = r->alltargets; w; w = w->next){
6533: - if(r->attr&META)
6534: - subst(aa->stem, w->s, buf);
6535: - else
6536: - strcpy(buf, w->s);
6537: - aw->next = newword(buf);
6538: - aw = aw->next;
6539: - if((s = symlook(buf, S_NODE, (char *)0)) == 0)
6540: - continue; /* not a node we are interested in */
6541: - n = (Node *)s->value;
6542: - ww->next = newword(buf);
6543: - ww = ww->next;
6544: - if(n == node) continue;
6545: - n->next = node->next;
6546: - node->next = n;
6547: - }
6548: - }
6549: - for(n = node; n; n = n->next)
6550: - if((n->flags&READY) == 0)
6551: - return(did);
6552: - /*
6553: - gather the params for the job
6554: - */
6555: - lp.next = ln.next = 0;
6556: - for(n = node; n; n = n->next){
6557: - for(a = n->prereqs; a; a = a->next){
6558: - if(a->n){
6559: - addw(&lp, a->n->name);
6560: - if(outofdate(n, a, 0)){
6561: - addw(&ln, a->n->name);
6562: - if(explain)
6563: - fprint(1, "%s(%ld) < %s(%ld)\n",
6564: - n->name, n->time, a->n->name, a->n->time);
6565: - }
6566: - } else {
6567: - if(explain)
6568: - fprint(1, "%s has no prerequisites\n",
6569: - n->name);
6570: - }
6571: - }
6572: - MADESET(n, BEINGMADE);
6573: - }
6574: -/* print("lt=%s ln=%s lp=%s\n",wtos(head.next),wtos(ln.next),wtos(lp.next));/**/
6575: - run(newjob(r, node, aa->stem, aa->match, lp.next, ln.next, head.next, ahead.next));
6576: - return(1);
6577: -}
6578: -
6579: -addw(w, s)
6580: - register Word *w;
6581: - char *s;
6582: -{
6583: - register Word *lw;
6584: -
6585: - for(lw = w; w = w->next; lw = w){
6586: - if(strcmp(s, w->s) == 0)
6587: - return;
6588: - }
6589: - lw->next = newword(s);
6590: -}
6591: //GO.SYSIN DD ./recipe.c
6592: echo ./regexp.c 1>&2
6593: sed 's/.//' >./regexp.c <<'//GO.SYSIN DD ./regexp.c'
6594: -#include "mk.h"
6595: -
6596: -Rule *patrule;
6597: -
6598: -regerror(s)
6599: - char *s;
6600: -{
6601: - if(patrule)
6602: - Fprint(2, "mk: %s:%d: regular expression error; %s\n",
6603: - patrule->file, patrule->line, s);
6604: - else
6605: - Fprint(2, "mk: %s:%d: regular expression error; %s\n",
6606: - infile, inline, s);
6607: - Exit();
6608: -}
6609: -
6610: -rsub(src, r, a, proto, dest)
6611: - char *src, *dest, *proto;
6612: - Rule *r;
6613: - Arc *a;
6614: -{
6615: - rdump("rsub", a->match);
6616: - print("rsub(src=%d '%s' proto=%d '%s')\n", src, src, proto, proto);
6617: - *dest = 0;
6618: -}
6619: -
6620: -rdump(s, m)
6621: - char *s;
6622: - register regsubexp *m;
6623: -{
6624: - register i;
6625: -
6626: - print("rdump: %s\n", s);
6627: - for(i = 0; i < NREGEXP; i++, m++)
6628: - print("\t%d: %d - %d '%s'\n", i, m->sp, m->ep, m->sp);
6629: -}
6630: //GO.SYSIN DD ./regexp.c
6631: echo ./rule.c 1>&2
6632: sed 's/.//' >./rule.c <<'//GO.SYSIN DD ./rule.c'
6633: -#include "mk.h"
6634: -
6635: -static Rule *lr, *lmr;
6636: -static rcmp();
6637: -static int nrules = 0;
6638: -
6639: -addrule(head, tail, body, ahead, attr, hline, override, prog)
6640: - Word *tail, *ahead;
6641: - char *head, *body, *prog;
6642: -{
6643: - register Rule *r;
6644: - Rule *rr;
6645: - Symtab *sym;
6646: - int reuse;
6647: -
6648: - if(sym = symlook(head, S_TARGET, (char *)0)){
6649: - for(r = (Rule *)sym->value; r; r = r->chain)
6650: - if(rcmp(r, head, tail) == 0) break;
6651: - if(r && !override)
6652: - return;
6653: - } else
6654: - r = 0;
6655: - reuse = r != 0;
6656: - if(r == 0)
6657: - r = (Rule *)Malloc(sizeof(Rule));
6658: - r->target = head;
6659: - r->tail = tail;
6660: - r->recipe = body;
6661: - r->line = hline;
6662: - r->file = infile;
6663: - r->attr = attr;
6664: - r->alltargets = ahead;
6665: - r->prog = prog;
6666: - r->rule = nrules++;
6667: - if(!reuse){
6668: - rr = (Rule *)symlook(head, S_TARGET, (char *)r)->value;
6669: - if(rr != r){
6670: - r->chain = rr->chain;
6671: - rr->chain = r;
6672: - } else
6673: - r->chain = 0;
6674: - }
6675: - if(strchr(head, '%') || strchr(head, '&') || (attr®EXP))
6676: - goto meta;
6677: - if(reuse)
6678: - return;
6679: - r->next = 0;
6680: - r->pat = 0;
6681: - if(rules == 0)
6682: - rules = lr = r;
6683: - else {
6684: - lr->next = r;
6685: - lr = r;
6686: - }
6687: - return;
6688: -meta:
6689: - r->attr |= META;
6690: - if(reuse)
6691: - return;
6692: - r->next = 0;
6693: - if(r->attr®EXP){
6694: - patrule = r;
6695: - r->pat = regcomp(head);
6696: - }
6697: - if(metarules == 0)
6698: - metarules = lmr = r;
6699: - else {
6700: - lmr->next = r;
6701: - lmr = r;
6702: - }
6703: -}
6704: -
6705: -dumpr(s, r)
6706: - char *s;
6707: - register Rule *r;
6708: -{
6709: - Fprint(1, "%s: start=%ld\n", s, r);
6710: - for(; r; r = r->next){
6711: - Fprint(1, "\tRule %ld: %s[%d] attr=%x next=%ld chain=%ld alltarget='%s'",
6712: - r, r->file, r->line, r->attr, r->next, r->chain, wtos(r->alltargets));
6713: - if(r->prog)
6714: - Fprint(1, " prog='%s'", r->prog);
6715: - Fprint(1, "\n\ttarget=%s: %s\n", r->target, wtos(r->tail));
6716: - Fprint(1, "\trecipe@%ld='%s'\n", r->recipe, r->recipe);
6717: - }
6718: -}
6719: -
6720: -frule(w)
6721: - Word *w;
6722: -{
6723: - extern Word *target1;
6724: - register Word *ww;
6725: - register char *s;
6726: -
6727: -#define ADD(s) {if(target1==0)target1=ww=newword(s);else ww=ww->next=newword(s);}
6728: -
6729: - for(ww = w; ww; ww = ww->next)
6730: - if(strchr(w->s, '%') || strchr(w->s, '&'))
6731: - return; /* no metarule targets */
6732: - while(w){
6733: - if(s = strchr(w->s, '+')){
6734: - *s++ = 0;
6735: - if(*w->s)
6736: - ADD(w->s);
6737: - if(*s)
6738: - ADD(s);
6739: - s[-1] = '+';
6740: - } else
6741: - ADD(w->s);
6742: - w = w->next;
6743: - }
6744: -}
6745: -
6746: -static
6747: -rcmp(r, target, tail)
6748: - register Rule *r;
6749: - char *target;
6750: - register Word *tail;
6751: -{
6752: - register Word *w;
6753: -
6754: - if(strcmp(r->target, target))
6755: - return(1);
6756: - for(w = r->tail; w && tail; w = w->next, tail = tail->next)
6757: - if(strcmp(w->s, tail->s))
6758: - return(1);
6759: - return(w || tail);
6760: -}
6761: -
6762: -char *
6763: -rulecnt()
6764: -{
6765: - register char *s;
6766: -
6767: - s = Malloc(nrules);
6768: - memset(s, 0, nrules);
6769: - return(s);
6770: -}
6771: -
6772: -ismeta(s)
6773: - register char *s;
6774: -{
6775: - for(; *s; s++)
6776: - switch(*s)
6777: - {
6778: - case '\\':
6779: - if(s[1])
6780: - s++;
6781: - break;
6782: - case '[':
6783: - case '*':
6784: - case '?':
6785: - return(1);
6786: - break;
6787: - }
6788: - return(0);
6789: -}
6790: //GO.SYSIN DD ./rule.c
6791: echo ./run.c 1>&2
6792: sed 's/.//' >./run.c <<'//GO.SYSIN DD ./run.c'
6793: -#include "mk.h"
6794: -
6795: -typedef struct Event
6796: -{
6797: - int pid;
6798: - Job *job;
6799: -} Event;
6800: -static Event *events;
6801: -static int nevents, nrunning;
6802: -typedef struct Process
6803: -{
6804: - int pid;
6805: - int status;
6806: - struct Process *b, *f;
6807: -} Process;
6808: -static Process *phead, *pfree;
6809: -static void pnew(), pdelete();
6810: -static char *envy[1024];
6811: -static char **special;
6812: -static pidslot();
6813: -
6814: -run(j)
6815: - Job *j;
6816: -{
6817: - register Job *jj;
6818: -
6819: - if(jobs){
6820: - for(jj = jobs; jj->next; jj = jj->next)
6821: - ;
6822: - jj->next = j;
6823: - } else
6824: - jobs = j;
6825: - j->next = 0;
6826: - /* this code also in waitup after parse redirect */
6827: - if(nrunning < nproclimit)
6828: - sched();
6829: -}
6830: -
6831: -sched()
6832: -{
6833: - register Job *j;
6834: - char buf[BIGBLOCK];
6835: - int slot, pip[2], pid;
6836: - Node *n;
6837: -
6838: - if(jobs == 0){
6839: - account();
6840: - return;
6841: - }
6842: - j = jobs;
6843: - jobs = j->next;
6844: - if(DEBUG(D_EXEC))
6845: - fprint(1, "firing up job for target %s\n", wtos(j->t));
6846: - slot = nextslot();
6847: - events[slot].job = j;
6848: - dovars(j, slot);
6849: - shprint(j->r->recipe, envy, buf);
6850: - if(!tflag && !mflag && (nflag || !(j->r->attr&QUIET)))
6851: - Fwrite(1, buf, (long)strlen(buf));
6852: - if(mflag){
6853: - for(n = j->n; n; n = n->next)
6854: - symlook(n->name, S_MAKEFILE, (char *)j);
6855: - }
6856: - if(nflag||tflag){
6857: - for(n = j->n; n; n = n->next){
6858: - if(tflag){
6859: - if(!(n->flags&VIRTUAL))
6860: - touch(n->name);
6861: - else if(explain)
6862: - Fprint(1, "no touch of virtual '%s'\n", n->name);
6863: - }
6864: - n->time = time((long *)0);
6865: - MADESET(n, MADE);
6866: - }
6867: - } else {
6868: - Fexit(0);
6869: - if(j->r->attr&RED){
6870: - if(pipe(pip) < 0){
6871: - perror("pipe");
6872: - Exit();
6873: - }
6874: - }
6875: - if((pid = fork()) < 0){
6876: - perror("mk fork");
6877: - Exit();
6878: - }
6879: - if(pid == 0){
6880: - if(j->r->attr&RED){
6881: - close(pip[0]);
6882: - dup2(pip[1], 1);
6883: - close(pip[1]);
6884: - }
6885: - if(pipe(pip) < 0){
6886: - perror("pipe-i");
6887: - Exit();
6888: - }
6889: - if((pid = fork()) < 0){
6890: - perror("mk fork");
6891: - Exit();
6892: - }
6893: - if(pid != 0){
6894: - close(pip[1]);
6895: - dup2(pip[0], 0);
6896: - close(pip[0]);
6897: - execle(SHELL, "sh", "-e", (char *)0, envy);
6898: - perror(SHELL);
6899: - _exit(1);
6900: - } else {
6901: - int k;
6902: - char *s, *send;
6903: -
6904: - close(pip[0]);
6905: - s = j->r->recipe;
6906: - send = s+strlen(s);
6907: - while(s < send){
6908: - if((k = write(pip[1], s, send-s)) < 0)
6909: - break;
6910: - s += k;
6911: - }
6912: - _exit(0);
6913: - }
6914: - }
6915: - account();
6916: - nrunning++;
6917: - if(j->r->attr&RED)
6918: - close(pip[1]), j->fd = pip[0];
6919: - else
6920: - j->fd = -1;
6921: - if(DEBUG(D_EXEC))
6922: - fprint(1, "pid for target %s = %d\n", wtos(j->t), pid);
6923: - events[slot].pid = pid;
6924: - }
6925: -}
6926: -
6927: -waitup(echildok, retstatus)
6928: - int *retstatus;
6929: -{
6930: - int status, pid;
6931: - int slot;
6932: - Symtab *s;
6933: - Word *w;
6934: - Job *j;
6935: - char buf[64];
6936: - char buf1[BIGBLOCK];
6937: - int uarg = 0;
6938: - int done;
6939: - Node *n;
6940: - Process *p;
6941: - extern int errno, runerrs;
6942: -
6943: - /* first check against the proces slist */
6944: - if(retstatus)
6945: - for(p = phead; p; p = p->f)
6946: - if(p->pid == *retstatus){
6947: - *retstatus = p->status;
6948: - pdelete(p);
6949: - return(-1);
6950: - }
6951: -again: /* rogue processes */
6952: - if((pid = wait(&status)) < 0){
6953: - if(echildok > 0){
6954: - return(1);
6955: - } else {
6956: - fprint(2, "mk: (waitup %d) ", echildok);
6957: - perror("mk wait");
6958: - Exit();
6959: - }
6960: - }
6961: - if(DEBUG(D_EXEC))
6962: - fprint(1, "waitup got pid=%d, status=0x%ux\n", pid, status);
6963: - if(retstatus && (pid == *retstatus)){
6964: - *retstatus = status;
6965: - return(-1);
6966: - }
6967: - slot = pidslot(pid);
6968: - if(slot < 0){
6969: - if(DEBUG(D_EXEC))
6970: - fprint(2, "mk: wait returned unexpected process %d\n", pid);
6971: - pnew(pid, status);
6972: - goto again;
6973: - }
6974: - j = events[slot].job;
6975: - account();
6976: - nrunning--;
6977: - events[slot].pid = -1;
6978: - if(status){
6979: - dovars(j, slot);
6980: - shprint(j->r->recipe, envy, buf1);
6981: - front(buf1);
6982: - Fprint(2, "mk: %s: exit status=%d", buf1, 0xFF&(status>>8));
6983: - status &= 0xFF;
6984: - if(status&0x7F)
6985: - Fprint(2, " signal=%d", status&0x7F);
6986: - if(status&0x80)
6987: - Fprint(2, ", core dumped");
6988: - for(n = j->n, done = 0; n; n = n->next)
6989: - if(n->flags&DELETE){
6990: - if(done++ == 0)
6991: - Fprint(2, ", deleting");
6992: - Fprint(2, " '%s'", n->name);
6993: - }
6994: - Fputc(2, '\n');
6995: - for(n = j->n, done = 0; n; n = n->next)
6996: - if(n->flags&DELETE){
6997: - if(done++ == 0)
6998: - Fflush(2);
6999: - delete(n->name);
7000: - }
7001: - if(kflag){
7002: - runerrs++;
7003: - uarg = 1;
7004: - Fflush(2);
7005: - } else {
7006: - jobs = 0;
7007: - Exit();
7008: - }
7009: - }
7010: - if(j->fd >= 0){
7011: - sprint(buf, "process %d", pid);
7012: - parse(buf, j->fd, 0, 0);
7013: - execinit(); /* reread environ */
7014: - nproc();
7015: - while(jobs && (nrunning < nproclimit))
7016: - sched();
7017: - }
7018: - for(w = j->t; w; w = w->next){
7019: - if((s = symlook(w->s, S_NODE, (char *)0)) == 0)
7020: - continue; /* not interested in this node */
7021: - update(uarg, (Node *)s->value);
7022: - }
7023: - if(nrunning < nproclimit)
7024: - sched();
7025: - return(0);
7026: -}
7027: -
7028: -execinit()
7029: -{
7030: - extern char **environ;
7031: - extern char **vardump();
7032: - register char *s, *ss, c;
7033: - Symtab *st;
7034: -
7035: - environ = envy;
7036: - special = vardump(envy);
7037: - if(st = symlook("ENVIRON", S_VAR, (char *)0))
7038: - for(s = st->value; *s;){
7039: - for(ss = s; *ss && (*ss != 1); ss++);
7040: - c = *ss;
7041: - *ss = 0;
7042: - *special++ = strdup(s);
7043: - s = ss;
7044: - if(*ss = c)
7045: - s++;
7046: - }
7047: - *special = 0;
7048: -}
7049: -
7050: -char *myenv[] =
7051: -{
7052: - "target", "stem", "prereq", "pid", "nproc", "newprereq",
7053: - "alltarget",
7054: - "stem1", "stem2", "stem3", "stem4", "stem5", "stem6",
7055: - "stem7", "stem8", "stem9", "stem0", 0
7056: -};
7057: -
7058: -dovars(j, slot)
7059: - register Job *j;
7060: -{
7061: - char buf[BIGBLOCK];
7062: - char *s, *t;
7063: - int i, n = 0;
7064: -
7065: -#define SPECIAL ((sizeof myenv)/(sizeof myenv[0])-1)
7066: -#define VSET(name, exp) {strcpy(buf, "name="); strcpy(strchr(buf, 0), exp);}
7067: -
7068: - for(i = 0; i < SPECIAL; i++)
7069: - if(special[i])
7070: - free(special[i]);
7071: - VSET(target, s = wtos(j->t));
7072: - special[n++] = strdup(buf);
7073: - free(s);
7074: - /* WATCH OUT; stem set below if reg exp!! */
7075: - VSET(stem, j->stem);
7076: - special[n++] = strdup(buf);
7077: - VSET(prereq, s = wtos(j->p));
7078: - special[n++] = strdup(buf);
7079: - free(s);
7080: - sprint(buf, "pid=%d", getpid());
7081: - special[n++] = strdup(buf);
7082: - sprint(buf, "nproc=%d", slot);
7083: - special[n++] = strdup(buf);
7084: - VSET(newprereq, s = wtos(j->np));
7085: - special[n++] = strdup(buf);
7086: - free(s);
7087: - VSET(alltarget, s = wtos(j->at));
7088: - special[n++] = strdup(buf);
7089: - free(s);
7090: - for(i = 0; i <= 9; i++){
7091: - sprint(buf, "stem%d=", i);
7092: - if(j->r->attr®EXP){
7093: - for(s = buf; *s; s++);
7094: - for(t = j->match[i].sp; t < j->match[i].ep; *s++ = *t++);
7095: - *s = 0;
7096: - }
7097: - special[n+i] = strdup(buf);
7098: - if((i == 1) && (j->r->attr®EXP)){
7099: - buf[1] = 's'; buf[2] = 't'; buf[3] = 'e'; buf[4] = 'm';
7100: - special[1] = strdup(buf+1);
7101: - }
7102: - }
7103: - special[SPECIAL] = 0;
7104: -}
7105: -
7106: -nproc()
7107: -{
7108: - register Symtab *sym;
7109: -
7110: - if(sym = symlook("NPROC", S_VAR, (char *)0))
7111: - nproclimit = atoi(sym->value);
7112: - if(nproclimit < 1)
7113: - nproclimit = 1;
7114: - if(DEBUG(D_EXEC))
7115: - fprint(1, "nprocs = %d\n", nproclimit);
7116: - if(nproclimit > nevents){
7117: - if(nevents)
7118: - events = (Event *)realloc((char *)events, nproclimit*sizeof(Event));
7119: - else
7120: - events = (Event *)malloc(nproclimit*sizeof(Event));
7121: - while(nevents < nproclimit)
7122: - events[nevents++].pid = 0;
7123: - }
7124: -}
7125: -
7126: -nextslot()
7127: -{
7128: - register i;
7129: -
7130: - for(i = 0; i < nproclimit; i++)
7131: - if(events[i].pid <= 0) return(i);
7132: - assert("out of slots!!", 0);
7133: - return(0); /* cyntax */
7134: -}
7135: -
7136: -static
7137: -pidslot(pid)
7138: -{
7139: - register i;
7140: -
7141: - for(i = 0; i < nevents; i++)
7142: - if(events[i].pid == pid) return(i);
7143: - return(-1);
7144: -}
7145: -
7146: -static void
7147: -pnew(pid, status)
7148: -{
7149: - register Process *p;
7150: -
7151: - if(pfree){
7152: - p = pfree;
7153: - pfree = p->f;
7154: - } else
7155: - p = (Process *)Malloc(sizeof(Process));
7156: - p->pid = pid;
7157: - p->status = status;
7158: - p->f = phead;
7159: - phead = p;
7160: - if(p->f)
7161: - p->f->b = p;
7162: - p->b = 0;
7163: -}
7164: -
7165: -static void
7166: -pdelete(p)
7167: - Process *p;
7168: -{
7169: - if(p->f)
7170: - p->f->b = p->b;
7171: - if(p->b)
7172: - p->b->f = p->f;
7173: - else
7174: - phead = p->f;
7175: - p->f = pfree;
7176: - pfree = p;
7177: -}
7178: -
7179: -static long tslot[1000];
7180: -static long tick;
7181: -
7182: -account()
7183: -{
7184: - long t;
7185: -
7186: - time(&t);
7187: - if(tick)
7188: - tslot[nrunning] += (t-tick);
7189: - tick = t;
7190: -}
7191: -
7192: -praccount()
7193: -{
7194: - int i;
7195: -
7196: - account();
7197: - for(i = 0; i <= nevents; i++)
7198: - Fprint(1, "%d: %ld\n", i, tslot[i]);
7199: -}
7200: //GO.SYSIN DD ./run.c
7201: echo ./shprint.c 1>&2
7202: sed 's/.//' >./shprint.c <<'//GO.SYSIN DD ./shprint.c'
7203: -#include "mk.h"
7204: -
7205: -shprint(s, env, dest)
7206: - char *s, **env, *dest;
7207: -{
7208: - register char *q = dest;
7209: -
7210: - while(*s)
7211: - switch(*s)
7212: - {
7213: - case '\\':
7214: - *q++ = *s++;
7215: - *q++ = *s++;
7216: - break;
7217: - case '$':
7218: - q = vexpand(&s, q, env);
7219: - break;
7220: - default:
7221: - *q++ = *s++;
7222: - break;
7223: - }
7224: - *q = 0;
7225: -}
7226: -
7227: -char *
7228: -mygetenv(name, env)
7229: - char *name, **env;
7230: -{
7231: - register char *p, *q;
7232: -
7233: - for(; *env; env++){
7234: - for(p = name, q = *env; *p == *q; p++, q++)
7235: - if(*p == 0) break;
7236: - if((*p == 0) && (*q == '='))
7237: - return(q+1);
7238: - }
7239: - return((char *)0);
7240: -}
7241: -
7242: -char *
7243: -vexpand(ww, dest, env)
7244: - char **ww, *dest, **env;
7245: -{
7246: - register char *s, *w = *ww;
7247: - char carry, *q;
7248: -
7249: - assert("vexpand no $", *w == '$');
7250: - if(*++w == '{'){
7251: - for(s = ++w; *s != '}'; s++)
7252: - if(*s == 0) break;
7253: - } else
7254: - s = shname(w);
7255: - carry = *s;
7256: - *s = 0;
7257: - if(q = mygetenv(w, env)){
7258: - while(*q)
7259: - *dest++ = *q++;
7260: - } else { /* copy name */
7261: - for(q = *ww; q != s;)
7262: - *dest++ = *q++;
7263: - if(carry == '}')
7264: - *dest++ = carry;
7265: - }
7266: - *s = carry;
7267: - if(carry == '}')
7268: - s++;
7269: - *ww = s;
7270: - return(dest);
7271: -}
7272: -
7273: -front(s)
7274: - char *s;
7275: -{
7276: - register char *t;
7277: - register i, j;
7278: - char *flds[512];
7279: - char buf[BIGBLOCK];
7280: -
7281: - setfields(" \t\n");
7282: - strcpy(buf, s);
7283: - i = getfields(buf, flds, 512);
7284: - if(i > 5){
7285: - flds[4] = flds[i-1];
7286: - flds[3] = "...";
7287: - i = 5;
7288: - }
7289: - t = s;
7290: - for(j = 0; j < i; j++){
7291: - for(s = flds[j]; *s; *t++ = *s++);
7292: - *t++ = ' ';
7293: - }
7294: - *t = 0;
7295: -}
7296: //GO.SYSIN DD ./shprint.c
7297: echo ./sig.c 1>&2
7298: sed 's/.//' >./sig.c <<'//GO.SYSIN DD ./sig.c'
7299: -#include "mk.h"
7300: -#include <signal.h>
7301: -
7302: -static
7303: -sigint()
7304: -{
7305: - extern errno;
7306: -
7307: - signal(SIGINT, SIG_IGN);
7308: - kflag = 1; /* to make sure waitup doesn't exit */
7309: - jobs = 0; /* make sure no more get scheduled */
7310: - while(waitup(1, (int *)0) == 0)
7311: - ;
7312: - Fprint(1, "mk: interrupted!\n");
7313: - Exit();
7314: -}
7315: -
7316: -sigcatch()
7317: -{
7318: - if(signal(SIGINT, SIG_IGN) != SIG_IGN)
7319: - signal(SIGINT, sigint);
7320: -}
7321: //GO.SYSIN DD ./sig.c
7322: echo ./symtab.c 1>&2
7323: sed 's/.//' >./symtab.c <<'//GO.SYSIN DD ./symtab.c'
7324: -#include "mk.h"
7325: -
7326: -#define NHASH 4099
7327: -#define HASHMUL 79L /* this is a good value */
7328: -static Symtab *hash[NHASH];
7329: -
7330: -syminit()
7331: -{
7332: - register Symtab **s, *ss;
7333: -
7334: - for(s = hash; s < &hash[NHASH]; s++){
7335: - for(ss = *s; ss; ss = ss->next)
7336: - free((char *)ss);
7337: - *s = 0;
7338: - }
7339: -}
7340: -
7341: -Symtab *
7342: -symlook(sym, space, install)
7343: - char *sym;
7344: - char *install;
7345: -{
7346: - register long h;
7347: - register char *p;
7348: - register Symtab *s;
7349: -
7350: - for(p = sym, h = space; *p; h += *p++)
7351: - h *= HASHMUL;
7352: - if(h < 0)
7353: - h = ~h;
7354: - h %= NHASH;
7355: - for(s = hash[h]; s; s = s->next)
7356: - if((s->space == space) && (strcmp(s->name, sym) == 0))
7357: - return(s);
7358: - if(install == 0)
7359: - return((Symtab *)0);
7360: - s = (Symtab *)Malloc(sizeof(Symtab));
7361: - s->space = space;
7362: - s->name = sym;
7363: - s->value = install;
7364: - s->next = hash[h];
7365: - hash[h] = s;
7366: - return(s);
7367: -}
7368: -
7369: -symdel(sym, space)
7370: - char *sym;
7371: -{
7372: - register long h;
7373: - register char *p;
7374: - register Symtab *s, *ls;
7375: -
7376: - for(p = sym, h = space; *p; h += *p++)
7377: - h *= HASHMUL;
7378: - if(h < 0)
7379: - h = ~h;
7380: - h %= NHASH;
7381: - for(s = hash[h], ls = 0; s; ls = s, s = s->next)
7382: - if((s->space == space) && (strcmp(s->name, sym) == 0)){
7383: - if(ls)
7384: - ls->next = s->next;
7385: - else
7386: - hash[h] = s->next;
7387: - free((char *)s);
7388: - }
7389: -}
7390: -
7391: -symtraverse(space, fn)
7392: - void (*fn)();
7393: -{
7394: - register Symtab **s, *ss;
7395: -
7396: - for(s = hash; s < &hash[NHASH]; s++)
7397: - for(ss = *s; ss; ss = ss->next)
7398: - if(ss->space == space)
7399: - (*fn)(ss);
7400: -}
7401: -
7402: -symstat()
7403: -{
7404: - register Symtab **s, *ss;
7405: - register n;
7406: - int l[1000];
7407: -
7408: - memset((char *)l, 0, sizeof(l));
7409: - for(s = hash; s < &hash[NHASH]; s++){
7410: - for(ss = *s, n = 0; ss; ss = ss->next)
7411: - n++;
7412: - l[n]++;
7413: - }
7414: - for(n = 0; n < 1000; n++)
7415: - if(l[n]) Fprint(1, "%ld of length %d\n", l[n], n);
7416: -}
7417: //GO.SYSIN DD ./symtab.c
7418: echo ./t_ar.c 1>&2
7419: sed 's/.//' >./t_ar.c <<'//GO.SYSIN DD ./t_ar.c'
7420: -#include "mk.h"
7421: -#include <sys/types.h>
7422: -#include <sys/stat.h>
7423: -#include <ar.h>
7424: -
7425: -static atimes();
7426: -
7427: -long
7428: -atimeof(force, name, ar, mem)
7429: - char *name, *ar, *mem;
7430: -{
7431: - struct stat sbuf;
7432: - Symtab *sym;
7433: -
7434: - if(stat(ar, &sbuf) < 0)
7435: - sbuf.st_mtime = 0;
7436: - if(sym = symlook(ar, S_AGG, (char *)0)){
7437: - if(force || (sbuf.st_mtime > (long)sym->value)){
7438: - atimes(ar);
7439: - symlook(ar, S_AGG, ar)->value = (char *)sbuf.st_mtime;
7440: - }
7441: - } else {
7442: - atimes(ar);
7443: - symlook(strdup(ar), S_AGG, ar)->value = (char *)sbuf.st_mtime;
7444: - }
7445: - if(sym = symlook(name, S_TIME, (char *)0))
7446: - sbuf.st_mtime = (long)sym->value;
7447: - else
7448: - sbuf.st_mtime = 0;
7449: - return((long)sbuf.st_mtime);
7450: -}
7451: -
7452: -void
7453: -atouch(name, ar, mem)
7454: - char *name, *ar, *mem;
7455: -{
7456: - int fd;
7457: - struct ar_hdr hdr;
7458: - char *s;
7459: - long t;
7460: - char buf[NAMEBLOCK];
7461: -
7462: - strcpy(buf, mem);
7463: -#ifdef SYSV
7464: - strcat(buf, "/");
7465: -#endif
7466: - if((fd = open(ar, 2)) < 0){
7467: - if((fd = creat(ar, 0666)) < 0){
7468: - perror(ar);
7469: - Exit();
7470: - }
7471: - write(fd, ARMAG, SARMAG);
7472: - }
7473: - if(symlook(name, S_TIME, (char *)0)){
7474: - /* hoon off and change it in situ */
7475: - lseek(fd, (long)SARMAG, 0);
7476: - while(read(fd, (char *)&hdr, sizeof(hdr)) == sizeof(hdr)){
7477: - for(s = &hdr.ar_name[sizeof(hdr.ar_name)]; *--s == ' ';);
7478: - s[1] = 0;
7479: - if(strcmp(buf, hdr.ar_name) == 0){
7480: - t = sizeof(hdr.ar_name)-sizeof(hdr);
7481: - lseek(fd, t, 1);
7482: - fprint(fd, "%-12ld", time((long *)0));
7483: - break;
7484: - }
7485: - t = atol(hdr.ar_size);
7486: -#ifdef CRAY
7487: - t = (t+7)&~7;
7488: - t -= sizeof(hdr)-60;
7489: -#else
7490: - if(t&01) t++;
7491: -#endif
7492: - lseek(fd, t, 1);
7493: - }
7494: - } else {
7495: - lseek(fd, 0L, 2);
7496: - fprint(fd, "%-16s%-12ld%-6d%-6d%-8lo%-10ld%2s", buf, time((long *)0),
7497: - getuid(), getgid(), 0100666L, 0L, ARFMAG);
7498: - }
7499: - close(fd);
7500: -}
7501: -
7502: -
7503: -void
7504: -adelete(name, ar, mem)
7505: - char *name, *ar, *mem;
7506: -{
7507: - Fprint(2, "sorry; mk doesn't know how to delete archive members yet\n");
7508: -}
7509: -
7510: -static
7511: -atimes(ar)
7512: - char *ar;
7513: -{
7514: - struct ar_hdr hdr;
7515: - long t;
7516: - int fd;
7517: - char buf[BIGBLOCK];
7518: - register char *s;
7519: -
7520: - if((fd = open(ar, 0)) < 0)
7521: - return;
7522: - if(read(fd, buf, SARMAG) != SARMAG){
7523: - close(fd);
7524: - return;
7525: - }
7526: - while(read(fd, (char *)&hdr, sizeof(hdr)) == sizeof(hdr)){
7527: - for(s = &hdr.ar_name[sizeof(hdr.ar_name)]; *--s == ' ';);
7528: -#ifdef SYSV
7529: - if(*s == '/') /* Damn you Sytem V */
7530: - s--;
7531: -#endif
7532: - s[1] = 0;
7533: - t = atol(hdr.ar_date);
7534: - sprint(buf, "%s(%s)", ar, hdr.ar_name);
7535: - symlook(strdup(buf), S_TIME, (char *)t)->value = (char *)t;
7536: - t = atol(hdr.ar_size);
7537: - if(t&01) t++;
7538: - lseek(fd, t, 1);
7539: - }
7540: - close(fd);
7541: -}
7542: //GO.SYSIN DD ./t_ar.c
7543: echo ./t_driver.c 1>&2
7544: sed 's/.//' >./t_driver.c <<'//GO.SYSIN DD ./t_driver.c'
7545: -#include "mk.h"
7546: -#include <ar.h>
7547: -
7548: -#define AR 123456L
7549: -
7550: -extern long ftimeof(), atimeof();
7551: -extern void ftouch(), atouch();
7552: -extern void fdelete(), adelete();
7553: -static long split();
7554: -
7555: -struct ftype
7556: -{
7557: - long magic;
7558: - long (*time)();
7559: - void (*touch)();
7560: - void (*delete)();
7561: -} ftab[] =
7562: -{
7563: - { 0L, ftimeof, ftouch, fdelete },
7564: - { AR, atimeof, atouch, adelete },
7565: - { 0L, (long (*)())0 }
7566: -};
7567: -
7568: -long
7569: -timeof(name, force)
7570: - char *name;
7571: -{
7572: - char buf[BIGBLOCK], *part2;
7573: - register struct ftype *f;
7574: - long magic;
7575: -
7576: - magic = split(name, buf, &part2);
7577: - for(f = ftab; f->time; f++)
7578: - if(f->magic == magic)
7579: - return((*f->time)(force, name, buf, part2));
7580: - Fprint(2, "mk: '%s' appears to have an unknown magic number (%ld)\n", name, magic);
7581: - Exit();
7582: - return(0L); /* shut cyntax up */
7583: -}
7584: -
7585: -void
7586: -touch(name)
7587: - char *name;
7588: -{
7589: - char buf[BIGBLOCK], *part2;
7590: - register struct ftype *f;
7591: - long magic;
7592: -
7593: - magic = split(name, buf, &part2);
7594: - Fprint(1, "touch(%s)\n", name);
7595: - if(nflag)
7596: - return;
7597: - for(f = ftab; f->time; f++)
7598: - if(f->magic == magic){
7599: - (*f->touch)(name, buf, part2);
7600: - return;
7601: - }
7602: - Fprint(2, "mk: give me a break! I never heard of magic=%ld\n", magic);
7603: - Exit();
7604: -}
7605: -
7606: -void
7607: -delete(name)
7608: - char *name;
7609: -{
7610: - char buf[BIGBLOCK], *part2;
7611: - register struct ftype *f;
7612: - long magic;
7613: -
7614: - magic = split(name, buf, &part2);
7615: - for(f = ftab; f->time; f++)
7616: - if(f->magic == magic){
7617: - (*f->delete)(name, buf, part2);
7618: - return;
7619: - }
7620: - Fprint(2, "mk: give me a break! I never heard of magic=%ld\n", magic);
7621: - Exit();
7622: -}
7623: -
7624: -static long
7625: -type(file)
7626: - char *file;
7627: -{
7628: - int fd;
7629: - char buf[SARMAG];
7630: - short m;
7631: - long goo;
7632: -
7633: - if(access(file, 0) < 0){
7634: - if(symlook(file, S_BITCH, (char *)0) == 0){
7635: - Fprint(1, "%s doesn't exist: assuming it will be an archive\n", file);
7636: - (void)symlook(file, S_BITCH, file);
7637: - }
7638: - return(AR);
7639: - }
7640: - if((fd = open(file, 0)) < 0){
7641: - perror(file);
7642: - Exit();
7643: - }
7644: - if(read(fd, buf, SARMAG) != SARMAG){
7645: - close(fd);
7646: - return(-1L);
7647: - }
7648: - if(strncmp(ARMAG, buf, SARMAG) == 0)
7649: - goo = AR;
7650: - else {
7651: - lseek(fd, 0L, 0);
7652: - if(read(fd, (char *)&m, sizeof m) == sizeof m)
7653: - goo = m;
7654: - else
7655: - goo = -1;
7656: - }
7657: - close(fd);
7658: - return(goo);
7659: -}
7660: -
7661: -static long
7662: -split(name, buf, p2)
7663: - char *name, *buf, **p2;
7664: -{
7665: - register char *s;
7666: -
7667: - strcpy(buf, name);
7668: - if(s = strchr(buf, '(')){
7669: - *s++ = 0;
7670: - *p2 = s;
7671: - while(*s && (*s != ')'))
7672: - s++;
7673: - *s = 0;
7674: - return(type(buf));
7675: - } else
7676: - return(0L);
7677: -}
7678: //GO.SYSIN DD ./t_driver.c
7679: echo ./t_file.c 1>&2
7680: sed 's/.//' >./t_file.c <<'//GO.SYSIN DD ./t_file.c'
7681: -#include "mk.h"
7682: -#include <sys/types.h>
7683: -#include <sys/stat.h>
7684: -#include <errno.h>
7685: -
7686: -#define MYSEP(s) ((*s == ' ') || (*s == ',') || (*s == '\n'))
7687: -
7688: -timeinit(s)
7689: - register char *s;
7690: -{
7691: - register long t;
7692: - register char *os;
7693: -
7694: - for(t = time((long *)0); *s; s = os){
7695: - for(os = s; !MYSEP(os); os++)
7696: - if(*os == 0){
7697: - symlook(strdup(s), S_TIME, (char *)t)->value = (char *)t;
7698: - return;
7699: - }
7700: - *os++ = 0;
7701: - symlook(strdup(s), S_TIME, (char *)t)->value = (char *)t;
7702: - while(MYSEP(os))
7703: - os++;
7704: - }
7705: -}
7706: -
7707: -long
7708: -ftimeof(force, name)
7709: - char *name;
7710: -{
7711: - struct stat sbuf;
7712: - Symtab *sym;
7713: -
7714: - if(!force && (sym = symlook(name, S_TIME, (char *)0))){
7715: - return((long)sym->value);
7716: - }
7717: - if(stat(name, &sbuf) < 0)
7718: - sbuf.st_mtime = 0;
7719: - symlook(name, S_TIME, (char *)sbuf.st_mtime);
7720: - return((long)sbuf.st_mtime);
7721: -}
7722: -
7723: -void
7724: -ftouch(name)
7725: - char *name;
7726: -{
7727: - int fd;
7728: - char buf[1];
7729: - struct stat sbuf;
7730: -
7731: - if(stat(name, &sbuf) < 0) /* not there and zero length are same case */
7732: - sbuf.st_size = 0;
7733: - if(sbuf.st_size == 0){
7734: - if((fd = creat(name, 0666)) < 0){
7735: - bad:
7736: - perror(name);
7737: - Exit();
7738: - }
7739: - close(fd);
7740: - return;
7741: - }
7742: - if((fd = open(name, 2)) < 0)
7743: - goto bad;
7744: - if(read(fd, buf, 1) != 1)
7745: - goto bad;
7746: - if(lseek(fd, 0L, 0) < 0)
7747: - goto bad;
7748: - if(write(fd, buf, 1) != 1)
7749: - goto bad;
7750: - close(fd);
7751: -}
7752: -
7753: -void
7754: -fdelete(s)
7755: - char *s;
7756: -{
7757: - if(unlink(s) < 0)
7758: - perror(s);
7759: -}
7760: //GO.SYSIN DD ./t_file.c
7761: echo ./var.c 1>&2
7762: sed 's/.//' >./var.c <<'//GO.SYSIN DD ./var.c'
7763: -#include "mk.h"
7764: -
7765: -setvar(name, value)
7766: - char *name;
7767: - char *value;
7768: -{
7769: - symlook(name, S_VAR, value)->value = value;
7770: - symlook(name, S_MAKEVAR, "");
7771: -}
7772: -
7773: -static char **nextv;
7774: -
7775: -static void
7776: -vcopy(s)
7777: - register Symtab *s;
7778: -{
7779: - register char **p;
7780: - extern char *myenv[];
7781: -
7782: - if(symlook(s->name, S_NOEXPORT, (char *)0))
7783: - return;
7784: - for(p = myenv; *p; p++)
7785: - if(strcmp(*p, s->name) == 0) return;
7786: - if(*nextv)
7787: - free(*nextv);
7788: - *nextv++ = envpr(s->name, s->value);
7789: -}
7790: -
7791: -char **
7792: -vardump(p)
7793: - char **p;
7794: -{
7795: - nextv = p;
7796: - symtraverse(S_VAR, vcopy);
7797: - *nextv = 0;
7798: - return(nextv);
7799: -}
7800: -
7801: -static void
7802: -print1(s)
7803: - register Symtab *s;
7804: -{
7805: - Fprint(1, "\t%s='%s'\n", s->name, s->value);
7806: -}
7807: -
7808: -dumpv(s)
7809: - char *s;
7810: -{
7811: - Fprint(1, "%s:\n", s);
7812: - symtraverse(S_VAR, print1);
7813: -}
7814: -
7815: -char *
7816: -envpr(name, value)
7817: - register char *name;
7818: - register char *value;
7819: -{
7820: - char buf[BIGBLOCK];
7821: -
7822: - sprint(buf, "%s=", name);
7823: - strcpy(strchr(buf, 0), value);
7824: - return(strdup(buf));
7825: -}
7826: -
7827: -#include <ctype.h>
7828: -
7829: -char *
7830: -shname(s)
7831: - char *s;
7832: -{
7833: - register unsigned char *a = (unsigned char *)s;
7834: -
7835: - /* always go one !! */
7836: - a++;
7837: - while(isalnum(*a) || (*a == '_')) a++;
7838: - return((char *)a);
7839: -}
7840: //GO.SYSIN DD ./var.c
7841: echo ./word.c 1>&2
7842: sed 's/.//' >./word.c <<'//GO.SYSIN DD ./word.c'
7843: -#include "mk.h"
7844: -
7845: -Word *
7846: -newword(s)
7847: - char *s;
7848: -{
7849: - register Word *w = (Word *)Malloc(sizeof(Word));
7850: -
7851: - w->s = strdup(s);
7852: - w->next = 0;
7853: - return(w);
7854: -}
7855: -
7856: -Word *
7857: -stow(s)
7858: - char *s;
7859: -{
7860: - char save;
7861: - register char *t;
7862: - Word *head, *w;
7863: -
7864: - w = head = newword("");
7865: - while(*s){
7866: - while(SEP(*s))
7867: - s++;
7868: - if(*s == 0) break;
7869: - for(t = s; *t && !SEP(*t); t++)
7870: - ;
7871: - save = *t;
7872: - *t = 0;
7873: - w->next = newword(s);
7874: - w = w->next;
7875: - *t = save;
7876: - s = t;
7877: - }
7878: - w = head->next;
7879: - delword(head);
7880: - return(w);
7881: -}
7882: -
7883: -char *
7884: -wtos(w)
7885: - register Word *w;
7886: -{
7887: - static char buf[BIGBLOCK];
7888: - register char *s = buf;
7889: - register char *t;
7890: -
7891: - for(; w; w = w->next){
7892: - for(t = w->s; *t;)
7893: - *s++ = *t++;
7894: - if(w->next)
7895: - *s++ = ' ';
7896: - }
7897: - *s = 0;
7898: - return(strdup(buf));
7899: -}
7900: -
7901: -delword(w)
7902: - Word *w;
7903: -{
7904: - free(w->s);
7905: - free((char *)w);
7906: -}
7907: -
7908: -dumpw(s, w)
7909: - char *s;
7910: - Word *w;
7911: -{
7912: - Fprint(1, "%s", s);
7913: - for(; w; w = w->next)
7914: - Fprint(1, " '%s'", w->s);
7915: - Fputc(1, '\n');
7916: -}
7917: //GO.SYSIN DD ./word.c
7918: echo ./ndir.h 1>&2
7919: sed 's/.//' >./ndir.h <<'//GO.SYSIN DD ./ndir.h'
7920: -/* Copyright (c) 1982 Regents of the University of California */
7921: -/* and modified by pjw in 1986 */
7922: -
7923: -/*
7924: - * this must be a power of 2 and a multiple of all the ones in the system
7925: - */
7926: -#define DIRBLKSIZ 512
7927: -
7928: -/*
7929: - * This limits the directory name length. Its main constraint
7930: - * is that it appears twice in the user structure. (u. area) in bsd systems
7931: - */
7932: -#define MAXNAMLEN 255
7933: -
7934: -struct direct {
7935: - unsigned long d_ino;
7936: - short d_reclen;
7937: - short d_namlen;
7938: - char d_name[MAXNAMLEN + 1];
7939: - /* typically shorter */
7940: -};
7941: -
7942: -struct _dirdesc {
7943: - int dd_fd;
7944: - long dd_loc; /* where we left off in dd_buf */
7945: - long dd_size; /* bytes back from system */
7946: - long dd_offset; /* lseek at beginning of dd_buf */
7947: - char dd_buf[DIRBLKSIZ];
7948: -};
7949: -
7950: -/*
7951: - * useful macros.
7952: - */
7953: -#define NDIRSIZ(dp) \
7954: - ((sizeof(struct direct) - MAXNAMLEN + (dp)->d_namlen + sizeof(ino_t) - 1) &\
7955: - ~(sizeof(ino_t) - 1))
7956: -typedef struct _dirdesc DIR;
7957: -#ifndef NULL
7958: -#define NULL 0
7959: -#endif
7960: -
7961: -/*
7962: - * functions defined on directories
7963: - */
7964: -extern DIR *opendir();
7965: -extern struct direct *readdir();
7966: -extern long telldir();
7967: -extern void seekdir();
7968: -#define rewinddir(dirp) seekdir((dirp), 0)
7969: -extern void closedir();
7970: //GO.SYSIN DD ./ndir.h
7971: echo ./tmac.an 1>&2
7972: sed 's/.//' >./tmac.an <<'//GO.SYSIN DD ./tmac.an'
7973: -'''\" PWB Manual Entry Macros - 1.36 of 11/11/80
7974: -'''\" Nroff/Troff Version @(#)1.36
7975: -'''\" Option -rs1 short (9") pages
7976: -'''\" Option -rp# set no. of first page, put no. of pgs. on stderr
7977: -'''\" Option -rd1 give modified date instead of printed date
7978: -.deth
7979: -.tmwrong version of man entry macros - use -man6
7980: -.ab
7981: -..
7982: -.ifn .ds Tm \uTM\d
7983: -.ift .ds Tm \v'-0.5m'\s-4TM\s+4\v'0.5m'
7984: -.de}E
7985: -.}f
7986: -.in\\n()Ru+\\n(INu
7987: -.ll\\n(LLu
7988: -.lt\\n(LLu
7989: -.pl\\n()Lu
7990: -..
7991: -.deDT
7992: -.ift .ta 3.6m 7.2m 10.8m 14.4m 18m 21.6m 25.2m 28.8m 32.4m 36m 39.6m 43.2m 46.8m
7993: -.ifn .ta 5n 10n 15n 20n 25n 30n 35n 40n 45n 50n 55n 60n 65n
7994: -..
7995: -.de HY
7996: -.hy14
7997: -..
7998: -.de}f
7999: -.ift .vs \\n()Vp
8000: -.ps\\n()S
8001: -.ft1
8002: -..
8003: -.de}H
8004: -.ev1
8005: -.}C
8006: -.}E
8007: -.ie\\n()s 'sp |2v
8008: -.el'sp |3v
8009: -.".ps\\n()S-1
8010: -.".iet .bd1 3
8011: -.".el.bd1 0
8012: -.tl \\*(]H\\*(]L\\*(]H
8013: -.bd1
8014: -.ps\\n()S
8015: -.ie\\n()s 'sp 1.5v
8016: -.el'sp 3v
8017: -.ev
8018: -.ns
8019: -.if \\n(CL .2C
8020: -..
8021: -.de}F
8022: -.ev1
8023: -.}E
8024: -.if\\n()s 'sp |\\n(.pu-1v-1p
8025: -.if\\n()t 'sp |\\n(.pu-3v
8026: -.ifn 'sp |\\n(.pu-4v
8027: -.ifn .tl Page %\\*(]D\\*(]W
8028: -.if\\n()s .tl - % -
8029: -.if\\n()t \{.if o .tl Page %\\*(]D\\*(]W
8030: -.ife .tl \\*(]W\\*(]DPage % \}
8031: -.ev
8032: -'bp
8033: -..
8034: -.ifn .ig
8035: -.de}C
8036: -.if "\\*(.T"aps"\{\
8037: -. po0i
8038: -. lt7.5i
8039: -. if\\n()s .tl \l0.25i\l0.25i\h1i\l0.25i
8040: -. if\\n()t .tl \l0.25i\l0.25i
8041: -. lt
8042: -. po\}
8043: -..
8044: -.de}M
8045: -.}N
8046: -.wh-.5p }C
8047: -.ll\\n(LLu
8048: -.}P
8049: -..
8050: -.de}K
8051: -.}N
8052: -.pl1
8053: -.ll\\n(LLu
8054: -..
8055: -.de}P
8056: -.nr )P \\n%+1-\\np
8057: -.if \\nq .tm \\n(.F \\n()P \\np
8058: -.bp
8059: -.if \\nq .nr p \\n%
8060: -..
8061: -.deTH
8062: -.PD
8063: -.nrIN \\n()Mu
8064: -.ift .ds ]H \\$1\^(\^\\$2\^)
8065: -.ifn .ds ]H \\$1(\\$2)
8066: -.if\\n()s .ds ]D
8067: -.if\\n()t .ds ]D Tenth Edition
8068: -.ifn .ds ]D Tenth Edition
8069: -.ds]L
8070: -.if!\\$3 .ds ]L (\^\\$3\^)
8071: -.if!\\$4 .ds ]D \\$4
8072: -.wh0 }H
8073: -.wh-\\n(:mu }F
8074: -.em}M
8075: -.if\\n(nl .}P
8076: -.nr)I \\n()Mu
8077: -.nr)R 0
8078: -.}E
8079: -.DT
8080: -.ifn \{.na
8081: -.nh\}
8082: -.ift \{.bd S 3 3
8083: -.HY \}
8084: -..
8085: -.deSH
8086: -.PD
8087: -.}X 0 "\\$1" smaller
8088: -.nr)E 2
8089: -\&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6
8090: -..
8091: -.deSS
8092: -.}X 3n "" ""
8093: -.nr)E 2
8094: -\&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6
8095: -..
8096: -.de}X
8097: -.}E
8098: -.ti\\$1
8099: -.sp\\n(PDu
8100: -.ne1.1v
8101: -.nr)R 0
8102: -.fi
8103: -'''ss12
8104: -'''if\\$2SYNOPSIS .ss 18
8105: -.it1 }N
8106: -.if!\\$3 .SM
8107: -.iet .bd1 3
8108: -.el.bd1 0
8109: -..
8110: -.de}2
8111: -.nr)E 0
8112: -.}E
8113: -.nr)I \\n()Mu
8114: -.ns
8115: -.bd1
8116: -..
8117: -.deSM
8118: -.nh
8119: -.ps\\n()S-1
8120: -.if!\\$1 \&\\$1
8121: -.if!\\$2 \&\\$2
8122: -.if!\\$3 \&\\$3
8123: -.if!\\$4 \&\\$4
8124: -.if!\\$5 \&\\$5
8125: -.if!\\$6 \&\\$6
8126: -.if!\\$1 .ps \\n()S
8127: -.if\\$1 .it 1 }N
8128: -.HY
8129: -..
8130: -.deI
8131: -.nh
8132: -.ft2
8133: -.it1 }N
8134: -.if!\\$1 \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6
8135: -.HY
8136: -..
8137: -.deB
8138: -.nh
8139: -.it1 }N
8140: -.ie!\\$1 \%\&\f5\\$1 \\$2 \\$3 \\$4 \\$5 \\$6
8141: -.el .ft5
8142: -.HY
8143: -..
8144: -.deL
8145: -.nh
8146: -.it1 }N
8147: -.ift \{.ie!\\$1 \%\&\f5\\$1 \\$2 \\$3 \\$4 \\$5 \\$6
8148: -.el .ft5 \}
8149: -.ifn \{.ft5
8150: -.if!\\$1 \{.ie\\$2 `\\$1'
8151: -.el .ie\\$3 `\\$1 \\$2'
8152: -.el .ie\\$4 `\\$1 \\$2 \\$3'
8153: -.el .ie\\$5 `\\$1 \\$2 \\$3 \\$4'
8154: -.el .ie\\$6 `\\$1 \\$2 \\$3 \\$4 \\$5'
8155: -.el `\\$1 \\$2 \\$3 \\$4 \\$5 \\$6'\}\}
8156: -.HY
8157: -..
8158: -.deF
8159: -.nh
8160: -.it1 }N
8161: -.ie!\\$1 \%\&\f5\\$1 \\$2 \\$3 \\$4 \\$5 \\$6
8162: -.el .ft5
8163: -.HY
8164: -..
8165: -.deRI
8166: -.nh
8167: -.}S 1 2 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
8168: -.HY
8169: -.}f
8170: -..
8171: -.deIR
8172: -.nh
8173: -.}S 2 1 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
8174: -.HY
8175: -.}f
8176: -..
8177: -.deIB
8178: -.nh
8179: -.ift .}S 2 5 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
8180: -.ifn .}S 2 1 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
8181: -.HY
8182: -.}f
8183: -..
8184: -.deRB
8185: -.nh
8186: -.ift .}S 1 5 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
8187: -.ifn .}S 1 1 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
8188: -.HY
8189: -.}f
8190: -..
8191: -.deBR
8192: -.nh
8193: -.ift .}S 5 1 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
8194: -.ifn .}S 1 1 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
8195: -.HY
8196: -.}f
8197: -..
8198: -.deBI
8199: -.nh
8200: -.ift .}S 5 2 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
8201: -.ifn .}S 1 2 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
8202: -.HY
8203: -.}f
8204: -..
8205: -.de LR
8206: -.nh
8207: -.ift \%\&\f5\\$1\f1\\$2
8208: -.ifn \%`\\$1'\\$2
8209: -.HY
8210: -..
8211: -.de RL
8212: -.nh
8213: -.ift \%\&\f1\\$1\\f5\\$2\\f1\\$3
8214: -.ifn \%\\$1`\\$2'\\$3
8215: -.HY
8216: -..
8217: -.de}S
8218: -.ds]F
8219: -.if\\$12 .if !\\$5 .ds ]F \^
8220: -.if\\$22 .if !\\$5 .ds ]F \^
8221: -.ie!\\$4 .}S \\$2 \\$1 "\\$3\f\\$1\\$4\\*(]F" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
8222: -.el\\$3
8223: -.}f
8224: -..
8225: -.deFR
8226: -\%\&\f5\\$1\f1\\$2 \\$3 \\$4 \\$5 \\$6
8227: -..
8228: -.deRF
8229: -\%\&\f1\\$1\f5\\$2\f1\\$3
8230: -..
8231: -.deEX
8232: -.ift .ft5
8233: -.nf
8234: -..
8235: -.deEE
8236: -.ft1
8237: -.fi
8238: -..
8239: -.dePP
8240: -.sp\\n(PDu
8241: -.ne1.1v
8242: -.}E
8243: -.nr)I \\n()Mu
8244: -.ns
8245: -..
8246: -.deP
8247: -.PP
8248: -..
8249: -.deLP
8250: -.PP
8251: -..
8252: -.dePD
8253: -.ift .nr PD .4v
8254: -.ifn .nr PD 1v
8255: -.if!\\$1 .nr PD \\$1v
8256: -..
8257: -.deHP
8258: -.sp\\n(PDu
8259: -.ne1.1v
8260: -.if!\\$1 .nr )I \\$1n
8261: -.ll\\n(LLu
8262: -.in\\n()Ru+\\n(INu+\\n()Iu
8263: -.ti\\n()Ru+\\n(INu
8264: -.}f
8265: -..
8266: -.deIP
8267: -.ie!\\$1 \{.TP "\\$2"
8268: -\&\\$1\}
8269: -.el\{.sp\\n(PDu
8270: -.ne1.1v
8271: -.if!\\$2 .nr )I \\$2n
8272: -.}f
8273: -.ll\\n(LLu
8274: -.in\\n()Ru+\\n(INu+\\n()Iu
8275: -.lg\}
8276: -..
8277: -.deTP
8278: -.if!\\$1 \{.nr )I \\$1n
8279: -.if\\$10 .nr )I \\n()M\}
8280: -.sp\\n(PDu
8281: -.ne1.1v
8282: -.in\\n()Ru
8283: -.lg0
8284: -.ns
8285: -.it1 }N
8286: -.nr)E 1
8287: -.di]B
8288: -..
8289: -.deTF
8290: -.IP "" \w'\f5\\$1\ \ \fP'u
8291: -.PD0
8292: -..
8293: -.de}1
8294: -.ds]X \&\\*(]B\\
8295: -.rm]B
8296: -.nr)E 0
8297: -.if!\\$1 .nr )I \\$1n
8298: -.}f
8299: -.ll\\n(LLu
8300: -.in\\n()Ru+\\n(INu+\\n()Iu
8301: -.ti\\n(INu
8302: -.ie!\\n()Iu+\\n()Ru-\w\\*(]Xu-3p \{\\*(]X
8303: -.br\}
8304: -.el\\*(]X\h|\\n()Iu+\\n()Ru\c
8305: -.}f
8306: -.lg
8307: -..
8308: -.de}N
8309: -.if\\n()E .br
8310: -.if\\n()E1 .di
8311: -.if\\n()E0 .}f
8312: -.if\\n()E1 .}1
8313: -.if\\n()E2 .}2
8314: -..
8315: -.deRS
8316: -.nr]\\n+()p \\n()I
8317: -.nr)\\n()p \\n()R
8318: -.ie!\\$1 .nr )R +\\$1n
8319: -.el.nr )R +\\n()I
8320: -.nr)I \\n()Mu
8321: -.}E
8322: -..
8323: -.deRE
8324: -.if!\\$1 \{.ie \\$10 .nr )p 1 1
8325: -.el.nr )p \\$1 1 \}
8326: -.ds]i \\*(]I\\n()p
8327: -.ds]r \\*(]R\\n()p
8328: -.nr)I \\*(]i
8329: -.nr)R \\*(]r
8330: -.if\\n()p .nr )p -1
8331: -.}E
8332: -..
8333: -'''\" .2C begin 2-column display, by diversion
8334: -'''\" CC=amount of text that will fit on page
8335: -'''\" CL=1 multicolumn in effect, else 0
8336: -'''\" CI saved indent
8337: -'''\" CB contains diverted text
8338: -.de 2C
8339: -.ne 2
8340: -.nf
8341: -.nr CC \\n(.t/1v*2v
8342: -.nr CI \\n(IN
8343: -.nr IN 0
8344: -.di CB
8345: -.nr CL 1
8346: -.}E
8347: -.dt \\n(CCu C1
8348: -..
8349: -'''\" .1C return to 1-column
8350: -.de 1C
8351: -.nr CL 0
8352: -.C1
8353: -.fi
8354: -..
8355: -'''\" end of diversion, at end of page or return to 1-column
8356: -'''\" CC=pos of nominal column end
8357: -.de C1
8358: -.dt
8359: -\!.C3
8360: -.di
8361: -.if \\n(dn \{.nr CC \\n(dnu/2u+\\n(nlu
8362: -.wh \\n(CCu C2
8363: -.mk
8364: -.nf
8365: -.nr IN \\n(CIu
8366: -.}E
8367: -.CB \}
8368: -..
8369: -'''\" end of first column retrieved from diversion
8370: -'''\" CC=pos of actual column end
8371: -.de C2
8372: -.wh \\n(CCu
8373: -.mk CC
8374: -.po +(\\n(LLu/2u)u
8375: -.rt
8376: -.if \\n(dn>1v .ns
8377: -..
8378: -'''\" end of second column
8379: -.de C3
8380: -.br
8381: -.po -(\\n(LLu/2u)u
8382: -.if \\n(CC>\\n(nl .sp |\\n(CCu
8383: -.ne 2
8384: -..
8385: -.dePM
8386: -.if\\$1 .nr !K 0
8387: -.if\w\\$1 \{\
8388: -.ie\\$1P .nr !K 1
8389: -.el.ie \\$1BP .nr !K 3
8390: -.el.ie \\$1BR .nr !K 4
8391: -.el.nr !K 2 \}
8392: -.if\\n(!K .wh -(\\n(:mu+5v) )G
8393: -..
8394: -.de)G
8395: -.if\\n(!K 'sp 2v
8396: -.ie\\n(!K=1 \{\
8397: -.iet .bd1 3
8398: -.el.bd1 0
8399: -.tlPRIVATE
8400: -.bd1
8401: -.tlThis information should not be disclosed to unauthorized persons.
8402: -.tlIt is meant solely for use by authorized Bell System employees. \}
8403: -.el.ie \\n(!K=3 \{\
8404: -.iet .bd1 3
8405: -.el.bd1 0
8406: -.tlBELL LABORATORIES PROPRIETARY
8407: -.bd1
8408: -.tlNot for use or disclosure outside Bell Laboratories except by
8409: -.tlwritten approval of the director of the distributing organization. \}
8410: -.el.ie \\n(!K=4 \{\
8411: -.iet .bd1 3
8412: -.el.bd1 0
8413: -.tlBELL LABORATORIES RESTRICTED
8414: -.bd1
8415: -.tlThe information herein is meant solely for use by authorized
8416: -.tlBell Laboratories employees and is not to be disclosed to others. \}
8417: -.el.if \\n(!K=2 \{\
8418: -.iet .bd1 3
8419: -.el.bd1 0
8420: -.tlNOTICE
8421: -.bd1
8422: -.tlNot for use or disclosure outside the
8423: -.tlBell System except under written agreement. \}
8424: -..
8425: -.nr)s 0
8426: -.ift .if \ns .nr )s 1
8427: -.nr)t 0
8428: -.ift .if !\ns .nr )t 1
8429: -.if\n()s \{.nr )L 9i
8430: -.nrLL 4.75i
8431: -.nr)O .75i
8432: -.nr)S 9
8433: -.nr)V 10 \}
8434: -.if\n()t \{.nr )L 11i
8435: -.nrLL 6.5i
8436: -.nr)O 1i
8437: -.nr)S 10
8438: -.nr)V 12 \}
8439: -.ift \{.ds R \(rg
8440: -.dsS \s\n()S
8441: -..\}
8442: -.ifn \{.nr )L 11i
8443: -.nrLL 6.5i
8444: -.nr)O .463i
8445: -.if '\*(.T'think' \{.nrLL 80n
8446: -.nr)O 0\}
8447: -.if '\*(.T'thinksmall' \{.nrLL 142n
8448: -.vs 9p
8449: -.nr)O 0\}
8450: -.dsR (Reg.)
8451: -.dsS
8452: -..\}
8453: -.if\nT .nr LL 80n
8454: -.if\nV>1 \{
8455: -.nrLL 82n
8456: -.nr)L 84v
8457: -.rmul \}
8458: -.nr)p 0 1
8459: -.ds]I \\\\n(]
8460: -.ds]R \\\\n()
8461: -.if\nd0 .nr m \n(mo-1
8462: -.if\nm0 .ds ]m January
8463: -.if\nm1 .ds ]m February
8464: -.if\nm2 .ds ]m March
8465: -.if\nm3 .ds ]m April
8466: -.if\nm4 .ds ]m May
8467: -.if\nm5 .ds ]m June
8468: -.if\nm6 .ds ]m July
8469: -.if\nm7 .ds ]m August
8470: -.if\nm8 .ds ]m September
8471: -.if\nm9 .ds ]m October
8472: -.if\nm10 .ds ]m November
8473: -.if\nm11 .ds ]m December
8474: -.ifn \{.nr m \nm+1
8475: -.ie\nd .ds ]W (last mod. \nm/\nd/\ny)
8476: -.el.ds ]W (printed \n(mo/\n(dy/\n(yr)
8477: -..\}
8478: -.if\n()s .ds ]W
8479: -.if\n()t \{.ie \nd .ds ]W \*(]m \nd, 19\ny
8480: -.el.ds ]W \*(]m \n(dy, 19\n(yr
8481: -..\}
8482: -.pl\n()Lu
8483: -.ll\n(LLu
8484: -.lt\n(LLu
8485: -.po\n()Ou
8486: -.fp 5 L CW
8487: -.ift .tr \``\''
8488: -.}f
8489: -.if\n()s .nr :m 3.5v
8490: -.if\n()t .nr :m 6v
8491: -.ifn .nr :m 7v
8492: -.ift .nr )M 3.6m
8493: -.ifn .nr )M 5n
8494: -.em}K
8495: -.nr q \np
8496: -.if!\np .nr p 1
8497: -.pn \np
8498: //GO.SYSIN DD ./tmac.an
8499: echo ./mkfile 1>&2
8500: sed 's/.//' >./mkfile <<'//GO.SYSIN DD ./mkfile'
8501: -NAMES=alloc arc bquote builtins dir expand gen glob graph job\
8502: - lex main makefile match mk parse quote\
8503: - recipe regexp rule run shprint sig symtab t_ar t_driver t_file var word
8504: -OBJ=${NAMES:%=%.o}
8505: -NPROC=2
8506: -BUILTINS=
8507: -# for profiling, use -p -DPROF
8508: -CFLAGS=-I.. -DSYSV
8509: -
8510: -nmk: $OBJ
8511: - $CC $CFLAGS -o nmk $OBJ fio/fio.a libc/libc.a math/math.a
8512: -
8513: -goo:V: nmk
8514: - nmk
8515: -
8516: -clean:V:
8517: - rm -f cyntax nmk *.o O/*
8518: -
8519: -install:V: nmk
8520: - cp nmk /usr/bin/mk
8521: - strip /usr/bin/mk
8522: -
8523: -pp:V:
8524: - pr *.h *.c | lp -dpsu -n2
8525: -
8526: -%.o: mk.h
8527: -
8528: -%.o: %.c
8529: - $CC $CFLAGS -c $stem.c
8530: -
8531: -tut.out: tut.ms
8532: - pic tut.ms | tbl | troff -Tpost -ms > tut.out
8533: -
8534: -sane:V: nmk
8535: - cp nmk goo
8536: - rm arc.o; goo -e
8537: - goo -e -wjob.o
8538: -
8539: -poot:V: nmk
8540: - echo 'pooter Any Dk,g nj/fart/whistle.uucp' >> /n/research/usr/lib/uucp/Systems.dk
8541: - ./nmk -k -i -f /usr/lib/upas/mkfile NPROC=1 systems
8542: //GO.SYSIN DD ./mkfile
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.