main.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  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 <string.h>
  9. #include "ack.h"
  10. #include "list.h"
  11. #include "trans.h"
  12. #include <local.h>
  13. #include "data.h"
  14. #include <signal.h>
  15. #ifndef NORCSID
  16. static char rcs_id[] = "$Id$" ;
  17. static char rcs_ack[] = RCS_ACK ;
  18. #endif
  19. static int sigs[] = { SIGINT, SIGHUP, SIGTERM, 0 } ;
  20. static int arg_count;
  21. extern char *getenv();
  22. main(argc,argv) char **argv ; {
  23. register list_elem *elem ;
  24. register char *frontend ;
  25. register int *n_sig ;
  26. register trf *phase ;
  27. progname=argv[0];
  28. varinit();
  29. vieuwargs(argc,argv);
  30. if ( (frontend=getenv("ACKFE")) ) {
  31. setlist(frontend) ;
  32. } else {
  33. setlist(FRONTENDS);
  34. }
  35. if ( callname ) {
  36. if ( machine ) {
  37. fuerror("can not produce code for both %s and %s",
  38. callname,machine) ;
  39. }
  40. machine= callname ;
  41. }
  42. if ( !machine && ! (machine=getenv("ACKM")) ) {
  43. #ifdef ACKM
  44. machine= ACKM; /* The default machine */
  45. #else
  46. fuerror("No machine specified") ;
  47. #endif
  48. }
  49. setlist(machine);
  50. /* Find the linker, needed for argument building */
  51. scanlist(l_first(tr_list),elem) {
  52. if ( t_cont(*elem)->t_linker ) {
  53. linker= t_cont(*elem) ;
  54. }
  55. }
  56. transini();
  57. scanneeds();
  58. sprintf(template,TMPNAME,getpid()) ;
  59. if ( n_error && !k_flag ) exit(n_error) ;
  60. for ( n_sig=sigs ; *n_sig ; n_sig++ ) {
  61. if ( signal(*n_sig,noodstop)==SIG_IGN ) {
  62. signal(*n_sig,SIG_IGN) ;
  63. }
  64. }
  65. scanlist ( l_first(arguments), elem ) {
  66. arg_count++;
  67. }
  68. scanlist ( l_first(arguments), elem ) {
  69. if ( !process(l_content(*elem)) && !k_flag ) exit(1) ;
  70. }
  71. orig.p_path= (char *)0 ;
  72. if ( !rts ) rts="." ;
  73. setsvar(keeps(RTS),rts) ;
  74. if ( linker ) getmapflags(linker) ;
  75. scanlist(l_first(tr_list),elem) {
  76. phase=t_cont(*elem) ;
  77. if ( phase->t_combine && phase->t_do ) {
  78. if ( phase->t_blocked ) {
  79. #ifdef DEBUG
  80. if ( debug ) {
  81. vprint("phase %s is blocked\n",
  82. phase->t_name) ;
  83. }
  84. #endif
  85. disc_inputs(phase) ;
  86. continue ;
  87. }
  88. orig.p_keep=YES ;
  89. orig.p_keeps=NO ;
  90. orig.p_path=phase->t_origname ;
  91. if ( p_basename ) throws(p_basename) ;
  92. if ( orig.p_path ) {
  93. p_basename= keeps(basename(orig.p_path)) ;
  94. } else {
  95. p_basename=0 ;
  96. }
  97. if ( !startrf(phase) && !k_flag ) exit(1) ;
  98. }
  99. }
  100. if ( n_error ) exit(n_error) ;
  101. exit(0) ;
  102. }
  103. char *srcvar() {
  104. return orig.p_path ;
  105. }
  106. char *getsuffix() {
  107. return strrchr(orig.p_path, SUFCHAR) ;
  108. }
  109. varinit() {
  110. /* initialize the string variables */
  111. register char *envstr ;
  112. extern char *em_dir;
  113. if ( envstr=getenv("ACKDIR") ) {
  114. em_dir = keeps(envstr);
  115. }
  116. setsvar(keeps(HOME),em_dir) ;
  117. setpvar(keeps(SRC),srcvar) ;
  118. setpvar(keeps(SUFFIX),getsuffix) ;
  119. }
  120. /************************* flag processing ***********************/
  121. vieuwargs(argc,argv) char **argv ; {
  122. register char *argp;
  123. register int nextarg ;
  124. register int eaten ;
  125. int hide ;
  126. firstarg(argv[0]) ;
  127. nextarg= 1 ;
  128. while ( nextarg<argc ) {
  129. argp= argv[nextarg] ;
  130. nextarg++ ;
  131. if ( argp[0]!='-' || argp[1]=='l' ) {
  132. /* Not a flag, or a library */
  133. l_add(&arguments,argp) ;
  134. continue ;
  135. }
  136. /* Flags */
  137. hide=NO ; /* Do not hide this flags to the phases */
  138. eaten=0 ; /* Did not 'eat' tail of flag yet */
  139. switch ( argp[1] ) {
  140. case 'm': if ( machine ) fuerror("Two machines?") ;
  141. machine= &argp[2];
  142. if (*machine == '\0') {
  143. fuerror("-m needs machine name");
  144. }
  145. eaten=1 ;
  146. break ;
  147. case 'o': if ( nextarg>=argc ) {
  148. fuerror("-o can't be the last flag") ;
  149. }
  150. if ( outfile ) fuerror("Two results?") ;
  151. outfile= argv[nextarg++] ;
  152. hide=YES ;
  153. break ;
  154. case 'O': Optlevel = atoi(&argp[2]);
  155. if (! Optlevel) Optlevel = 1;
  156. Optlist= &argp[2] ;
  157. eaten=1 ;
  158. break ;
  159. case 'v': if ( argp[2] ) {
  160. v_flag += atoi(&argp[2]) ;
  161. eaten=1 ;
  162. } else {
  163. v_flag++ ;
  164. }
  165. #ifdef DEBUG
  166. if ( v_flag>=3 ) debug=v_flag-2 ;
  167. #endif
  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=strrchr(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= strrchr(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 && arg_count > 1 ) {
  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. int do_preprocess = 0;
  303. int only_prep = 0;
  304. switch ( phase->t_prep ) {
  305. /* BEWARE, sign extension */
  306. case NO : break ;
  307. default : if ( !mayprep() ) break ;
  308. case YES: do_preprocess = 1;
  309. break;
  310. }
  311. if ( cpp_trafo && stopsuffix &&
  312. strcmp(cpp_trafo->t_out,stopsuffix)==0 ) {
  313. /* user explicitly asked for preprocessing */
  314. do_preprocess = 1;
  315. only_prep = 1;
  316. }
  317. if (do_preprocess && !transform(cpp_trafo) ) {
  318. n_error++ ;
  319. #ifdef DEBUG
  320. vprint("Pre-processor failed\n") ;
  321. #endif
  322. return 0 ;
  323. }
  324. if ( only_prep ) {
  325. break ;
  326. }
  327. if ( !transform(phase) ) {
  328. n_error++ ;
  329. block(phase->t_next) ;
  330. #ifdef DEBUG
  331. if ( debug ) {
  332. if ( !orig.p_path ) {
  333. vprint("phase %s failed\n",
  334. phase->t_name ) ;
  335. } else {
  336. vprint("phase %s for %s failed\n",
  337. phase->t_name,orig.p_path) ;
  338. }
  339. }
  340. #endif
  341. return 0 ;
  342. }
  343. first=NO ;
  344. phase=phase->t_next ;
  345. if ( !phase ) {
  346. #ifdef DEBUG
  347. if ( debug ) vprint("Transformation sequence complete for %s\n",
  348. orig.p_path) ;
  349. #endif
  350. /* No more work on this file */
  351. if ( !in.p_keep ) {
  352. fatal("attempt to discard the result file") ;
  353. }
  354. if ( in.p_keeps ) throws(in.p_path) ;
  355. in.p_keep=NO ; in.p_keeps=NO ; in.p_path= (char *) 0 ;
  356. return 1 ;
  357. }
  358. if ( phase->t_combine ) {
  359. add_input(&in,phase) ;
  360. break ;
  361. }
  362. }
  363. return 1 ;
  364. }
  365. block(first) trf *first ; {
  366. /* One of the input files of this phase could not be produced,
  367. block all combiners taking their input from this one.
  368. */
  369. register trf *phase ;
  370. for ( phase=first ; phase ; phase=phase->t_next ) {
  371. if ( phase->t_combine ) phase->t_blocked=YES ;
  372. }
  373. }
  374. mayprep() {
  375. int file ;
  376. char fc ;
  377. file=open(in.p_path,0);
  378. if ( file<0 ) return 0 ;
  379. if ( read(file,&fc,1)!=1 ) fc=0 ;
  380. close(file) ;
  381. return fc=='#' ;
  382. }
  383. keephead(suffix) char *suffix ; {
  384. l_add(&head_list, suffix) ;
  385. }
  386. keeptail(suffix) char *suffix ; {
  387. l_add(&tail_list, suffix) ;
  388. }
  389. scanneeds() {
  390. register list_elem *elem ;
  391. scanlist(l_first(head_list), elem) { setneeds(l_content(*elem),0) ; }
  392. l_clear(&head_list) ;
  393. scanlist(l_first(tail_list), elem) { setneeds(l_content(*elem),1) ; }
  394. l_clear(&tail_list) ;
  395. }
  396. setneeds(suffix,tail) char *suffix ; {
  397. trf *phase ;
  398. p_suffix= suffix ;
  399. switch ( getpath(&phase) ) {
  400. case F_OK :
  401. for ( ; phase ; phase= phase->t_next ) {
  402. if ( phase->t_needed ) {
  403. if ( tail )
  404. add_tail(phase->t_needed) ;
  405. else
  406. add_head(phase->t_needed) ;
  407. }
  408. }
  409. break ;
  410. case F_NOMATCH :
  411. werror("\"%s\": unrecognized suffix",suffix) ;
  412. break ;
  413. case F_NOPATH :
  414. werror("sorry, cannot produce the desired file(s) from %s files",
  415. suffix) ;
  416. break ;
  417. }
  418. }