123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 |
- #include "defs.h"
- static int hasslash(char *);
- static int haspercent(char *);
- static void rehash(void);
- /* simple linear hash. hash function is sum of
- characters mod hash table size.
- */
- static int
- hashloc(char *s)
- {
- int i;
- int hashval;
- char *t;
- hashval = 0;
- for(t=s; *t!='\0' ; ++t)
- hashval += *t;
- hashval %= hashsize;
- for(i=hashval;
- hashtab[i]!=0 && !equal(s,hashtab[i]->namep);
- i = i >= hashsize-1 ? 0 : i+1) ;
- return i;
- }
- nameblkp
- srchname(char *s)
- {
- return hashtab[hashloc(s)] ;
- }
- nameblkp
- makename(char *s)
- {
- nameblkp p;
- if(nhashed > hashthresh)
- rehash();
- ++nhashed;
- hashtab[hashloc(s)] = p = ALLOC(nameblock);
- p->nxtnameblock = firstname;
- p->namep = copys(s); /* make a fresh copy of the string s */
- /* p->linep = 0; p->done = 0; p->septype = 0; p->modtime = 0; */
- firstname = p;
- if(mainname==NULL && !haspercent(s) && (*s!='.' || hasslash(s)) )
- mainname = p;
- return p;
- }
- static int
- hasslash(char *s)
- {
- for( ; *s ; ++s)
- if(*s == '/')
- return YES;
- return NO;
- }
- static int
- haspercent(char *s)
- {
- for( ; *s ; ++s)
- if(*s == '%')
- return YES;
- return NO;
- }
- int
- hasparen(char *s)
- {
- for( ; *s ; ++s)
- if(*s == '(')
- return YES;
- return NO;
- }
- static void
- rehash(void)
- {
- nameblkp *ohash;
- nameblkp p, *hp, *endohash;
- hp = ohash = hashtab;
- endohash = hashtab + hashsize;
- newhash(2*hashsize);
- while( hp<endohash )
- if(p = *hp++)
- hashtab[hashloc(p->namep)] = p;
- free( (char *) ohash);
- }
- void
- newhash(int newsize)
- {
- hashsize = newsize;
- hashtab = (nameblkp *) ckalloc(hashsize * sizeof(nameblkp));
- hashthresh = (2*hashsize)/3;
- }
- nameblkp chkname(char *s)
- {
- nameblkp p;
- time_t k;
- /*TEMP NEW */
- if(hasparen(s))
- {
- k = lookarch(s);
- /*TEMP fprintf(stderr, "chkname(%s): look=%d\n", s, k); */
- if(k == 0)
- return NULL;
- }
- if(p = srchname(s))
- return p;
- dirsrch(s);
- return srchname(s);
- }
- char *
- copys(char *s)
- {
- char *t;
- if( (t = malloc( strlen(s)+1 ) ) == NULL)
- fatal("out of memory");
- strcpy(t, s);
- return t;
- }
- char *
- concat(char *a, char *b, char *c) /* c = concatenation of a and b */
- {
- char *t;
- t = c;
- while(*t = *a++) t++;
- while(*t++ = *b++);
- return c;
- }
- int
- suffix(char *a, char *b, char *p) /* is b the suffix of a? if so, set p = prefix */
- {
- char *a0,*b0;
- a0 = a;
- b0 = b;
- while(*a++);
- while(*b++);
- if( (a-a0) < (b-b0) ) return 0;
- while(b>b0)
- if(*--a != *--b) return 0;
- while(a0<a) *p++ = *a0++;
- *p = '\0';
- return 1;
- }
- int *
- ckalloc(int n)
- {
- int *p;
- if( p = (int *) calloc(1,n) )
- return p;
- fatal("out of memory");
- /* NOTREACHED */
- return 0;
- }
- /* copy string a into b, substituting for arguments */
- char *
- subst(char *a, char *b, char *e)
- {
- static depth = 0;
- char *s;
- char vname[100];
- struct varblock *vbp;
- char closer;
- if(++depth > 100)
- fatal("infinitely recursive macro?");
- if(a) while(*a)
- {
- if(*a!='$' || a[1]=='\0' || *++a=='$')
- /* if a non-macro character copy it. if $$ or $\0, copy $ */
- *b++ = *a++;
- else {
- s = vname;
- if( *a=='(' || *a=='{' )
- {
- closer = ( *a=='(' ? ')' : '}');
- ++a;
- while(*a == ' ') ++a;
- while(*a!=' ' && *a!=closer && *a!='\0') *s++ = *a++;
- while(*a!=closer && *a!='\0') ++a;
- if(*a == closer) ++a;
- }
- else *s++ = *a++;
- *s = '\0';
- if( (vbp = varptr(vname)) ->varval != 0)
- {
- b = subst(vbp->varval, b, e);
- vbp->used = YES;
- }
- }
- if(b >= e)
- fatal("macro expanded too far");
- }
- *b = '\0';
- --depth;
- return b;
- }
- void
- setvar(char *v, char *s, int dyn)
- {
- struct varblock *p;
- p = varptr(v);
- if( ! p->noreset )
- {
- p->varval = s;
- p->noreset = inarglist;
- if(p->used && !dyn)
- fprintf(stderr, "Warning: %s changed after being used\n",v);
- if(p->export)
- {
- /* change string pointed to by environment to new v=s */
- char *t;
- int lenv;
- lenv = strlen(v);
- *(p->export) = t = (char *) ckalloc(lenv + strlen(s) + 2);
- strcpy(t,v);
- t[lenv] = '=';
- strcpy(t+lenv+1, s);
- }
- else
- p->export = envpp;
- }
- }
- /* for setting Bradford's *D and *F family of macros whens setting * etc */
- void
- set3var(char *macro, char *value)
- {
- char *s;
- char macjunk[8], *lastslash, *dirpart, *filepart;
- setvar(macro, value, YES);
- if(value == CHNULL)
- dirpart = filepart = CHNULL;
- else
- {
- lastslash = CHNULL;
- for(s = value; *s; ++s)
- if(*s == '/')
- lastslash = s;
- if(lastslash)
- {
- dirpart = copys(value);
- filepart = dirpart + (lastslash-value);
- filepart[-1] = '\0';
- }
- else
- {
- dirpart = "";
- filepart = value;
- }
- }
- setvar(concat(macro, "D", macjunk), dirpart, YES);
- setvar(concat(macro, "F", macjunk), filepart, YES);
- }
- int
- eqsign(char *a) /*look for arguments with equal signs but not colons */
- {
- char *s, *t;
- char c;
- while(*a == ' ') ++a;
- for(s=a ; *s!='\0' && *s!=':' ; ++s)
- if(*s == '=')
- {
- for(t = a ; *t!='=' && *t!=' ' && *t!='\t' ; ++t );
- c = *t;
- *t = '\0';
- for(++s; *s==' ' || *s=='\t' ; ++s);
- setvar(a, copys(s), NO);
- *t = c;
- return YES;
- }
- return NO;
- }
- struct varblock *
- varptr(char *v)
- {
- struct varblock *vp;
- /* for compatibility, $(TGS) = $^ */
- if(equal(v, "TGS") )
- v = "^";
- for(vp = firstvar; vp ; vp = vp->nxtvarblock)
- if(equal(v , vp->varname))
- return vp;
- vp = ALLOC(varblock);
- vp->nxtvarblock = firstvar;
- firstvar = vp;
- vp->varname = copys(v);
- vp->varval = 0;
- return vp;
- }
- int
- dynmacro(char *line)
- {
- char *s;
- char endc, *endp;
- if(!isalpha(line[0]))
- return NO;
- for(s=line+1 ; *s && (isalpha(*s) | isdigit(*s)) ; ++s)
- ;
- endp = s;
- while( isspace(*s) )
- ++s;
- if(s[0]!=':' || s[1]!='=')
- return NO;
- endc = *endp;
- *endp = '\0';
- setvar(line, copys(s+2), YES);
- *endp = endc;
- return YES;
- }
- void
- fatal1(char *s, char *t)
- {
- char buf[100];
- sprintf(buf, s, t);
- fatal(buf);
- }
- void
- fatal(char *s)
- {
- fflush(stdout);
- if(s)
- fprintf(stderr, "Make: %s. Stop.\n", s);
- else
- fprintf(stderr, "\nStop.\n");
- waitstack(0);
- exit(1);
- }
- /* appends to the chain for $? and $^ */
- chainp
- appendq(chainp head, char *tail)
- {
- chainp p, q;
- p = ALLOC(chain);
- p->datap = tail;
- if(head)
- {
- for(q = head ; q->nextp ; q = q->nextp)
- ;
- q->nextp = p;
- return head;
- }
- else
- return p;
- }
- /* builds the value for $? and $^ */
- char *
- mkqlist(chainp p, char *qbuf)
- {
- char *qbufp, *s;
- if(p == NULL)
- return "";
- qbufp = qbuf;
- for( ; p ; p = p->nextp)
- {
- s = p->datap;
- if(qbufp+strlen(s) > &qbuf[QBUFMAX-3])
- {
- fprintf(stderr, "$? list too long\n");
- break;
- }
- while (*s)
- *qbufp++ = *s++;
- *qbufp++ = ' ';
- }
- *--qbufp = '\0';
- return qbuf;
- }
- wildp
- iswild(char *name)
- {
- char *s;
- wildp p;
- for(s=name; *s; ++s)
- if(*s == '%')
- {
- p = ALLOC(wild);
- *s = '\0';
- p->left = copys(name);
- *s = '%';
- p->right = copys(s+1);
- p->llen = strlen(p->left);
- p->rlen = strlen(p->right);
- p->totlen = p->llen + p->rlen;
- return p;
- }
- return NULL;
- }
- char *
- wildmatch(wildp p, char *name, int len)
- {
- char *stem;
- char *s;
- char c;
- if(len < p->totlen ||
- strncmp(name, p->left, p->llen) ||
- strncmp(s = name+len-p->rlen, p->right, p->rlen) )
- return CHNULL;
- /*TEMP fprintf(stderr, "wildmatch(%s)=%s%%%s)\n", name,p->left,p->right); */
- c = *s;
- *s = '\0';
- stem = copys(name + p->llen);
- *s = c;
- return stem;
- }
- /* substitute stem for any % marks */
- char *
- wildsub(char *pat, char *stem)
- {
- static char temp[100];
- char *s, *t;
- s = temp;
- for(; *pat; ++pat)
- if(*pat == '%')
- for(t = stem ; *t; )
- *s++ = *t++;
- else
- *s++ = *pat;
- *s = '\0';
- return temp;
- }
|