PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/utils/mk/mk.c

https://bitbucket.org/floren/inferno/
C | 226 lines | 194 code | 15 blank | 17 comment | 86 complexity | 64eba3811266e3ffc0dc2e331e6dcc73 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. #include "mk.h"
  2. int runerrs;
  3. void
  4. mk(char *target)
  5. {
  6. Node *node;
  7. int did = 0;
  8. nproc(); /* it can be updated dynamically */
  9. nrep(); /* it can be updated dynamically */
  10. runerrs = 0;
  11. node = graph(target);
  12. if(DEBUG(D_GRAPH)){
  13. dumpn("new target\n", node);
  14. Bflush(&bout);
  15. }
  16. clrmade(node);
  17. while(node->flags&NOTMADE){
  18. if(work(node, (Node *)0, (Arc *)0))
  19. did = 1; /* found something to do */
  20. else {
  21. if(waitup(1, (int *)0) > 0){
  22. if(node->flags&(NOTMADE|BEINGMADE)){
  23. assert("must be run errors", runerrs);
  24. break; /* nothing more waiting */
  25. }
  26. }
  27. }
  28. }
  29. if(node->flags&BEINGMADE)
  30. waitup(-1, (int *)0);
  31. while(jobs)
  32. waitup(-2, (int *)0);
  33. assert("target didn't get done", runerrs || (node->flags&MADE));
  34. if(did == 0)
  35. Bprint(&bout, "mk: '%s' is up to date\n", node->name);
  36. }
  37. void
  38. clrmade(Node *n)
  39. {
  40. Arc *a;
  41. n->flags &= ~(CANPRETEND|PRETENDING);
  42. if(strchr(n->name, '(') ==0 || n->time)
  43. n->flags |= CANPRETEND;
  44. MADESET(n, NOTMADE);
  45. for(a = n->prereqs; a; a = a->next)
  46. if(a->n)
  47. clrmade(a->n);
  48. }
  49. static void
  50. unpretend(Node *n)
  51. {
  52. MADESET(n, NOTMADE);
  53. n->flags &= ~(CANPRETEND|PRETENDING);
  54. n->time = 0;
  55. }
  56. int
  57. work(Node *node, Node *p, Arc *parc)
  58. {
  59. Arc *a, *ra;
  60. int weoutofdate;
  61. int ready;
  62. int did = 0;
  63. /*print("work(%s) flags=0x%x time=%ld\n", node->name, node->flags, node->time);/**/
  64. if(node->flags&BEINGMADE)
  65. return(did);
  66. if((node->flags&MADE) && (node->flags&PRETENDING) && p && outofdate(p, parc, 0)){
  67. if(explain)
  68. fprint(1, "unpretending %s(%ld) because %s is out of date(%ld)\n",
  69. node->name, node->time, p->name, p->time);
  70. unpretend(node);
  71. }
  72. /*
  73. have a look if we are pretending in case
  74. someone has been unpretended out from underneath us
  75. */
  76. if(node->flags&MADE){
  77. if(node->flags&PRETENDING){
  78. node->time = 0;
  79. }else
  80. return(did);
  81. }
  82. /* consider no prerequsite case */
  83. if(node->prereqs == 0){
  84. if(node->time == 0){
  85. fprint(2, "mk: don't know how to make '%s'\n", node->name);
  86. if(kflag){
  87. node->flags |= BEINGMADE;
  88. runerrs++;
  89. } else
  90. Exit();
  91. } else
  92. MADESET(node, MADE);
  93. return(did);
  94. }
  95. /*
  96. now see if we are out of date or what
  97. */
  98. ready = 1;
  99. weoutofdate = aflag;
  100. ra = 0;
  101. for(a = node->prereqs; a; a = a->next)
  102. if(a->n){
  103. did = work(a->n, node, a) || did;
  104. if(a->n->flags&(NOTMADE|BEINGMADE))
  105. ready = 0;
  106. if(outofdate(node, a, 0)){
  107. weoutofdate = 1;
  108. if((ra == 0) || (ra->n == 0)
  109. || (ra->n->time < a->n->time))
  110. ra = a;
  111. }
  112. } else {
  113. if(node->time == 0){
  114. if(ra == 0)
  115. ra = a;
  116. weoutofdate = 1;
  117. }
  118. }
  119. if(ready == 0) /* can't do anything now */
  120. return(did);
  121. if(weoutofdate == 0){
  122. MADESET(node, MADE);
  123. return(did);
  124. }
  125. /*
  126. can we pretend to be made?
  127. */
  128. if((iflag == 0) && (node->time == 0) && (node->flags&(PRETENDING|CANPRETEND))
  129. && p && ra->n && !outofdate(p, ra, 0)){
  130. node->flags &= ~CANPRETEND;
  131. MADESET(node, MADE);
  132. if(explain && ((node->flags&PRETENDING) == 0))
  133. fprint(1, "pretending %s has time %ld\n", node->name, node->time);
  134. node->flags |= PRETENDING;
  135. return(did);
  136. }
  137. /*
  138. node is out of date and we REALLY do have to do something.
  139. quickly rescan for pretenders
  140. */
  141. for(a = node->prereqs; a; a = a->next)
  142. if(a->n && (a->n->flags&PRETENDING)){
  143. if(explain)
  144. Bprint(&bout, "unpretending %s because of %s because of %s\n",
  145. a->n->name, node->name, ra->n? ra->n->name : "rule with no prerequisites");
  146. unpretend(a->n);
  147. did = work(a->n, node, a) || did;
  148. ready = 0;
  149. }
  150. if(ready == 0) /* try later unless nothing has happened for -k's sake */
  151. return(did || work(node, p, parc));
  152. did = dorecipe(node) || did;
  153. return(did);
  154. }
  155. void
  156. update(int fake, Node *node)
  157. {
  158. Arc *a;
  159. MADESET(node, fake? BEINGMADE : MADE);
  160. if(((node->flags&VIRTUAL) == 0) && (access(node->name, 0) == 0)){
  161. node->time = timeof(node->name, 1);
  162. node->flags &= ~(CANPRETEND|PRETENDING);
  163. for(a = node->prereqs; a; a = a->next)
  164. if(a->prog)
  165. outofdate(node, a, 1);
  166. } else {
  167. node->time = 1;
  168. for(a = node->prereqs; a; a = a->next)
  169. if(a->n && outofdate(node, a, 1))
  170. node->time = a->n->time;
  171. }
  172. /* print("----node %s time=%ld flags=0x%x\n", node->name, node->time, node->flags);/**/
  173. }
  174. static int
  175. pcmp(char *prog, char *p, char *q)
  176. {
  177. char buf[3*NAMEBLOCK];
  178. int pid;
  179. Bflush(&bout);
  180. sprint(buf, "%s '%s' '%s'\n", prog, p, q);
  181. pid = pipecmd(buf, 0, 0);
  182. while(waitup(-3, &pid) >= 0)
  183. ;
  184. return(pid? 2:1);
  185. }
  186. int
  187. outofdate(Node *node, Arc *arc, int eval)
  188. {
  189. char buf[3*NAMEBLOCK], *str;
  190. Symtab *sym;
  191. int ret;
  192. str = 0;
  193. if(arc->prog){
  194. sprint(buf, "%s%c%s", node->name, 0377, arc->n->name);
  195. sym = symlook(buf, S_OUTOFDATE, 0);
  196. if(sym == 0 || eval){
  197. if(sym == 0)
  198. str = strdup(buf);
  199. ret = pcmp(arc->prog, node->name, arc->n->name);
  200. if(sym)
  201. sym->value = (void *)ret;
  202. else
  203. symlook(str, S_OUTOFDATE, (void *)ret);
  204. } else
  205. ret = (int)sym->value;
  206. return(ret-1);
  207. } else if(strchr(arc->n->name, '(') && arc->n->time == 0) /* missing archive member */
  208. return 1;
  209. else
  210. return node->time <= arc->n->time;
  211. }