main.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  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 <sys/types.h>
  10. #include <unistd.h>
  11. #include "ack.h"
  12. #include "list.h"
  13. #include "trans.h"
  14. #include "system.h"
  15. #include "print.h"
  16. #include <local.h>
  17. #include "data.h"
  18. #include <signal.h>
  19. static int sigs[] = { SIGINT, SIGHUP, SIGTERM, 0 } ;
  20. static int arg_count;
  21. int main(int argc, char *argv[])
  22. {
  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. {
  105. return orig.p_path ;
  106. }
  107. char *getsuffix()
  108. {
  109. return strrchr(orig.p_path, SUFCHAR) ;
  110. }
  111. void varinit()
  112. {
  113. /* initialize the string variables */
  114. register char *envstr ;
  115. extern char *em_dir;
  116. if ( (envstr=getenv("ACKDIR")) ) {
  117. em_dir = keeps(envstr);
  118. }
  119. setsvar(keeps(HOME),em_dir) ;
  120. setpvar(keeps(SRC),srcvar) ;
  121. setpvar(keeps(SUFFIX),getsuffix) ;
  122. }
  123. /************************* flag processing ***********************/
  124. void vieuwargs(int argc, char *argv[])
  125. {
  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. if (*machine == '\0') {
  147. fuerror("-m needs machine name");
  148. }
  149. eaten=1 ;
  150. break ;
  151. case 'o': if ( nextarg>=argc ) {
  152. fuerror("-o can't be the last flag") ;
  153. }
  154. if ( outfile ) fuerror("Two results?") ;
  155. outfile= argv[nextarg++] ;
  156. hide=YES ;
  157. break ;
  158. case 'O': Optlevel = atoi(&argp[2]);
  159. if (! Optlevel) Optlevel = 1;
  160. Optlist= &argp[2] ;
  161. eaten=1 ;
  162. break ;
  163. case 'v': if ( argp[2] ) {
  164. v_flag += atoi(&argp[2]) ;
  165. eaten=1 ;
  166. } else {
  167. v_flag++ ;
  168. }
  169. #ifdef DEBUG
  170. if ( v_flag>=3 ) debug=v_flag-2 ;
  171. #endif
  172. break ;
  173. case 'c': if ( stopsuffix ) fuerror("Two -c flags") ;
  174. stopsuffix= &argp[2]; eaten=1;
  175. if ( *stopsuffix && *stopsuffix!=SUFCHAR ) {
  176. fuerror("-c flag has invalid tail") ;
  177. }
  178. break ;
  179. case 'k': k_flag++ ;
  180. break ;
  181. case 't': t_flag++ ;
  182. break ;
  183. case 'R': eaten=1;
  184. break ;
  185. case 'r': if ( argp[2]!=SUFCHAR ) {
  186. error("-r must be followed by %c",SUFCHAR) ;
  187. }
  188. keeptail(&argp[2]); eaten=1 ;
  189. break ;
  190. case '.': if ( rts ) {
  191. if ( strcmp(rts,&argp[1])!=0 )
  192. fuerror("Two run-time systems?") ;
  193. } else {
  194. rts= &argp[1] ;
  195. keephead(rts) ; keeptail(rts) ;
  196. }
  197. eaten=1 ;
  198. break ;
  199. case 0 : nill_flag++ ; eaten++ ;
  200. hide=YES ;
  201. break;
  202. case 'w': w_flag++;
  203. break ;
  204. default: /* The flag is not recognized,
  205. put it on the list for the sub-processes
  206. */
  207. #ifdef DEBUG
  208. if ( debug ) {
  209. vprint("Flag %s: phase dependent\n",argp) ;
  210. }
  211. #endif
  212. l_add(&flags,keeps(argp)) ;
  213. eaten=1 ;
  214. hide=YES ;
  215. }
  216. if ( !hide ) {
  217. register char *tokeep ;
  218. tokeep=keeps(argp) ;
  219. if ( argp[1]=='R' ) {
  220. do_Rflag(tokeep);
  221. } else {
  222. *tokeep |= NO_SCAN ;
  223. }
  224. l_add(&flags,tokeep) ;
  225. }
  226. if ( argp[2] && !eaten ) {
  227. werror("Unexpected characters at end of %s",argp) ;
  228. }
  229. }
  230. return ;
  231. }
  232. void firstarg(char *argp)
  233. {
  234. register char *name ;
  235. name=strrchr(argp,'/') ;
  236. if ( name && *(name+1) ) {
  237. name++ ;
  238. } else {
  239. name= argp ;
  240. }
  241. callname= name;
  242. }
  243. /************************* argument processing ***********************/
  244. int process(char *arg)
  245. {
  246. /* Process files & library arguments */
  247. trf *phase ;
  248. register trf *tmp ;
  249. #ifdef DEBUG
  250. if ( debug ) vprint("Processing %s\n",arg) ;
  251. #endif
  252. p_suffix= strrchr(arg,SUFCHAR) ;
  253. orig.p_keep= YES ; /* Don't throw away the original ! */
  254. orig.p_keeps= NO;
  255. orig.p_path= arg ;
  256. if ( arg[0]=='-' || !p_suffix ) {
  257. if ( linker ) add_input(&orig,linker) ;
  258. return 1 ;
  259. }
  260. if ( p_basename ) throws(p_basename) ;
  261. p_basename= keeps(basename(arg)) ;
  262. /* Try to find a path through the transformations */
  263. switch( getpath(&phase) ) {
  264. case FP_NOPATH :
  265. error("Cannot produce the desired file from %s",arg) ;
  266. if ( linker ) add_input(&orig,linker) ;
  267. return 1 ;
  268. case FP_NOMATCH :
  269. if ( stopsuffix ) werror("Unknown suffix in %s",arg) ;
  270. if ( linker ) add_input(&orig,linker) ;
  271. return 1 ;
  272. case FP_OK :
  273. break ;
  274. }
  275. if ( !phase ) return 1 ;
  276. for ( tmp=phase ; tmp ; tmp=tmp->t_next )
  277. if ( !tmp->t_visited ) {
  278. /* The flags are set up once.
  279. At the first time each phase is in a list.
  280. The program name and flags may already be touched
  281. by vieuwargs.
  282. */
  283. tmp->t_visited=YES ;
  284. if ( tmp->t_priority<0 )
  285. werror("Using phase %s (negative priority)",
  286. tmp->t_name) ;
  287. if ( !rts && tmp->t_rts ) rts= tmp->t_rts ;
  288. if ( tmp->t_needed ) {
  289. add_head(tmp->t_needed) ;
  290. add_tail(tmp->t_needed) ;
  291. }
  292. }
  293. if ( phase->t_combine ) {
  294. add_input(&orig,phase) ;
  295. return 1 ;
  296. }
  297. in= orig ;
  298. if ( !nill_flag && arg_count > 1 ) {
  299. printf("%s\n",arg) ;
  300. }
  301. return startrf(phase) ;
  302. }
  303. int startrf(trf *first)
  304. {
  305. /* Start the transformations at the indicated phase */
  306. register trf *phase ;
  307. phase=first ;
  308. for(;;) {
  309. int do_preprocess = 0;
  310. int only_prep = 0;
  311. switch ( phase->t_prep ) {
  312. /* BEWARE, sign extension */
  313. case NO : break ;
  314. default : if ( !mayprep() ) break ;
  315. case YES: do_preprocess = 1;
  316. break;
  317. }
  318. if ( cpp_trafo && stopsuffix &&
  319. strcmp(cpp_trafo->t_out,stopsuffix)==0 ) {
  320. /* user explicitly asked for preprocessing */
  321. do_preprocess = 1;
  322. only_prep = 1;
  323. }
  324. if (do_preprocess && !transform(cpp_trafo) ) {
  325. n_error++ ;
  326. #ifdef DEBUG
  327. vprint("Pre-processor failed\n") ;
  328. #endif
  329. return 0 ;
  330. }
  331. if ( only_prep ) {
  332. break ;
  333. }
  334. if ( !transform(phase) ) {
  335. n_error++ ;
  336. block(phase->t_next) ;
  337. #ifdef DEBUG
  338. if ( debug ) {
  339. if ( !orig.p_path ) {
  340. vprint("phase %s failed\n",
  341. phase->t_name ) ;
  342. } else {
  343. vprint("phase %s for %s failed\n",
  344. phase->t_name,orig.p_path) ;
  345. }
  346. }
  347. #endif
  348. return 0 ;
  349. }
  350. first=NO ;
  351. phase=phase->t_next ;
  352. if ( !phase ) {
  353. #ifdef DEBUG
  354. if ( debug ) vprint("Transformation sequence complete for %s\n",
  355. orig.p_path) ;
  356. #endif
  357. /* No more work on this file */
  358. if ( !in.p_keep ) {
  359. fatal("attempt to discard the result file") ;
  360. }
  361. if ( in.p_keeps ) throws(in.p_path) ;
  362. in.p_keep=NO ; in.p_keeps=NO ; in.p_path= (char *) 0 ;
  363. return 1 ;
  364. }
  365. if ( phase->t_combine ) {
  366. add_input(&in,phase) ;
  367. break ;
  368. }
  369. }
  370. return 1 ;
  371. }
  372. void block(trf *first)
  373. {
  374. /* One of the input files of this phase could not be produced,
  375. block all combiners taking their input from this one.
  376. */
  377. register trf *phase ;
  378. for ( phase=first ; phase ; phase=phase->t_next ) {
  379. if ( phase->t_combine ) phase->t_blocked=YES ;
  380. }
  381. }
  382. int mayprep()
  383. {
  384. int file ;
  385. char fc ;
  386. file=open(in.p_path,0);
  387. if ( file<0 ) return 0 ;
  388. if ( read(file,&fc,1)!=1 ) fc=0 ;
  389. close(file) ;
  390. return fc=='#' ;
  391. }
  392. void keephead(char *suffix)
  393. {
  394. l_add(&head_list, suffix) ;
  395. }
  396. void keeptail(char *suffix)
  397. {
  398. l_add(&tail_list, suffix) ;
  399. }
  400. void scanneeds()
  401. {
  402. register list_elem *elem ;
  403. scanlist(l_first(head_list), elem) { setneeds(l_content(*elem),0) ; }
  404. l_clear(&head_list) ;
  405. scanlist(l_first(tail_list), elem) { setneeds(l_content(*elem),1) ; }
  406. l_clear(&tail_list) ;
  407. }
  408. void setneeds(char *suffix, int tail)
  409. {
  410. trf *phase ;
  411. p_suffix= suffix ;
  412. switch ( getpath(&phase) ) {
  413. case FP_OK :
  414. for ( ; phase ; phase= phase->t_next ) {
  415. if ( phase->t_needed ) {
  416. if ( tail )
  417. add_tail(phase->t_needed) ;
  418. else
  419. add_head(phase->t_needed) ;
  420. }
  421. }
  422. break ;
  423. case FP_NOMATCH :
  424. werror("\"%s\": unrecognized suffix",suffix) ;
  425. break ;
  426. case FP_NOPATH :
  427. werror("sorry, cannot produce the desired file(s) from %s files",
  428. suffix) ;
  429. break ;
  430. }
  431. }