diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/ape/cmd/make/files.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/ape/cmd/make/files.c')
-rwxr-xr-x | sys/src/ape/cmd/make/files.c | 552 |
1 files changed, 552 insertions, 0 deletions
diff --git a/sys/src/ape/cmd/make/files.c b/sys/src/ape/cmd/make/files.c new file mode 100755 index 000000000..59b8ddf84 --- /dev/null +++ b/sys/src/ape/cmd/make/files.c @@ -0,0 +1,552 @@ +/* POSIX DEPENDENT PROCEDURES */ +#include "defs.h" +#include <sys/stat.h> +#include <ar.h> + +#define NAMESPERBLOCK 32 + +/* DEFAULT RULES FOR POSIX */ + +char *dfltmacro[] = + { + ".SUFFIXES : .o .c .y .l .a .sh .f", + "MAKE=make", + "AR=ar", + "ARFLAGS=rv", + "YACC=yacc", + "YFLAGS=", + "LEX=lex", + "LFLAGS=", + "LDFLAGS=", + "CC=c89", + "CFLAGS=-O", + "FC=fort77", + "FFLAGS=-O 1", + 0 }; + +char *dfltpat[] = + { + "%.o : %.c", + "\t$(CC) $(CFLAGS) -c $<", + + "%.o : %.y", + "\t$(YACC) $(YFLAGS) $<", + "\t$(CC) $(CFLAGS) -c y.tab.c", + "\trm y.tab.c", + "\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 $@", + + "% : %.o", + "\t$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<", + + "% : %.c", + "\t$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<", + + 0 }; + + + +char *dfltsuff[] = + { + ".SUFFIXES : .o .c .y .l .a .sh .f", + ".c.o :", + "\t$(CC) $(CFLAGS) -c $<", + + ".f.o :", + "\t$(FC) $(FFLAGS) -c $<", + + ".y.o :", + "\t$(YACC) $(YFLAGS) $<", + "\t$(CC) $(CFLAGS) -c y.tab.c", + "\trm -f y.tab.c", + "\tmv y.tab.o $@", + + ".l.o :", + "\t$(LEX) $(LFLAGS) $<", + "\t$(CC) $(CFLAGS) -c lex.yy.c", + "\trm -f lex.yy.c", + "\tmv lex.yy.o $@", + + ".y.c :", + "\t$(YACC) $(YFLAGS) $<", + "\tmv y.tab.c $@", + + ".l.c :", + "\t$(LEX) $(LFLAGS) $<", + "\tmv lex.yy.c $@", + + ".c.a:", + "\t$(CC) -c $(CFLAGS) $<", + "\t$(AR) $(ARFLAGS) $@ $*.o", + "\trm -f $*.o", + + ".f.a:", + "\t$(FC) -c $(FFLAGS) $<", + "\t$(AR) $(ARFLAGS) $@ $*.o", + "\trm -f $*.o", + + ".c:", + "\t$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<", + + ".f:", + "\t$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $<", + + ".sh:", + "\tcp $< $@", + "\tchmod a+x $@", + + 0 }; + + +static struct dirhd *opdir(char *, int); +static void cldir(struct dirhd *, int); +static int amatch(char *, char *); +static int umatch(char *, char *); +static void clarch(void); +static int openarch(char *); +static int getarch(void); + +time_t +exists(char *filename) +{ +struct stat buf; +char *s; + +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; +} + + +time_t +prestime(void) +{ +time_t t; +time(&t); +return t; +} + +static char nmtemp[MAXNAMLEN+1]; /* guarantees a null after the name */ +static char *tempend = nmtemp + MAXNAMLEN; + + + +depblkp +srchdir(char *pat, int mkchain, depblkp nextdbl) +{ +DIR *dirf; +struct dirhd *dirptr; +char *dirname, *dirpref, *endir, *filepat, *p, temp[100]; +char fullname[100]; +nameblkp q; +depblkp thisdbl; +struct pattern *patp; + +struct dirent *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) ) + { + 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; +} + +static struct dirhd * +opdir(char *dirname, int stopifbad) +{ +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; +} + + +static void +cldir(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 int +amatch(char *s, char *p) +{ + 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 int +umatch(char *s, char *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 */ + +extern void meter(char *file) +{ +time_t tvec; +char *p; +FILE * mout; +struct passwd *pwd; + +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 notation a(b) + a(b) is file member b in archive a +*/ + +static long arflen; +static long arfdate; +static char arfname[16]; +FILE *arfd; +long int arpos, arlen; + +time_t +lookarch(char *filename) +{ +char *p, *q, *send, s[15], pad; +int i, nc, nsym; + +for(p = filename; *p!= '(' ; ++p) + ; + +*p = '\0'; +if( ! openarch(filename) ) + { + *p = '('; + return 0L; + } +*p++ = '('; +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( !strncmp(arfname, s, nc)) + { + clarch(); +/*TEMP fprintf(stderr, "found archive member %14s, time=%d\n", s, arfdate); */ + return arfdate; + } + } + +clarch(); +return 0L; +} + +static void +clarch(void) +{ +fclose( arfd ); +} + +static int +openarch(char *f) +{ +char magic[SARMAG]; +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); + +fseek(arfd, 0L, 0); +fread(magic, SARMAG, 1, arfd); +arpos = SARMAG; +if( strncmp(magic, ARMAG, SARMAG) ) + fatal1("%s is not an archive", f); + +if( !(p = srchname(f)) ) + p = makename( copys(f) ); +p->isarch = YES; +arflen = 0; +return YES; +} + + +static int +getarch(void) +{ +struct ar_hdr arhead; + +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); +arflen = atol(arhead.ar_size); +arfdate = atol(arhead.ar_date); +strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name)); +return 1; +} + +/* 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 +*/ + +void +dirsrch(char *name) +{ +DIR *dirf; +struct dirhd *dirp; +time_t dirt, objt; +int dirused, hasparen; +char *dirname, *lastslash; +char *fullname, *filepart, *fileend, *s; +struct dirent *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) ) + { + 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 = '/'; +} + + + +void +baddirs(void) +{ +struct dirhd *od; + +for(od = firstod; od; od = od->nxtdirhd) + od->dirok = NO; +} |