main.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /*
  2. * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. *
  4. * This product is part of the Amsterdam Compiler Kit.
  5. *
  6. * Permission to use, sell, duplicate or disclose this software must be
  7. * obtained in writing. Requests for such permissions may be sent to
  8. *
  9. * Dr. Andrew S. Tanenbaum
  10. * Wiskundig Seminarium
  11. * Vrije Universiteit
  12. * Postbox 7161
  13. * 1007 MC Amsterdam
  14. * The Netherlands
  15. *
  16. */
  17. #include "ack.h"
  18. #include "list.h"
  19. #include "trans.h"
  20. #include "../../h/em_path.h"
  21. #include "../../h/local.h"
  22. #include "data.h"
  23. #include <signal.h>
  24. #ifndef NORCSID
  25. static char rcs_id[] = "$Header$" ;
  26. static char rcs_ack[] = RCS_ACK ;
  27. #endif
  28. static int sigs[] = { SIGINT, SIGHUP, SIGTERM, 0 } ;
  29. extern char *getenv();
  30. main(argc,argv) char **argv ; {
  31. register list_elem *elem ;
  32. register char *frontend ;
  33. register int *n_sig ;
  34. progname=argv[0];
  35. varinit();
  36. vieuwargs(argc,argv);
  37. if ( (frontend=getenv("ACKFE")) ) {
  38. setlist(frontend) ;
  39. } else {
  40. setlist(FRONTENDS);
  41. }
  42. setlist(machine);
  43. transini();
  44. scanneeds();
  45. template= mktemp(ACKNAME) ;
  46. if ( n_error && !k_flag ) return n_error ;
  47. for ( n_sig=sigs ; *n_sig ; n_sig++ ) {
  48. if ( signal(*n_sig,noodstop)==SIG_IGN ) {
  49. signal(*n_sig,SIG_IGN) ;
  50. }
  51. }
  52. scanlist ( l_first(arguments), elem ) {
  53. if ( !process(l_content(*elem)) && !k_flag ) return 1 ;
  54. }
  55. orig.p_path= (char *)0 ;
  56. if ( !combiner && !stopsuffix ) {
  57. /* Call combiner directly without any transformation */
  58. scanlist(l_first(tr_list),elem) {
  59. if ( t_cont(*elem)->t_combine ) {
  60. combiner= t_cont(*elem) ;
  61. }
  62. }
  63. }
  64. if ( !combiner || n_error ) return n_error ;
  65. if ( !do_combine() ) return 1 ;
  66. if ( g_flag ) {
  67. return do_run();
  68. }
  69. return 0 ;
  70. }
  71. char *srcvar() {
  72. return orig.p_path ;
  73. }
  74. varinit() {
  75. /* initialize the string variables */
  76. setsvar(keeps(HOME),keeps(EM_DIR)) ;
  77. setpvar(keeps(SRC),srcvar) ;
  78. }
  79. /************************* flag processing ***********************/
  80. vieuwargs(argc,argv) char **argv ; {
  81. register char *argp;
  82. register int nextarg ;
  83. register int eaten ;
  84. firstarg(argv[0]) ;
  85. nextarg= 1 ;
  86. while ( nextarg<argc ) {
  87. argp= argv[nextarg] ;
  88. nextarg++ ;
  89. if ( argp[0]!='-' || argp[1]=='l' ) {
  90. /* Not a flag, or a library */
  91. l_add(&arguments,argp) ;
  92. continue ;
  93. }
  94. /* Flags */
  95. eaten=0 ; /* Did not 'eat' tail of flag yet */
  96. switch ( argp[1] ) {
  97. case 'm': if ( machine ) fuerror("Two machines?") ;
  98. machine= &argp[2];
  99. eaten=1 ;
  100. break ;
  101. case 'o': if ( nextarg>=argc ) {
  102. fuerror("-o can't be the last flag") ;
  103. }
  104. if ( outfile ) fuerror("Two results?") ;
  105. outfile= argv[nextarg++] ;
  106. break ;
  107. case 'O': Optflag++ ;
  108. break ;
  109. case 'v': v_flag++ ;
  110. break ;
  111. case 'g': g_flag++ ;
  112. break ;
  113. case 'c': if ( stopsuffix ) fuerror("Two -c flags") ;
  114. stopsuffix= &argp[2]; eaten=1;
  115. if ( *stopsuffix && *stopsuffix!=SUFCHAR ) {
  116. fuerror("-c flag has invalid tail") ;
  117. }
  118. break ;
  119. case 'k': k_flag++ ;
  120. break ;
  121. case 't': t_flag++ ;
  122. break ;
  123. case 'R': do_Rflag(argp); eaten=1;
  124. break ;
  125. case 'r': if ( argp[2]!=SUFCHAR ) {
  126. error("-r must be followed by %c",SUFCHAR) ;
  127. }
  128. keeptail(&argp[2]); eaten=1 ;
  129. break ;
  130. case '.': if ( rts ) fuerror("Two run-time systems?") ;
  131. rts= &argp[1] ; eaten=1;
  132. keephead(rts) ; keeptail(rts) ;
  133. break ;
  134. #ifdef DEBUG
  135. case 'd': debug++ ;
  136. break ;
  137. #endif
  138. case 0 : nill_flag++ ; eaten++ ;
  139. break;
  140. case 'w': { register char *tokeep ;
  141. w_flag++;
  142. tokeep=keeps(argp) ;
  143. *tokeep |= NO_SCAN ;
  144. l_add(&flags,tokeep) ;
  145. }
  146. break ;
  147. default: /* The flag is not recognized,
  148. put it on the list for the sub-processes
  149. */
  150. #ifdef DEBUG
  151. if ( debug ) {
  152. vprint("Flag %s: phase dependent\n",argp) ;
  153. }
  154. #endif
  155. l_add(&flags,keeps(argp)) ;
  156. eaten=1 ;
  157. }
  158. if ( argp[2] && !eaten ) {
  159. werror("Unexpected characters at end of %s",argp) ;
  160. }
  161. }
  162. if ( !machine && ! (machine=getenv("ACKM")) ) {
  163. #ifdef ACKM
  164. machine= ACKM; /* The default machine */
  165. #else
  166. fuerror("No machine specified") ;
  167. #endif
  168. }
  169. return ;
  170. }
  171. firstarg(argp) register char *argp ; {
  172. register char *name ;
  173. name=rindex(argp,'/') ;
  174. if ( name && *(name+1) ) {
  175. name++ ;
  176. } else {
  177. name= argp ;
  178. }
  179. if ( strcmp(name,"ack")==0 ) return ;
  180. if ( strcmp(name,"acc")==0 || strcmp(name,"cc")==0 ) {
  181. rts= ".c" ; keephead(rts) ; keeptail(rts) ;
  182. return ;
  183. }
  184. if ( strcmp(name,"apc")==0 || strcmp(name,"pc")==0 ) {
  185. rts= ".p" ; keephead(rts) ; keeptail(rts) ;
  186. return ;
  187. }
  188. machine= name;
  189. }
  190. /************************* argument processing ***********************/
  191. process(arg) char *arg ; {
  192. /* Process files & library arguments */
  193. register list_elem *elem ;
  194. register trf *phase ;
  195. int first=YES ;
  196. #ifdef DEBUG
  197. if ( debug ) vprint("Processing %s\n",arg) ;
  198. #endif
  199. if ( arg[0]=='-' ) { l_add(&c_arguments,keeps(arg)) ; return 1 ; }
  200. p_suffix= rindex(arg,SUFCHAR) ;
  201. if ( p_basename ) throws(p_basename) ;
  202. orig.p_keep= YES ; /* Don't throw away the original ! */
  203. orig.p_path= arg ;
  204. p_basename= keeps(basename(arg)) ;
  205. if ( !p_suffix ) { l_add(&c_arguments,keeps(arg)) ; return 1 ; }
  206. /* Try to find a path through the transformations */
  207. switch( setpath() ) {
  208. case F_NOPATH :
  209. error("Cannot produce the desired file from %s",arg) ;
  210. l_add(&c_arguments,keeps(arg)) ;
  211. return 1 ;
  212. case F_NOMATCH :
  213. if ( stopsuffix ) werror("Unknown suffix in %s",arg) ;
  214. l_add(&c_arguments,keeps(arg)) ;
  215. return 1 ;
  216. case F_OK :
  217. break ;
  218. }
  219. orig.p_keeps= NO;
  220. in= orig ;
  221. scanlist(l_first(tr_list), elem) {
  222. phase= t_cont(*elem) ;
  223. if ( phase->t_do ) { /* perform this transformation */
  224. if ( first ) {
  225. if ( !nill_flag ) {
  226. printf("%s\n",arg) ;
  227. }
  228. }
  229. switch ( phase->t_prep ) {
  230. default : if ( !mayprep() ) break ;
  231. case YES: if ( !transform(cpp_trafo) ) {
  232. n_error++ ;
  233. #ifdef DEBUG
  234. vprint("Pre-processor failed\n") ;
  235. #endif
  236. return 0 ;
  237. }
  238. case NO :
  239. break ;
  240. }
  241. if ( cpp_trafo && stopsuffix &&
  242. strcmp(cpp_trafo->t_out,stopsuffix)==0 ) {
  243. break ;
  244. }
  245. if ( !transform(phase) ) {
  246. n_error++ ;
  247. #ifdef DEBUG
  248. if ( debug ) {
  249. vprint("phase %s for %s failed\n",
  250. phase->t_name,orig.p_path) ;
  251. }
  252. #endif
  253. return 0 ;
  254. }
  255. first=NO ;
  256. }
  257. }
  258. #ifdef DEBUG
  259. if ( debug ) vprint("Transformation complete for %s\n",orig.p_path) ;
  260. #endif
  261. if ( !in.p_keep ) fatal("attempt to discard the result file") ;
  262. l_add(&c_arguments,keeps(in.p_path));
  263. disc_files() ;
  264. return 1 ;
  265. }
  266. mayprep() {
  267. int file ;
  268. char fc ;
  269. file=open(in.p_path,0);
  270. if ( file<0 ) return 0 ;
  271. if ( read(file,&fc,1)!=1 ) fc=0 ;
  272. close(file) ;
  273. return fc=='#' ;
  274. }
  275. keephead(suffix) char *suffix ; {
  276. l_add(&head_list, suffix) ;
  277. }
  278. keeptail(suffix) char *suffix ; {
  279. l_add(&tail_list, suffix) ;
  280. }
  281. scanneeds() {
  282. register list_elem *elem ;
  283. scanlist(l_first(head_list), elem) { setneeds(l_content(*elem),0) ; }
  284. l_clear(&head_list) ;
  285. scanlist(l_first(tail_list), elem) { setneeds(l_content(*elem),1) ; }
  286. l_clear(&tail_list) ;
  287. }
  288. setneeds(suffix,tail) char *suffix ; {
  289. register list_elem *elem ;
  290. register trf *phase ;
  291. p_suffix= suffix ;
  292. switch ( setpath() ) {
  293. case F_OK :
  294. scanlist( l_first(tr_list), elem ) {
  295. phase = t_cont(*elem) ;
  296. if ( phase->t_do ) {
  297. if ( phase->t_needed ) {
  298. if ( tail )
  299. add_tail(phase->t_needed) ;
  300. else
  301. add_head(phase->t_needed) ;
  302. }
  303. }
  304. }
  305. break ;
  306. case F_NOMATCH :
  307. werror("\"%s\": unrecognized suffix",suffix) ;
  308. break ;
  309. case F_NOPATH :
  310. werror("incomplete internal specification for %s files",
  311. suffix) ;
  312. break ;
  313. }
  314. }