xref: /csrg-svn/old/make/misc.c (revision 58769)
1*58769Sbostic static	char *sccsid = "@(#)misc.c	4.6 (Berkeley) 93/03/23";
22810Swnj #include "defs"
3*58769Sbostic #include <stdlib.h>
42810Swnj 
52810Swnj FSTATIC struct nameblock *hashtab[HASHSIZE];
62810Swnj FSTATIC int nhashed	= 0;
72810Swnj 
82810Swnj 
92810Swnj /* simple linear hash.  hash function is sum of
102810Swnj    characters mod hash table size.
112810Swnj */
hashloc(s)122810Swnj hashloc(s)
132810Swnj char *s;
142810Swnj {
152810Swnj register int i;
162810Swnj register int hashval;
172810Swnj register char *t;
182810Swnj 
192810Swnj hashval = 0;
202810Swnj 
212810Swnj for(t=s; *t!='\0' ; ++t)
222810Swnj 	hashval += *t;
232810Swnj 
242810Swnj hashval %= HASHSIZE;
252810Swnj 
262810Swnj for(i=hashval;
272810Swnj 	hashtab[i]!=0 && unequal(s,hashtab[i]->namep);
282810Swnj 	i = (i+1)%HASHSIZE ) ;
292810Swnj 
302810Swnj return(i);
312810Swnj }
322810Swnj 
332810Swnj 
srchname(s)342810Swnj struct nameblock *srchname(s)
352810Swnj char *s;
362810Swnj {
372810Swnj return( hashtab[hashloc(s)] );
382810Swnj }
392810Swnj 
402810Swnj 
412810Swnj 
makename(s)422810Swnj struct nameblock *makename(s)
432810Swnj char *s;
442810Swnj {
452810Swnj /* make a fresh copy of the string s */
462810Swnj 
472810Swnj char *copys();
482810Swnj register struct nameblock *p;
492810Swnj 
502810Swnj if(nhashed++ > HASHSIZE-3)
512810Swnj 	fatal("Hash table overflow");
522810Swnj 
532810Swnj p = ALLOC(nameblock);
542810Swnj p->nxtnameblock = firstname;
552810Swnj p->namep = copys(s);
562810Swnj p->linep = 0;
572810Swnj p->done = 0;
582810Swnj p->septype = 0;
592810Swnj p->modtime = 0;
602810Swnj 
612810Swnj firstname = p;
622810Swnj if(mainname == NULL)
632810Swnj 	if(s[0]!='.' || hasslash(s) )
642810Swnj 		mainname = p;
652810Swnj 
662810Swnj hashtab[hashloc(s)] = p;
672810Swnj 
682810Swnj return(p);
692810Swnj }
702810Swnj 
712810Swnj 
722810Swnj 
hasslash(s)732810Swnj hasslash(s)
742810Swnj char *s;
752810Swnj {
762810Swnj for( ; *s ; ++s)
772810Swnj 	if(*s == '/')
782810Swnj 		return(YES);
792810Swnj return(NO);
802810Swnj }
812810Swnj 
822810Swnj 
832810Swnj 
copys(s)842810Swnj char *copys(s)
852810Swnj register char *s;
862810Swnj {
872810Swnj register char *t, *t0;
882810Swnj 
892810Swnj if( (t = t0 = calloc( strlen(s)+1 , sizeof(char)) ) == NULL)
902810Swnj 	fatal("out of memory");
912810Swnj while(*t++ = *s++)
922810Swnj 	;
932810Swnj return(t0);
942810Swnj }
952810Swnj 
962810Swnj 
972810Swnj 
concat(a,b,c)982810Swnj char *concat(a,b,c)   /* c = concatenation of a and b */
992810Swnj register char *a,*b;
1002810Swnj char *c;
1012810Swnj {
1022810Swnj register char *t;
1032810Swnj t = c;
1042810Swnj 
1052810Swnj while(*t = *a++) t++;
1062810Swnj while(*t++ = *b++);
1072810Swnj return(c);
1082810Swnj }
1092810Swnj 
1102810Swnj 
1112810Swnj 
suffix(a,b,p)1122810Swnj suffix(a,b,p)  /* is b the suffix of a?  if so, set p = prefix */
1132810Swnj register char *a,*b,*p;
1142810Swnj {
1152810Swnj char *a0,*b0;
1162810Swnj a0 = a;
1172810Swnj b0 = b;
1182810Swnj 
1192810Swnj while(*a++);
1202810Swnj while(*b++);
1212810Swnj 
1222810Swnj if( (a-a0) < (b-b0) ) return(0);
1232810Swnj 
1242810Swnj while(b>b0)
1252810Swnj 	if(*--a != *--b) return(0);
1262810Swnj 
1272810Swnj while(a0<a) *p++ = *a0++;
1282810Swnj *p = '\0';
1292810Swnj 
1302810Swnj return(1);
1312810Swnj }
1322810Swnj 
1332810Swnj 
1342810Swnj 
1352810Swnj 
1362810Swnj 
1372810Swnj 
ckalloc(n)1382810Swnj int *ckalloc(n)
1392810Swnj register int n;
1402810Swnj {
1412810Swnj register int *p;
1422810Swnj 
1432810Swnj if( p = (int *) calloc(1,n) )
1442810Swnj 	return(p);
1452810Swnj 
1462810Swnj fatal("out of memory");
1472810Swnj /* NOTREACHED */
1482810Swnj }
1492810Swnj 
1502810Swnj /* copy string a into b, substituting for arguments */
subst(a,b)1512810Swnj char *subst(a,b)
1522810Swnj register char *a,*b;
1532810Swnj {
1542810Swnj static depth	= 0;
1552810Swnj register char *s;
15624493Sbloom char vname[BUFSIZ];
1572810Swnj struct varblock *varptr(), *vbp;
1582810Swnj char closer;
1592810Swnj 
1602810Swnj if(++depth > 100)
1612810Swnj 	fatal("infinitely recursive macro?");
1622810Swnj if(a!=0)  while(*a)
1632810Swnj 	{
1642810Swnj 	if(*a != '$') *b++ = *a++;
1652810Swnj 	else if(*++a=='\0' || *a=='$')
1662810Swnj 		*b++ = *a++;
1672810Swnj 	else	{
1682810Swnj 		s = vname;
1692810Swnj 		if( *a=='(' || *a=='{' )
1702810Swnj 			{
1712810Swnj 			closer = ( *a=='(' ? ')' : '}');
1722810Swnj 			++a;
1732810Swnj 			while(*a == ' ') ++a;
1742810Swnj 			while(*a!=' ' && *a!=closer && *a!='\0') *s++ = *a++;
1752810Swnj 			while(*a!=closer && *a!='\0') ++a;
1762810Swnj 			if(*a == closer) ++a;
1772810Swnj 			}
1782810Swnj 		else	*s++ = *a++;
1792810Swnj 
1802810Swnj 		*s = '\0';
1812810Swnj 		if( (vbp = varptr(vname)) ->varval != 0)
1822810Swnj 			{
1832810Swnj 			b = subst(vbp->varval, b);
1842810Swnj 			vbp->used = YES;
1852810Swnj 			}
1862810Swnj 		}
1872810Swnj 	}
1882810Swnj 
1892810Swnj *b = '\0';
1902810Swnj --depth;
1912810Swnj return(b);
1922810Swnj }
1932810Swnj 
1942810Swnj 
setvar(v,s)1952810Swnj setvar(v,s)
1962810Swnj char *v, *s;
1972810Swnj {
1982810Swnj struct varblock *varptr(), *p;
1992810Swnj 
2002810Swnj p = varptr(v);
2012810Swnj if(p->noreset == 0)
2022810Swnj 	{
2032810Swnj 	p->varval = s;
2042810Swnj 	p->noreset = inarglist;
2052810Swnj 	if(p->used && unequal(v,"@") && unequal(v,"*")
2062810Swnj 	    && unequal(v,"<") && unequal(v,"?") )
2072810Swnj 		fprintf(stderr, "Warning: %s changed after being used\n",v);
2082810Swnj 	}
2092810Swnj }
2102810Swnj 
2112810Swnj 
eqsign(a)2122810Swnj eqsign(a)   /*look for arguments with equal signs but not colons */
2132810Swnj char *a;
2142810Swnj {
21531164Sbostic register char *s, *t, c;
2162810Swnj 
2172810Swnj while(*a == ' ') ++a;
2182810Swnj for(s=a  ;   *s!='\0' && *s!=':'  ; ++s)
2192810Swnj 	if(*s == '=')
2202810Swnj 		{
2212810Swnj 		for(t = a ; *t!='=' && *t!=' ' && *t!='\t' ;  ++t );
22231164Sbostic 		c = *t;
2232810Swnj 		*t = '\0';
2242810Swnj 
2252810Swnj 		for(++s; *s==' ' || *s=='\t' ; ++s);
2262810Swnj 		setvar(a, copys(s));
22731164Sbostic 		*t = c;
2282810Swnj 		return(YES);
2292810Swnj 		}
2302810Swnj 
2312810Swnj return(NO);
2322810Swnj }
2332810Swnj 
2342810Swnj 
varptr(v)2352810Swnj struct varblock *varptr(v)
2362810Swnj char *v;
2372810Swnj {
2382810Swnj register struct varblock *vp;
2392810Swnj 
2402810Swnj for(vp = firstvar; vp ; vp = vp->nxtvarblock)
2412810Swnj 	if(! unequal(v , vp->varname))
2422810Swnj 		return(vp);
2432810Swnj 
2442810Swnj vp = ALLOC(varblock);
2452810Swnj vp->nxtvarblock = firstvar;
2462810Swnj firstvar = vp;
2472810Swnj vp->varname = copys(v);
2482810Swnj vp->varval = 0;
2492810Swnj return(vp);
2502810Swnj }
2512810Swnj 
2522810Swnj 
fatal1(s,t)2532810Swnj fatal1(s, t)
2542810Swnj char *s, *t;
2552810Swnj {
2568677Ssam char buf[BUFSIZ];
25732427Sbostic (void)sprintf(buf, s, t);
2582810Swnj fatal(buf);
2592810Swnj }
2602810Swnj 
2612810Swnj 
2622810Swnj 
fatal(s)2632810Swnj fatal(s)
2642810Swnj char *s;
2652810Swnj {
2662810Swnj if(s) fprintf(stderr, "Make: %s.  Stop.\n", s);
2672810Swnj else fprintf(stderr, "\nStop.\n");
2682810Swnj #ifdef unix
2692810Swnj exit(1);
2702810Swnj #endif
2712810Swnj #ifdef gcos
2722810Swnj exit(0);
2732810Swnj #endif
2742810Swnj }
2752810Swnj 
2762810Swnj 
2772810Swnj 
yyerror(s)2782810Swnj yyerror(s)
2792810Swnj char *s;
2802810Swnj {
2812810Swnj char buf[50];
2822810Swnj extern int yylineno;
2832810Swnj 
28432427Sbostic (void)sprintf(buf, "line %d: %s", yylineno, s);
2852810Swnj fatal(buf);
2862810Swnj }
2872810Swnj 
2882810Swnj 
2892810Swnj 
appendq(head,tail)2902810Swnj struct chain *appendq(head, tail)
2912810Swnj struct chain *head;
2922810Swnj char *tail;
2932810Swnj {
2942810Swnj register struct chain *p, *q;
2952810Swnj 
2962810Swnj p = ALLOC(chain);
2972810Swnj p->datap = tail;
2982810Swnj 
2992810Swnj if(head)
3002810Swnj 	{
3012810Swnj 	for(q = head ; q->nextp ; q = q->nextp)
3022810Swnj 		;
3032810Swnj 	q->nextp = p;
3042810Swnj 	return(head);
3052810Swnj 	}
3062810Swnj else
3072810Swnj 	return(p);
3082810Swnj }
3092810Swnj 
3102810Swnj 
3112810Swnj 
3122810Swnj 
3132810Swnj 
mkqlist(p)3142810Swnj char *mkqlist(p)
3152810Swnj struct chain *p;
3162810Swnj {
3172810Swnj register char *qbufp, *s;
3182810Swnj static char qbuf[QBUFMAX];
3192810Swnj 
3202810Swnj if(p == NULL)
3212810Swnj 	{
3222810Swnj 	qbuf[0] = '\0';
3232810Swnj 	return;
3242810Swnj 	}
3252810Swnj 
3262810Swnj qbufp = qbuf;
3272810Swnj 
3282810Swnj for( ; p ; p = p->nextp)
3292810Swnj 	{
3302810Swnj 	s = p->datap;
3312810Swnj 	if(qbufp+strlen(s) > &qbuf[QBUFMAX-3])
3322810Swnj 		{
3332810Swnj 		fprintf(stderr, "$? list too long\n");
3342810Swnj 		break;
3352810Swnj 		}
3362810Swnj 	while (*s)
3372810Swnj 		*qbufp++ = *s++;
3382810Swnj 	*qbufp++ = ' ';
3392810Swnj 	}
3402810Swnj *--qbufp = '\0';
3412810Swnj return(qbuf);
3422810Swnj }
343