xref: /original-bsd/old/make/files.c (revision 3708840b)
1 static	char *sccsid = "@(#)files.c	4.7 (Berkeley) 83/05/18";
2 /* UNIX DEPENDENT PROCEDURES */
3 
4 
5 /* DEFAULT RULES FOR UNIX */
6 
7 char *builtin[] =
8 	{
9 #ifdef pwb
10 	".SUFFIXES : .L .out .o .c .f .e .r .y .yr .ye .l .s .z .x .t .h .cl",
11 #else
12 	".SUFFIXES : .out .o .c .f .F .e .r .y .yr .ye .l .s .cl .p",
13 #endif
14 	"YACC=yacc",
15 	"YACCR=yacc -r",
16 	"YACCE=yacc -e",
17 	"YFLAGS=",
18 	"LEX=lex",
19 	"LFLAGS=",
20 	"CC=cc",
21 #if defined(vax) || defined(sun)
22 	"AS=as",
23 #else
24 	"AS=as -",
25 #endif
26 	"PC=pc",
27 	"PFLAGS=",
28 	"CFLAGS=",
29 	"RC=f77",
30 	"RFLAGS=",
31 	"FC=f77",
32 	"EFLAGS=",
33 	"FFLAGS=",
34 	"LOADLIBES=",
35 #ifdef pwb
36 	"SCOMP=scomp",
37 	"SCFLAGS=",
38 	"CMDICT=cmdict",
39 	"CMFLAGS=",
40 #endif
41 
42 	".c.o :",
43 	"\t$(CC) $(CFLAGS) -c $<",
44 
45 	".p.o :",
46 	"\t$(PC) $(PFLAGS) -c $<",
47 
48 	".cl.o :",
49 	"\tclass -c $<",
50 
51 	".e.o .r.o .F.o .f.o :",
52 	"\t$(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<",
53 
54 	".s.o :",
55 	"\t$(AS) -o $@ $<",
56 
57 	".y.o :",
58 	"\t$(YACC) $(YFLAGS) $<",
59 	"\t$(CC) $(CFLAGS) -c y.tab.c",
60 	"\trm y.tab.c",
61 	"\tmv y.tab.o $@",
62 
63 	".yr.o:",
64 	"\t$(YACCR) $(YFLAGS) $<",
65 	"\t$(RC) $(RFLAGS) -c y.tab.r",
66 	"\trm y.tab.r",
67 	"\tmv y.tab.o $@",
68 
69 	".ye.o :",
70 	"\t$(YACCE) $(YFLAGS) $<",
71 	"\t$(EC) $(RFLAGS) -c y.tab.e",
72 	"\trm y.tab.e",
73 	"\tmv y.tab.o $@",
74 
75 	".l.o :",
76 	"\t$(LEX) $(LFLAGS) $<",
77 	"\t$(CC) $(CFLAGS) -c lex.yy.c",
78 	"\trm lex.yy.c",
79 	"\tmv lex.yy.o $@",
80 
81 	".y.c :",
82 	"\t$(YACC) $(YFLAGS) $<",
83 	"\tmv y.tab.c $@",
84 
85 	".l.c :",
86 	"\t$(LEX) $(LFLAGS) $<",
87 	"\tmv lex.yy.c $@",
88 
89 	".yr.r:",
90 	"\t$(YACCR) $(YFLAGS) $<",
91 	"\tmv y.tab.r $@",
92 
93 	".ye.e :",
94 	"\t$(YACCE) $(YFLAGS) $<",
95 	"\tmv y.tab.e $@",
96 
97 #ifdef pwb
98 	".o.L .c.L .t.L:",
99 	"\t$(SCOMP) $(SCFLAGS) $<",
100 
101 	".t.o:",
102 	"\t$(SCOMP) $(SCFLAGS) -c $<",
103 
104 	".t.c:",
105 	"\t$(SCOMP) $(SCFLAGS) -t $<",
106 
107 	".h.z .t.z:",
108 	"\t$(CMDICT) $(CMFLAGS) $<",
109 
110 	".h.x .t.x:",
111 	"\t$(CMDICT) $(CMFLAGS) -c $<",
112 #endif
113 
114 	".s.out .c.out .o.out :",
115 	"\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",
116 
117 	".f.out .F.out .r.out .e.out :",
118 	"\t$(FC) $(EFLAGS) $(RFLAGS) $(FFLAGS) $< $(LOADLIBES) -o $@",
119 	"\t-rm $*.o",
120 
121 	".y.out :",
122 	"\t$(YACC) $(YFLAGS) $<",
123 	"\t$(CC) $(CFLAGS) y.tab.c $(LOADLIBES) -ly -o $@",
124 	"\trm y.tab.c",
125 
126 	".l.out :",
127 	"\t$(LEX) $(LFLAGS) $<",
128 	"\t$(CC) $(CFLAGS) lex.yy.c $(LOADLIBES) -ll -o $@",
129 	"\trm lex.yy.c",
130 
131 	0 };
132 
133 #include "defs"
134 
135 
136 TIMETYPE exists(filename)
137 char *filename;
138 {
139 #include <sys/stat.h>
140 struct stat buf;
141 register char *s;
142 TIMETYPE lookarch();
143 
144 for(s = filename ; *s!='\0' && *s!='(' ; ++s)
145 	;
146 
147 if(*s == '(')
148 	return(lookarch(filename));
149 
150 if (stat(filename, &buf) < 0)
151 	return(0);
152 else	return(buf.st_mtime);
153 }
154 
155 
156 TIMETYPE prestime()
157 {
158 TIMETYPE t;
159 time(&t);
160 return(t);
161 }
162 
163 
164 
165 FSTATIC char nbuf[MAXNAMLEN + 1];
166 FSTATIC char *nbufend	= &nbuf[MAXNAMLEN];
167 
168 
169 
170 struct depblock *srchdir(pat, mkchain, nextdbl)
171 register char *pat; /* pattern to be matched in directory */
172 int mkchain;  /* nonzero if results to be remembered */
173 struct depblock *nextdbl;  /* final value for chain */
174 {
175 DIR *dirf;
176 register int i;
177 int nread, cldir;
178 char *dirname, *dirpref, *endir, *filepat, *p, temp[100];
179 char fullname[100], *p1, *p2;
180 struct nameblock *q;
181 struct depblock *thisdbl;
182 struct dirhdr *od;
183 struct pattern *patp;
184 
185 struct direct *dptr;
186 
187 
188 thisdbl = 0;
189 
190 if(mkchain == NO)
191 	for(patp=firstpat ; patp ; patp = patp->nxtpattern)
192 		if(! unequal(pat, patp->patval)) return(0);
193 
194 patp = ALLOC(pattern);
195 patp->nxtpattern = firstpat;
196 firstpat = patp;
197 patp->patval = copys(pat);
198 
199 endir = 0;
200 
201 for(p=pat; *p!='\0'; ++p)
202 	if(*p=='/') endir = p;
203 
204 if(endir==0)
205 	{
206 	dirname = ".";
207 	dirpref = "";
208 	filepat = pat;
209 	}
210 else	{
211 	dirname = pat;
212 	*endir = '\0';
213 	dirpref = concat(dirname, "/", temp);
214 	filepat = endir+1;
215 	}
216 
217 dirf = NULL;
218 cldir = NO;
219 
220 for(od = firstod; od; od = od->nxtopendir)
221 	if(! unequal(dirname, od->dirn) )
222 		{
223 		dirf = od->dirfc;
224 		if (dirf != NULL)
225 			rewinddir(dirf); /* start over at the beginning  */
226 		break;
227 		}
228 
229 if(dirf == NULL)
230 	{
231 	dirf = opendir(dirname);
232 	if(nopdir >= MAXDIR)
233 		cldir = YES;
234 	else	{
235 		++nopdir;
236 		od = ALLOC(dirhdr);
237 		od->nxtopendir = firstod;
238 		firstod = od;
239 		od->dirfc = dirf;
240 		od->dirn = copys(dirname);
241 		}
242 	}
243 
244 if(dirf == NULL)
245 	{
246 	fprintf(stderr, "Directory %s: ", dirname);
247 	fatal("Cannot open");
248 	}
249 
250 else for (dptr = readdir(dirf); dptr != NULL; dptr = readdir(dirf))
251 	{
252 	p1 = dptr->d_name;
253 	p2 = nbuf;
254 	while( (p2<nbufend) && (*p2++ = *p1++)!='\0' )
255 		/* void */;
256 	if( amatch(nbuf,filepat) )
257 		{
258 		concat(dirpref,nbuf,fullname);
259 		if( (q=srchname(fullname)) ==0)
260 			q = makename(copys(fullname));
261 		if(mkchain)
262 			{
263 			thisdbl = ALLOC(depblock);
264 			thisdbl->nxtdepblock = nextdbl;
265 			thisdbl->depname = q;
266 			nextdbl = thisdbl;
267 			}
268 		}
269 	}
270 
271 if(endir != 0)  *endir = '/';
272 
273 if(cldir) {
274 	closedir(dirf);
275 	dirf = NULL;
276 }
277 return(thisdbl);
278 }
279 
280 /* stolen from glob through find */
281 
282 static amatch(s, p)
283 char *s, *p;
284 {
285 	register int cc, scc, k;
286 	int c, lc;
287 
288 	scc = *s;
289 	lc = 077777;
290 	switch (c = *p) {
291 
292 	case '[':
293 		k = 0;
294 		while (cc = *++p) {
295 			switch (cc) {
296 
297 			case ']':
298 				if (k)
299 					return(amatch(++s, ++p));
300 				else
301 					return(0);
302 
303 			case '-':
304 				k |= (lc <= scc)  & (scc <= (cc=p[1]) ) ;
305 			}
306 			if (scc==(lc=cc)) k++;
307 		}
308 		return(0);
309 
310 	case '?':
311 	caseq:
312 		if(scc) return(amatch(++s, ++p));
313 		return(0);
314 	case '*':
315 		return(umatch(s, ++p));
316 	case 0:
317 		return(!scc);
318 	}
319 	if (c==scc) goto caseq;
320 	return(0);
321 }
322 
323 static umatch(s, p)
324 char *s, *p;
325 {
326 	if(*p==0) return(1);
327 	while(*s)
328 		if (amatch(s++,p)) return(1);
329 	return(0);
330 }
331 
332 #ifdef METERFILE
333 #include <pwd.h>
334 int meteron	= 0;	/* default: metering off */
335 
336 meter(file)
337 char *file;
338 {
339 TIMETYPE tvec;
340 char *p, *ctime();
341 FILE * mout;
342 struct passwd *pwd, *getpwuid();
343 
344 if(file==0 || meteron==0) return;
345 
346 pwd = getpwuid(getuid());
347 
348 time(&tvec);
349 
350 if( (mout=fopen(file,"a")) != NULL )
351 	{
352 	p = ctime(&tvec);
353 	p[16] = '\0';
354 	fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4);
355 	fclose(mout);
356 	}
357 }
358 #endif
359 
360 
361 /* look inside archives for notations a(b) and a((b))
362 	a(b)	is file member   b   in archive a
363 	a((b))	is entry point  _b  in object archive a
364 */
365 
366 #ifdef ASCARCH
367 #	include <ar.h>
368 #else
369 #	include <ar.h>
370 #endif
371 #include <a.out.h>
372 
373 static long arflen;
374 static long arfdate;
375 static char arfname[16];
376 FILE *arfd;
377 long int arpos, arlen;
378 
379 static struct exec objhead;
380 
381 static struct nlist objentry;
382 
383 
384 TIMETYPE lookarch(filename)
385 char *filename;
386 {
387 char *p, *q, *send, s[MAXNAMLEN + 1];
388 int i, nc, nsym, objarch;
389 
390 for(p = filename; *p!= '(' ; ++p)
391 	;
392 *p = '\0';
393 openarch(filename);
394 *p++ = '(';
395 
396 if(*p == '(')
397 	{
398 	objarch = YES;
399 	nc = 8;
400 	++p;
401 	}
402 else
403 	{
404 	objarch = NO;
405 	nc = MAXNAMLEN;
406 	}
407 send = s + nc;
408 
409 for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
410 	;
411 while(q < send)
412 	*q++ = '\0';
413 while(getarch())
414 	{
415 	if(objarch)
416 		{
417 		getobj();
418 		nsym = objhead.a_syms / sizeof(objentry);
419 		for(i = 0; i<nsym ; ++i)
420 			{
421 			fread( (char *) &objentry, sizeof(objentry),1,arfd);
422 			if( (objentry.n_type & N_EXT)
423 			   && ((objentry.n_type & ~N_EXT) || objentry.n_value)
424 			   && eqstr(objentry.n_un.n_name,s,nc))
425 				{
426 				clarch();
427 				return(arfdate);
428 				}
429 			}
430 		}
431 
432 	else if( eqstr(arfname, s, nc))
433 		{
434 		clarch();
435 		return(arfdate);
436 		}
437 	}
438 
439 clarch();
440 return( 0L);
441 }
442 
443 
444 clarch()
445 {
446 fclose( arfd );
447 }
448 
449 
450 openarch(f)
451 register char *f;
452 {
453 #ifdef ASCARCH
454 char magic[SARMAG];
455 #endif
456 int word;
457 #include <sys/stat.h>
458 struct stat buf;
459 
460 stat(f, &buf);
461 arlen = buf.st_size;
462 
463 arfd = fopen(f, "r");
464 if(arfd == NULL)
465 	fatal1("cannot open %s", f);
466 
467 	fread( (char *) &word, sizeof(word), 1, arfd);
468 #ifdef ASCARCH
469 	fseek(arfd, 0L, 0);
470 	fread(magic, SARMAG, 1, arfd);
471 	arpos = SARMAG;
472 	if( ! eqstr(magic, ARMAG, SARMAG) )
473 #else
474 	arpos = sizeof(word);
475 	if(word != ARMAG)
476 #endif
477 		fatal1("%s is not an archive", f);
478 
479 arflen = 0;
480 }
481 
482 
483 
484 getarch()
485 {
486 	struct ar_hdr arhead;
487 	long atol();
488 
489 arpos += (arflen + 1) & ~1L;	/* round archived file length up to even */
490 if(arpos >= arlen)
491 	return(0);
492 fseek(arfd, arpos, 0);
493 
494 	fread( (char *) &arhead, sizeof(arhead), 1, arfd);
495 	arpos += sizeof(arhead);
496 #ifdef ASCARCH
497 	arflen = atol(arhead.ar_size);
498 	arfdate = atol(arhead.ar_date);
499 #else
500 	arflen = arhead.ar_size;
501 	arfdate = arhead.ar_date;
502 #endif
503 	strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));
504 return(1);
505 }
506 
507 
508 getobj()
509 {
510 long int skip;
511 
512 fread( (char *) &objhead, sizeof(objhead), 1, arfd);
513 if (N_BADMAG(objhead))
514 	fatal1("%s is not an object module", arfname);
515 skip = objhead.a_text + objhead.a_data;
516 #if defined(vax) || defined(sun)
517 skip += objhead.a_trsize + objhead.a_drsize;
518 #else
519 if(! objhead.a_flag )
520 	skip *= 2;
521 #endif
522 fseek(arfd, skip, 1);
523 }
524 
525 
526 eqstr(a,b,n)
527 register char *a, *b;
528 int n;
529 {
530 register int i;
531 for(i = 0 ; i < n ; ++i)
532 	if(*a++ != *b++)
533 		return(NO);
534 return(YES);
535 }
536