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".
15 static char rcs_id[] = "$Id: main.c,v 2.21 1994/06/24 10:12:52 ceriel Exp $" ;
16 static char rcs_ack[] = RCS_ACK ;
19 static int sigs[] = { SIGINT, SIGHUP, SIGTERM, 0 } ;
22 extern char *getenv();
24 main(argc,argv) char **argv ; {
25 register list_elem *elem ;
26 register char *frontend ;
33 if ( (frontend=getenv("ACKFE")) ) {
40 fuerror("can not produce code for both %s and %s",
45 if ( !machine && ! (machine=getenv("ACKM")) ) {
47 machine= ACKM; /* The default machine */
49 fuerror("No machine specified") ;
53 /* Find the linker, needed for argument building */
54 scanlist(l_first(tr_list),elem) {
55 if ( t_cont(*elem)->t_linker ) {
56 linker= t_cont(*elem) ;
61 sprintf(template,TMPNAME,getpid()) ;
62 if ( n_error && !k_flag ) exit(n_error) ;
64 for ( n_sig=sigs ; *n_sig ; n_sig++ ) {
65 if ( signal(*n_sig,noodstop)==SIG_IGN ) {
66 signal(*n_sig,SIG_IGN) ;
70 scanlist ( l_first(arguments), elem ) {
74 scanlist ( l_first(arguments), elem ) {
75 if ( !process(l_content(*elem)) && !k_flag ) exit(1) ;
77 orig.p_path= (char *)0 ;
79 setsvar(keeps(RTS),rts) ;
80 if ( linker ) getmapflags(linker) ;
82 scanlist(l_first(tr_list),elem) {
84 if ( phase->t_combine && phase->t_do ) {
85 if ( phase->t_blocked ) {
88 vprint("phase %s is blocked\n",
97 orig.p_path=phase->t_origname ;
98 if ( p_basename ) throws(p_basename) ;
100 p_basename= keeps(basename(orig.p_path)) ;
104 if ( !startrf(phase) && !k_flag ) exit(1) ;
108 if ( n_error ) exit(n_error) ;
118 return strrindex(orig.p_path, SUFCHAR) ;
122 /* initialize the string variables */
123 register char *envstr ;
126 if ( envstr=getenv("ACKDIR") ) {
127 em_dir = keeps(envstr);
129 setsvar(keeps(HOME),em_dir) ;
130 setpvar(keeps(SRC),srcvar) ;
131 setpvar(keeps(SUFFIX),getsuffix) ;
134 /************************* flag processing ***********************/
136 vieuwargs(argc,argv) char **argv ; {
138 register int nextarg ;
146 while ( nextarg<argc ) {
147 argp= argv[nextarg] ;
149 if ( argp[0]!='-' || argp[1]=='l' ) {
150 /* Not a flag, or a library */
151 l_add(&arguments,argp) ;
156 hide=NO ; /* Do not hide this flags to the phases */
157 eaten=0 ; /* Did not 'eat' tail of flag yet */
159 case 'm': if ( machine ) fuerror("Two machines?") ;
161 if (*machine == '\0') {
162 fuerror("-m needs machine name");
166 case 'o': if ( nextarg>=argc ) {
167 fuerror("-o can't be the last flag") ;
169 if ( outfile ) fuerror("Two results?") ;
170 outfile= argv[nextarg++] ;
173 case 'O': Optlevel = atoi(&argp[2]);
174 if (! Optlevel) Optlevel = 1;
178 case 'v': if ( argp[2] ) {
179 v_flag += atoi(&argp[2]) ;
185 if ( v_flag>=3 ) debug=v_flag-2 ;
188 case 'c': if ( stopsuffix ) fuerror("Two -c flags") ;
189 stopsuffix= &argp[2]; eaten=1;
190 if ( *stopsuffix && *stopsuffix!=SUFCHAR ) {
191 fuerror("-c flag has invalid tail") ;
200 case 'r': if ( argp[2]!=SUFCHAR ) {
201 error("-r must be followed by %c",SUFCHAR) ;
203 keeptail(&argp[2]); eaten=1 ;
205 case '.': if ( rts ) {
206 if ( strcmp(rts,&argp[1])!=0 )
207 fuerror("Two run-time systems?") ;
210 keephead(rts) ; keeptail(rts) ;
214 case 0 : nill_flag++ ; eaten++ ;
219 default: /* The flag is not recognized,
220 put it on the list for the sub-processes
224 vprint("Flag %s: phase dependent\n",argp) ;
227 l_add(&flags,keeps(argp)) ;
232 register char *tokeep ;
234 if ( argp[1]=='R' ) {
239 l_add(&flags,tokeep) ;
241 if ( argp[2] && !eaten ) {
242 werror("Unexpected characters at end of %s",argp) ;
248 firstarg(argp) register char *argp ; {
249 register char *name ;
251 name=strrindex(argp,'/') ;
252 if ( name && *(name+1) ) {
260 /************************* argument processing ***********************/
262 process(arg) char *arg ; {
263 /* Process files & library arguments */
268 if ( debug ) vprint("Processing %s\n",arg) ;
270 p_suffix= strrindex(arg,SUFCHAR) ;
271 orig.p_keep= YES ; /* Don't throw away the original ! */
274 if ( arg[0]=='-' || !p_suffix ) {
275 if ( linker ) add_input(&orig,linker) ;
278 if ( p_basename ) throws(p_basename) ;
279 p_basename= keeps(basename(arg)) ;
280 /* Try to find a path through the transformations */
281 switch( getpath(&phase) ) {
283 error("Cannot produce the desired file from %s",arg) ;
284 if ( linker ) add_input(&orig,linker) ;
287 if ( stopsuffix ) werror("Unknown suffix in %s",arg) ;
288 if ( linker ) add_input(&orig,linker) ;
293 if ( !phase ) return 1 ;
294 for ( tmp=phase ; tmp ; tmp=tmp->t_next )
295 if ( !tmp->t_visited ) {
296 /* The flags are set up once.
297 At the first time each phase is in a list.
298 The program name and flags may already be touched
302 if ( tmp->t_priority<0 )
303 werror("Using phase %s (negative priority)",
305 if ( !rts && tmp->t_rts ) rts= tmp->t_rts ;
306 if ( tmp->t_needed ) {
307 add_head(tmp->t_needed) ;
308 add_tail(tmp->t_needed) ;
311 if ( phase->t_combine ) {
312 add_input(&orig,phase) ;
316 if ( !nill_flag && arg_count > 1 ) {
319 return startrf(phase) ;
322 int startrf(first) trf *first ; {
323 /* Start the transformations at the indicated phase */
324 register trf *phase ;
328 int do_preprocess = 0;
331 switch ( phase->t_prep ) {
332 /* BEWARE, sign extension */
334 default : if ( !mayprep() ) break ;
335 case YES: do_preprocess = 1;
338 if ( cpp_trafo && stopsuffix &&
339 strcmp(cpp_trafo->t_out,stopsuffix)==0 ) {
340 /* user explicitly asked for preprocessing */
345 if (do_preprocess && !transform(cpp_trafo) ) {
348 vprint("Pre-processor failed\n") ;
355 if ( !transform(phase) ) {
357 block(phase->t_next) ;
360 if ( !orig.p_path ) {
361 vprint("phase %s failed\n",
364 vprint("phase %s for %s failed\n",
365 phase->t_name,orig.p_path) ;
372 phase=phase->t_next ;
375 if ( debug ) vprint("Transformation sequence complete for %s\n",
378 /* No more work on this file */
380 fatal("attempt to discard the result file") ;
382 if ( in.p_keeps ) throws(in.p_path) ;
383 in.p_keep=NO ; in.p_keeps=NO ; in.p_path= (char *) 0 ;
386 if ( phase->t_combine ) {
387 add_input(&in,phase) ;
394 block(first) trf *first ; {
395 /* One of the input files of this phase could not be produced,
396 block all combiners taking their input from this one.
398 register trf *phase ;
399 for ( phase=first ; phase ; phase=phase->t_next ) {
400 if ( phase->t_combine ) phase->t_blocked=YES ;
406 file=open(in.p_path,0);
407 if ( file<0 ) return 0 ;
408 if ( read(file,&fc,1)!=1 ) fc=0 ;
413 keephead(suffix) char *suffix ; {
414 l_add(&head_list, suffix) ;
417 keeptail(suffix) char *suffix ; {
418 l_add(&tail_list, suffix) ;
422 register list_elem *elem ;
423 scanlist(l_first(head_list), elem) { setneeds(l_content(*elem),0) ; }
424 l_clear(&head_list) ;
425 scanlist(l_first(tail_list), elem) { setneeds(l_content(*elem),1) ; }
426 l_clear(&tail_list) ;
429 setneeds(suffix,tail) char *suffix ; {
433 switch ( getpath(&phase) ) {
435 for ( ; phase ; phase= phase->t_next ) {
436 if ( phase->t_needed ) {
438 add_tail(phase->t_needed) ;
440 add_head(phase->t_needed) ;
445 werror("\"%s\": unrecognized suffix",suffix) ;
448 werror("sorry, cannot produce the desired file(s) from %s files",