xref: /csrg-svn/old/make/files.c (revision 6178)
1 static	char *sccsid = "@(#)files.c	4.3 (Berkeley) 82/03/14";
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 .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 #ifdef vax
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 :",
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 .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 #include <sys/types.h>
135 
136 
137 TIMETYPE exists(filename)
138 char *filename;
139 {
140 #include <sys/stat.h>
141 struct stat buf;
142 register char *s;
143 TIMETYPE lookarch();
144 
145 for(s = filename ; *s!='\0' && *s!='(' ; ++s)
146 	;
147 
148 if(*s == '(')
149 	return(lookarch(filename));
150 
151 #if vax
152 if (lstat(filename, &buf) < 0)
153 #else
154 if(stat(filename,&buf) < 0)
155 #endif
156 	return(0);
157 else	return(buf.st_mtime);
158 }
159 
160 
161 TIMETYPE prestime()
162 {
163 TIMETYPE t;
164 time(&t);
165 return(t);
166 }
167 
168 
169 
170 #include <sys/dir.h>
171 FSTATIC char n15[15];
172 FSTATIC char *n15end	= &n15[14];
173 
174 
175 
176 struct depblock *srchdir(pat, mkchain, nextdbl)
177 register char *pat; /* pattern to be matched in directory */
178 int mkchain;  /* nonzero if results to be remembered */
179 struct depblock *nextdbl;  /* final value for chain */
180 {
181 FILE * dirf;
182 register int i;
183 int nread, cldir;
184 char *dirname, *dirpref, *endir, *filepat, *p, temp[100];
185 char fullname[100], *p1, *p2;
186 struct nameblock *q;
187 struct depblock *thisdbl;
188 struct opendir *od;
189 struct pattern *patp;
190 
191 struct direct entry[32];
192 
193 
194 thisdbl = 0;
195 
196 if(mkchain == NO)
197 	for(patp=firstpat ; patp ; patp = patp->nxtpattern)
198 		if(! unequal(pat, patp->patval)) return(0);
199 
200 patp = ALLOC(pattern);
201 patp->nxtpattern = firstpat;
202 firstpat = patp;
203 patp->patval = copys(pat);
204 
205 endir = 0;
206 
207 for(p=pat; *p!='\0'; ++p)
208 	if(*p=='/') endir = p;
209 
210 if(endir==0)
211 	{
212 	dirname = ".";
213 	dirpref = "";
214 	filepat = pat;
215 	}
216 else	{
217 	dirname = pat;
218 	*endir = '\0';
219 	dirpref = concat(dirname, "/", temp);
220 	filepat = endir+1;
221 	}
222 
223 dirf = NULL;
224 cldir = NO;
225 
226 for(od = firstod; od; od = od->nxtopendir)
227 	if(! unequal(dirname, od->dirn) )
228 		{
229 		dirf = od->dirfc;
230 		fseek(dirf, 0L, 0); /* start over at the beginning  */
231 		break;
232 		}
233 
234 if(dirf == NULL)
235 	{
236 	dirf = fopen(dirname, "r");
237 	if(nopdir >= MAXDIR)
238 		cldir = YES;
239 	else	{
240 		++nopdir;
241 		od = ALLOC(opendir);
242 		od->nxtopendir = firstod;
243 		firstod = od;
244 		od->dirfc = dirf;
245 		od->dirn = copys(dirname);
246 		}
247 	}
248 
249 if(dirf == NULL)
250 	{
251 	fprintf(stderr, "Directory %s: ", dirname);
252 	fatal("Cannot open");
253 	}
254 
255 else do
256 	{
257 	nread = fread( (char *) &entry[0], sizeof(struct direct), 32, dirf) ;
258 	for(i=0; i<nread; ++i)
259 		if(entry[i].d_ino!= 0)
260 			{
261 			p1 = entry[i].d_name;
262 			p2 = n15;
263 			while( (p2<n15end) &&
264 			  (*p2++ = *p1++)!='\0' );
265 			if( amatch(n15,filepat) )
266 				{
267 				concat(dirpref,n15,fullname);
268 				if( (q=srchname(fullname)) ==0)
269 					q = makename(copys(fullname));
270 				if(mkchain)
271 					{
272 					thisdbl = ALLOC(depblock);
273 					thisdbl->nxtdepblock = nextdbl;
274 					thisdbl->depname = q;
275 					nextdbl = thisdbl;
276 					}
277 				}
278 			}
279 
280 	} while(nread==32);
281 
282 if(endir != 0)  *endir = '/';
283 
284 if(cldir)
285 	fclose(dirf);
286 return(thisdbl);
287 }
288 
289 /* stolen from glob through find */
290 
291 static amatch(s, p)
292 char *s, *p;
293 {
294 	register int cc, scc, k;
295 	int c, lc;
296 
297 	scc = *s;
298 	lc = 077777;
299 	switch (c = *p) {
300 
301 	case '[':
302 		k = 0;
303 		while (cc = *++p) {
304 			switch (cc) {
305 
306 			case ']':
307 				if (k)
308 					return(amatch(++s, ++p));
309 				else
310 					return(0);
311 
312 			case '-':
313 				k |= (lc <= scc)  & (scc <= (cc=p[1]) ) ;
314 			}
315 			if (scc==(lc=cc)) k++;
316 		}
317 		return(0);
318 
319 	case '?':
320 	caseq:
321 		if(scc) return(amatch(++s, ++p));
322 		return(0);
323 	case '*':
324 		return(umatch(s, ++p));
325 	case 0:
326 		return(!scc);
327 	}
328 	if (c==scc) goto caseq;
329 	return(0);
330 }
331 
332 static umatch(s, p)
333 char *s, *p;
334 {
335 	if(*p==0) return(1);
336 	while(*s)
337 		if (amatch(s++,p)) return(1);
338 	return(0);
339 }
340 
341 #ifdef METERFILE
342 #include <pwd.h>
343 int meteron	= 0;	/* default: metering off */
344 
345 meter(file)
346 char *file;
347 {
348 TIMETYPE tvec;
349 char *p, *ctime();
350 FILE * mout;
351 struct passwd *pwd, *getpwuid();
352 
353 if(file==0 || meteron==0) return;
354 
355 pwd = getpwuid(getuid());
356 
357 time(&tvec);
358 
359 if( (mout=fopen(file,"a")) != NULL )
360 	{
361 	p = ctime(&tvec);
362 	p[16] = '\0';
363 	fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4);
364 	fclose(mout);
365 	}
366 }
367 #endif
368 
369 
370 /* look inside archives for notations a(b) and a((b))
371 	a(b)	is file member   b   in archive a
372 	a((b))	is entry point  _b  in object archive a
373 */
374 
375 #ifdef ASCARCH
376 #	include <ar.h>
377 #else
378 #	include <ar.h>
379 #endif
380 #include <a.out.h>
381 
382 static long arflen;
383 static long arfdate;
384 static char arfname[16];
385 FILE *arfd;
386 long int arpos, arlen;
387 
388 static struct exec objhead;
389 
390 static struct nlist objentry;
391 
392 
393 TIMETYPE lookarch(filename)
394 char *filename;
395 {
396 char *p, *q, *send, s[15];
397 int i, nc, nsym, objarch;
398 
399 for(p = filename; *p!= '(' ; ++p)
400 	;
401 *p = '\0';
402 openarch(filename);
403 *p++ = '(';
404 
405 if(*p == '(')
406 	{
407 	objarch = YES;
408 	nc = 8;
409 	++p;
410 	}
411 else
412 	{
413 	objarch = NO;
414 	nc = 14;
415 	}
416 send = s + nc;
417 
418 for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
419 	;
420 while(q < send)
421 	*q++ = '\0';
422 while(getarch())
423 	{
424 	if(objarch)
425 		{
426 		getobj();
427 		nsym = objhead.a_syms / sizeof(objentry);
428 		for(i = 0; i<nsym ; ++i)
429 			{
430 			fread( (char *) &objentry, sizeof(objentry),1,arfd);
431 			if( (objentry.n_type & N_EXT)
432 			   && ((objentry.n_type & ~N_EXT) || objentry.n_value)
433 			   && eqstr(objentry.n_un.n_name,s,nc))
434 				{
435 				clarch();
436 				return(arfdate);
437 				}
438 			}
439 		}
440 
441 	else if( eqstr(arfname, s, nc))
442 		{
443 		clarch();
444 		return(arfdate);
445 		}
446 	}
447 
448 clarch();
449 return( 0L);
450 }
451 
452 
453 clarch()
454 {
455 fclose( arfd );
456 }
457 
458 
459 openarch(f)
460 register char *f;
461 {
462 #ifdef ASCARCH
463 char magic[SARMAG];
464 #endif
465 int word;
466 #include <sys/stat.h>
467 struct stat buf;
468 
469 #if vax
470 lstat(f, &buf);
471 #else
472 stat(f, &buf);
473 #endif
474 arlen = buf.st_size;
475 
476 arfd = fopen(f, "r");
477 if(arfd == NULL)
478 	fatal1("cannot open %s", f);
479 
480 	fread( (char *) &word, sizeof(word), 1, arfd);
481 #ifdef ASCARCH
482 	fseek(arfd, 0L, 0);
483 	fread(magic, SARMAG, 1, arfd);
484 	arpos = SARMAG;
485 	if( ! eqstr(magic, ARMAG, SARMAG) )
486 #else
487 	arpos = sizeof(word);
488 	if(word != ARMAG)
489 #endif
490 		fatal1("%s is not an archive", f);
491 
492 arflen = 0;
493 }
494 
495 
496 
497 getarch()
498 {
499 	struct ar_hdr arhead;
500 	long atol();
501 
502 arpos += (arflen + 1) & ~1L;	/* round archived file length up to even */
503 if(arpos >= arlen)
504 	return(0);
505 fseek(arfd, arpos, 0);
506 
507 	fread( (char *) &arhead, sizeof(arhead), 1, arfd);
508 	arpos += sizeof(arhead);
509 #ifdef ASCARCH
510 	arflen = atol(arhead.ar_size);
511 	arfdate = atol(arhead.ar_date);
512 #else
513 	arflen = arhead.ar_size;
514 	arfdate = arhead.ar_date;
515 #endif
516 	strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));
517 return(1);
518 }
519 
520 
521 getobj()
522 {
523 long int skip;
524 
525 fread( (char *) &objhead, sizeof(objhead), 1, arfd);
526 if (N_BADMAG(objhead))
527 	fatal1("%s is not an object module", arfname);
528 skip = objhead.a_text + objhead.a_data;
529 #ifdef vax
530 skip += objhead.a_trsize + objhead.a_drsize;
531 #else
532 if(! objhead.a_flag )
533 	skip *= 2;
534 #endif
535 fseek(arfd, skip, 1);
536 }
537 
538 
539 eqstr(a,b,n)
540 register char *a, *b;
541 int n;
542 {
543 register int i;
544 for(i = 0 ; i < n ; ++i)
545 	if(*a++ != *b++)
546 		return(NO);
547 return(YES);
548 }
549