123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 |
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- *
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "ack.h"
- #include "list.h"
- #include "trans.h"
- #include <local.h>
- #include "data.h"
- #include <signal.h>
- #ifndef NORCSID
- static char rcs_id[] = "$Id$" ;
- static char rcs_ack[] = RCS_ACK ;
- #endif
- static int sigs[] = { SIGINT, SIGHUP, SIGTERM, 0 } ;
- static int arg_count;
- void varinit();
- void vieuwargs(int argc, char *argv[]);
- void firstarg(char *argp);
- void block(trf *first);
- void keephead(char *suffix);
- void keeptail(char *suffix);
- void scanneeds();
- void setneeds(char *suffix, int tail);
- int main(int argc, char *argv[])
- {
- register list_elem *elem ;
- register char *frontend ;
- register int *n_sig ;
- register trf *phase ;
- progname=argv[0];
- varinit();
- vieuwargs(argc,argv);
- if ( (frontend=getenv("ACKFE")) ) {
- setlist(frontend) ;
- } else {
- setlist(FRONTENDS);
- }
- if ( callname ) {
- if ( machine ) {
- fuerror("can not produce code for both %s and %s",
- callname,machine) ;
- }
- machine= callname ;
- }
- if ( !machine && ! (machine=getenv("ACKM")) ) {
- #ifdef ACKM
- machine= ACKM; /* The default machine */
- #else
- fuerror("No machine specified") ;
- #endif
- }
- setlist(machine);
- /* Find the linker, needed for argument building */
- scanlist(l_first(tr_list),elem) {
- if ( t_cont(*elem)->t_linker ) {
- linker= t_cont(*elem) ;
- }
- }
- transini();
- scanneeds();
- sprintf(template,TMPNAME,getpid()) ;
- if ( n_error && !k_flag ) exit(n_error) ;
- for ( n_sig=sigs ; *n_sig ; n_sig++ ) {
- if ( signal(*n_sig,noodstop)==SIG_IGN ) {
- signal(*n_sig,SIG_IGN) ;
- }
- }
- scanlist ( l_first(arguments), elem ) {
- arg_count++;
- }
- scanlist ( l_first(arguments), elem ) {
- if ( !process(l_content(*elem)) && !k_flag ) exit(1) ;
- }
- orig.p_path= (char *)0 ;
- if ( !rts ) rts="." ;
- setsvar(keeps(RTS),rts) ;
- if ( linker ) getmapflags(linker) ;
- scanlist(l_first(tr_list),elem) {
- phase=t_cont(*elem) ;
- if ( phase->t_combine && phase->t_do ) {
- if ( phase->t_blocked ) {
- #ifdef DEBUG
- if ( debug ) {
- vprint("phase %s is blocked\n",
- phase->t_name) ;
- }
- #endif
- disc_inputs(phase) ;
- continue ;
- }
- orig.p_keep=YES ;
- orig.p_keeps=NO ;
- orig.p_path=phase->t_origname ;
- if ( p_basename ) throws(p_basename) ;
- if ( orig.p_path ) {
- p_basename= keeps(basename(orig.p_path)) ;
- } else {
- p_basename=0 ;
- }
- if ( !startrf(phase) && !k_flag ) exit(1) ;
- }
- }
- if ( n_error ) exit(n_error) ;
- exit(0) ;
- }
- char *srcvar()
- {
- return orig.p_path ;
- }
- char *getsuffix()
- {
- return strrchr(orig.p_path, SUFCHAR) ;
- }
- void varinit()
- {
- /* initialize the string variables */
- register char *envstr ;
- extern char *em_dir;
- if ( (envstr=getenv("ACKDIR")) ) {
- em_dir = keeps(envstr);
- }
- setsvar(keeps(HOME),em_dir) ;
- setpvar(keeps(SRC),srcvar) ;
- setpvar(keeps(SUFFIX),getsuffix) ;
- }
- /************************* flag processing ***********************/
- void vieuwargs(int argc, char *argv[])
- {
- register char *argp;
- register int nextarg ;
- register int eaten ;
- int hide ;
- firstarg(argv[0]) ;
- nextarg= 1 ;
- while ( nextarg<argc ) {
- argp= argv[nextarg] ;
- nextarg++ ;
- if ( argp[0]!='-' || argp[1]=='l' ) {
- /* Not a flag, or a library */
- l_add(&arguments,argp) ;
- continue ;
- }
- /* Flags */
- hide=NO ; /* Do not hide this flags to the phases */
- eaten=0 ; /* Did not 'eat' tail of flag yet */
- switch ( argp[1] ) {
- case 'm': if ( machine ) fuerror("Two machines?") ;
- machine= &argp[2];
- if (*machine == '\0') {
- fuerror("-m needs machine name");
- }
- eaten=1 ;
- break ;
- case 'o': if ( nextarg>=argc ) {
- fuerror("-o can't be the last flag") ;
- }
- if ( outfile ) fuerror("Two results?") ;
- outfile= argv[nextarg++] ;
- hide=YES ;
- break ;
- case 'O': Optlevel = atoi(&argp[2]);
- if (! Optlevel) Optlevel = 1;
- Optlist= &argp[2] ;
- eaten=1 ;
- break ;
- case 'v': if ( argp[2] ) {
- v_flag += atoi(&argp[2]) ;
- eaten=1 ;
- } else {
- v_flag++ ;
- }
- #ifdef DEBUG
- if ( v_flag>=3 ) debug=v_flag-2 ;
- #endif
- break ;
- case 'c': if ( stopsuffix ) fuerror("Two -c flags") ;
- stopsuffix= &argp[2]; eaten=1;
- if ( *stopsuffix && *stopsuffix!=SUFCHAR ) {
- fuerror("-c flag has invalid tail") ;
- }
- break ;
- case 'k': k_flag++ ;
- break ;
- case 't': t_flag++ ;
- break ;
- case 'R': eaten=1;
- break ;
- case 'r': if ( argp[2]!=SUFCHAR ) {
- error("-r must be followed by %c",SUFCHAR) ;
- }
- keeptail(&argp[2]); eaten=1 ;
- break ;
- case '.': if ( rts ) {
- if ( strcmp(rts,&argp[1])!=0 )
- fuerror("Two run-time systems?") ;
- } else {
- rts= &argp[1] ;
- keephead(rts) ; keeptail(rts) ;
- }
- eaten=1 ;
- break ;
- case 0 : nill_flag++ ; eaten++ ;
- hide=YES ;
- break;
- case 'w': w_flag++;
- break ;
- default: /* The flag is not recognized,
- put it on the list for the sub-processes
- */
- #ifdef DEBUG
- if ( debug ) {
- vprint("Flag %s: phase dependent\n",argp) ;
- }
- #endif
- l_add(&flags,keeps(argp)) ;
- eaten=1 ;
- hide=YES ;
- }
- if ( !hide ) {
- register char *tokeep ;
- tokeep=keeps(argp) ;
- if ( argp[1]=='R' ) {
- do_Rflag(tokeep);
- } else {
- *tokeep |= NO_SCAN ;
- }
- l_add(&flags,tokeep) ;
- }
- if ( argp[2] && !eaten ) {
- werror("Unexpected characters at end of %s",argp) ;
- }
- }
- return ;
- }
- void firstarg(char *argp)
- {
- register char *name ;
- name=strrchr(argp,'/') ;
- if ( name && *(name+1) ) {
- name++ ;
- } else {
- name= argp ;
- }
- callname= name;
- }
- /************************* argument processing ***********************/
- int process(char *arg)
- {
- /* Process files & library arguments */
- trf *phase ;
- register trf *tmp ;
- #ifdef DEBUG
- if ( debug ) vprint("Processing %s\n",arg) ;
- #endif
- p_suffix= strrchr(arg,SUFCHAR) ;
- orig.p_keep= YES ; /* Don't throw away the original ! */
- orig.p_keeps= NO;
- orig.p_path= arg ;
- if ( arg[0]=='-' || !p_suffix ) {
- if ( linker ) add_input(&orig,linker) ;
- return 1 ;
- }
- if ( p_basename ) throws(p_basename) ;
- p_basename= keeps(basename(arg)) ;
- /* Try to find a path through the transformations */
- switch( getpath(&phase) ) {
- case F_NOPATH :
- error("Cannot produce the desired file from %s",arg) ;
- if ( linker ) add_input(&orig,linker) ;
- return 1 ;
- case F_NOMATCH :
- if ( stopsuffix ) werror("Unknown suffix in %s",arg) ;
- if ( linker ) add_input(&orig,linker) ;
- return 1 ;
- case F_OK :
- break ;
- }
- if ( !phase ) return 1 ;
- for ( tmp=phase ; tmp ; tmp=tmp->t_next )
- if ( !tmp->t_visited ) {
- /* The flags are set up once.
- At the first time each phase is in a list.
- The program name and flags may already be touched
- by vieuwargs.
- */
- tmp->t_visited=YES ;
- if ( tmp->t_priority<0 )
- werror("Using phase %s (negative priority)",
- tmp->t_name) ;
- if ( !rts && tmp->t_rts ) rts= tmp->t_rts ;
- if ( tmp->t_needed ) {
- add_head(tmp->t_needed) ;
- add_tail(tmp->t_needed) ;
- }
- }
- if ( phase->t_combine ) {
- add_input(&orig,phase) ;
- return 1 ;
- }
- in= orig ;
- if ( !nill_flag && arg_count > 1 ) {
- printf("%s\n",arg) ;
- }
- return startrf(phase) ;
- }
- int startrf(trf *first)
- {
- /* Start the transformations at the indicated phase */
- register trf *phase ;
- phase=first ;
- for(;;) {
- int do_preprocess = 0;
- int only_prep = 0;
- switch ( phase->t_prep ) {
- /* BEWARE, sign extension */
- case NO : break ;
- default : if ( !mayprep() ) break ;
- case YES: do_preprocess = 1;
- break;
- }
- if ( cpp_trafo && stopsuffix &&
- strcmp(cpp_trafo->t_out,stopsuffix)==0 ) {
- /* user explicitly asked for preprocessing */
- do_preprocess = 1;
- only_prep = 1;
- }
- if (do_preprocess && !transform(cpp_trafo) ) {
- n_error++ ;
- #ifdef DEBUG
- vprint("Pre-processor failed\n") ;
- #endif
- return 0 ;
- }
- if ( only_prep ) {
- break ;
- }
- if ( !transform(phase) ) {
- n_error++ ;
- block(phase->t_next) ;
- #ifdef DEBUG
- if ( debug ) {
- if ( !orig.p_path ) {
- vprint("phase %s failed\n",
- phase->t_name ) ;
- } else {
- vprint("phase %s for %s failed\n",
- phase->t_name,orig.p_path) ;
- }
- }
- #endif
- return 0 ;
- }
- first=NO ;
- phase=phase->t_next ;
- if ( !phase ) {
- #ifdef DEBUG
- if ( debug ) vprint("Transformation sequence complete for %s\n",
- orig.p_path) ;
- #endif
- /* No more work on this file */
- if ( !in.p_keep ) {
- fatal("attempt to discard the result file") ;
- }
- if ( in.p_keeps ) throws(in.p_path) ;
- in.p_keep=NO ; in.p_keeps=NO ; in.p_path= (char *) 0 ;
- return 1 ;
- }
- if ( phase->t_combine ) {
- add_input(&in,phase) ;
- break ;
- }
- }
- return 1 ;
- }
- void block(trf *first)
- {
- /* One of the input files of this phase could not be produced,
- block all combiners taking their input from this one.
- */
- register trf *phase ;
- for ( phase=first ; phase ; phase=phase->t_next ) {
- if ( phase->t_combine ) phase->t_blocked=YES ;
- }
- }
- int mayprep()
- {
- int file ;
- char fc ;
- file=open(in.p_path,0);
- if ( file<0 ) return 0 ;
- if ( read(file,&fc,1)!=1 ) fc=0 ;
- close(file) ;
- return fc=='#' ;
- }
- void keephead(char *suffix)
- {
- l_add(&head_list, suffix) ;
- }
- void keeptail(char *suffix)
- {
- l_add(&tail_list, suffix) ;
- }
- void scanneeds()
- {
- register list_elem *elem ;
- scanlist(l_first(head_list), elem) { setneeds(l_content(*elem),0) ; }
- l_clear(&head_list) ;
- scanlist(l_first(tail_list), elem) { setneeds(l_content(*elem),1) ; }
- l_clear(&tail_list) ;
- }
- void setneeds(char *suffix, int tail)
- {
- trf *phase ;
- p_suffix= suffix ;
- switch ( getpath(&phase) ) {
- case F_OK :
- for ( ; phase ; phase= phase->t_next ) {
- if ( phase->t_needed ) {
- if ( tail )
- add_tail(phase->t_needed) ;
- else
- add_head(phase->t_needed) ;
- }
- }
- break ;
- case F_NOMATCH :
- werror("\"%s\": unrecognized suffix",suffix) ;
- break ;
- case F_NOPATH :
- werror("sorry, cannot produce the desired file(s) from %s files",
- suffix) ;
- break ;
- }
- }
|