Files
retrobsd/src/cmd/make/misc.c
2014-04-09 14:27:18 +01:00

320 lines
5.7 KiB
C

#include "defs.h"
#include <string.h>
#include <stdlib.h>
FSTATIC struct nameblock *hashtab[HASHSIZE];
FSTATIC int nhashed = 0;
/*
* simple linear hash. hash function is sum of
* characters mod hash table size.
*/
int hashloc(s)
char *s;
{
register int i;
register int hashval;
register char *t;
hashval = 0;
for(t=s; *t!='\0' ; ++t)
hashval += *t;
hashval %= HASHSIZE;
for(i=hashval;
hashtab[i]!=0 && unequal(s,hashtab[i]->namep);
i = (i+1)%HASHSIZE ) ;
return(i);
}
struct nameblock *srchname(s)
char *s;
{
return( hashtab[hashloc(s)] );
}
int hasslash(s)
char *s;
{
for (; *s; ++s)
if (*s == '/')
return(YES);
return(NO);
}
struct nameblock *makename(s)
char *s;
{
/* make a fresh copy of the string s */
register struct nameblock *p;
if (nhashed++ > HASHSIZE-3)
fatal("Hash table overflow");
p = ALLOC(nameblock);
p->nxtnameblock = firstname;
p->namep = copys(s);
p->linep = 0;
p->done = 0;
p->septype = 0;
p->modtime = 0;
firstname = p;
if (mainname == NULL)
if (s[0]!='.' || hasslash(s))
mainname = p;
hashtab[hashloc(s)] = p;
return(p);
}
char *copys(s)
register char *s;
{
register char *t, *t0;
t = t0 = calloc(strlen(s) + 1, sizeof(char));
if (t == NULL)
fatal("out of memory");
while ((*t++ = *s++))
;
return(t0);
}
/*
* c = concatenation of a and b
*/
char *concat(a, b, c)
register char *a, *b;
char *c;
{
register char *t;
t = c;
while ((*t = *a++))
t++;
while ((*t++ = *b++));
return c;
}
/*
* is b the suffix of a? if so, set p = prefix
*/
int suffix(a, b, p)
register char *a, *b, *p;
{
char *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(n)
register int n;
{
register int *p;
p = (int *) calloc(1,n);
if (! p)
fatal("out of memory");
return p;
}
/*
* copy string a into b, substituting for arguments
*/
char *subst(a,b)
register char *a,*b;
{
static int depth = 0;
register char *s;
char vname[BUFSIZ];
struct varblock *vbp;
char closer;
if (++depth > 100)
fatal("infinitely recursive macro?");
if (a != 0) {
while(*a) {
if (*a != '$')
*b++ = *a++;
else if (*++a=='\0' || *a=='$')
*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';
vbp = varptr(vname);
if (vbp->varval != 0) {
b = subst(vbp->varval, b);
vbp->used = YES;
}
}
}
}
*b = '\0';
--depth;
return(b);
}
void setvar(v, s)
char *v, *s;
{
struct varblock *p;
p = varptr(v);
if (p->noreset == 0) {
p->varval = s;
p->noreset = inarglist;
if (p->used && unequal(v, "@") && unequal(v, "*")
&& unequal(v, "<") && unequal(v, "?"))
fprintf(stderr, "Warning: %s changed after being used\n", v);
}
}
/*
* look for arguments with equal signs but not colons
*/
int eqsign(a)
char *a;
{
register char *s, *t, *b;
char buf[256];
while (*a == ' ')
++a;
for (s=a; *s!='\0' && *s!=':'; ++s) {
if (*s == '=') {
b = buf;
for (t = a; *t!='=' && *t!=' ' && *t!='\t'; t++)
*b++ = *t;
*b = '\0';
for (++s; *s==' ' || *s=='\t'; ++s);
setvar(buf, copys(s));
return(YES);
}
}
return(NO);
}
struct varblock *varptr(v)
char *v;
{
register struct varblock *vp;
for (vp = firstvar; vp ; vp = vp->nxtvarblock)
if (! unequal(v, vp->varname))
return(vp);
vp = ALLOC(varblock);
vp->nxtvarblock = firstvar;
firstvar = vp;
vp->varname = copys(v);
vp->varval = 0;
return(vp);
}
void fatal1(s, t)
char *s, *t;
{
char buf[BUFSIZ];
sprintf(buf, s, t);
fatal(buf);
}
void fatal(s)
char *s;
{
if (s)
fprintf(stderr, "Make: %s. Stop.\n", s);
else
fprintf(stderr, "\nStop.\n");
exit(1);
}
void yyerror(s)
char *s;
{
char buf[50];
extern int yylineno;
sprintf(buf, "line %d: %s", yylineno, s);
fatal(buf);
}
struct chain *appendq(head, tail)
struct chain *head;
char *tail;
{
register struct chain *p, *q;
p = ALLOC(chain);
p->datap = tail;
if (! head)
return(p);
for(q = head ; q->nextp ; q = q->nextp)
;
q->nextp = p;
return(head);
}
char *mkqlist(p)
struct chain *p;
{
register char *qbufp, *s;
static char qbuf[QBUFMAX];
if (p == NULL) {
qbuf[0] = '\0';
return 0;
}
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;
}