commit 4625855
shrub
·
2026-04-26 21:16:18 +0000 UTC
parent 4625855
initial
16 files changed,
+2176,
-0
A
Makefile
+32,
-0
1@@ -0,0 +1,32 @@
2+# Description file for the Make command
3+.POSIX:
4+CC = cc
5+CFLAGS = -std=c89 -w -O2 -Dpwb -Dunix
6+YACC = byacc
7+
8+OBJ = version.o main.o doname.o misc.o files.o dosys.o pwb.o gram.o
9+
10+make: $(OBJ)
11+ $(CC) $(CFLAGS) $(OBJ) -o make
12+
13+$(OBJ): defs
14+
15+gram.o: gram.y lex.c
16+ $(YACC) gram.y
17+ $(CC) $(CFLAGS) -c y.tab.c -o gram.o
18+ rm -f y.tab.c
19+
20+.c.o:
21+ $(CC) -c $(CFLAGS) $<
22+
23+FILES = Makefile pwinfo pr_make.sh rc version.c defs main.c doname.c \
24+ misc.c files.c dosys.c gram.y lex.c gcos.c pwb.c
25+
26+install: make
27+ cp make /bin/pwmake
28+
29+arch:
30+ tar czf make.tar.gz $(FILES)
31+
32+clean:
33+ -rm -f *.o y.tab.c make
A
defs
+125,
-0
1@@ -0,0 +1,125 @@
2+#include <stdio.h>
3+#include <signal.h>
4+
5+#define pwb
6+
7+#define SHELLCOM "/bin/sh"
8+#define TIMETYPE long int
9+
10+#ifdef gcos
11+#undef TIMETYPE
12+#define TIMETYPE int
13+#endif
14+
15+/* define FSTATIC to be static on systems with C compilers
16+ supporting file-static; otherwise define it to be null
17+*/
18+#define FSTATIC static
19+
20+#define HASHSIZE 255
21+#define NLEFTS 40
22+#define NCHARS 500
23+#define NINTS 250
24+#define YYLMAX 400
25+
26+#define ALLDEPS 1
27+#define SOMEDEPS 2
28+
29+
30+extern int sigivalue;
31+extern int sigqvalue;
32+extern int dbgflag;
33+extern int prtrflag;
34+extern int silflag;
35+extern int noexflag;
36+extern int noruleflag;
37+extern int touchflag;
38+extern int questflag;
39+extern int ndocoms;
40+extern int ignerr;
41+extern int okdel;
42+extern int inarglist;
43+extern char *prompt;
44+
45+
46+
47+struct nameblock
48+ {
49+ struct nameblock *nextp;
50+ char *namep;
51+ struct lineblock *linep;
52+ int done;
53+ int septype;
54+ TIMETYPE modtime;
55+ };
56+
57+extern struct nameblock *mainname ;
58+extern struct nameblock *firstname;
59+
60+struct lineblock
61+ {
62+ struct lineblock *nextp;
63+ struct depblock *depp;
64+ struct shblock *shp;
65+ };
66+extern struct lineblock *sufflist;
67+
68+struct depblock
69+ {
70+ struct depblock *nextp;
71+ struct nameblock *depname;
72+ };
73+
74+struct shblock
75+ {
76+ struct shblock *nextp;
77+ char *shbp;
78+ };
79+
80+struct varblock
81+ {
82+ struct varblock *nextp;
83+ char *varname;
84+ char *varval;
85+ int noreset:1;
86+ int used:1;
87+ };
88+extern struct varblock *firstvar;
89+
90+struct pattern
91+ {
92+ struct pattern *nextp;
93+ char *patval;
94+ };
95+extern struct pattern *firstpat;
96+
97+struct opendir
98+ {
99+ struct opendir *nextp;
100+ FILE * dirfc;
101+ char *dirn;
102+ };
103+extern struct opendir *firstod;
104+
105+
106+struct chain
107+ {
108+ struct chain *nextp;
109+ char *datap;
110+ };
111+
112+extern void *intalloc(int);
113+extern char *copys(char *);
114+extern char *concat(char *, char *, char *);
115+extern TIMETYPE exists(char *);
116+extern TIMETYPE prestime(void);
117+extern struct nameblock *srchname(char *);
118+extern struct nameblock *makename(char *);
119+extern struct varblock *varptr(char *);
120+extern struct depblock *srchdir(char *, int, struct depblock *);
121+extern void disint(void);
122+extern void intrupt(int);
123+extern void enbint(void (*)(int));
124+extern char *logdir(void);
125+extern void pexinit(void);
126+extern void pexec(char *, char **);
A
doname.c
+270,
-0
1@@ -0,0 +1,270 @@
2+#include "defs"
3+
4+void docom(struct shblock *);
5+void expand(struct depblock *);
6+
7+/* BASIC PROCEDURE. RECURSIVE. */
8+
9+/*
10+p->done = 0 don't know what to do yet
11+p->done = 1 file in process of being updated
12+p->done = 2 file already exists in current state
13+*/
14+
15+TIMETYPE doname(p,reclevel)
16+struct nameblock *p;
17+int reclevel;
18+{
19+int okdel1;
20+int didwork;
21+TIMETYPE td, td1, tdep, ptime, ptime1, prestime(), exists();
22+struct depblock *q, *qtemp, *srchdir(), *suffp, *suffp1;
23+struct nameblock *p1, *p2, *srchname();
24+struct shblock *implcom, *explcom;
25+struct lineblock *lp, *lp1, *lp2;
26+char *concat(),sourcename[100],prefix[100],temp[100],concsuff[20];
27+char *pnamep, *p1namep;
28+struct chain *qchain;
29+
30+if(p == 0) return(0);
31+
32+if(dbgflag)
33+ {
34+ printf("doname(%s,%d)\n",p->namep,reclevel);
35+ fflush(stdout);
36+ }
37+
38+if(p->done > 0) return(p->modtime);
39+
40+tdep = 0;
41+implcom = 0;
42+explcom = 0;
43+ptime = exists(p->namep);
44+ptime1 = 0;
45+didwork = 0;
46+p->done = 1; /* avoid infinite loops */
47+
48+qchain = 0;
49+
50+/* Expand any names that have embedded metacharaters */
51+
52+for(lp = p->linep ; lp!=0 ; lp = lp->nextp)
53+ for(q=lp->depp ; q!=0 ; q=qtemp )
54+ {
55+ qtemp = q->nextp;
56+ expand(q);
57+ }
58+
59+/* make sure all dependents are up to date */
60+
61+for(lp = p->linep ; lp!=0 ; lp = lp->nextp)
62+ {
63+ td = 0;
64+ for(q = lp->depp ; q!=0 ; q=q->nextp)
65+ {
66+ td1 = doname(q->depname,reclevel+1);
67+ if(dbgflag)
68+ printf("TIME(%s)=%ld\n", q->depname->namep, td1);
69+ if(td1 > td) td = td1;
70+ if(ptime < td1)
71+ appendq(&qchain, q->depname->namep);
72+ }
73+ if(p->septype == SOMEDEPS)
74+ {
75+ if(lp->shp!=0)
76+ if( ptime<td || (ptime==0 && td==0) )
77+ {
78+ okdel1 = okdel;
79+ okdel = 0;
80+ setvar("@", p->namep);
81+ setvar("?", mkqlist(qchain) );
82+ qchain = 0;
83+ if( !questflag )
84+ docom(lp->shp);
85+ setvar("@", 0);
86+ okdel = okdel1;
87+ ptime1 = prestime();
88+ ++didwork;
89+ }
90+ }
91+
92+ else {
93+ if(lp->shp != 0)
94+ if(explcom)
95+ fprintf(stderr, "Too many command lines for `%s'\n",
96+ p->namep);
97+ else explcom = lp->shp;
98+
99+ if(td > tdep) tdep = td;
100+ }
101+ }
102+
103+/* Look for implicit dependents, using suffix rules */
104+
105+for(lp=sufflist ; lp!=0 ; lp = lp->nextp)
106+ for(suffp = lp->depp ; suffp!=0 ; suffp = suffp->nextp)
107+ {
108+ pnamep = suffp->depname->namep;
109+ if(suffix(p->namep , pnamep , prefix))
110+ {
111+ srchdir( concat(prefix,"*",temp) , 0,0);
112+ for(lp1 = sufflist ; lp1!=0 ; lp1 = lp1->nextp)
113+ for(suffp1=lp1->depp ; suffp1!=0 ; suffp1 = suffp1->nextp)
114+ {
115+ p1namep = suffp1->depname->namep;
116+ if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
117+ (p2=srchname(concat(prefix, p1namep ,sourcename))) )
118+ {
119+ td = doname(p2,reclevel+1);
120+ if(ptime < td)
121+ appendq(&qchain, p2->namep);
122+if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
123+ if(td > tdep) tdep = td;
124+ setvar("*", prefix);
125+ setvar("<", copys(sourcename));
126+ for(lp2=p1->linep ; lp2!=0 ; lp2 = lp2->nextp)
127+ if(implcom = lp2->shp) break;
128+ goto endloop;
129+ }
130+ }
131+ }
132+ }
133+
134+endloop:
135+
136+
137+if(ptime<tdep || (ptime==0 && tdep==0) )
138+ {
139+ ptime = (tdep>0 ? tdep : prestime() );
140+ setvar("@", p->namep);
141+ setvar("?", mkqlist(qchain) );
142+ if(explcom) docom(explcom);
143+ else if(implcom) docom(implcom);
144+ else if(p->septype == 0)
145+ if(p1=srchname(".DEFAULT"))
146+ {
147+ setvar("<", p->namep);
148+ for(lp2=p1->linep ; lp2!=0 ; lp2 = lp2->nextp)
149+ if(implcom = lp2->shp)
150+ {
151+ docom(implcom);
152+ break;
153+ }
154+ }
155+ else {
156+ fprintf(stderr," Don't know how to make %s", p->namep);
157+ fatal("");
158+ }
159+
160+ setvar("@", 0);
161+ if( (ptime = exists(p->namep)) == 0)
162+ ptime = prestime();
163+ }
164+
165+else if(!questflag && reclevel==0 && didwork==0)
166+ printf("`%s' is up to date.\n", p->namep);
167+
168+if(questflag && reclevel==0)
169+ exit(ndocoms>0 ? -1 : 0);
170+
171+p->done = 2;
172+if(ptime1 > ptime) ptime = ptime1;
173+p->modtime = ptime;
174+return(ptime);
175+}
176+
177+void docom(q)
178+struct shblock *q;
179+{
180+char *s;
181+struct varblock *varptr();
182+int status;
183+int ign, nopr;
184+char string[400];
185+
186+++ndocoms;
187+if(questflag)
188+ return;
189+
190+if(touchflag)
191+ {
192+ s = varptr("@")->varval;
193+ if(!silflag)
194+ printf("touch(%s)\n", s);
195+ if(!noexflag)
196+ touch(s);
197+ }
198+
199+else for( status = 0; q!=0 ; q = q->nextp )
200+ {
201+ subst(q->shbp,string);
202+
203+ ign = ignerr;
204+ nopr = 0;
205+ for(s = string ; *s=='-' || *s=='@' ; ++s)
206+ if(*s == '-') ign = 1;
207+ else nopr = 1;
208+
209+ status |= docom1(s, ign, nopr);
210+
211+ }
212+}
213+
214+
215+
216+docom1(comstring, nohalt, noprint)
217+char *comstring;
218+int nohalt, noprint;
219+{
220+int status;
221+
222+if(comstring[0] == '\0') return(0);
223+
224+if(!silflag && (!noprint || noexflag) )
225+ {
226+ printf("%s%s\n", (noexflag ? "" : prompt), comstring);
227+ fflush(stdout);
228+ }
229+
230+if(noexflag) return(0);
231+
232+if( status = dosys(comstring, nohalt) )
233+ if (!nohalt)
234+ {
235+ printf("*** Error code %d", status );
236+ fatal(0);
237+ }
238+
239+return(status);
240+}
241+
242+
243+/*
244+ If there are any Shell meta characters in the name,
245+ expand into a list, after searching directory
246+*/
247+
248+void expand(q)
249+struct depblock *q;
250+{
251+register char *s;
252+char *s1;
253+struct depblock *p, *srchdir();
254+
255+s1 = q->depname->namep;
256+for(s=s1 ; ;) switch(*s++)
257+ {
258+ case '\0':
259+ return;
260+
261+ case '*':
262+ case '?':
263+ case '[':
264+ if(p = srchdir(s1 , 1 , q->nextp) )
265+ {
266+ q->nextp = p;
267+ q->depname = 0;
268+ }
269+ return;
270+ }
271+}
A
dosys.c
+136,
-0
1@@ -0,0 +1,136 @@
2+# include "defs"
3+#include <unistd.h>
4+
5+dosys(comstring,nohalt)
6+char *comstring;
7+int nohalt;
8+{
9+int status;
10+
11+if(metas(comstring))
12+ status = doshell(comstring,nohalt);
13+else status = doexec(comstring);
14+
15+return(status>>8);
16+}
17+
18+
19+
20+metas(s) /* Are there are any Shell meta-characters? */
21+char *s;
22+{
23+for(;;) switch(*s++)
24+ {
25+ case '|': case '^':
26+ case '(': case ')':
27+ case ';': case '&':
28+ case '<': case '>':
29+ case '*': case '?':
30+ case '[': case ']':
31+ case '\\': case '\n':
32+ case '\'': case '"':
33+ case '`': case '$':
34+ case ':':
35+ return(1);
36+
37+ case '\0':
38+ return(0);
39+ };
40+}
41+
42+doshell(comstring,nohalt)
43+char *comstring;
44+int nohalt;
45+{
46+if(fork() == 0)
47+ {
48+ enbint(SIG_DFL);
49+ doclose();
50+
51+ if( execl(SHELLCOM, "sh", "-c", comstring, 0) )
52+ fatal("Couldn't load Shell");
53+ }
54+
55+return( await() );
56+}
57+
58+
59+
60+
61+await()
62+{
63+int status;
64+
65+disint();
66+wait(&status);
67+enbint(intrupt);
68+return(status);
69+}
70+
71+
72+
73+
74+
75+
76+doclose() /* Close open directory files before exec'ing */
77+{
78+register struct opendir *od;
79+for (od = firstod; od != 0; od = od->nextp)
80+ if (od->dirfc != NULL)
81+ fclose(od->dirfc);
82+}
83+
84+
85+
86+
87+doexec(str)
88+char *str;
89+{
90+register char *s, *t;
91+char *argv[100], pool[1000];
92+int status;
93+int argc;
94+
95+
96+argc = 0;
97+s = pool;
98+
99+for(t=str ; *t!='\0' ; )
100+ {
101+ while(*t==' '|| *t=='\t') ++t;
102+ if(*t == '\0') break;
103+
104+ argv[argc++] = s;
105+ while(*t!=' ' && *t!='\t' && *t!='\0') *s++ = *t++;
106+ *s++ = '\0';
107+ }
108+
109+if(argc == 0) /* no command */
110+ return(-1);
111+argv[argc] = 0;
112+
113+if(fork() == 0)
114+ {
115+ enbint(SIG_DFL);
116+ doclose();
117+
118+ pexec(argv[0], argv);
119+ fprintf(stderr, "*** Cannot load %s",argv[0]);
120+ fatal("");
121+ }
122+
123+return( await() );
124+}
125+
126+
127+ char junkname[16];
128+
129+touch(s)
130+char *s;
131+{
132+if(junkname[0] == 0)
133+ sprintf(junkname, "MAKEJUNK%d", getpid() );
134+
135+link(s, junkname);
136+unlink(junkname);
137+}
A
files.c
+236,
-0
1@@ -0,0 +1,236 @@
2+/* UNIX DEPENDENT PROCEDURES */
3+
4+#include <sys/stat.h>
5+#include <dirent.h>
6+#include <stdlib.h>
7+
8+/* DEFAULT RULES FOR UNIX */
9+
10+char *builtin[] =
11+ {
12+ ".SUFFIXES : .o .c .e .r .f .y .yr .ye .l .s .w .t .h .z .x",
13+ "YACC=yacc",
14+ "YACCR=yacc -r",
15+ "YACCE=yacc -e",
16+ "YFLAGS=",
17+ "LEX=lex",
18+ "LFLAGS=",
19+ "CC=cc",
20+ "AS=as -",
21+ "CFLAGS=",
22+ "RC=ec",
23+ "RFLAGS=",
24+ "EC=ec",
25+ "EFLAGS=",
26+ "FFLAGS=",
27+ "CAWK=awk -c -f",
28+ "SCOMP=scomp",
29+ "SCFLAGS=",
30+ "CMDICT=cmdict",
31+ "CMFLAGS=",
32+ ".c.o :",
33+ "\t$(CC) $(CFLAGS) -c $<",
34+ ".e.o .r.o .f.o :",
35+ "\t$(EC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<",
36+ ".s.o :",
37+ "\t$(AS) -o $@ $<",
38+ ".y.o :",
39+ "\t$(YACC) $(YFLAGS) $<",
40+ "\t$(CC) $(CFLAGS) -c y.tab.c",
41+ "\trm y.tab.c",
42+ "\tmv y.tab.o $@",
43+ ".yr.o:",
44+ "\t$(YACCR) $(YFLAGS) $<",
45+ "\t$(RC) $(RFLAGS) -c -2 y.tab.r",
46+ "\trm y.tab.r",
47+ "\tmv y.tab.o $@",
48+ ".ye.o :",
49+ "\t$(YACCE) $(YFLAGS) $<",
50+ "\t$(EC) $(RFLAGS) -c -2 y.tab.e",
51+ "\trm y.tab.e",
52+ "\tmv y.tab.o $@",
53+ ".l.o :",
54+ "\t$(LEX) $(LFLAGS) $<",
55+ "\t$(CC) $(CFLAGS) -c lex.yy.c",
56+ "\trm lex.yy.c",
57+ "\tmv lex.yy.o $@",
58+ ".y.c :",
59+ "\t$(YACC) $(YFLAGS) $<",
60+ "\tmv y.tab.c $@",
61+ ".l.c :",
62+ "\t$(LEX) $<",
63+ "\tmv lex.yy.c $@",
64+ ".yr.r:",
65+ "\t$(YACCR) $(YFLAGS) $<",
66+ "\tmv y.tab.r $@",
67+ ".ye.e :",
68+ "\t$(YACCE) $(YFLAGS) $<",
69+ "\tmv y.tab.e $@",
70+ ".w.c:",
71+ "\t$(CAWK) $<",
72+ "\tmv yy.awk.c $@",
73+ ".w.o:",
74+ "\t$(CAWK) $<",
75+ "\t$(CC) $(CFLAGS) -c yy.awk.c",
76+ "\trm yy.awk.c",
77+ "\tmv yy.awk.o $@",
78+ ".t.o:",
79+ "\t$(SCOMP) $(SCFLAGS) -c $<",
80+ ".t.c:",
81+ "\t$(SCOMP) $(SCFLAGS) -t $<",
82+ ".h.z .t.z:",
83+ "\t$(CMDICT) $(CMFLAGS) $<",
84+ ".h.x .t.x:",
85+ "\t$(CMDICT) $(CMFLAGS) -x $<",
86+ 0 };
87+
88+#include "defs"
89+
90+
91+TIMETYPE exists(filename)
92+char *filename;
93+{
94+struct stat buf;
95+
96+if(stat(filename,&buf) < 0)
97+ return(0);
98+else return(buf.st_mtime);
99+}
100+
101+
102+TIMETYPE prestime()
103+{
104+long int t;
105+time(&t);
106+return(t);
107+}
108+
109+
110+
111+struct depblock *srchdir(pat, mkchain, nextdbl)
112+
113+char *pat; /* pattern to be matched in directory */
114+int mkchain; /* nonzero if results to be remembered */
115+struct depblock *nextdbl; /* final value for chain */
116+{
117+DIR *dirf;
118+struct dirent *entry;
119+char *dirname, *dirpref, *endir, *filepat, *p, temp[100];
120+char fullname[100], *copys();
121+struct nameblock *q, *srchname(), *makename();
122+struct depblock *thisdbl;
123+struct pattern *patp;
124+
125+thisdbl = 0;
126+
127+if(mkchain == 0)
128+ for(patp=firstpat ; patp!=0 ; patp = patp->nextp)
129+ if(equals(pat, patp->patval)) return(0);
130+
131+patp = intalloc(sizeof(*patp));
132+patp->nextp = firstpat;
133+firstpat = patp;
134+patp->patval = copys(pat);
135+
136+endir = 0;
137+
138+for(p=pat; *p!='\0'; ++p)
139+ if(*p=='/') endir = p;
140+
141+if(endir==0)
142+ {
143+ dirname = ".";
144+ dirpref = "";
145+ filepat = pat;
146+ }
147+else {
148+ dirname = pat;
149+ *endir = '\0';
150+ dirpref = concat(dirname, "/", temp);
151+ filepat = endir+1;
152+ }
153+
154+dirf = opendir(dirname);
155+
156+if(dirf == NULL)
157+ {
158+ fprintf(stderr, "Directory %s: ", dirname);
159+ fatal("Cannot open");
160+ }
161+
162+while( (entry = readdir(dirf)) != NULL )
163+ {
164+ if(entry->d_ino == 0) continue;
165+ if( amatch(entry->d_name, filepat) )
166+ {
167+ concat(dirpref, entry->d_name, fullname);
168+ if( (q=srchname(fullname)) == 0)
169+ q = makename(copys(fullname));
170+ if(mkchain)
171+ {
172+ thisdbl = intalloc(sizeof(*thisdbl));
173+ thisdbl->nextp = nextdbl;
174+ thisdbl->depname = q;
175+ nextdbl = thisdbl;
176+ }
177+ }
178+ }
179+
180+closedir(dirf);
181+
182+if(endir != 0) *endir = '/';
183+
184+return(thisdbl);
185+}
186+
187+/* stolen from glob through find */
188+
189+amatch(s, p)
190+char *s, *p;
191+{
192+ register int cc, scc, k;
193+ int c, lc;
194+
195+ scc = *s;
196+ lc = 077777;
197+ switch (c = *p) {
198+
199+ case '[':
200+ k = 0;
201+ while (cc = *++p) {
202+ switch (cc) {
203+
204+ case ']':
205+ if (k)
206+ return(amatch(++s, ++p));
207+ else
208+ return(0);
209+
210+ case '-':
211+ k |= lc <= scc & scc <= (cc=p[1]);
212+ }
213+ if (scc==(lc=cc)) k++;
214+ }
215+ return(0);
216+
217+ case '?':
218+ caseq:
219+ if(scc) return(amatch(++s, ++p));
220+ return(0);
221+ case '*':
222+ return(umatch(s, ++p));
223+ case 0:
224+ return(!scc);
225+ }
226+ if (c==scc) goto caseq;
227+ return(0);
228+}
229+
230+umatch(s, p)
231+char *s, *p;
232+{
233+ if(*p==0) return(1);
234+ while(*s)
235+ if (amatch(s++,p)) return(1);
236+ return(0);
237+}
A
gcos.c
+331,
-0
1@@ -0,0 +1,331 @@
2+/* GCOS DEPENDENT PROCEDURES */
3+
4+
5+/* DEFAULT RULES FOR GCOS */
6+
7+char *builtin[]
8+ {
9+ ".SUFFIXES : .d .c .y .lib",
10+ ".d.c:",
11+ "\t./dtgen $<",
12+ ".y.c:",
13+ "\t./yacc $<",
14+ "\tcopy y.tab.c; /$@",
15+ ".y.lib:",
16+ "\t./yacc $<",
17+ "\t./cc y.tab.c r=$@",
18+ ".c.lib:",
19+ "\t./cc $< r=$@",
20+ 0 };
21+
22+# define MAXCSIZE 500
23+# define YZERO 60
24+
25+int gtcalled 0;
26+
27+/* all kinds of static declarations that must be used.. */
28+
29+static double day { 64*1000*60*60*24 }; /* length of day in clock ticks */
30+
31+struct { int lhs:18, rhs:18; };
32+struct catb {
33+ int words[6],
34+ name1, name2,
35+ passw1, passw2,
36+ word10, word11,
37+ datcreat, datmod, datused,
38+ stuff[6],
39+ jjjj:18, tused:18;
40+ };
41+struct { int :3, slot:18; }; /* slot where time from cat. block fits */
42+
43+struct catdesc {
44+ int cat1, cat2, cpass1, cpass2,
45+ file1, file2, filep1, filep2,
46+ endmark; };
47+
48+extern int _q_reg, _a_reg;
49+
50+
51+# define A10(x,y) 10*x + y
52+
53+/* interpret the mm/dd/yy format */
54+
55+struct d9 { int :5, m1:4, :5, m2:4, :9,
56+ :5, d1:4, :5, d2:4, :9,
57+ :5, y1:4, :5, y2:4 ;};
58+
59+struct d6 { int :2, m61:4, :2, m62:4,
60+ :2, d61:4, :2, d62:4,
61+ :2, y61:4, :2, y62:4; };
62+
63+static day6( d6word ){ /* return the day number of a word in bci format */
64+ int m, y, d;
65+
66+ y = A10( d6word.y61, d6word.y62 );
67+ m = A10( d6word.m61, d6word.m62 );
68+ d = A10( d6word.d61, d6word.d62 );
69+
70+ return( d + 31*( m + 12*(y-YZERO) ) );
71+ }
72+
73+static day9( p ) register int *p; {
74+
75+ int m, y, d;
76+
77+ y = A10( p->y1, p->y2 );
78+ m = A10( p->m1, p->m2 );
79+ d = A10( p->d1, p->d2 );
80+
81+ return( d + 31*( m + 12*(y-YZERO) ) );
82+ }
83+
84+
85+static int dfold( dayno, timeno ){
86+ int kk;
87+ kk = ( day*dayno + timeno) / 32768.;
88+ }
89+
90+int prestime(){
91+ int date[2];
92+ drldrl( 021, date );
93+ return( dfold( day9(date), _q_reg ) );
94+ }
95+
96+
97+
98+# define DODRL ar[0] = status; ar[1] = &b.cat1; drldrl(30,sp1,sp2); p=ar[0]<<18;
99+
100+static struct { int fn1, fn2; int ftm; } fbb[MAXCSIZE];
101+static int catsiz;
102+
103+getcat() {
104+
105+ register i, *p, j;
106+ int asname[4];
107+ struct catdesc b;
108+ int sp1, sp2, temp;
109+ int ar[2], status[2];
110+ int filbuf[380];
111+
112+ gtcalled = 1;
113+
114+ sp1 = ar;
115+ sp1 =>> 18;
116+ sp2 = filbuf;
117+ sp2 =>>18;
118+ sp2.lhs = 19;
119+
120+ b.cat1 = b.cat2 = b.file1 = -1;
121+ b.cpass1 = b.cpass2 = 0202020202020;
122+
123+ DODRL
124+ sp2.lhs++;
125+ for( i=0; p!=0 && i<MAXCSIZE; ++i ){
126+
127+ fbb[i].fn1 = b.file1 = p->name1;
128+ fbb[i].fn2 = b.file2 = p->name2;
129+ b.filep1 = p->passw1;
130+ b.filep2 = p->passw2;
131+ b.endmark = -1;
132+ temp = 0;
133+ temp.slot = p->tused;
134+ fbb[i].ftm = dfold( day6(p->datmod), temp );
135+ DODRL
136+ }
137+ catsiz = i;
138+ }
139+
140+ exists( cp ) char *cp; {
141+ char *s, name[13];
142+ int i, *p, bcd[2];
143+
144+/*
145+ cheat about names with slashes -- try opening;
146+ if it is openable, it exists, and assume it was made
147+ at t=1 (long time ago); otherwise, assume it
148+ does not exist
149+*/
150+
151+for(s=cp ; *s ; ++s)
152+ if(*s == '/')
153+ if(i = copen(cp,'r') < 0)
154+ return(0);
155+ else {
156+ cclose(i);
157+ return(1);
158+ }
159+
160+if(gtcalled == 0) getcat();
161+
162+ p = name;
163+ for( i=0; *cp; ++i ) name[i] = *cp++;
164+ while( i<12 ) name[i++] = ' ';
165+ f9to6( *p, bcd[0], 12 );
166+ for ( i=0; i<catsiz; ++i ){
167+ if( fbb[i].fn1 == bcd[0] && fbb[i].fn2 == bcd[1] )
168+ return( fbb[i].ftm );
169+ }
170+ return( 0 );
171+ }
172+
173+
174+#include "defs"
175+
176+static char n13[13];
177+static char *n13end &n13[12];
178+
179+
180+
181+struct depblock *srchdir(pat, mkchain, nextdbl)
182+
183+char *pat; /* pattern to be matched in directory */
184+int mkchain; /* nonzero if results to be remembered */
185+struct depblock *nextdbl; /* final value for chain */
186+{
187+int dirf;
188+int i, nread;
189+char *dirname, *dirpref, *endir, *filepat, *p, temp[100];
190+char fullname[100], *p1, *p2, *copys();
191+struct nameblock *q, *srchname(), *makename();
192+struct depblock *thisdbl;
193+struct opendir *od;
194+struct pattern *patp;
195+int *intp1, *intp2;
196+
197+if(gtcalled == 0) getcat();
198+thisdbl=0;
199+
200+if(mkchain == 0)
201+ for(patp=firstpat ; patp!=0 ; patp = patp->nextp)
202+ if(equals(pat, patp->patval)) return(0);
203+
204+patp = intalloc(sizeof(*patp));
205+patp->nextp = firstpat;
206+firstpat = patp;
207+patp->patval = copys(pat);
208+
209+endir = 0;
210+
211+for(p=pat; *p!='\0'; ++p)
212+ if(*p=='/') endir = p;
213+
214+if(endir==0)
215+ {
216+ dirname = "";
217+ dirpref = "";
218+ filepat = pat;
219+ }
220+else {
221+fatal("File name has an embedded slash");
222+ dirname = pat;
223+ *endir = '\0';
224+ dirpref = concat(dirname, "/", temp);
225+ filepat = endir+1;
226+ }
227+
228+for(i=0;i<catsiz;++i)
229+ {
230+ intp1 = &fbb[i].fn1;
231+ intp2 = n13;
232+ f6to9(*intp1, *intp2, 12);
233+ for(p1=n13; p1<n13end && *p1!=' ' ; ++p1)
234+ if('A'<=*p1 && *p1<='Z') *p1 =+ ('a'-'A');
235+ *p1 = '\0';
236+
237+ if( amatch(n13,filepat) )
238+ {
239+ concat(dirpref,n13,fullname);
240+ if( (q=srchname(fullname)) ==0)
241+ q = makename(copys(fullname));
242+ if(mkchain)
243+ {
244+ thisdbl = intalloc(sizeof(*thisdbl));
245+ thisdbl->nextp = nextdbl;
246+ thisdbl->depname = q;
247+ nextdbl = thisdbl;
248+ }
249+ }
250+ }
251+
252+if(endir != 0) *endir = '/';
253+
254+return(thisdbl);
255+}
256+
257+/* stolen from glob through find */
258+
259+amatch(s, p)
260+char *s, *p;
261+{
262+ register int cc, scc, k;
263+ int c, lc;
264+
265+ scc = *s;
266+ lc = 077777;
267+ switch (c = *p) {
268+
269+ case '[':
270+ k = 0;
271+ while (cc = *++p) {
272+ switch (cc) {
273+
274+ case ']':
275+ if (k)
276+ return(amatch(++s, ++p));
277+ else
278+ return(0);
279+
280+ case '-':
281+ k =| lc <= scc & scc <= (cc=p[1]);
282+ }
283+ if (scc==(lc=cc)) k++;
284+ }
285+ return(0);
286+
287+ case '?':
288+ caseq:
289+ if(scc) return(amatch(++s, ++p));
290+ return(0);
291+ case '*':
292+ return(umatch(s, ++p));
293+ case 0:
294+ return(!scc);
295+ }
296+ if (c==scc) goto caseq;
297+ return(0);
298+}
299+
300+umatch(s, p)
301+char *s, *p;
302+{
303+ if(*p==0) return(1);
304+ while(*s)
305+ if (amatch(s++,p)) return(1);
306+ return(0);
307+}
308+
309+
310+
311+dosys(comstring,nohalt)
312+char *comstring;
313+int nohalt;
314+{
315+char *p;
316+
317+for(p=comstring ; *p!='\0' ; ++p);
318+if( p-comstring > 80)
319+ fatal("Command string longer than 80 characters");
320+
321+system(comstring);
322+
323+return(0);
324+}
325+
326+
327+touch(s)
328+char *s;
329+{
330+fprintf(stderr, "touch not yet implemented on GCOS\n");
331+cexit(2);
332+}
A
gram.y
+107,
-0
1@@ -0,0 +1,107 @@
2+%{
3+#include "defs"
4+#define YYSTYPE void *
5+%}
6+%term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER
7+
8+
9+%%
10+
11+%{
12+struct depblock *pp;
13+FSTATIC struct shblock *prevshp;
14+
15+FSTATIC struct nameblock *lefts[NLEFTS];
16+struct nameblock *leftp;
17+FSTATIC int nlefts;
18+
19+struct lineblock *lp, *lpp;
20+FSTATIC struct depblock *prevdep;
21+FSTATIC int sepc;
22+%}
23+
24+
25+file:
26+ | file comline
27+ ;
28+
29+comline: START
30+ | MACRODEF
31+ | START namelist deplist shellist = {
32+ while( --nlefts >= 0)
33+ {
34+ leftp = lefts[nlefts];
35+ if(leftp->septype == 0)
36+ leftp->septype = sepc;
37+ else if(leftp->septype != sepc)
38+ fprintf(stderr, "Inconsistent rules lines for `%s'\n",
39+ leftp->namep);
40+ else if(sepc==ALLDEPS && *(leftp->namep)!='.' && $4!=0)
41+ {
42+ for(lp=leftp->linep; lp->nextp!=0; lp=lp->nextp)
43+ if(lp->shp)
44+ fprintf(stderr, "Multiple rules lines for `%s'\n",
45+ leftp->namep);
46+ }
47+
48+ lp = intalloc(sizeof(*lp));
49+ lp->nextp = 0;
50+ lp->depp = $3;
51+ lp->shp = $4;
52+
53+ if(equals(leftp->namep, ".SUFFIXES") && $3==0)
54+ leftp->linep = 0;
55+ else if(leftp->linep == 0)
56+ leftp->linep = lp;
57+ else {
58+ for(lpp = leftp->linep; lpp->nextp!=0;
59+ lpp = lpp->nextp) ;
60+ if(sepc == ALLDEPS)
61+ lpp->shp = 0;
62+ lpp->nextp = lp;
63+ }
64+ }
65+ }
66+ | error
67+ ;
68+
69+namelist: NAME = { lefts[0] = $1; nlefts = 1; }
70+ | namelist NAME = { lefts[nlefts++] = $2;
71+ if(nlefts>NLEFTS) fatal("Too many lefts"); }
72+ ;
73+
74+deplist: = { fatal("Must be a separator on rules line"); }
75+ | dlist
76+ ;
77+
78+dlist: sepchar = { prevdep = 0; $$ = 0; }
79+ | dlist NAME = {
80+ pp = intalloc(sizeof(*pp));
81+ pp->nextp = 0;
82+ pp->depname = $2;
83+ if(prevdep == 0) $$ = pp;
84+ else prevdep->nextp = pp;
85+ prevdep = pp;
86+ }
87+ ;
88+
89+sepchar: COLON = { sepc = ALLDEPS; }
90+ | DOUBLECOLON = { sepc = SOMEDEPS; }
91+ ;
92+
93+shellist: = {$$ = 0; }
94+ | shlist = { $$ = $1; }
95+ ;
96+
97+shlist: SHELLINE = { $$ = $1; prevshp = $1; }
98+ | shlist SHELLINE = { $$ = $1;
99+ prevshp->nextp = $2;
100+ prevshp = $2;
101+ }
102+ ;
103+
104+%%
105+
106+
107+
108+# include "lex.c"
A
lex.c
+183,
-0
1@@ -0,0 +1,183 @@
2+#define W(x) (x==' ' || x=='\t' || x=='\n')
3+#define L(x) ('a'<=x&&x<='z')||('A'<=x&&x<='Z')
4+#define D(x) ('0'<=x&&x<='9')
5+#define S(x) (x=='/'||x=='.'||x=='?'||x=='*'||x=='['||x=='-'||x==']'||x=='_')
6+#define NONTERM(x) (x!='\0'&&x!='\n'&&x!=' '&&x!='\t'&&x!=':'&&x!=';'&&x!='&'&&x!='>')
7+
8+char *zznextc; /* zero if need another line; otherwise points to next char */
9+int yylineno;
10+extern FILE *fin;
11+
12+yylex()
13+{
14+register char *p;
15+register char *q;
16+char word[YYLMAX];
17+
18+if(zznextc == 0)
19+ return( nextlin() );
20+
21+while(W(*zznextc)) ++zznextc;
22+
23+if(*zznextc == '\0')
24+ return( nextlin() );
25+
26+if(*zznextc == ':')
27+ {
28+ if(*++zznextc == ':')
29+ {
30+ ++zznextc;
31+ return(DOUBLECOLON);
32+ }
33+ else return(COLON);
34+ }
35+
36+if(*zznextc == '>')
37+ {
38+ ++zznextc;
39+ return(GREATER);
40+ }
41+
42+if(*zznextc == ';')
43+ return( retsh(zznextc) );
44+
45+p = zznextc;
46+q = word;
47+
48+while(NONTERM(*p))
49+ *q++ = *p++;
50+
51+if(p != zznextc)
52+ {
53+ *q = '\0';
54+ if((yylval=srchname(word))==0)
55+ yylval = makename(word);
56+ zznextc = p;
57+ return(NAME);
58+ }
59+
60+else {
61+ fprintf(stderr,"Bad character %c (octal %o), line %d",
62+ *zznextc,*zznextc,yylineno);
63+ fatal("");
64+ }
65+return(0); /* never executed */
66+}
67+
68+
69+
70+
71+
72+retsh(q)
73+char *q;
74+{
75+register char *p;
76+struct shblock *sp;
77+char *copys();
78+
79+for(p=q+1 ; *p==' '||*p=='\t' ; ++p) ;
80+
81+sp = intalloc(sizeof(*sp));
82+sp->nextp = 0;
83+sp->shbp = (fin == NULL ? p : copys(p) );
84+yylval = sp;
85+zznextc = 0;
86+return(SHELLINE);
87+}
88+
89+nextlin()
90+{
91+static char yytext[YYLMAX];
92+static char *yytextl = yytext+YYLMAX;
93+char *text, templin[YYLMAX];
94+register char c;
95+register char *p, *t;
96+char lastch, *lastchp;
97+extern char **linesptr;
98+int incom;
99+
100+incom = 0;
101+zznextc = 0;
102+
103+if(fin == NULL)
104+ {
105+ char *src;
106+ if( (src = *linesptr++) == 0)
107+ return(0);
108+ ++yylineno;
109+ for(p=yytext; p<yytextl && (*p = *src++); ++p) ;
110+ *p = '\0';
111+ text = yytext;
112+ }
113+
114+else {
115+ for(p=yytext ; ; ++p)
116+ {
117+ if(p > yytextl) fatal("line too long");
118+ *p = getc(fin);
119+ if(*p == EOF)
120+ {
121+ *p = '\0';
122+ return(0);
123+ }
124+ else if(*p == ';') ++incom;
125+ else if (*p=='#' && !incom && yytext[0]!='\t')
126+ *p = '\0';
127+ else if (*p == '\n')
128+ {
129+ ++yylineno;
130+ if(p==text || p[-1]!='\\') break;
131+ p[-1] = ' ';
132+ while( (*p=getc(fin))=='\t' || *p==' ' || *p=='\n')
133+ if(*p == '\n') ++yylineno;
134+
135+ if(*p == EOF)
136+ {
137+ *p = '\0';
138+ return(0);
139+ }
140+ }
141+ }
142+ *p = '\0';
143+ text = yytext;
144+ }
145+
146+c = text[0];
147+
148+if(c == '\t') return( retsh(text) );
149+
150+if(L(c)||D(c)||c==' '||c=='.')
151+ for(p=text+1; *p!='\0'; )
152+ if(*p++ == '=')
153+ {
154+ eqsign(text);
155+ return(MACRODEF);
156+ }
157+
158+/* substtitute for macros on dependency line up to the semicolon if any */
159+
160+for(t = yytext ; *t!='\0' && *t!=';' ; ++t)
161+ ;
162+
163+lastchp = t;
164+lastch = *t;
165+*t = '\0';
166+
167+subst(yytext, templin); /* Substitute for macros on dependency lines */
168+
169+if(lastch)
170+ {
171+ for(t = templin ; *t ; ++t)
172+ ;
173+ *t = lastch;
174+ while( *++t = *++lastchp ) ;
175+ }
176+
177+p = templin;
178+t = yytext;
179+while( *t++ = *p++ )
180+ ;
181+
182+zznextc = text;
183+return(START);
184+}
A
main.c
+329,
-0
1@@ -0,0 +1,329 @@
2+# include "defs"
3+#include <unistd.h>
4+/*
5+command make to update programs.
6+Flags: 'd' print out debugging comments
7+ 'p' print out a version of the input graph
8+ 's' silent mode--don't print out commands
9+ 'f' the next argument is the name of the description file;
10+ "makefile" is the default
11+ 'i' ignore error codes from the shell
12+ 'n' don't issue, just print, commands
13+ 't' touch (update time of) files but don't issue command
14+ 'q' don't do anything, but check if object is up to date;
15+ returns exit code 0 if up to date, -1 if not
16+*/
17+
18+struct nameblock *mainname ;
19+struct nameblock *firstname;
20+struct lineblock *sufflist;
21+struct varblock *firstvar;
22+struct pattern *firstpat ;
23+struct opendir *firstod;
24+
25+int sigivalue = 0;
26+int sigqvalue = 0;
27+int dbgflag = 0;
28+int prtrflag = 0;
29+int silflag = 0;
30+int noexflag = 0;
31+int noruleflag = 0;
32+int touchflag = 0;
33+int questflag = 0;
34+int ndocoms = 0;
35+int ignerr = 0; /* default is to stop on error */
36+int okdel = 1;
37+int inarglist;
38+char *prompt = ">"; /* other systems -- pick what you want */
39+
40+main(argc,argv)
41+int argc;
42+char **argv;
43+{
44+struct nameblock *p, *makename(), *srchname();
45+int i, j;
46+int descset, nfargs;
47+char c, *s;
48+#ifdef unix
49+void intrupt(int);
50+#endif
51+
52+pexinit();
53+descset = 0;
54+
55+inarglist = 1;
56+for(i=1; i<argc; ++i)
57+ if(argv[i]!=0 && argv[i][0]!='-' && eqsign(argv[i]))
58+ argv[i] = 0;
59+
60+setvar("$","$");
61+inarglist = 0;
62+
63+for(i=1; i<argc; ++i)
64+ if(argv[i]!=0 && argv[i][0]=='-')
65+ {
66+ for(j=1 ; (c=argv[i][j])!='\0' ; ++j) switch(c)
67+ {
68+ case 'd':
69+ dbgflag = 1;
70+ break;
71+
72+ case 'p':
73+ prtrflag = 1;
74+ break;
75+
76+ case 's':
77+ silflag = 1;
78+ break;
79+
80+ case 'i':
81+ ignerr = 1;
82+ break;
83+
84+ case 'n':
85+ noexflag = 1;
86+ break;
87+
88+ case 'r':
89+ noruleflag = 1;
90+ break;
91+
92+ case 't':
93+ touchflag = 1;
94+ break;
95+
96+ case 'q':
97+ questflag = 1;
98+ break;
99+
100+ case 'f':
101+ if(i >= argc-1)
102+ fatal("No description argument after -f flag");
103+ if( rddescf(argv[i+1]) )
104+ {
105+ fprintf(stderr,"Cannot open %s",argv[i+1]);
106+ fatal("");
107+ }
108+ argv[i+1] = 0;
109+ ++descset;
110+ break;
111+
112+ default:
113+ fprintf(stderr,"Unknown flag argument %c", c);
114+ fatal("");
115+ }
116+
117+ argv[i] = 0;
118+ }
119+
120+if( !descset )
121+#ifdef unix
122+ if( rddescf("makefile") ) rddescf("Makefile");
123+#endif
124+#ifdef gcos
125+ rddescf("makefile");
126+#endif
127+
128+if(prtrflag) printdesc(0);
129+
130+if( srchname(".IGNORE") ) ++ignerr;
131+if( srchname(".SILENT") ) silflag = 1;
132+if(p=srchname(".SUFFIXES")) sufflist = p->linep;
133+if( !sufflist ) fprintf(stderr,"No suffix list.\n");
134+
135+#ifdef unix
136+sigivalue = (signal(SIGINT, SIG_IGN) == SIG_IGN) ? 1 : 0;
137+sigqvalue = (signal(SIGQUIT, SIG_IGN) == SIG_IGN) ? 1 : 0;
138+enbint(intrupt);
139+#endif
140+
141+nfargs = 0;
142+
143+for(i=1; i<argc; ++i)
144+ if((s=argv[i]) != 0)
145+ {
146+ if((p=srchname(s)) == 0)
147+ {
148+ p = makename(s);
149+/*
150+ fprintf(stderr,"Warning: %s not in description.\n",s);
151+*/
152+ }
153+ ++nfargs;
154+ doname(p,0);
155+ if(dbgflag) printdesc(1);
156+ }
157+
158+/*
159+If no file arguments have been encountered, make the first
160+name encountered that doesn't start with a dot
161+*/
162+
163+if(nfargs == 0)
164+ if(mainname == 0)
165+ fatal("No arguments or description file");
166+ else {
167+ doname(mainname,0);
168+ if(dbgflag) printdesc(1);
169+ }
170+
171+exit(0);
172+}
173+
174+
175+
176+#ifdef unix
177+void intrupt(int sig)
178+{
179+struct varblock *varptr();
180+char *p;
181+
182+if( okdel && (p=varptr("@")->varval) && exists(p)>0 && !noexflag && !touchflag )
183+ {
184+ fprintf(stderr, "\n*** %s removed.", p);
185+ unlink(p);
186+ }
187+
188+fprintf(stderr, "\n");
189+exit(2);
190+}
191+
192+
193+
194+void disint()
195+{
196+signal(SIGINT, SIG_IGN);
197+signal(SIGQUIT, SIG_IGN);
198+}
199+
200+
201+
202+void enbint(k)
203+void (*k)(int);
204+{
205+if(sigivalue == 0)
206+ signal(SIGINT,k);
207+if(sigqvalue == 0)
208+ signal(SIGQUIT,k);
209+}
210+#endif
211+
212+extern char *builtin[];
213+
214+char **linesptr = builtin;
215+
216+FILE * fin;
217+int firstrd = 0;
218+
219+
220+rddescf(descfile)
221+char *descfile;
222+{
223+extern int yylineno;
224+extern char *zznextc;
225+FILE * k;
226+
227+/* read and parse description */
228+
229+if( !firstrd++ )
230+ {
231+ if( !noruleflag )
232+ rdd1(NULL);
233+
234+#ifdef pwb
235+ {
236+ char *nlog, s[100];
237+ nlog = logdir();
238+ if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL)
239+ rdd1(k);
240+ else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL)
241+ rdd1(k);
242+
243+ if ( (k=fopen("makecomm", "r")) != NULL)
244+ rdd1(k);
245+ else if ( (k=fopen("Makecomm", "r")) != NULL)
246+ rdd1(k);
247+ }
248+#endif
249+
250+ }
251+if(equals(descfile, "-"))
252+ return( rdd1(stdin) );
253+
254+if( (k = fopen(descfile,"r")) != NULL)
255+ return( rdd1(k) );
256+
257+return(1);
258+}
259+
260+
261+
262+
263+rdd1(k)
264+FILE * k;
265+{
266+extern int yylineno;
267+extern char *zznextc;
268+fin = k;
269+yylineno = 0;
270+zznextc = 0;
271+
272+if( yyparse() )
273+ fatal("Description file error");
274+
275+if(fin != NULL)
276+ fclose(fin);
277+
278+return(0);
279+}
280+
281+printdesc(prntflag)
282+int prntflag;
283+{
284+struct nameblock *p;
285+struct depblock *dp;
286+struct varblock *vp;
287+struct opendir *od;
288+struct shblock *sp;
289+struct lineblock *lp;
290+
291+#ifdef unix
292+if(prntflag)
293+ {
294+ printf("Open directories:\n");
295+ for(od=firstod; od!=0; od = od->nextp)
296+ printf("\t%d: %s\n", fileno(od->dirfc), od->dirn);
297+ }
298+#endif
299+
300+if(firstvar != 0) printf("Macros:\n");
301+for(vp=firstvar; vp!=0; vp=vp->nextp)
302+ printf("\t%s = %s\n" , vp->varname , vp->varval);
303+
304+for(p=firstname; p!=0; p = p->nextp)
305+ {
306+ printf("\n\n%s",p->namep);
307+ if(p->linep != 0) printf(":");
308+ if(prntflag) printf(" done=%d",p->done);
309+ if(p==mainname) printf(" (MAIN NAME)");
310+ for(lp = p->linep ; lp!=0 ; lp = lp->nextp)
311+ {
312+ if( dp = lp->depp )
313+ {
314+ printf("\n depends on:");
315+ for(; dp!=0 ; dp = dp->nextp)
316+ if(dp->depname != 0)
317+ printf(" %s ", dp->depname->namep);
318+ }
319+
320+ if(sp = lp->shp)
321+ {
322+ printf("\n commands:\n");
323+ for( ; sp!=0 ; sp = sp->nextp)
324+ printf("\t%s\n", sp->shbp);
325+ }
326+ }
327+ }
328+printf("\n");
329+fflush(stdout);
330+}
A
misc.c
+313,
-0
1@@ -0,0 +1,313 @@
2+#include "defs"
3+#include <stdlib.h>
4+#include <string.h>
5+
6+
7+FSTATIC char *nextchar = 0;
8+FSTATIC char *lastchar = 0;
9+
10+FSTATIC struct nameblock *hashtab[HASHSIZE];
11+FSTATIC int nhashed = 0;
12+
13+
14+/* simple linear hash. hash function is sum of
15+ characters mod hash table size.
16+*/
17+hashloc(s)
18+char *s;
19+{
20+register int i;
21+register int hashval;
22+register char *t;
23+
24+hashval = 0;
25+
26+for(t=s; *t!='\0' ; ++t)
27+ hashval += *t;
28+
29+hashval %= HASHSIZE;
30+
31+for(i=hashval;
32+ hashtab[i]!=0 && equals(s,hashtab[i]->namep)==0;
33+ i = (i+1)%HASHSIZE ) ;
34+
35+return(i);
36+}
37+
38+
39+struct nameblock *srchname(s)
40+char *s;
41+{
42+return( hashtab[hashloc(s)] );
43+}
44+
45+
46+
47+struct nameblock *makename(s)
48+char *s;
49+{
50+/* make a fresh copy of the string s */
51+
52+char *copys();
53+register struct nameblock *p;
54+
55+if(nhashed++ > HASHSIZE-3)
56+ fatal("Hash table overflow");
57+
58+p = intalloc(sizeof(*p));
59+p->nextp = firstname;
60+p->namep = copys(s);
61+p->linep = 0;
62+p->done = 0;
63+p->septype = 0;
64+p->modtime = 0;
65+
66+firstname = p;
67+if(mainname==0 && s[0]!='.') mainname = p;
68+
69+hashtab[hashloc(s)] = p;
70+
71+return(p);
72+}
73+
74+
75+
76+char *copys(s)
77+register char *s;
78+{
79+register char *t;
80+
81+for(t=s; *t++ ; );
82+if( (t-s) >= (lastchar-nextchar) )
83+ {
84+ if( (nextchar=calloc(NCHARS,sizeof(*t))) == NULL)
85+ fatal("Cannot allocate memory");
86+ lastchar = nextchar + NCHARS;
87+ }
88+
89+t = nextchar;
90+while(*nextchar++ = *s++);
91+return(t);
92+}
93+
94+equals(a,b)
95+register char *a,*b;
96+{
97+while(*a == *b)
98+ if(*a == '\0') return(1);
99+ else {++a; ++b;}
100+
101+return(0);
102+}
103+
104+
105+char *concat(a,b,c) /* c = concatenation of a and b */
106+register char *a,*b;
107+char *c;
108+{
109+register char *t;
110+t = c;
111+
112+while(*t = *a++) t++;
113+while(*t++ = *b++);
114+return(c);
115+}
116+
117+suffix(a,b,p) /* is b the suffix of a? if so, set p = prefix */
118+register char *a,*b,*p;
119+{
120+char *a0,*b0;
121+a0 = a;
122+b0 = b;
123+
124+while(*a++);
125+while(*b++);
126+
127+if( (a-a0) < (b-b0) ) return(0);
128+
129+while(b>b0)
130+ if(*--a != *--b) return(0);
131+
132+while(a0<a) *p++ = *a0++;
133+*p = '\0';
134+
135+return(1);
136+}
137+
138+
139+
140+void *intalloc(n)
141+int n;
142+{
143+void *p;
144+if( (p = calloc(1, n)) == NULL )
145+ fatal("Cannot allocate memory");
146+return(p);
147+}
148+
149+/* copy string a into b, substituting for arguments */
150+char *subst(a,b)
151+register char *a,*b;
152+{
153+register char *s;
154+char vname[100];
155+struct varblock *varptr(), *vbp;
156+char *copstr();
157+char closer;
158+
159+if(a!=0) while(*a)
160+ {
161+ if(*a != '$') *b++ = *a++;
162+ else if (*++a == '\0') *b++ = *a++;
163+ else {
164+ s = vname;
165+ if( *a=='(' || *a=='{' )
166+ {
167+ closer = ( *a=='(' ? ')' : '}');
168+ ++a;
169+ while(*a == ' ') ++a;
170+ while(*a!=' ' && *a!=closer && *a!='\0') *s++ = *a++;
171+ while(*a!=closer && *a!='\0') ++a;
172+ if(*a == closer) ++a;
173+ }
174+ else *s++ = *a++;
175+
176+ *s = '\0';
177+ if( (vbp = varptr(vname)) ->varval != 0)
178+ {
179+ b = copstr(b, vbp->varval);
180+ vbp->used = 1;
181+ }
182+ }
183+ }
184+
185+*b++ = '\0';
186+return(b);
187+}
188+
189+/* copy s into t, return the location of the next
190+free character in s */
191+char *copstr(s,t)
192+char *s,*t;
193+{
194+while (*t) *s++ = *t++;
195+return(s);
196+}
197+
198+setvar(v,s)
199+char *v, *s;
200+{
201+struct varblock *varptr(), *p;
202+
203+p = varptr(v);
204+if(p->noreset == 0)
205+ {
206+ p->varval = s;
207+ p->noreset = inarglist;
208+ if(p->used && !equals(v,"@") && !equals(v,"*")
209+ && !equals(v,"<") && !equals(v,"?") )
210+ fprintf(stderr, "Warning: %s changed after being used\n",v);
211+ }
212+}
213+
214+
215+eqsign(a) /*look for arguments with equal signs but not colons */
216+char *a;
217+{
218+register char *s, *t;
219+
220+while(*a == ' ') ++a;
221+for(s=a ; *s!='\0' && *s!=':' ; ++s)
222+ if(*s == '=')
223+ {
224+ for(t=a ; *t!='=' && *t!=' ' ; ++t );
225+ *t = '\0';
226+
227+ for(++s; *s==' ' || *s=='\t' ; ++s);
228+ setvar(a, copys(s));
229+ return(1);
230+ }
231+
232+return(0);
233+}
234+
235+
236+struct varblock *varptr(v)
237+char *v;
238+{
239+register struct varblock *vp;
240+
241+for(vp=firstvar; vp!=0 ; vp = vp->nextp)
242+ if(equals(v , vp->varname)) return(vp);
243+
244+vp = intalloc(sizeof(*vp));
245+vp->nextp = firstvar;
246+firstvar = vp;
247+vp->varname = copys(v);
248+vp->varval = 0;
249+return(vp);
250+}
251+
252+
253+fatal(s)
254+char *s;
255+{
256+if(s) fprintf(stderr, "%s. Stop.\n", s);
257+else fprintf(stderr, "\nStop.\n");
258+#ifdef unix
259+exit(1);
260+#endif
261+#ifdef gcos
262+exit(0);
263+#endif
264+}
265+
266+
267+
268+yyerror(s)
269+char *s;
270+{
271+char buf[50];
272+extern int yylineno;
273+
274+sprintf(buf, "line %d: %s", yylineno, s);
275+fatal(buf);
276+}
277+
278+
279+
280+appendq(head,tail)
281+struct chain **head;
282+char *tail;
283+{
284+struct chain *p;
285+p = intalloc(sizeof(*p));
286+p->datap = tail;
287+p->nextp = 0;
288+while(*head) head = &(*head)->nextp;
289+*head = p;
290+}
291+
292+
293+
294+
295+char *mkqlist(p)
296+struct chain *p;
297+{
298+register char *qbufp, *s;
299+static char qbuf[300];
300+
301+qbufp = qbuf;
302+
303+for( ; p ; p = p->nextp)
304+ {
305+ s = p->datap;
306+ if (qbufp+strlen(s)+2 >= &qbuf[300])
307+ break;
308+ *qbufp++ = ' ';
309+ while (*s)
310+ *qbufp++ = *s++;
311+ }
312+*qbufp = '\0';
313+return(qbuf);
314+}
+3,
-0
1@@ -0,0 +1,3 @@
2+(date; pwd; ls -l) | pr $1
3+if -w gram.c rm gram.c
4+pr $1 pr_make.sh pwinfo Makefile defs *.[cy]
A
pwb.c
+21,
-0
1@@ -0,0 +1,21 @@
2+/* PWB libPW replacement */
3+
4+#include <stdlib.h>
5+#include <unistd.h>
6+
7+void pexinit()
8+{
9+}
10+
11+void pexec(path, argv)
12+char *path;
13+char **argv;
14+{
15+execvp(path, argv);
16+}
17+
18+char *logdir()
19+{
20+char *home = getenv("HOME");
21+return(home ? home : ".");
22+}
A
pwinfo
+13,
-0
1@@ -0,0 +1,13 @@
2+Differences between PW make & original make:
3+- If exit status is ignored for an executed command,
4+ a warning is not printed if the command returns a non-zero status.
5+ The original prints such a warning.
6+- When the command is printed prior to execution,
7+ the command name is prefixed with ">"; this makes the commands stand out.
8+- Has builtin suffix rules for LEAP script .t-.o files, and .z-.h files.
9+- After reading internal "makerules" file,
10+ but before reading the local "makefile" file,
11+ PW version reads "makecomm"/"Makecomm"in login directory,
12+ and then in local directory.
13+ "makecomm" is useful for defining "common" macro names.
14+- PW version exec's commands by using pexec(), which uses the .path file.
A
rc
+6,
-0
1@@ -0,0 +1,6 @@
2+byacc gram.y
3+mv y.tab.c gram.c
4+cc -std=gnu89 -w -O2 -Dpwb -Dunix version.c main.c doname.c misc.c files.c dosys.c pexec.c gram.c -o make
5+rm gram.c
6+strip make
7+echo 'To re-archive, use: "make arch"'
A
readme
+9,
-0
1@@ -0,0 +1,9 @@
2+pw make
3+--------
4+
5+this is the 'make' utility from pwb/unix (1977). i have modified it so it will compile on modern systems.
6+you can compile it with the 'rc' script or using the 'make' command you probably already have.
7+you will need the 'byacc' implementation of yacc, or some compatible version. GNU bison will not work,
8+as it is not backwards compatible with 70's yacc grammars.
9+
10+
+62,
-0
1@@ -0,0 +1,62 @@
2+char *xxxvers = "@(#)VERSION 3.1(PWB) 21 APRIL 1977\n" ;
3+
4+/*
5+2.1 4/24/76 Base version
6+
7+2.2 4/26/76 Error found by SRB in overriding pattern rules;
8+ corrected gram.y
9+
10+2.3 4/27/76 Further correction for overriding pattern rules;
11+ corrected doname.c
12+
13+2.4 Removed .CLEAR name, added .IGNORE.
14+ A .SUFFIXES rule without dependents clears the list
15+
16+2.5 Stripped output
17+
18+2.6 Changed doshell to accomodate new shell.
19+
20+2.7 Following SRB's sugestion, added ${...} as
21+ alternate macro name
22+
23+2.8 Defined macros AS and DTGEN in files.c.
24+
25+2.9 Put in a fix to prevent removal of files
26+ upon interrupt in a :: rule.
27+
28+2.10 Fixed bugs involving messages for ::
29+ and closing standard input
30+
31+2.11 Changed time test from <= to <
32+ (equal times are considered in sync)
33+
34+2.12 Installed -t flag (touch and update time of
35+ files rather than issue commands)
36+ Fixed bug in dosys
37+
38+2.13 Fixed lex.c to allow sharps (#) in commands
39+
40+2.14 Added .DEFAULT rule
41+
42+2.15 Changed to <lS> I/O System (stdio.h)
43+
44+2.16 Removed references to double floats and macro HAVELONGS;
45+ committed to use of long ints for times.
46+2.17 Corrected metacharacter list in dosys.c.
47+2.18 Miscellaneous fixes
48+2.19 Updated files.c to use include file stat.h
49+2.20 Added -q flag for Mike Lesk
50+2.21 Added AWK rules and .w suffix to files.c
51+2.22 Added colon to the list of metacharacters
52+2.23 Macro substitutions on dependency lines.
53+ Redid argument and macro setting.
54+ Close files before exec'ing.
55+ Print > at beginning of command lines.
56+ No printing of commands beginnng with @.
57+2.24 Parametrized propt sequence in doname.c (4/1/77)
58+2.25 Added $? facility
59+2.26 Fixed bug in macro expansion
60+2.27 Repaired interrupt handling
61+
62+3.1(PWB) Use pexec(), add LEAP builtin rules - WDR 4/21/77.
63+*/