misc.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  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. return 0;
  147. }
  148. /* copy string a into b, substituting for arguments */
  149. char *
  150. subst(char *a, char *b, char *e)
  151. {
  152. static depth = 0;
  153. char *s;
  154. char vname[100];
  155. struct varblock *vbp;
  156. char closer;
  157. if(++depth > 100)
  158. fatal("infinitely recursive macro?");
  159. if(a) while(*a)
  160. {
  161. if(*a!='$' || a[1]=='\0' || *++a=='$')
  162. /* if a non-macro character copy it. if $$ or $\0, copy $ */
  163. *b++ = *a++;
  164. else {
  165. s = vname;
  166. if( *a=='(' || *a=='{' )
  167. {
  168. closer = ( *a=='(' ? ')' : '}');
  169. ++a;
  170. while(*a == ' ') ++a;
  171. while(*a!=' ' && *a!=closer && *a!='\0') *s++ = *a++;
  172. while(*a!=closer && *a!='\0') ++a;
  173. if(*a == closer) ++a;
  174. }
  175. else *s++ = *a++;
  176. *s = '\0';
  177. if( (vbp = varptr(vname)) ->varval != 0)
  178. {
  179. b = subst(vbp->varval, b, e);
  180. vbp->used = YES;
  181. }
  182. }
  183. if(b >= e)
  184. fatal("macro expanded too far");
  185. }
  186. *b = '\0';
  187. --depth;
  188. return b;
  189. }
  190. void
  191. setvar(char *v, char *s, int dyn)
  192. {
  193. struct varblock *p;
  194. p = varptr(v);
  195. if( ! p->noreset )
  196. {
  197. p->varval = s;
  198. p->noreset = inarglist;
  199. if(p->used && !dyn)
  200. fprintf(stderr, "Warning: %s changed after being used\n",v);
  201. if(p->export)
  202. {
  203. /* change string pointed to by environment to new v=s */
  204. char *t;
  205. int lenv;
  206. lenv = strlen(v);
  207. *(p->export) = t = (char *) ckalloc(lenv + strlen(s) + 2);
  208. strcpy(t,v);
  209. t[lenv] = '=';
  210. strcpy(t+lenv+1, s);
  211. }
  212. else
  213. p->export = envpp;
  214. }
  215. }
  216. /* for setting Bradford's *D and *F family of macros whens setting * etc */
  217. void
  218. set3var(char *macro, char *value)
  219. {
  220. char *s;
  221. char macjunk[8], *lastslash, *dirpart, *filepart;
  222. setvar(macro, value, YES);
  223. if(value == CHNULL)
  224. dirpart = filepart = CHNULL;
  225. else
  226. {
  227. lastslash = CHNULL;
  228. for(s = value; *s; ++s)
  229. if(*s == '/')
  230. lastslash = s;
  231. if(lastslash)
  232. {
  233. dirpart = copys(value);
  234. filepart = dirpart + (lastslash-value);
  235. filepart[-1] = '\0';
  236. }
  237. else
  238. {
  239. dirpart = "";
  240. filepart = value;
  241. }
  242. }
  243. setvar(concat(macro, "D", macjunk), dirpart, YES);
  244. setvar(concat(macro, "F", macjunk), filepart, YES);
  245. }
  246. int
  247. eqsign(char *a) /*look for arguments with equal signs but not colons */
  248. {
  249. char *s, *t;
  250. char c;
  251. while(*a == ' ') ++a;
  252. for(s=a ; *s!='\0' && *s!=':' ; ++s)
  253. if(*s == '=')
  254. {
  255. for(t = a ; *t!='=' && *t!=' ' && *t!='\t' ; ++t );
  256. c = *t;
  257. *t = '\0';
  258. for(++s; *s==' ' || *s=='\t' ; ++s);
  259. setvar(a, copys(s), NO);
  260. *t = c;
  261. return YES;
  262. }
  263. return NO;
  264. }
  265. struct varblock *
  266. varptr(char *v)
  267. {
  268. struct varblock *vp;
  269. /* for compatibility, $(TGS) = $^ */
  270. if(equal(v, "TGS") )
  271. v = "^";
  272. for(vp = firstvar; vp ; vp = vp->nxtvarblock)
  273. if(equal(v , vp->varname))
  274. return vp;
  275. vp = ALLOC(varblock);
  276. vp->nxtvarblock = firstvar;
  277. firstvar = vp;
  278. vp->varname = copys(v);
  279. vp->varval = 0;
  280. return vp;
  281. }
  282. int
  283. dynmacro(char *line)
  284. {
  285. char *s;
  286. char endc, *endp;
  287. if(!isalpha(line[0]))
  288. return NO;
  289. for(s=line+1 ; *s && (isalpha(*s) | isdigit(*s)) ; ++s)
  290. ;
  291. endp = s;
  292. while( isspace(*s) )
  293. ++s;
  294. if(s[0]!=':' || s[1]!='=')
  295. return NO;
  296. endc = *endp;
  297. *endp = '\0';
  298. setvar(line, copys(s+2), YES);
  299. *endp = endc;
  300. return YES;
  301. }
  302. void
  303. fatal1(char *s, char *t)
  304. {
  305. char buf[100];
  306. sprintf(buf, s, t);
  307. fatal(buf);
  308. }
  309. void
  310. fatal(char *s)
  311. {
  312. fflush(stdout);
  313. if(s)
  314. fprintf(stderr, "Make: %s. Stop.\n", s);
  315. else
  316. fprintf(stderr, "\nStop.\n");
  317. waitstack(0);
  318. exit(1);
  319. }
  320. /* appends to the chain for $? and $^ */
  321. chainp
  322. appendq(chainp head, char *tail)
  323. {
  324. chainp p, q;
  325. p = ALLOC(chain);
  326. p->datap = tail;
  327. if(head)
  328. {
  329. for(q = head ; q->nextp ; q = q->nextp)
  330. ;
  331. q->nextp = p;
  332. return head;
  333. }
  334. else
  335. return p;
  336. }
  337. /* builds the value for $? and $^ */
  338. char *
  339. mkqlist(chainp p, char *qbuf)
  340. {
  341. char *qbufp, *s;
  342. if(p == NULL)
  343. return "";
  344. qbufp = qbuf;
  345. for( ; p ; p = p->nextp)
  346. {
  347. s = p->datap;
  348. if(qbufp+strlen(s) > &qbuf[QBUFMAX-3])
  349. {
  350. fprintf(stderr, "$? list too long\n");
  351. break;
  352. }
  353. while (*s)
  354. *qbufp++ = *s++;
  355. *qbufp++ = ' ';
  356. }
  357. *--qbufp = '\0';
  358. return qbuf;
  359. }
  360. wildp
  361. iswild(char *name)
  362. {
  363. char *s;
  364. wildp p;
  365. for(s=name; *s; ++s)
  366. if(*s == '%')
  367. {
  368. p = ALLOC(wild);
  369. *s = '\0';
  370. p->left = copys(name);
  371. *s = '%';
  372. p->right = copys(s+1);
  373. p->llen = strlen(p->left);
  374. p->rlen = strlen(p->right);
  375. p->totlen = p->llen + p->rlen;
  376. return p;
  377. }
  378. return NULL;
  379. }
  380. char *
  381. wildmatch(wildp p, char *name, int len)
  382. {
  383. char *stem;
  384. char *s;
  385. char c;
  386. if(len < p->totlen ||
  387. strncmp(name, p->left, p->llen) ||
  388. strncmp(s = name+len-p->rlen, p->right, p->rlen) )
  389. return CHNULL;
  390. /*TEMP fprintf(stderr, "wildmatch(%s)=%s%%%s)\n", name,p->left,p->right); */
  391. c = *s;
  392. *s = '\0';
  393. stem = copys(name + p->llen);
  394. *s = c;
  395. return stem;
  396. }
  397. /* substitute stem for any % marks */
  398. char *
  399. wildsub(char *pat, char *stem)
  400. {
  401. static char temp[100];
  402. char *s, *t;
  403. s = temp;
  404. for(; *pat; ++pat)
  405. if(*pat == '%')
  406. for(t = stem ; *t; )
  407. *s++ = *t++;
  408. else
  409. *s++ = *pat;
  410. *s = '\0';
  411. return temp;
  412. }