summaryrefslogtreecommitdiff
path: root/sys/src/ape/cmd/make/files.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /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-xsys/src/ape/cmd/make/files.c552
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;
+}