new version from Chris Torek
[unix-history] / usr / src / old / make / files.c
CommitLineData
14724fce 1static char *sccsid = "@(#)files.c 4.18 (Berkeley) 88/09/13";
5ec84434
RC
2#include <fcntl.h>
3
fbf6641c
BJ
4/* UNIX DEPENDENT PROCEDURES */
5
6
7/* DEFAULT RULES FOR UNIX */
8
9char *builtin[] =
10 {
11#ifdef pwb
12 ".SUFFIXES : .L .out .o .c .f .e .r .y .yr .ye .l .s .z .x .t .h .cl",
13#else
14724fce 14 ".SUFFIXES : .out .o .c .F .f .e .r .y .yr .ye .l .s .cl .p .8 .7 .6 .5 .4 .3 .2 .1 .0",
fbf6641c
BJ
15#endif
16 "YACC=yacc",
17 "YACCR=yacc -r",
18 "YACCE=yacc -e",
19 "YFLAGS=",
20 "LEX=lex",
21 "LFLAGS=",
22 "CC=cc",
76ed2017 23#if defined(vax) || defined(sun) || defined(tahoe)
fbf6641c
BJ
24 "AS=as",
25#else
26 "AS=as -",
27#endif
28 "PC=pc",
29 "PFLAGS=",
30 "CFLAGS=",
31 "RC=f77",
32 "RFLAGS=",
0609ddad 33 "FC=f77",
fbf6641c
BJ
34 "EFLAGS=",
35 "FFLAGS=",
36 "LOADLIBES=",
14724fce 37 "NROFF=nroff",
fbf6641c
BJ
38#ifdef pwb
39 "SCOMP=scomp",
40 "SCFLAGS=",
41 "CMDICT=cmdict",
42 "CMFLAGS=",
43#endif
44
45 ".c.o :",
46 "\t$(CC) $(CFLAGS) -c $<",
47
48 ".p.o :",
49 "\t$(PC) $(PFLAGS) -c $<",
50
51 ".cl.o :",
52 "\tclass -c $<",
53
16afe48d 54 ".e.o .r.o .F.o .f.o :",
fbf6641c
BJ
55 "\t$(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<",
56
57 ".s.o :",
58 "\t$(AS) -o $@ $<",
59
60 ".y.o :",
61 "\t$(YACC) $(YFLAGS) $<",
62 "\t$(CC) $(CFLAGS) -c y.tab.c",
63 "\trm y.tab.c",
64 "\tmv y.tab.o $@",
65
66 ".yr.o:",
67 "\t$(YACCR) $(YFLAGS) $<",
68 "\t$(RC) $(RFLAGS) -c y.tab.r",
69 "\trm y.tab.r",
70 "\tmv y.tab.o $@",
71
72 ".ye.o :",
73 "\t$(YACCE) $(YFLAGS) $<",
74 "\t$(EC) $(RFLAGS) -c y.tab.e",
75 "\trm y.tab.e",
76 "\tmv y.tab.o $@",
77
78 ".l.o :",
79 "\t$(LEX) $(LFLAGS) $<",
80 "\t$(CC) $(CFLAGS) -c lex.yy.c",
81 "\trm lex.yy.c",
82 "\tmv lex.yy.o $@",
83
84 ".y.c :",
85 "\t$(YACC) $(YFLAGS) $<",
86 "\tmv y.tab.c $@",
87
88 ".l.c :",
89 "\t$(LEX) $(LFLAGS) $<",
90 "\tmv lex.yy.c $@",
91
92 ".yr.r:",
93 "\t$(YACCR) $(YFLAGS) $<",
94 "\tmv y.tab.r $@",
95
96 ".ye.e :",
97 "\t$(YACCE) $(YFLAGS) $<",
98 "\tmv y.tab.e $@",
99
100#ifdef pwb
101 ".o.L .c.L .t.L:",
102 "\t$(SCOMP) $(SCFLAGS) $<",
103
104 ".t.o:",
105 "\t$(SCOMP) $(SCFLAGS) -c $<",
106
107 ".t.c:",
108 "\t$(SCOMP) $(SCFLAGS) -t $<",
109
110 ".h.z .t.z:",
111 "\t$(CMDICT) $(CMFLAGS) $<",
112
113 ".h.x .t.x:",
114 "\t$(CMDICT) $(CMFLAGS) -c $<",
115#endif
116
117 ".s.out .c.out .o.out :",
118 "\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",
119
16afe48d 120 ".f.out .F.out .r.out .e.out :",
fbf6641c
BJ
121 "\t$(FC) $(EFLAGS) $(RFLAGS) $(FFLAGS) $< $(LOADLIBES) -o $@",
122 "\t-rm $*.o",
123
124 ".y.out :",
125 "\t$(YACC) $(YFLAGS) $<",
126 "\t$(CC) $(CFLAGS) y.tab.c $(LOADLIBES) -ly -o $@",
127 "\trm y.tab.c",
128
129 ".l.out :",
130 "\t$(LEX) $(LFLAGS) $<",
131 "\t$(CC) $(CFLAGS) lex.yy.c $(LOADLIBES) -ll -o $@",
132 "\trm lex.yy.c",
133
14724fce
KB
134 ".8.0 :",
135 "\t$(NROFF) -man -h $< > $@",
136
137 ".7.0 :",
138 "\t$(NROFF) -man -h $< > $@",
139
140 ".6.0 :",
141 "\t$(NROFF) -man -h $< > $@",
142
143 ".5.0 :",
144 "\t$(NROFF) -man -h $< > $@",
145
146 ".4.0 :",
147 "\t$(NROFF) -man -h $< > $@",
148
149 ".3.0 :",
150 "\t$(NROFF) -man -h $< > $@",
151
152 ".2.0 :",
153 "\t$(NROFF) -man -h $< > $@",
154
155 ".1.0 :",
156 "\t$(NROFF) -man -h $< > $@",
157
fbf6641c
BJ
158 0 };
159\f
160#include "defs"
a10b24d4 161#include <sys/stat.h>
fbf6641c
BJ
162
163
a10b24d4
KM
164
165TIMETYPE
166exists(pname)
167struct nameblock *pname;
fbf6641c 168{
fbf6641c 169struct stat buf;
a10b24d4 170register char *s, *filename;
fbf6641c 171TIMETYPE lookarch();
a10b24d4
KM
172extern char *findfl();
173
174filename = pname->namep;
fbf6641c
BJ
175
176for(s = filename ; *s!='\0' && *s!='(' ; ++s)
177 ;
178
179if(*s == '(')
180 return(lookarch(filename));
181
0e7207aa 182if (stat(filename, &buf) < 0)
a10b24d4
KM
183{
184 s = findfl(filename);
185 if(s != (char *)-1)
186 {
187 pname->alias = copys(s);
188 if(stat(pname->alias, &buf) == 0)
189 return(buf.st_mtime);
190 }
fbf6641c 191 return(0);
a10b24d4 192}
fbf6641c
BJ
193else return(buf.st_mtime);
194}
195
196
197TIMETYPE prestime()
198{
199TIMETYPE t;
200time(&t);
201return(t);
202}
203
204\f
205
b342e078
KM
206FSTATIC char nbuf[MAXNAMLEN + 1];
207FSTATIC char *nbufend = &nbuf[MAXNAMLEN];
fbf6641c
BJ
208
209
210
211struct depblock *srchdir(pat, mkchain, nextdbl)
212register char *pat; /* pattern to be matched in directory */
213int mkchain; /* nonzero if results to be remembered */
214struct depblock *nextdbl; /* final value for chain */
215{
b342e078 216DIR *dirf;
fbf6641c
BJ
217register int i;
218int nread, cldir;
dbf5cc74
JB
219char *dirname, *dirpref, *endir, *filepat, *p, temp[BUFSIZ];
220char fullname[BUFSIZ], *p1, *p2;
fbf6641c
BJ
221struct nameblock *q;
222struct depblock *thisdbl;
b342e078 223struct dirhdr *od;
fbf6641c 224struct pattern *patp;
a10b24d4 225struct varblock *cp, *varptr();
dbf5cc74 226char *path, pth[BUFSIZ], *strcpy();
b342e078 227struct direct *dptr;
fbf6641c
BJ
228
229
230thisdbl = 0;
231
232if(mkchain == NO)
233 for(patp=firstpat ; patp ; patp = patp->nxtpattern)
234 if(! unequal(pat, patp->patval)) return(0);
235
236patp = ALLOC(pattern);
237patp->nxtpattern = firstpat;
238firstpat = patp;
239patp->patval = copys(pat);
240
241endir = 0;
242
243for(p=pat; *p!='\0'; ++p)
244 if(*p=='/') endir = p;
245
246if(endir==0)
247 {
fbf6641c
BJ
248 dirpref = "";
249 filepat = pat;
a10b24d4 250 cp = varptr("VPATH");
d85b33c2 251 if (cp->varval == NULL) path = ".";
a10b24d4
KM
252 else {
253 path = pth;
254 *path = '\0';
d14eaed2 255 if (strncmp(cp->varval, ".:", 2) != 0) strcpy(pth,".:");
a10b24d4
KM
256 strcat(pth, cp->varval);
257 }
fbf6641c
BJ
258 }
259else {
fbf6641c 260 *endir = '\0';
a10b24d4
KM
261 path = strcpy(pth, pat);
262 dirpref = concat(pat, "/", temp);
fbf6641c
BJ
263 filepat = endir+1;
264 }
265
a10b24d4
KM
266while (*path) { /* Loop thru each VPATH directory */
267 dirname = path;
268 for (; *path; path++)
269 if (*path == ':') {
270 *path++ = '\0';
271 break;
272 }
273
fbf6641c
BJ
274dirf = NULL;
275cldir = NO;
276
277for(od = firstod; od; od = od->nxtopendir)
278 if(! unequal(dirname, od->dirn) )
279 {
280 dirf = od->dirfc;
b342e078
KM
281 if (dirf != NULL)
282 rewinddir(dirf); /* start over at the beginning */
fbf6641c
BJ
283 break;
284 }
285
286if(dirf == NULL)
287 {
b342e078 288 dirf = opendir(dirname);
fbf6641c
BJ
289 if(nopdir >= MAXDIR)
290 cldir = YES;
291 else {
292 ++nopdir;
b342e078 293 od = ALLOC(dirhdr);
fbf6641c
BJ
294 od->nxtopendir = firstod;
295 firstod = od;
296 od->dirfc = dirf;
297 od->dirn = copys(dirname);
c01bbea7 298 fcntl(dirfd(dirf), F_SETFD, 1);
fbf6641c
BJ
299 }
300 }
301
302if(dirf == NULL)
303 {
304 fprintf(stderr, "Directory %s: ", dirname);
305 fatal("Cannot open");
306 }
307
b342e078 308else for (dptr = readdir(dirf); dptr != NULL; dptr = readdir(dirf))
fbf6641c 309 {
b342e078
KM
310 p1 = dptr->d_name;
311 p2 = nbuf;
312 while( (p2<nbufend) && (*p2++ = *p1++)!='\0' )
313 /* void */;
314 if( amatch(nbuf,filepat) )
315 {
316 concat(dirpref,nbuf,fullname);
317 if( (q=srchname(fullname)) ==0)
318 q = makename(copys(fullname));
319 if(mkchain)
fbf6641c 320 {
b342e078
KM
321 thisdbl = ALLOC(depblock);
322 thisdbl->nxtdepblock = nextdbl;
323 thisdbl->depname = q;
324 nextdbl = thisdbl;
fbf6641c 325 }
b342e078
KM
326 }
327 }
fbf6641c
BJ
328
329if(endir != 0) *endir = '/';
330
b342e078
KM
331if(cldir) {
332 closedir(dirf);
333 dirf = NULL;
334}
a10b24d4 335} /* End of VPATH loop */
fbf6641c
BJ
336return(thisdbl);
337}
338\f
339/* stolen from glob through find */
340
341static amatch(s, p)
342char *s, *p;
343{
344 register int cc, scc, k;
345 int c, lc;
346
347 scc = *s;
348 lc = 077777;
349 switch (c = *p) {
350
351 case '[':
352 k = 0;
353 while (cc = *++p) {
354 switch (cc) {
355
356 case ']':
357 if (k)
358 return(amatch(++s, ++p));
359 else
360 return(0);
361
362 case '-':
363 k |= (lc <= scc) & (scc <= (cc=p[1]) ) ;
364 }
365 if (scc==(lc=cc)) k++;
366 }
367 return(0);
368
369 case '?':
370 caseq:
371 if(scc) return(amatch(++s, ++p));
372 return(0);
373 case '*':
374 return(umatch(s, ++p));
375 case 0:
376 return(!scc);
377 }
378 if (c==scc) goto caseq;
379 return(0);
380}
381
382static umatch(s, p)
383char *s, *p;
384{
385 if(*p==0) return(1);
386 while(*s)
387 if (amatch(s++,p)) return(1);
388 return(0);
389}
390\f
391#ifdef METERFILE
392#include <pwd.h>
393int meteron = 0; /* default: metering off */
394
395meter(file)
396char *file;
397{
398TIMETYPE tvec;
399char *p, *ctime();
400FILE * mout;
401struct passwd *pwd, *getpwuid();
402
403if(file==0 || meteron==0) return;
404
405pwd = getpwuid(getuid());
406
407time(&tvec);
408
409if( (mout=fopen(file,"a")) != NULL )
410 {
411 p = ctime(&tvec);
412 p[16] = '\0';
413 fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4);
414 fclose(mout);
415 }
416}
417#endif
418\f
419
420/* look inside archives for notations a(b) and a((b))
421 a(b) is file member b in archive a
422 a((b)) is entry point _b in object archive a
423*/
424
425#ifdef ASCARCH
426# include <ar.h>
427#else
428# include <ar.h>
429#endif
430#include <a.out.h>
431
432static long arflen;
433static long arfdate;
434static char arfname[16];
435FILE *arfd;
436long int arpos, arlen;
437
438static struct exec objhead;
439
440static struct nlist objentry;
441
442
443TIMETYPE lookarch(filename)
444char *filename;
445{
b342e078 446char *p, *q, *send, s[MAXNAMLEN + 1];
fbf6641c
BJ
447int i, nc, nsym, objarch;
448
449for(p = filename; *p!= '(' ; ++p)
450 ;
451*p = '\0';
452openarch(filename);
453*p++ = '(';
454
455if(*p == '(')
456 {
457 objarch = YES;
458 nc = 8;
459 ++p;
460 }
461else
462 {
463 objarch = NO;
b342e078 464 nc = MAXNAMLEN;
fbf6641c
BJ
465 }
466send = s + nc;
467
468for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
469 ;
470while(q < send)
471 *q++ = '\0';
472while(getarch())
473 {
474 if(objarch)
475 {
476 getobj();
477 nsym = objhead.a_syms / sizeof(objentry);
478 for(i = 0; i<nsym ; ++i)
479 {
480 fread( (char *) &objentry, sizeof(objentry),1,arfd);
481 if( (objentry.n_type & N_EXT)
482 && ((objentry.n_type & ~N_EXT) || objentry.n_value)
483 && eqstr(objentry.n_un.n_name,s,nc))
484 {
485 clarch();
486 return(arfdate);
487 }
488 }
489 }
490
491 else if( eqstr(arfname, s, nc))
492 {
493 clarch();
494 return(arfdate);
495 }
496 }
497
498clarch();
499return( 0L);
500}
501
502
503clarch()
504{
505fclose( arfd );
506}
507
508
509openarch(f)
510register char *f;
511{
512#ifdef ASCARCH
513char magic[SARMAG];
514#endif
515int word;
516#include <sys/stat.h>
517struct stat buf;
518
519stat(f, &buf);
520arlen = buf.st_size;
521
522arfd = fopen(f, "r");
523if(arfd == NULL)
524 fatal1("cannot open %s", f);
525
526 fread( (char *) &word, sizeof(word), 1, arfd);
527#ifdef ASCARCH
528 fseek(arfd, 0L, 0);
529 fread(magic, SARMAG, 1, arfd);
530 arpos = SARMAG;
531 if( ! eqstr(magic, ARMAG, SARMAG) )
532#else
533 arpos = sizeof(word);
534 if(word != ARMAG)
535#endif
536 fatal1("%s is not an archive", f);
537
538arflen = 0;
539}
540
541
542
543getarch()
544{
545 struct ar_hdr arhead;
546 long atol();
547
548arpos += (arflen + 1) & ~1L; /* round archived file length up to even */
549if(arpos >= arlen)
550 return(0);
551fseek(arfd, arpos, 0);
552
553 fread( (char *) &arhead, sizeof(arhead), 1, arfd);
554 arpos += sizeof(arhead);
555#ifdef ASCARCH
556 arflen = atol(arhead.ar_size);
557 arfdate = atol(arhead.ar_date);
558#else
559 arflen = arhead.ar_size;
560 arfdate = arhead.ar_date;
561#endif
562 strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));
563return(1);
564}
565
566
567getobj()
568{
569long int skip;
570
571fread( (char *) &objhead, sizeof(objhead), 1, arfd);
572if (N_BADMAG(objhead))
573 fatal1("%s is not an object module", arfname);
574skip = objhead.a_text + objhead.a_data;
4b952a85 575#ifndef pdp11
fbf6641c
BJ
576skip += objhead.a_trsize + objhead.a_drsize;
577#else
578if(! objhead.a_flag )
579 skip *= 2;
580#endif
581fseek(arfd, skip, 1);
582}
583
584
585eqstr(a,b,n)
586register char *a, *b;
587int n;
588{
589register int i;
590for(i = 0 ; i < n ; ++i)
591 if(*a++ != *b++)
592 return(NO);
593return(YES);
594}
a10b24d4
KM
595
596
597/*
598 * findfl(name) (like execvp, but does path search and finds files)
599 */
600static char fname[128];
601
602char *execat();
603
604char *findfl(name)
605register char *name;
606{
607 register char *p;
608 register struct varblock *cp;
609 struct stat buf;
eb1efbca 610 struct varblock *varptr();
a10b24d4
KM
611
612 for (p = name; *p; p++)
613 if(*p == '/') return(name);
614
615 cp = varptr("VPATH");
616 if(cp->varval == NULL || *cp->varval == 0)
617 p = ":";
618 else
619 p = cp->varval;
620
621 do
622 {
623 p = execat(p, name, fname);
624 if(stat(fname,&buf) >= 0)
625 return(fname);
626 } while (p);
627 return((char *)-1);
628}
629
630char *execat(s1, s2, si)
631register char *s1, *s2;
632char *si;
633{
634 register char *s;
635
636 s = si;
637 while (*s1 && *s1 != ':' && *s1 != '-')
638 *s++ = *s1++;
639 if (si != s)
640 *s++ = '/';
641 while (*s2)
642 *s++ = *s2++;
643 *s = '\0';
644 return(*s1? ++s1: 0);
645}
646
647
648/* copy s to d, changing file names to file aliases */
649fixname(s, d)
650char *s, *d;
651{
652 register char *r, *q;
653 struct nameblock *pn;
dbf5cc74 654 char name[BUFSIZ];
a10b24d4
KM
655
656 while (*s) {
657 if (isspace(*s)) *d++ = *s++;
658 else {
659 r = name;
660 while (*s) {
661 if (isspace(*s)) break;
662 *r++ = *s++;
663 }
664 *r = '\0';
665
666 if (((pn = srchname(name)) != 0) && (pn->alias))
667 q = pn->alias;
668 else q = name;
669
670 while (*q) *d++ = *q++;
671 }
672 }
673 *d = '\0';
674}