main.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. * Author: Ceriel J.H. Jacobs
  6. */
  7. /* M A I N P R O G R A M */
  8. /* stripped down version from the one in the Modula-2 compiler */
  9. /* $Id$ */
  10. #include <alloc.h>
  11. #include "input.h"
  12. #include "f_info.h"
  13. #include "idf.h"
  14. #include "LLlex.h"
  15. #include "Lpars.h"
  16. #include "tokenname.h"
  17. int state; /* either IMPLEMENTATION or PROGRAM */
  18. char *ProgName;
  19. char **DEFPATH;
  20. int nDEF, mDEF;
  21. struct file_list *CurrentArg;
  22. extern int err_occurred;
  23. extern int Roption;
  24. extern char *strrchr();
  25. extern char *strcpy(), *strcat();
  26. char *
  27. basename(s)
  28. char *s;
  29. {
  30. static char buf[256];
  31. char *p = strrchr(s, '.');
  32. if (p != 0) *p = 0;
  33. strcpy(buf, s);
  34. if (p != 0) *p = '.';
  35. return buf;
  36. }
  37. char *
  38. getwdir(fn)
  39. register char *fn;
  40. {
  41. register char *p;
  42. p = strrchr(fn, '/');
  43. while (p && *(p + 1) == '\0') { /* remove trailing /'s */
  44. *p = '\0';
  45. p = strrchr(fn, '/');
  46. }
  47. if (p) {
  48. register char **d = DEFPATH;
  49. *p = '\0';
  50. while (*d && strcmp(*d, fn) != 0) d++;
  51. if (*d) {
  52. *p = '/';
  53. return *d;
  54. }
  55. fn = Salloc(fn, (unsigned) (p - &fn[0] + 1));
  56. *p = '/';
  57. return fn;
  58. }
  59. return ".";
  60. }
  61. static struct file_list *arglist;
  62. #ifndef M2COMPILER
  63. #define M2COMPILER "m2"
  64. #endif
  65. char *mflags = "";
  66. char *compiler = M2COMPILER;
  67. char *suff = "o";
  68. char *llibs = 0;
  69. main(argc, argv)
  70. register char **argv;
  71. {
  72. extern struct tokenname tkidf[];
  73. extern char *getwdir();
  74. int i;
  75. ProgName = *argv++;
  76. DEFPATH = (char **) Malloc(10 * sizeof(char *));
  77. DEFPATH[1] = 0;
  78. mDEF = 10;
  79. nDEF = 2;
  80. while (--argc > 0) {
  81. if (**argv == '-')
  82. DoOption((*argv++) + 1);
  83. else {
  84. Add(&arglist, *argv, getwdir(*argv), 1);
  85. argv++;
  86. }
  87. }
  88. init_idf();
  89. reserve(tkidf);
  90. print("IFLAGS =");
  91. for (i = 1; i < nDEF; i++) {
  92. if (DEFPATH[i]) print(" -I%s", DEFPATH[i]);
  93. }
  94. print("\nM2FLAGS = %s\nMOD = %s\nSUFFIX = %s\nLIBS = %s\n", mflags, compiler, suff, llibs ? llibs : "");
  95. init_lib();
  96. ProcessArgs();
  97. find_dependencies();
  98. print_dep();
  99. programs();
  100. exit(err_occurred);
  101. }
  102. struct file_list *
  103. new_file_list()
  104. {
  105. static struct file_list *p;
  106. register struct file_list *f;
  107. static int cnt;
  108. if (--cnt < 0) {
  109. p = (struct file_list *)Malloc(50*sizeof(struct file_list));
  110. cnt = 49;
  111. }
  112. f = p++;
  113. f->a_filename = 0;
  114. f->a_dir = 0;
  115. f->a_next = 0;
  116. f->a_idf = 0;
  117. f->a_notfound = 0;
  118. return f;
  119. }
  120. Add(parglist, f, d, copy)
  121. char *f, *d;
  122. struct file_list **parglist;
  123. {
  124. register struct file_list *a, *b = 0;
  125. if (f == 0) return;
  126. f_walk(*parglist, a) {
  127. if (strcmp(f_filename(a), f) == 0) break;
  128. b = a;
  129. }
  130. if (a) return 0;
  131. a = new_file_list();
  132. if (copy) {
  133. a->a_filename = Salloc(f, (unsigned) (strlen(f)+1));
  134. }
  135. else {
  136. a->a_filename = f;
  137. }
  138. a->a_dir = d;
  139. if (! b) *parglist = a;
  140. else b->a_next = a;
  141. return 1;
  142. }
  143. int
  144. openfile(a)
  145. register struct file_list *a;
  146. {
  147. char *fn;
  148. if (!f_notfound(a) && ! InsertFile(f_filename(a), DEFPATH, &fn)) {
  149. a->a_notfound = 1;
  150. Gerror("Could not find %s", f_filename(a));
  151. return 0;
  152. }
  153. FileName = fn;
  154. LineNumber = 1;
  155. a->a_dir = WorkingDir = getwdir(FileName);
  156. return 1;
  157. }
  158. ProcessArgs()
  159. {
  160. register struct file_list *a;
  161. f_walk(arglist, a) {
  162. register char *p = strrchr(f_filename(a), '.');
  163. CurrentArg = a;
  164. DEFPATH[0] = f_dir(a);
  165. if ( p && strcmp(p, ".def") == 0) {
  166. ForeignFlag = 0;
  167. if (! openfile(a)) {
  168. continue;
  169. }
  170. DefModule();
  171. }
  172. else if (p && strcmp(p, ".mod") == 0) {
  173. if (! openfile(a)) {
  174. *p = 0; /* ??? */
  175. continue;
  176. }
  177. CompUnit();
  178. }
  179. else fatal("No Modula-2 file: %s", f_filename(a));
  180. }
  181. }
  182. void
  183. No_Mem()
  184. {
  185. fatal("out of memory");
  186. }
  187. AddToList(name, ext)
  188. char *name, *ext;
  189. {
  190. /* Try to find a file with basename "name" and extension ".def",
  191. in the directories mentioned in "DEFPATH".
  192. */
  193. char buf[15];
  194. char *strncpy();
  195. if (strcmp(name, "SYSTEM") != 0 && ! is_library_dir(WorkingDir)) {
  196. strncpy(buf, name, 10);
  197. buf[10] = '\0'; /* maximum length */
  198. strcat(buf, ext);
  199. Add(&arglist, buf, WorkingDir, 1);
  200. return 1;
  201. }
  202. return 0;
  203. }
  204. find_dependencies()
  205. {
  206. register struct file_list *arg;
  207. print("\nall:\t");
  208. f_walk(arglist, arg) {
  209. char *fn = f_filename(arg);
  210. char *dotspot = strrchr(fn, '.');
  211. if (dotspot && strcmp(dotspot, ".mod") == 0) {
  212. register struct idf *id = f_idf(arg);
  213. if (! f_notfound(arg) && id) {
  214. if (id->id_type == PROGRAM) {
  215. *dotspot = 0;
  216. print("%s ", fn);
  217. *dotspot = '.';
  218. }
  219. file_dep(id);
  220. }
  221. }
  222. }
  223. print("\n\n");
  224. print("objects:\t");
  225. f_walk(arglist, arg) {
  226. char *fn = f_filename(arg);
  227. char *dotspot = strrchr(fn, '.');
  228. if (dotspot && strcmp(dotspot, ".mod") == 0) {
  229. register struct idf *id = f_idf(arg);
  230. if (! f_notfound(arg) && id) {
  231. if (id->id_type == PROGRAM) {
  232. *dotspot = 0;
  233. print("%s_o_files ", fn);
  234. *dotspot = '.';
  235. }
  236. }
  237. }
  238. }
  239. print("\n\n\n");
  240. }
  241. file_dep(id)
  242. register struct idf *id;
  243. {
  244. register struct lnk *m;
  245. if (id->id_ddependson || id->id_mdependson) return;
  246. if (id->id_def) Add(&(id->id_mdependson), id->id_def, id->id_dir, 0);
  247. for (m = id->id_defimports; m; m = m->lnk_next) {
  248. register struct idf *iid = m->lnk_imp;
  249. Add(&(id->id_mdependson), iid->id_def, iid->id_dir, 0);
  250. if (Add(&(id->id_ddependson), iid->id_def, iid->id_dir, 0)) {
  251. register struct file_list *p;
  252. file_dep(iid);
  253. f_walk(iid->id_ddependson, p) {
  254. Add(&(id->id_ddependson), f_filename(p),
  255. f_dir(p), 0);
  256. Add(&(id->id_mdependson), f_filename(p),
  257. f_dir(p), 0);
  258. }
  259. }
  260. }
  261. for (m = id->id_modimports; m; m = m->lnk_next) {
  262. register struct idf *iid = m->lnk_imp;
  263. if (Add(&(id->id_mdependson), iid->id_def, iid->id_dir, 0)) {
  264. register struct file_list *p;
  265. file_dep(iid);
  266. f_walk(iid->id_ddependson, p) {
  267. Add(&(id->id_mdependson), f_filename(p),
  268. f_dir(p), 0);
  269. }
  270. }
  271. }
  272. }
  273. char *
  274. object(arg)
  275. register struct file_list *arg;
  276. {
  277. static char buf[512];
  278. char *dotp = strrchr(f_filename(arg), '.');
  279. buf[0] = 0;
  280. /*
  281. if (strcmp(f_dir(arg), ".") != 0) {
  282. strcpy(buf, f_dir(arg));
  283. strcat(buf, "/");
  284. }
  285. */
  286. if (dotp) *dotp = 0;
  287. strcat(buf, f_filename(arg));
  288. if (dotp) *dotp = '.';
  289. strcat(buf, ".$(SUFFIX)");
  290. return buf;
  291. }
  292. pr_arg(a)
  293. register struct file_list *a;
  294. {
  295. char *f = f_filename(a);
  296. char *d = f_dir(a);
  297. if (strcmp(d, ".") == 0 || *f == '/' || *f == '.') {
  298. print(f);
  299. }
  300. else print("%s/%s", d, f);
  301. }
  302. print_dep()
  303. {
  304. register struct file_list *arg;
  305. f_walk(arglist, arg) {
  306. char *dotspot = strrchr(f_filename(arg), '.');
  307. if (dotspot && strcmp(dotspot, ".mod") == 0) {
  308. register struct idf *id = f_idf(arg);
  309. if (! f_notfound(arg) && id) {
  310. char *obj = object(arg);
  311. register struct file_list *a;
  312. print("%s: \\\n\t", obj);
  313. pr_arg(arg);
  314. f_walk(id->id_mdependson, a) {
  315. if (*(f_filename(a))) /* ??? */ {
  316. print(" \\\n\t");
  317. pr_arg(a);
  318. }
  319. }
  320. print("\n\t$(MOD) -c $(M2FLAGS) $(IFLAGS) ");
  321. pr_arg(arg);
  322. print("\n");
  323. }
  324. }
  325. }
  326. }
  327. prog_dep(id, a)
  328. register struct idf *id;
  329. struct file_list *a;
  330. {
  331. register struct lnk *m;
  332. register struct file_list *p;
  333. id->id_mdependson = 0;
  334. id->id_def = 0;
  335. if (id->id_type == PROGRAM) {
  336. Add(&(id->id_mdependson), f_filename(a), f_dir(a), 0);
  337. }
  338. else {
  339. if (strlen(id->id_text) >= 10) id->id_text[10] = 0;
  340. Add(&(id->id_mdependson), id->id_text, id->id_dir, 0);
  341. }
  342. for (m = id->id_modimports; m; m = m->lnk_next) {
  343. register struct idf *iid = m->lnk_imp;
  344. if (Add(&(id->id_mdependson), iid->id_text, iid->id_dir, 0)) {
  345. if (iid->id_def) prog_dep(iid);
  346. f_walk(iid->id_mdependson, p) {
  347. Add(&(id->id_mdependson), f_filename(p),
  348. f_dir(p), 0);
  349. }
  350. }
  351. }
  352. }
  353. module_in_arglist(n)
  354. char *n;
  355. {
  356. register struct file_list *a;
  357. f_walk(arglist, a) {
  358. char *dotp = strrchr(f_filename(a), '.');
  359. if (dotp && strcmp(dotp, ".mod") == 0 && ! f_notfound(a)) {
  360. *dotp = 0;
  361. if (strcmp(f_filename(a), n) == 0) {
  362. *dotp = '.';
  363. return 1;
  364. }
  365. *dotp = '.';
  366. }
  367. }
  368. return 0;
  369. }
  370. pr_prog_dep(id, a)
  371. register struct idf *id;
  372. struct file_list *a;
  373. {
  374. register struct file_list *p;
  375. print("\nOBS_%s =", id->id_text);
  376. f_walk(id->id_mdependson, p) {
  377. if (module_in_arglist(f_filename(p)) || ! f_dir(p)) {
  378. print(" \\\n\t%s", object(p));
  379. }
  380. }
  381. print("\n\nOBS2_%s =", id->id_text);
  382. f_walk(id->id_mdependson, p) {
  383. if (module_in_arglist(f_filename(p)) || ! f_dir(p)) {
  384. /* nothing */
  385. }
  386. else if (! is_library_dir(f_dir(p))) {
  387. print(" \\\n\t%s/%s", f_dir(p), object(p));
  388. }
  389. }
  390. print("\n\n");
  391. print("%s_o_files:\t$(OBS_%s)\n\n", basename(f_filename(a)), id->id_text);
  392. print("%s:\t$(OBS_%s) $(OBS2_%s)\n", basename(f_filename(a)), id->id_text, id->id_text);
  393. print("\t$(MOD) -o %s $(M2FLAGS) $(OBS_%s) $(OBS2_%s) $(LIBS)\n", basename(f_filename(a)), id->id_text, id->id_text);
  394. }
  395. programs()
  396. {
  397. register struct file_list *a;
  398. f_walk(arglist, a) {
  399. char *dotspot = strrchr(f_filename(a), '.');
  400. if (dotspot && strcmp(dotspot, ".mod") == 0) {
  401. register struct idf *id = f_idf(a);
  402. if (! f_notfound(a) && id && id->id_type == PROGRAM) {
  403. prog_dep(id, a);
  404. /* *dotspot = 0; */
  405. pr_prog_dep(id, a);
  406. /* *dotspot = '.'; */
  407. }
  408. }
  409. }
  410. }