V10/cmd/make/files.c

Compare this file to the similar file:
Show the results in this format:

static	char *sccsid = "@(#)files.c	8th Edition (Bell Labs) 85/10/23";
/* UNIX DEPENDENT PROCEDURES */

#define NAMESPERBLOCK	32

/* DEFAULT RULES FOR UNIX */

char *dfltmacro[] =
	{
#ifdef pwb
	".SUFFIXES : .L .out .o .c .f .e .r .y .yr .ye .l .s .z .x .t .h .cl",
#else
	".SUFFIXES :",
#endif
	"YACC=yacc",
	"YACCR=yacc -r",
	"YACCE=yacc -e",
	"YFLAGS=",
	"LEX=lex",
	"LFLAGS=",
	"CC=cc",
	"XI=xi",
	"AR=ar",
	"AS=as",
	"PC=pc",
	"PFLAGS=",
	"CFLAGS=",
	"XIFLAGS=",
	"FC=f77",
	"RC=f77",
	"RFLAGS=",
	"EC=f77",
	"EFLAGS=",
	"FFLAGS=",
	"LOADLIBES=",
#ifdef pwb
	"SCOMP=scomp",
	"SCFLAGS=",
	"CMDICT=cmdict",
	"CMFLAGS=",
#endif

#ifdef pwb
	".o.L .c.L .t.L:",
	"\t$(SCOMP) $(SCFLAGS) $<",

	".t.o:",
	"\t$(SCOMP) $(SCFLAGS) -c $<",

	".t.c:",
	"\t$(SCOMP) $(SCFLAGS) -t $<",

	".h.z .t.z:",
	"\t$(CMDICT) $(CMFLAGS) $<",

	".h.x .t.x:",
	"\t$(CMDICT) $(CMFLAGS) -c $<",
#endif
	0 };

char *dfltpat[] =
	{
	"%.o : %.c",
	"\t$(CC) $(CFLAGS) -c $<",

	"%.s : %.c",
	"\t$(CC) $(CFLAGS) -S $<",

	"%.o : %.xi",
	"\t$(XI) $(XIFLAGS) -c $<",

	"%.o : %.p",
	"\t$(PC) $(PFLAGS) -c $<",

	"%.o : %.cl",
	"\tclass -c $<",

	"%.o : %.e",
	"\t$(FC) $(EFLAGS) -c $<",

	"%.o : %.r",
	"\t$(FC) $(RFLAGS) -c $<",

	"%.o : %.f",
	"\t$(FC) $(FFLAGS) -c $<",

	"%.o : %.s",
	"\t$(AS) -o $@ $<",

	"%.o : %.y",
	"\t$(YACC) $(YFLAGS) $<",
	"\t$(CC) $(CFLAGS) -c y.tab.c",
	"\trm y.tab.c",
	"\tmv y.tab.o $@",

	"%.o : %.yr",
	"\t$(YACCR) $(YFLAGS) $<",
	"\t$(RC) $(RFLAGS) -c y.tab.r",
	"\trm y.tab.r",
	"\tmv y.tab.o $@",

	"%.o : %.ye",
	"\t$(YACCE) $(YFLAGS) $<",
	"\t$(EC) $(RFLAGS) -c y.tab.e",
	"\trm y.tab.e",
	"\tmv y.tab.o $@",

	"%.o : %.l",
	"\t$(LEX) $(LFLAGS) $<",
	"\t$(CC) $(CFLAGS) -c lex.yy.c",
	"\trm lex.yy.c",
	"\tmv lex.yy.o $@",

	"%.c : %.y",
	"\t$(YACC) $(YFLAGS) $<",
	"\tmv y.tab.c $@",

	"%.c : %.l",
	"\t$(LEX) $(LFLAGS) $<",
	"\tmv lex.yy.c $@",

	"%.r : %.yr",
	"\t$(YACCR) $(YFLAGS) $<",
	"\tmv y.tab.r $@",

	"%.e : %.ye",
	"\t$(YACCE) $(YFLAGS) $<",
	"\tmv y.tab.e $@",

	"% : %.o",
	"\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",

	"% : %.s",
	"\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",

	"% : %.c",
	"\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",

	"% : %.f",
	"\t$(FC) $(FFLAGS) $< $(LOADLIBES) -o $@",
	"\t-rm $*.o",

	"% : %.r",
	"\t$(FC) $(RFLAGS) $< $(LOADLIBES) -o $@",
	"\t-rm $*.o",

	"% : %.e",
	"\t$(FC) $(EFLAGS) $< $(LOADLIBES) -o $@",
	"\t-rm $*.o",

	"% : %.y",
	"\t$(YACC) $(YFLAGS) $<",
	"\t$(CC) $(CFLAGS) y.tab.c $(LOADLIBES) -ly -o $@",
	"\trm y.tab.c",

	"% : %.l",
	"\t$(LEX) $(LFLAGS) $<",
	"\t$(CC) $(CFLAGS) lex.yy.c $(LOADLIBES) -ll -o $@",
	"\trm lex.yy.c",

	"% : %.xi",
	"\t$(XI) $(XIFLAGS) $< -o $@",

	0 };



char *dfltsuff[] =
	{
#ifdef pwb
	".SUFFIXES : .L .out .o .c .f .e .r .y .yr .ye .l .s .z .x .t .h .cl",
#else
	".SUFFIXES : .out .o .c .f .e .r .y .yr .ye .l .s .cl .p",
#endif
	".c.o :",
	"\t$(CC) $(CFLAGS) -c $<",

	".p.o :",
	"\t$(PC) $(PFLAGS) -c $<",

	".cl.o :",
	"\tclass -c $<",

	".e.o .r.o .f.o :",
	"\t$(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<",

	".s.o :",
	"\t$(AS) -o $@ $<",

	".y.o :",
	"\t$(YACC) $(YFLAGS) $<",
	"\t$(CC) $(CFLAGS) -c y.tab.c",
	"\trm y.tab.c",
	"\tmv y.tab.o $@",

	".yr.o:",
	"\t$(YACCR) $(YFLAGS) $<",
	"\t$(RC) $(RFLAGS) -c y.tab.r",
	"\trm y.tab.r",
	"\tmv y.tab.o $@",

	".ye.o :",
	"\t$(YACCE) $(YFLAGS) $<",
	"\t$(EC) $(RFLAGS) -c y.tab.e",
	"\trm y.tab.e",
	"\tmv y.tab.o $@",

	".l.o :",
	"\t$(LEX) $(LFLAGS) $<",
	"\t$(CC) $(CFLAGS) -c lex.yy.c",
	"\trm lex.yy.c",
	"\tmv lex.yy.o $@",

	".xi.o :",
	"\t$(XI) -c $<",

	".y.c :",
	"\t$(YACC) $(YFLAGS) $<",
	"\tmv y.tab.c $@",

	".l.c :",
	"\t$(LEX) $(LFLAGS) $<",
	"\tmv lex.yy.c $@",

	".yr.r:",
	"\t$(YACCR) $(YFLAGS) $<",
	"\tmv y.tab.r $@",

	".ye.e :",
	"\t$(YACCE) $(YFLAGS) $<",
	"\tmv y.tab.e $@",

#ifdef pwb
	".o.L .c.L .t.L:",
	"\t$(SCOMP) $(SCFLAGS) $<",

	".t.o:",
	"\t$(SCOMP) $(SCFLAGS) -c $<",

	".t.c:",
	"\t$(SCOMP) $(SCFLAGS) -t $<",

	".h.z .t.z:",
	"\t$(CMDICT) $(CMFLAGS) $<",

	".h.x .t.x:",
	"\t$(CMDICT) $(CMFLAGS) -c $<",
#endif

	".s.out .c.out .o.out :",
	"\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",

	".f.out .r.out .e.out :",
	"\t$(FC) $(EFLAGS) $(RFLAGS) $(FFLAGS) $< $(LOADLIBES) -o $@",
	"\t-rm $*.o",

	".y.out :",
	"\t$(YACC) $(YFLAGS) $<",
	"\t$(CC) $(CFLAGS) y.tab.c $(LOADLIBES) -ly -o $@",
	"\trm y.tab.c",

	".l.out :",
	"\t$(LEX) $(LFLAGS) $<",
	"\t$(CC) $(CFLAGS) lex.yy.c $(LOADLIBES) -ll -o $@",
	"\trm lex.yy.c",

	0 };

#include "defs"


#include <sys/stat.h>

TIMETYPE exists(filename)
char *filename;
{
struct stat buf;
register char *s;
TIMETYPE lookarch();

for(s = filename ; *s!='\0' && *s!='(' &&  *s!=')' ; ++s)
	;

if(*s != '\0')
	return lookarch(filename);

if(stat(filename,&buf) < 0) 
	return 0;
else	return buf.st_mtime;
}


TIMETYPE prestime()
{
TIMETYPE t;
time(&t);
return t;
}

FSTATIC char nmtemp[MAXNAMLEN+1];	/* guarantees a null after the name */
FSTATIC char *tempend = nmtemp + MAXNAMLEN;



depblkp srchdir(pat, mkchain, nextdbl)
register char *pat;	/* pattern to be matched in directory */
int mkchain;		/* nonzero if results to be remembered */
depblkp nextdbl;	/* final value for chain */
{
DIR *dirf;
struct dirhd *dirptr, *opdir();
char *dirname, *dirpref, *endir, *filepat, *p, temp[100];
char fullname[100];
nameblkp q;
depblkp thisdbl;
struct pattern *patp;

struct direct *dptr;


thisdbl = 0;

if(mkchain == NO)
	for(patp=firstpat ; patp ; patp = patp->nxtpattern)
		if(equal(pat, patp->patval)) return 0;

patp = ALLOC(pattern);
patp->nxtpattern = firstpat;
firstpat = patp;
patp->patval = copys(pat);

endir = 0;

for(p=pat; *p!='\0'; ++p)
	if(*p=='/') endir = p;

if(endir==0)
	{
	dirname = ".";
	dirpref = "";
	filepat = pat;
	}
else	{
	dirname = pat;
	*endir = '\0';
	dirpref = concat(dirname, "/", temp);
	filepat = endir+1;
	}

dirptr = opdir(dirname,YES);
dirf = dirptr->dirfc;

for( dptr = readdir(dirf) ; dptr ; dptr = readdir(dirf) )
	{
	register char *p1, *p2;
	p1 = dptr->d_name;
	p2 = nmtemp;
	while( (p2<tempend) && (*p2++ = *p1++)!='\0')
		;
	if( amatch(nmtemp,filepat) )
		{
		concat(dirpref,nmtemp,fullname);
		if( (q=srchname(fullname)) ==0)
			q = makename(copys(fullname));
		if(mkchain)
			{
			thisdbl = ALLOC(depblock);
			thisdbl->nxtdepblock = nextdbl;
			thisdbl->depname = q;
			nextdbl = thisdbl;
			}
		}
	}


if(endir)
	*endir = '/';

cldir(dirptr, YES);

return thisdbl;
}

struct dirhd *opdir(dirname, stopifbad)
char *dirname;
int stopifbad;
{
register struct dirhd *od;

for(od = firstod; od; od = od->nxtdirhd)
	if(equal(dirname, od->dirn) )
		break;

if(od == NULL)
	{
	++nopdir;
	od = ALLOC(dirhd);
	od->nxtdirhd = firstod;
	firstod = od;
	od->dirn = copys(dirname);
	}

if(od->dirfc==NULL && (od->dirfc = opendir(dirname)) == NULL && stopifbad)
	{
	fprintf(stderr, "Directory %s: ", dirname);
	fatal("Cannot open");
	}

return od;
}



cldir(dp, used)
register struct dirhd *dp;
int used;
{
if(nopdir >= MAXDIR)
	{
	closedir(dp->dirfc);
	dp->dirfc = NULL;
	}
else if(used)
	rewinddir(dp->dirfc); /* start over at the beginning  */
}

/* stolen from glob through find */

static amatch(s, p)
char *s, *p;
{
	register int cc, scc, k;
	int c, lc;

	scc = *s;
	lc = 077777;
	switch (c = *p) {

	case '[':
		k = 0;
		while (cc = *++p) {
			switch (cc) {

			case ']':
				if (k)
					return amatch(++s, ++p);
				else
					return 0;

			case '-':
				k |= (lc <= scc)  & (scc <= (cc=p[1]) ) ;
			}
			if (scc==(lc=cc)) k++;
		}
		return 0;

	case '?':
	caseq:
		if(scc) return amatch(++s, ++p);
		return 0;
	case '*':
		return umatch(s, ++p);
	case 0:
		return !scc;
	}
	if (c==scc) goto caseq;
	return 0;
}

static umatch(s, p)
char *s, *p;
{
	if(*p==0) return 1;
	while(*s)
		if (amatch(s++,p)) return 1;
	return 0;
}

#ifdef METERFILE
#include <pwd.h>
int meteron	= 0;	/* default: metering off */

meter(file)
char *file;
{
TIMETYPE tvec;
char *p, *ctime();
FILE * mout;
struct passwd *pwd, *getpwuid();

if(file==0 || meteron==0) return;

pwd = getpwuid(getuid());

time(&tvec);

if( mout = fopen(file,"a") )
	{
	p = ctime(&tvec);
	p[16] = '\0';
	fprintf(mout, "User %s, %s\n", pwd->pw_name, p+4);
	fclose(mout);
	}
}
#endif


/* look inside archives for notations a(b) and a((b))
	a(b)	is file member   b   in archive a
	a((b))	is entry point  _b  in object archive a
*/

#ifdef ASCARCH
#	include <ar.h>
#else
#	include <ar.h>
#endif
#include <a.out.h>

static long arflen;
static long arfdate;
static char arfname[16];
FILE *arfd;
long int arpos, arlen;

static struct exec objhead;

static struct nlist objentry;


TIMETYPE lookarch(filename)
char *filename;
{
char *p, *q, *send, s[15], pad;
int i, nc, nsym, objarch;

for(p = filename; *p!= '(' ; ++p)
	;

*p = '\0';
if( ! openarch(filename) )
	{
	*p = '(';
	return 0L;
	}
*p++ = '(';
if(*p == '(')
	{
	objarch = YES;
	nc = 8;
	pad = '\0';
	++p;
	}
else
	{
	objarch = NO;
	nc = 14;
	pad = ' ';
	}

send = s + nc;
for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
	;
if(p[0]==')' && p[1]!='\0')	/* forbid stuff after the paren */
	{
	clarch();
	return 0L;
	}
while(q < send)
	*q++ = pad;
while(getarch())
	{
	if(objarch)
		{
		getobj();
		nsym = objhead.a_syms / sizeof(objentry);
		for(i = 0; i<nsym ; ++i)
			{
			fread( (char *) &objentry, sizeof(objentry),1,arfd);
			if( (objentry.n_type & N_EXT)
			   && ((objentry.n_type & ~N_EXT) || objentry.n_value)
			   && eqstr(objentry.n_un.n_name,s,nc))
				{
				clarch();
				return arfdate;
				}
			}
		}

	else if( eqstr(arfname, s, nc))
		{
		clarch();
/*TEMP fprintf(stderr, "found archive member %14s, time=%d\n", s, arfdate); */
		return arfdate;
		}
	}

clarch();
return  0L;
}


clarch()
{
fclose( arfd );
}


openarch(f)
register char *f;
{
#ifdef ASCARCH
char magic[SARMAG];
#endif
int word;
struct stat buf;
nameblkp p;

stat(f, &buf);
arlen = buf.st_size;

arfd = fopen(f, "r");
if(arfd == NULL)
	return NO;
	/* fatal1("cannot open %s", f); */

fread( (char *) &word, sizeof(word), 1, arfd);

#ifdef ASCARCH
	fseek(arfd, 0L, 0);
	fread(magic, SARMAG, 1, arfd);
	arpos = SARMAG;
	if( ! eqstr(magic, ARMAG, SARMAG) )
		fatal1("%s is not an archive", f);
#else
	arpos = sizeof(word);
	if(word != ARMAG)
		fatal1("%s is not an archive", f);
#endif

if( !(p = srchname(f)) )
	p = makename( copys(f) );
p->isarch = YES;
arflen = 0;
return YES;
}



getarch()
{
struct ar_hdr arhead;
long atol();

arpos += (arflen + 1) & ~1L;	/* round archived file length up to even */
if(arpos >= arlen)
	return 0;
fseek(arfd, arpos, 0);

	fread( (char *) &arhead, sizeof(arhead), 1, arfd);
	arpos += sizeof(arhead);
#ifdef ASCARCH
	arflen = atol(arhead.ar_size);
	arfdate = atol(arhead.ar_date);
#else
	arflen = arhead.ar_size;
	arfdate = arhead.ar_date;
#endif
	strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));
return 1;
}


getobj()
{
long int skip;

fread( (char *) &objhead, sizeof(objhead), 1, arfd);
if (N_BADMAG(objhead))
	fatal1("%s is not an object module", arfname);
skip = objhead.a_text + objhead.a_data;
skip += objhead.a_trsize + objhead.a_drsize;
fseek(arfd, skip, 1);
}


eqstr(a,b,n)
register char *a, *b;
int n;
{
register int i;
for(i = 0 ; i < n ; ++i)
	if(*a++ != *b++)
		return NO;
return YES;
}

/* find the directory containing name.
   read it into the hash table if it hasn't been used before or if
   if might have changed since last reference
*/

dirsrch(name)
char *name;
{
DIR *dirf;
struct dirhd *opdir(), *dirp;
TIMETYPE dirt, objt, lookarch();
int dirused, hasparen;
char *dirname, *lastslash;
char *fullname, *filepart, *fileend, *s;
struct direct *dptr;

lastslash = NULL;
hasparen = NO;

for(s=name; *s; ++s)
	if(*s == '/')
		lastslash = s;
	else if(*s=='(' || *s==')')
		hasparen = YES;

if(hasparen)
	{
	if(objt = lookarch(name))
		makename(name)->modtime = objt;
	return;
	}

if(lastslash)
	{
	dirname = name;
	*lastslash = '\0';
	}
else
	dirname = ".";

dirused = NO;
dirp = opdir(dirname, NO);
dirf = dirp->dirfc;
if(dirp->dirok || !dirf)
	goto ret;
dirt = exists(dirname);
if(dirp->dirtime == dirt)
	goto ret;

dirp->dirok = YES;
dirp->dirtime = dirt;
dirused = YES;

/* allocate buffer to hold full file name */
if(lastslash)
	{
	fullname = (char *) ckalloc(strlen(dirname)+MAXNAMLEN+2);
	concat(dirname, "/", fullname);
	filepart = fullname + strlen(fullname);
	}
else
	filepart = fullname = (char *) ckalloc(MAXNAMLEN+1);


fileend = filepart + MAXNAMLEN;
*fileend = '\0';
for(dptr = readdir(dirf) ; dptr ; dptr = readdir(dirf) )
	{
	register char *p1, *p2;
	p1 = dptr->d_name;
	p2 = filepart;
	while( (p2<fileend) && (*p2++ = *p1++)!='\0')
		;
	if( ! srchname(fullname) )
		(void) makename(copys(fullname));
	}

free(fullname);

ret:
	cldir(dirp, dirused);
	if(lastslash)
		*lastslash = '/';
}




baddirs()
{
register struct dirhd *od;

for(od = firstod; od; od = od->nxtdirhd)
	od->dirok = NO;
}