main.c 9.6 KB

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