main.c 9.7 KB

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