misc.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. #include "defs.h"
  2. static int hasslash(char *);
  3. static int haspercent(char *);
  4. static void rehash(void);
  5. /* simple linear hash. hash function is sum of
  6. characters mod hash table size.
  7. */
  8. static int
  9. hashloc(char *s)
  10. {
  11. int i;
  12. int hashval;
  13. char *t;
  14. hashval = 0;
  15. for(t=s; *t!='\0' ; ++t)
  16. hashval += *t;
  17. hashval %= hashsize;
  18. for(i=hashval;
  19. hashtab[i]!=0 && !equal(s,hashtab[i]->namep);
  20. i = i >= hashsize-1 ? 0 : i+1) ;
  21. return i;
  22. }
  23. nameblkp
  24. srchname(char *s)
  25. {
  26. return hashtab[hashloc(s)] ;
  27. }
  28. nameblkp
  29. makename(char *s)
  30. {
  31. nameblkp p;
  32. if(nhashed > hashthresh)
  33. rehash();
  34. ++nhashed;
  35. hashtab[hashloc(s)] = p = ALLOC(nameblock);
  36. p->nxtnameblock = firstname;
  37. p->namep = copys(s); /* make a fresh copy of the string s */
  38. /* p->linep = 0; p->done = 0; p->septype = 0; p->modtime = 0; */
  39. firstname = p;
  40. if(mainname==NULL && !haspercent(s) && (*s!='.' || hasslash(s)) )
  41. mainname = p;
  42. return p;
  43. }
  44. static int
  45. hasslash(char *s)
  46. {
  47. for( ; *s ; ++s)
  48. if(*s == '/')
  49. return YES;
  50. return NO;
  51. }
  52. static int
  53. haspercent(char *s)
  54. {
  55. for( ; *s ; ++s)
  56. if(*s == '%')
  57. return YES;
  58. return NO;
  59. }
  60. int
  61. hasparen(char *s)
  62. {
  63. for( ; *s ; ++s)
  64. if(*s == '(')
  65. return YES;
  66. return NO;
  67. }
  68. static void
  69. rehash(void)
  70. {
  71. nameblkp *ohash;
  72. nameblkp p, *hp, *endohash;
  73. hp = ohash = hashtab;
  74. endohash = hashtab + hashsize;
  75. newhash(2*hashsize);
  76. while( hp<endohash )
  77. if(p = *hp++)
  78. hashtab[hashloc(p->namep)] = p;
  79. free( (char *) ohash);
  80. }
  81. void
  82. newhash(int newsize)
  83. {
  84. hashsize = newsize;
  85. hashtab = (nameblkp *) ckalloc(hashsize * sizeof(nameblkp));
  86. hashthresh = (2*hashsize)/3;
  87. }
  88. nameblkp chkname(char *s)
  89. {
  90. nameblkp p;
  91. time_t k;
  92. /*TEMP NEW */
  93. if(hasparen(s))
  94. {
  95. k = lookarch(s);
  96. /*TEMP fprintf(stderr, "chkname(%s): look=%d\n", s, k); */
  97. if(k == 0)
  98. return NULL;
  99. }
  100. if(p = srchname(s))
  101. return p;
  102. dirsrch(s);
  103. return srchname(s);
  104. }
  105. char *
  106. copys(char *s)
  107. {
  108. char *t;
  109. if( (t = malloc( strlen(s)+1 ) ) == NULL)
  110. fatal("out of memory");
  111. strcpy(t, s);
  112. return t;
  113. }
  114. char *
  115. concat(char *a, char *b, char *c) /* c = concatenation of a and b */
  116. {
  117. char *t;
  118. t = c;
  119. while(*t = *a++) t++;
  120. while(*t++ = *b++);
  121. return c;
  122. }
  123. int
  124. suffix(char *a, char *b, char *p) /* is b the suffix of a? if so, set p = prefix */
  125. {
  126. char *a0,*b0;
  127. a0 = a;
  128. b0 = b;
  129. while(*a++);
  130. while(*b++);
  131. if( (a-a0) < (b-b0) ) return 0;
  132. while(b>b0)
  133. if(*--a != *--b) return 0;
  134. while(a0<a) *p++ = *a0++;
  135. *p = '\0';
  136. return 1;
  137. }
  138. int *
  139. ckalloc(int n)
  140. {
  141. int *p;
  142. if( p = (int *) calloc(1,n) )
  143. return p;
  144. fatal("out of memory");
  145. /* NOTREACHED */
  146. }
  147. /* copy string a into b, substituting for arguments */
  148. char *
  149. subst(char *a, char *b)
  150. {
  151. static depth = 0;
  152. char *s;
  153. char vname[100];
  154. struct varblock *vbp;
  155. char closer;
  156. if(++depth > 100)
  157. fatal("infinitely recursive macro?");
  158. if(a) while(*a)
  159. {
  160. if(*a!='$' || a[1]=='\0' || *++a=='$')
  161. /* if a non-macro character copy it. if $$ or $\0, copy $ */
  162. *b++ = *a++;
  163. else {
  164. s = vname;
  165. if( *a=='(' || *a=='{' )
  166. {
  167. closer = ( *a=='(' ? ')' : '}');
  168. ++a;
  169. while(*a == ' ') ++a;
  170. while(*a!=' ' && *a!=closer && *a!='\0') *s++ = *a++;
  171. while(*a!=closer && *a!='\0') ++a;
  172. if(*a == closer) ++a;
  173. }
  174. else *s++ = *a++;
  175. *s = '\0';
  176. if( (vbp = varptr(vname)) ->varval != 0)
  177. {
  178. b = subst(vbp->varval, b);
  179. vbp->used = YES;
  180. }
  181. }
  182. }
  183. *b = '\0';
  184. --depth;
  185. return b;
  186. }
  187. void
  188. setvar(char *v, char *s, int dyn)
  189. {
  190. struct varblock *p;
  191. p = varptr(v);
  192. if( ! p->noreset )
  193. {
  194. p->varval = s;
  195. p->noreset = inarglist;
  196. if(p->used && !dyn)
  197. fprintf(stderr, "Warning: %s changed after being used\n",v);
  198. if(p->export)
  199. {
  200. /* change string pointed to by environment to new v=s */
  201. char *t;
  202. int lenv;
  203. lenv = strlen(v);
  204. *(p->export) = t = (char *) ckalloc(lenv + strlen(s) + 2);
  205. strcpy(t,v);
  206. t[lenv] = '=';
  207. strcpy(t+lenv+1, s);
  208. }
  209. else
  210. p->export = envpp;
  211. }
  212. }
  213. /* for setting Bradford's *D and *F family of macros whens setting * etc */
  214. void
  215. set3var(char *macro, char *value)
  216. {
  217. char *s;
  218. char macjunk[8], *lastslash, *dirpart, *filepart;
  219. setvar(macro, value, YES);
  220. if(value == CHNULL)
  221. dirpart = filepart = CHNULL;
  222. else
  223. {
  224. lastslash = CHNULL;
  225. for(s = value; *s; ++s)
  226. if(*s == '/')
  227. lastslash = s;
  228. if(lastslash)
  229. {
  230. dirpart = copys(value);
  231. filepart = dirpart + (lastslash-value);
  232. filepart[-1] = '\0';
  233. }
  234. else
  235. {
  236. dirpart = "";
  237. filepart = value;
  238. }
  239. }
  240. setvar(concat(macro, "D", macjunk), dirpart, YES);
  241. setvar(concat(macro, "F", macjunk), filepart, YES);
  242. }
  243. int
  244. eqsign(char *a) /*look for arguments with equal signs but not colons */
  245. {
  246. char *s, *t;
  247. char c;
  248. while(*a == ' ') ++a;
  249. for(s=a ; *s!='\0' && *s!=':' ; ++s)
  250. if(*s == '=')
  251. {
  252. for(t = a ; *t!='=' && *t!=' ' && *t!='\t' ; ++t );
  253. c = *t;
  254. *t = '\0';
  255. for(++s; *s==' ' || *s=='\t' ; ++s);
  256. setvar(a, copys(s), NO);
  257. *t = c;
  258. return YES;
  259. }
  260. return NO;
  261. }
  262. struct varblock *
  263. varptr(char *v)
  264. {
  265. struct varblock *vp;
  266. /* for compatibility, $(TGS) = $^ */
  267. if(equal(v, "TGS") )
  268. v = "^";
  269. for(vp = firstvar; vp ; vp = vp->nxtvarblock)
  270. if(equal(v , vp->varname))
  271. return vp;
  272. vp = ALLOC(varblock);
  273. vp->nxtvarblock = firstvar;
  274. firstvar = vp;
  275. vp->varname = copys(v);
  276. vp->varval = 0;
  277. return vp;
  278. }
  279. int
  280. dynmacro(char *line)
  281. {
  282. char *s;
  283. char endc, *endp;
  284. if(!isalpha(line[0]))
  285. return NO;
  286. for(s=line+1 ; *s && (isalpha(*s) | isdigit(*s)) ; ++s)
  287. ;
  288. endp = s;
  289. while( isspace(*s) )
  290. ++s;
  291. if(s[0]!=':' || s[1]!='=')
  292. return NO;
  293. endc = *endp;
  294. *endp = '\0';
  295. setvar(line, copys(s+2), YES);
  296. *endp = endc;
  297. return YES;
  298. }
  299. void
  300. fatal1(char *s, char *t)
  301. {
  302. char buf[100];
  303. sprintf(buf, s, t);
  304. fatal(buf);
  305. }
  306. void
  307. fatal(char *s)
  308. {
  309. fflush(stdout);
  310. if(s)
  311. fprintf(stderr, "Make: %s. Stop.\n", s);
  312. else
  313. fprintf(stderr, "\nStop.\n");
  314. waitstack(0);
  315. exit(1);
  316. }
  317. /* appends to the chain for $? and $^ */
  318. chainp
  319. appendq(chainp head, char *tail)
  320. {
  321. chainp p, q;
  322. p = ALLOC(chain);
  323. p->datap = tail;
  324. if(head)
  325. {
  326. for(q = head ; q->nextp ; q = q->nextp)
  327. ;
  328. q->nextp = p;
  329. return head;
  330. }
  331. else
  332. return p;
  333. }
  334. /* builds the value for $? and $^ */
  335. char *
  336. mkqlist(chainp p, char *qbuf)
  337. {
  338. char *qbufp, *s;
  339. if(p == NULL)
  340. return "";
  341. qbufp = qbuf;
  342. for( ; p ; p = p->nextp)
  343. {
  344. s = p->datap;
  345. if(qbufp+strlen(s) > &qbuf[QBUFMAX-3])
  346. {
  347. fprintf(stderr, "$? list too long\n");
  348. break;
  349. }
  350. while (*s)
  351. *qbufp++ = *s++;
  352. *qbufp++ = ' ';
  353. }
  354. *--qbufp = '\0';
  355. return qbuf;
  356. }
  357. wildp
  358. iswild(char *name)
  359. {
  360. char *s;
  361. wildp p;
  362. for(s=name; *s; ++s)
  363. if(*s == '%')
  364. {
  365. p = ALLOC(wild);
  366. *s = '\0';
  367. p->left = copys(name);
  368. *s = '%';
  369. p->right = copys(s+1);
  370. p->llen = strlen(p->left);
  371. p->rlen = strlen(p->right);
  372. p->totlen = p->llen + p->rlen;
  373. return p;
  374. }
  375. return NULL;
  376. }
  377. char *
  378. wildmatch(wildp p, char *name, int len)
  379. {
  380. char *stem;
  381. char *s;
  382. char c;
  383. if(len < p->totlen ||
  384. strncmp(name, p->left, p->llen) ||
  385. strncmp(s = name+len-p->rlen, p->right, p->rlen) )
  386. return CHNULL;
  387. /*TEMP fprintf(stderr, "wildmatch(%s)=%s%%%s)\n", name,p->left,p->right); */
  388. c = *s;
  389. *s = '\0';
  390. stem = copys(name + p->llen);
  391. *s = c;
  392. return stem;
  393. }
  394. /* substitute stem for any % marks */
  395. char *
  396. wildsub(char *pat, char *stem)
  397. {
  398. static char temp[100];
  399. char *s, *t;
  400. s = temp;
  401. for(; *pat; ++pat)
  402. if(*pat == '%')
  403. for(t = stem ; *t; )
  404. *s++ = *t++;
  405. else
  406. *s++ = *pat;
  407. *s = '\0';
  408. return temp;
  409. }