main.c 9.9 KB

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