1 static char *sccsid = "@(#)misc.c 4.5 (Berkeley) 87/10/22"; 2 #include "defs" 3 4 FSTATIC struct nameblock *hashtab[HASHSIZE]; 5 FSTATIC int nhashed = 0; 6 7 8 /* simple linear hash. hash function is sum of 9 characters mod hash table size. 10 */ 11 hashloc(s) 12 char *s; 13 { 14 register int i; 15 register int hashval; 16 register char *t; 17 18 hashval = 0; 19 20 for(t=s; *t!='\0' ; ++t) 21 hashval += *t; 22 23 hashval %= HASHSIZE; 24 25 for(i=hashval; 26 hashtab[i]!=0 && unequal(s,hashtab[i]->namep); 27 i = (i+1)%HASHSIZE ) ; 28 29 return(i); 30 } 31 32 33 struct nameblock *srchname(s) 34 char *s; 35 { 36 return( hashtab[hashloc(s)] ); 37 } 38 39 40 41 struct nameblock *makename(s) 42 char *s; 43 { 44 /* make a fresh copy of the string s */ 45 46 char *copys(); 47 register struct nameblock *p; 48 49 if(nhashed++ > HASHSIZE-3) 50 fatal("Hash table overflow"); 51 52 p = ALLOC(nameblock); 53 p->nxtnameblock = firstname; 54 p->namep = copys(s); 55 p->linep = 0; 56 p->done = 0; 57 p->septype = 0; 58 p->modtime = 0; 59 60 firstname = p; 61 if(mainname == NULL) 62 if(s[0]!='.' || hasslash(s) ) 63 mainname = p; 64 65 hashtab[hashloc(s)] = p; 66 67 return(p); 68 } 69 70 71 72 hasslash(s) 73 char *s; 74 { 75 for( ; *s ; ++s) 76 if(*s == '/') 77 return(YES); 78 return(NO); 79 } 80 81 82 83 char *copys(s) 84 register char *s; 85 { 86 char *calloc(); 87 register char *t, *t0; 88 89 if( (t = t0 = calloc( strlen(s)+1 , sizeof(char)) ) == NULL) 90 fatal("out of memory"); 91 while(*t++ = *s++) 92 ; 93 return(t0); 94 } 95 96 97 98 char *concat(a,b,c) /* c = concatenation of a and b */ 99 register char *a,*b; 100 char *c; 101 { 102 register char *t; 103 t = c; 104 105 while(*t = *a++) t++; 106 while(*t++ = *b++); 107 return(c); 108 } 109 110 111 112 suffix(a,b,p) /* is b the suffix of a? if so, set p = prefix */ 113 register char *a,*b,*p; 114 { 115 char *a0,*b0; 116 a0 = a; 117 b0 = b; 118 119 while(*a++); 120 while(*b++); 121 122 if( (a-a0) < (b-b0) ) return(0); 123 124 while(b>b0) 125 if(*--a != *--b) return(0); 126 127 while(a0<a) *p++ = *a0++; 128 *p = '\0'; 129 130 return(1); 131 } 132 133 134 135 136 137 138 int *ckalloc(n) 139 register int n; 140 { 141 register int *p; 142 143 if( p = (int *) calloc(1,n) ) 144 return(p); 145 146 fatal("out of memory"); 147 /* NOTREACHED */ 148 } 149 150 /* copy string a into b, substituting for arguments */ 151 char *subst(a,b) 152 register char *a,*b; 153 { 154 static depth = 0; 155 register char *s; 156 char vname[BUFSIZ]; 157 struct varblock *varptr(), *vbp; 158 char closer; 159 160 if(++depth > 100) 161 fatal("infinitely recursive macro?"); 162 if(a!=0) while(*a) 163 { 164 if(*a != '$') *b++ = *a++; 165 else if(*++a=='\0' || *a=='$') 166 *b++ = *a++; 167 else { 168 s = vname; 169 if( *a=='(' || *a=='{' ) 170 { 171 closer = ( *a=='(' ? ')' : '}'); 172 ++a; 173 while(*a == ' ') ++a; 174 while(*a!=' ' && *a!=closer && *a!='\0') *s++ = *a++; 175 while(*a!=closer && *a!='\0') ++a; 176 if(*a == closer) ++a; 177 } 178 else *s++ = *a++; 179 180 *s = '\0'; 181 if( (vbp = varptr(vname)) ->varval != 0) 182 { 183 b = subst(vbp->varval, b); 184 vbp->used = YES; 185 } 186 } 187 } 188 189 *b = '\0'; 190 --depth; 191 return(b); 192 } 193 194 195 setvar(v,s) 196 char *v, *s; 197 { 198 struct varblock *varptr(), *p; 199 200 p = varptr(v); 201 if(p->noreset == 0) 202 { 203 p->varval = s; 204 p->noreset = inarglist; 205 if(p->used && unequal(v,"@") && unequal(v,"*") 206 && unequal(v,"<") && unequal(v,"?") ) 207 fprintf(stderr, "Warning: %s changed after being used\n",v); 208 } 209 } 210 211 212 eqsign(a) /*look for arguments with equal signs but not colons */ 213 char *a; 214 { 215 register char *s, *t, c; 216 217 while(*a == ' ') ++a; 218 for(s=a ; *s!='\0' && *s!=':' ; ++s) 219 if(*s == '=') 220 { 221 for(t = a ; *t!='=' && *t!=' ' && *t!='\t' ; ++t ); 222 c = *t; 223 *t = '\0'; 224 225 for(++s; *s==' ' || *s=='\t' ; ++s); 226 setvar(a, copys(s)); 227 *t = c; 228 return(YES); 229 } 230 231 return(NO); 232 } 233 234 235 struct varblock *varptr(v) 236 char *v; 237 { 238 register struct varblock *vp; 239 240 for(vp = firstvar; vp ; vp = vp->nxtvarblock) 241 if(! unequal(v , vp->varname)) 242 return(vp); 243 244 vp = ALLOC(varblock); 245 vp->nxtvarblock = firstvar; 246 firstvar = vp; 247 vp->varname = copys(v); 248 vp->varval = 0; 249 return(vp); 250 } 251 252 253 fatal1(s, t) 254 char *s, *t; 255 { 256 char buf[BUFSIZ]; 257 (void)sprintf(buf, s, t); 258 fatal(buf); 259 } 260 261 262 263 fatal(s) 264 char *s; 265 { 266 if(s) fprintf(stderr, "Make: %s. Stop.\n", s); 267 else fprintf(stderr, "\nStop.\n"); 268 #ifdef unix 269 exit(1); 270 #endif 271 #ifdef gcos 272 exit(0); 273 #endif 274 } 275 276 277 278 yyerror(s) 279 char *s; 280 { 281 char buf[50]; 282 extern int yylineno; 283 284 (void)sprintf(buf, "line %d: %s", yylineno, s); 285 fatal(buf); 286 } 287 288 289 290 struct chain *appendq(head, tail) 291 struct chain *head; 292 char *tail; 293 { 294 register struct chain *p, *q; 295 296 p = ALLOC(chain); 297 p->datap = tail; 298 299 if(head) 300 { 301 for(q = head ; q->nextp ; q = q->nextp) 302 ; 303 q->nextp = p; 304 return(head); 305 } 306 else 307 return(p); 308 } 309 310 311 312 313 314 char *mkqlist(p) 315 struct chain *p; 316 { 317 register char *qbufp, *s; 318 static char qbuf[QBUFMAX]; 319 320 if(p == NULL) 321 { 322 qbuf[0] = '\0'; 323 return; 324 } 325 326 qbufp = qbuf; 327 328 for( ; p ; p = p->nextp) 329 { 330 s = p->datap; 331 if(qbufp+strlen(s) > &qbuf[QBUFMAX-3]) 332 { 333 fprintf(stderr, "$? list too long\n"); 334 break; 335 } 336 while (*s) 337 *qbufp++ = *s++; 338 *qbufp++ = ' '; 339 } 340 *--qbufp = '\0'; 341 return(qbuf); 342 } 343