main.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /*
  2. * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. *
  4. * This product is part of the Amsterdam Compiler Kit.
  5. *
  6. * Permission to use, sell, duplicate or disclose this software must be
  7. * obtained in writing. Requests for such permissions may be sent to
  8. *
  9. * Dr. Andrew S. Tanenbaum
  10. * Wiskundig Seminarium
  11. * Vrije Universiteit
  12. * Postbox 7161
  13. * 1007 MC Amsterdam
  14. * The Netherlands
  15. *
  16. */
  17. #include "ack.h"
  18. #include "list.h"
  19. #include "trans.h"
  20. #include "../../h/em_path.h"
  21. #include "../../h/local.h"
  22. #include "data.h"
  23. #include <signal.h>
  24. #ifndef NORCSID
  25. static char rcs_id[] = "$Header$" ;
  26. static char rcs_ack[] = RCS_ACK ;
  27. #endif
  28. static int sigs[] = { SIGINT, SIGHUP, SIGTERM, 0 } ;
  29. extern char *getenv();
  30. main(argc,argv) char **argv ; {
  31. register list_elem *elem ;
  32. register char *frontend ;
  33. register int *n_sig ;
  34. register trf *phase ;
  35. progname=argv[0];
  36. varinit();
  37. vieuwargs(argc,argv);
  38. if ( (frontend=getenv("ACKFE")) ) {
  39. setlist(frontend) ;
  40. } else {
  41. setlist(FRONTENDS);
  42. }
  43. if ( callname ) {
  44. if ( machine ) {
  45. fuerror("can not produce code for both %s and %s",
  46. callname,machine) ;
  47. }
  48. machine= callname ;
  49. }
  50. if ( !machine && ! (machine=getenv("ACKM")) ) {
  51. #ifdef ACKM
  52. machine= ACKM; /* The default machine */
  53. #else
  54. fuerror("No machine specified") ;
  55. #endif
  56. }
  57. setlist(machine);
  58. /* Find the linker, needed for argument building */
  59. scanlist(l_first(tr_list),elem) {
  60. if ( t_cont(*elem)->t_linker ) {
  61. linker= t_cont(*elem) ;
  62. }
  63. }
  64. transini();
  65. scanneeds();
  66. sprintf(template,TMPNAME,getpid()) ;
  67. if ( n_error && !k_flag ) return n_error ;
  68. for ( n_sig=sigs ; *n_sig ; n_sig++ ) {
  69. if ( signal(*n_sig,noodstop)==SIG_IGN ) {
  70. signal(*n_sig,SIG_IGN) ;
  71. }
  72. }
  73. scanlist ( l_first(arguments), elem ) {
  74. if ( !process(l_content(*elem)) && !k_flag ) return 1 ;
  75. }
  76. orig.p_path= (char *)0 ;
  77. if ( !rts ) rts="" ;
  78. setsvar(keeps(RTS),rts) ;
  79. if ( linker ) getmapflags(linker) ;
  80. scanlist(l_first(tr_list),elem) {
  81. phase=t_cont(*elem) ;
  82. if ( phase->t_combine && phase->t_do ) {
  83. if ( phase->t_blocked ) {
  84. #ifdef DEBUG
  85. if ( debug ) {
  86. vprint("phase %s is blocked\n",
  87. phase->t_name) ;
  88. }
  89. #endif
  90. disc_inputs(phase) ;
  91. continue ;
  92. }
  93. orig.p_keep=YES ;
  94. orig.p_keeps=NO ;
  95. orig.p_path=phase->t_origname ;
  96. if ( p_basename ) throws(p_basename) ;
  97. if ( orig.p_path ) {
  98. p_basename= keeps(basename(orig.p_path)) ;
  99. } else {
  100. p_basename=0 ;
  101. }
  102. if ( !startrf(phase) && !k_flag ) return 1 ;
  103. }
  104. }
  105. if ( n_error ) return n_error ;
  106. if ( g_flag ) {
  107. return do_run();
  108. }
  109. return 0 ;
  110. }
  111. char *srcvar() {
  112. return orig.p_path ;
  113. }
  114. varinit() {
  115. /* initialize the string variables */
  116. register char *envstr ;
  117. if ( envstr=getenv("EM_DIR") ) {
  118. setsvar(keeps(HOME),keeps(envstr)) ;
  119. } else {
  120. setsvar(keeps(HOME),keeps(EM_DIR)) ;
  121. }
  122. setpvar(keeps(SRC),srcvar) ;
  123. }
  124. /************************* flag processing ***********************/
  125. vieuwargs(argc,argv) char **argv ; {
  126. register char *argp;
  127. register int nextarg ;
  128. register int eaten ;
  129. int hide ;
  130. firstarg(argv[0]) ;
  131. nextarg= 1 ;
  132. while ( nextarg<argc ) {
  133. argp= argv[nextarg] ;
  134. nextarg++ ;
  135. if ( argp[0]!='-' || argp[1]=='l' ) {
  136. /* Not a flag, or a library */
  137. l_add(&arguments,argp) ;
  138. continue ;
  139. }
  140. /* Flags */
  141. hide=NO ; /* Do not hide this flags to the phases */
  142. eaten=0 ; /* Did not 'eat' tail of flag yet */
  143. switch ( argp[1] ) {
  144. case 'm': if ( machine ) fuerror("Two machines?") ;
  145. machine= &argp[2];
  146. eaten=1 ;
  147. break ;
  148. case 'o': if ( nextarg>=argc ) {
  149. fuerror("-o can't be the last flag") ;
  150. }
  151. if ( outfile ) fuerror("Two results?") ;
  152. outfile= argv[nextarg++] ;
  153. hide=YES ;
  154. break ;
  155. case 'O': Optflag++ ;
  156. break ;
  157. case 'v': if ( argp[2] ) {
  158. v_flag += atoi(&argp[2]) ;
  159. eaten=1 ;
  160. } else {
  161. v_flag++ ;
  162. }
  163. #ifdef DEBUG
  164. if ( v_flag>=3 ) debug=v_flag-2 ;
  165. #endif
  166. break ;
  167. case 'g': g_flag++ ;
  168. break ;
  169. case 'c': if ( stopsuffix ) fuerror("Two -c flags") ;
  170. stopsuffix= &argp[2]; eaten=1;
  171. if ( *stopsuffix && *stopsuffix!=SUFCHAR ) {
  172. fuerror("-c flag has invalid tail") ;
  173. }
  174. break ;
  175. case 'k': k_flag++ ;
  176. break ;
  177. case 't': t_flag++ ;
  178. break ;
  179. case 'R': eaten=1;
  180. break ;
  181. case 'r': if ( argp[2]!=SUFCHAR ) {
  182. error("-r must be followed by %c",SUFCHAR) ;
  183. }
  184. keeptail(&argp[2]); eaten=1 ;
  185. break ;
  186. case '.': if ( rts ) {
  187. if ( strcmp(rts,&argp[1])!=0 )
  188. fuerror("Two run-time systems?") ;
  189. } else {
  190. rts= &argp[1] ;
  191. keephead(rts) ; keeptail(rts) ;
  192. }
  193. eaten=1 ;
  194. break ;
  195. case 0 : nill_flag++ ; eaten++ ;
  196. hide=YES ;
  197. break;
  198. case 'w': w_flag++;
  199. break ;
  200. default: /* The flag is not recognized,
  201. put it on the list for the sub-processes
  202. */
  203. #ifdef DEBUG
  204. if ( debug ) {
  205. vprint("Flag %s: phase dependent\n",argp) ;
  206. }
  207. #endif
  208. l_add(&flags,keeps(argp)) ;
  209. eaten=1 ;
  210. hide=YES ;
  211. }
  212. if ( !hide ) {
  213. register char *tokeep ;
  214. tokeep=keeps(argp) ;
  215. if ( argp[1]=='R' ) {
  216. do_Rflag(tokeep);
  217. } else {
  218. *tokeep |= NO_SCAN ;
  219. }
  220. l_add(&flags,tokeep) ;
  221. }
  222. if ( argp[2] && !eaten ) {
  223. werror("Unexpected characters at end of %s",argp) ;
  224. }
  225. }
  226. return ;
  227. }
  228. firstarg(argp) register char *argp ; {
  229. register char *name ;
  230. name=rindex(argp,'/') ;
  231. if ( name && *(name+1) ) {
  232. name++ ;
  233. } else {
  234. name= argp ;
  235. }
  236. callname= name;
  237. }
  238. /************************* argument processing ***********************/
  239. process(arg) char *arg ; {
  240. /* Process files & library arguments */
  241. trf *phase ;
  242. register trf *tmp ;
  243. #ifdef DEBUG
  244. if ( debug ) vprint("Processing %s\n",arg) ;
  245. #endif
  246. p_suffix= rindex(arg,SUFCHAR) ;
  247. orig.p_keep= YES ; /* Don't throw away the original ! */
  248. orig.p_keeps= NO;
  249. orig.p_path= arg ;
  250. if ( arg[0]=='-' || !p_suffix ) {
  251. if ( linker ) add_input(&orig,linker) ;
  252. return 1 ;
  253. }
  254. if ( p_basename ) throws(p_basename) ;
  255. p_basename= keeps(basename(arg)) ;
  256. /* Try to find a path through the transformations */
  257. switch( getpath(&phase) ) {
  258. case F_NOPATH :
  259. error("Cannot produce the desired file from %s",arg) ;
  260. if ( linker ) add_input(&orig,linker) ;
  261. return 1 ;
  262. case F_NOMATCH :
  263. if ( stopsuffix ) werror("Unknown suffix in %s",arg) ;
  264. if ( linker ) add_input(&orig,linker) ;
  265. return 1 ;
  266. case F_OK :
  267. break ;
  268. }
  269. if ( !phase ) return 1 ;
  270. for ( tmp=phase ; tmp ; tmp=tmp->t_next )
  271. if ( !tmp->t_visited ) {
  272. /* The flags are set up once.
  273. At the first time each phase is in a list.
  274. The program name and flags may already be touched
  275. by vieuwargs.
  276. */
  277. tmp->t_visited=YES ;
  278. if ( tmp->t_priority<0 )
  279. werror("Using phase %s (negative priority)",
  280. tmp->t_name) ;
  281. if ( !rts && tmp->t_rts ) rts= tmp->t_rts ;
  282. if ( tmp->t_needed ) {
  283. add_head(tmp->t_needed) ;
  284. add_tail(tmp->t_needed) ;
  285. }
  286. }
  287. if ( phase->t_combine ) {
  288. add_input(&orig,phase) ;
  289. return 1 ;
  290. }
  291. in= orig ;
  292. if ( !nill_flag ) {
  293. printf("%s\n",arg) ;
  294. }
  295. return startrf(phase) ;
  296. }
  297. int startrf(first) trf *first ; {
  298. /* Start the transformations at the indicated phase */
  299. register trf *phase ;
  300. phase=first ;
  301. for(;;) {
  302. switch ( phase->t_prep ) {
  303. /* BEWARE, sign extension */
  304. default : if ( !mayprep() ) break ;
  305. case YES: if ( !transform(cpp_trafo) ) {
  306. n_error++ ;
  307. #ifdef DEBUG
  308. vprint("Pre-processor failed\n") ;
  309. #endif
  310. return 0 ;
  311. }
  312. case NO :
  313. break ;
  314. }
  315. if ( cpp_trafo && stopsuffix &&
  316. strcmp(cpp_trafo->t_out,stopsuffix)==0 ) {
  317. break ;
  318. }
  319. if ( !transform(phase) ) {
  320. n_error++ ;
  321. block(phase->t_next) ;
  322. #ifdef DEBUG
  323. if ( debug ) {
  324. if ( !orig.p_path ) {
  325. vprint("phase %s failed\n",
  326. phase->t_name ) ;
  327. } else {
  328. vprint("phase %s for %s failed\n",
  329. phase->t_name,orig.p_path) ;
  330. }
  331. }
  332. #endif
  333. return 0 ;
  334. }
  335. first=NO ;
  336. phase=phase->t_next ;
  337. if ( !phase ) {
  338. #ifdef DEBUG
  339. if ( debug ) vprint("Transformation sequence complete for %s\n",
  340. orig.p_path) ;
  341. #endif
  342. /* No more work on this file */
  343. if ( !in.p_keep ) {
  344. fatal("attempt to discard the result file") ;
  345. }
  346. if ( in.p_keeps ) throws(in.p_path) ;
  347. in.p_keep=NO ; in.p_keeps=NO ; in.p_path= (char *) 0 ;
  348. return 1 ;
  349. }
  350. if ( phase->t_combine ) {
  351. add_input(&in,phase) ;
  352. break ;
  353. }
  354. }
  355. return 1 ;
  356. }
  357. block(first) trf *first ; {
  358. /* One of the input files of this phase could not be produced,
  359. block all combiners taking their input from this one.
  360. */
  361. register trf *phase ;
  362. for ( phase=first ; phase ; phase=phase->t_next ) {
  363. if ( phase->t_combine ) phase->t_blocked=YES ;
  364. }
  365. }
  366. mayprep() {
  367. int file ;
  368. char fc ;
  369. file=open(in.p_path,0);
  370. if ( file<0 ) return 0 ;
  371. if ( read(file,&fc,1)!=1 ) fc=0 ;
  372. close(file) ;
  373. return fc=='#' ;
  374. }
  375. keephead(suffix) char *suffix ; {
  376. l_add(&head_list, suffix) ;
  377. }
  378. keeptail(suffix) char *suffix ; {
  379. l_add(&tail_list, suffix) ;
  380. }
  381. scanneeds() {
  382. register list_elem *elem ;
  383. scanlist(l_first(head_list), elem) { setneeds(l_content(*elem),0) ; }
  384. l_clear(&head_list) ;
  385. scanlist(l_first(tail_list), elem) { setneeds(l_content(*elem),1) ; }
  386. l_clear(&tail_list) ;
  387. }
  388. setneeds(suffix,tail) char *suffix ; {
  389. trf *phase ;
  390. p_suffix= suffix ;
  391. switch ( getpath(&phase) ) {
  392. case F_OK :
  393. for ( ; phase ; phase= phase->t_next ) {
  394. if ( phase->t_needed ) {
  395. if ( tail )
  396. add_tail(phase->t_needed) ;
  397. else
  398. add_head(phase->t_needed) ;
  399. }
  400. }
  401. break ;
  402. case F_NOMATCH :
  403. werror("\"%s\": unrecognized suffix",suffix) ;
  404. break ;
  405. case F_NOPATH :
  406. werror("sorry, cannot produce the desired file(s) from %s files",
  407. suffix) ;
  408. break ;
  409. }
  410. }