1 static char *sccsid = "@(#)misc.c 4.3 (Berkeley) 85/08/30"; 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; 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 *t = '\0'; 223 224 for(++s; *s==' ' || *s=='\t' ; ++s); 225 setvar(a, copys(s)); 226 return(YES); 227 } 228 229 return(NO); 230 } 231 232 233 struct varblock *varptr(v) 234 char *v; 235 { 236 register struct varblock *vp; 237 238 for(vp = firstvar; vp ; vp = vp->nxtvarblock) 239 if(! unequal(v , vp->varname)) 240 return(vp); 241 242 vp = ALLOC(varblock); 243 vp->nxtvarblock = firstvar; 244 firstvar = vp; 245 vp->varname = copys(v); 246 vp->varval = 0; 247 return(vp); 248 } 249 250 251 fatal1(s, t) 252 char *s, *t; 253 { 254 char buf[BUFSIZ]; 255 sprintf(buf, s, t); 256 fatal(buf); 257 } 258 259 260 261 fatal(s) 262 char *s; 263 { 264 if(s) fprintf(stderr, "Make: %s. Stop.\n", s); 265 else fprintf(stderr, "\nStop.\n"); 266 #ifdef unix 267 exit(1); 268 #endif 269 #ifdef gcos 270 exit(0); 271 #endif 272 } 273 274 275 276 yyerror(s) 277 char *s; 278 { 279 char buf[50]; 280 extern int yylineno; 281 282 sprintf(buf, "line %d: %s", yylineno, s); 283 fatal(buf); 284 } 285 286 287 288 struct chain *appendq(head, tail) 289 struct chain *head; 290 char *tail; 291 { 292 register struct chain *p, *q; 293 294 p = ALLOC(chain); 295 p->datap = tail; 296 297 if(head) 298 { 299 for(q = head ; q->nextp ; q = q->nextp) 300 ; 301 q->nextp = p; 302 return(head); 303 } 304 else 305 return(p); 306 } 307 308 309 310 311 312 char *mkqlist(p) 313 struct chain *p; 314 { 315 register char *qbufp, *s; 316 static char qbuf[QBUFMAX]; 317 318 if(p == NULL) 319 { 320 qbuf[0] = '\0'; 321 return; 322 } 323 324 qbufp = qbuf; 325 326 for( ; p ; p = p->nextp) 327 { 328 s = p->datap; 329 if(qbufp+strlen(s) > &qbuf[QBUFMAX-3]) 330 { 331 fprintf(stderr, "$? list too long\n"); 332 break; 333 } 334 while (*s) 335 *qbufp++ = *s++; 336 *qbufp++ = ' '; 337 } 338 *--qbufp = '\0'; 339 return(qbuf); 340 } 341