123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- /*
- * (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 <string.h>
- #include "ack.h"
- #include <em_path.h>
- #include "list.h"
- #include "trans.h"
- #include "grows.h"
- #include "dmach.h"
- #include "data.h"
- #include <stdio.h>
- /************************************************************************/
- /* */
- /* Read machine definitions and transformations */
- /* */
- /************************************************************************/
- #define COMMENT '#'
- #define VAR "var"
- #define PASS "name"
- #define IN "from"
- #define OUT "to"
- #define RES "outfile"
- #define PROG "program"
- #define MAPF "mapflag"
- #define ARGS "args"
- #define STD_IN "stdin"
- #define STD_OUT "stdout"
- #define PREP "prep"
- #define OPT "optimizer"
- #define LINKER "linker"
- #define COMBINER "combiner"
- #define PRIO "priority"
- #define RUNT "rts"
- #define NEEDT "need"
- #define CALL "callname"
- #define END "end"
- static char *ty_name ;
- static char *bol ;
- static char *inname ;
- void setlist(char *name)
- {
- /* Name is sought in the internal tables,
- if not present, the a file of that name is sought
- in first the current and then the EM Lib directory
- */
- inname=name ;
- open_in(name) ;
- while ( getln() ) {
- if ( strcmp(VAR,ty_name)==0 ) {
- doassign(bol,(char *)0,0) ;
- } else
- if ( strcmp(CALL,ty_name)==0 ) {
- if ( callname && strcmp(bol,callname)==0 ) {
- callname= (char *)0 ;
- #ifdef DEBUG
- if ( debug>=3 ) {
- vprint("found call name\n");
- }
- #endif
- }
- } else
- if ( strcmp(PASS,ty_name)==0 ) {
- intrf() ;
- } else
- error("unknown keyword %s",ty_name) ;
- }
- close_in();
- #ifdef DEBUG
- if ( debug>=3 ) vprint("End %s\n",name) ;
- #endif
- }
- static int inoptlist(char *nm)
- {
- register char *p=Optlist ;
- while ( p && *p ) {
- register char *q=nm ;
- while ( *q!='\0' && *q++==*p ) p++ ;
- if ( *q=='\0' && ( *p=='\0' || *p==',' ) ) return 1 ;
- while ( *p!='\0' && *p++!=',' ) /* nothing */ ;
- }
- return 0;
- }
- void intrf()
- {
- register trf *new ;
- growstring bline ;
- int twice ;
- int name_seen=0 ;
- new= (trf *)getcore(sizeof *new) ;
- new->t_name= keeps(bol) ;
- for (;;) {
- if ( !getln() ) {
- fuerror("unexpected EOF on %s",inname) ;
- }
- twice= NO ;
- if ( strcmp(ty_name,IN)==0 ) {
- if ( new->t_in ) twice=YES ;
- new->t_in= keeps(bol);
- } else
- if ( strcmp(ty_name,OUT)==0 ) {
- if ( new->t_out ) twice=YES ;
- new->t_out= keeps(bol);
- } else
- if ( strcmp(ty_name,PROG)==0 ) {
- if ( new->t_prog ) twice=YES ;
- bline= scanb(bol); /* Scan for \ */
- new->t_prog= gr_final(&bline);
- } else
- if ( strcmp(ty_name,MAPF)==0 ) {
- /* First read the mapflags line
- and scan for backslashes */
- bline= scanb(bol) ;
- l_add(&new->t_mapf,gr_final(&bline)) ;
- } else
- if ( strcmp(ty_name,ARGS)==0 ) {
- if ( new->t_argd ) twice=YES ;
- bline= scanb(bol) ;
- new->t_argd= keeps(gr_start(bline)) ;
- gr_throw(&bline) ;
- } else
- if ( strcmp(ty_name,STD_IN)==0 ) {
- if ( new->t_stdin ) twice=YES ;
- new->t_stdin= YES ;
- } else
- if ( strcmp(ty_name,STD_OUT)==0 ) {
- if ( new->t_stdout ) twice=YES ;
- new->t_stdout= YES ;
- } else
- if ( strcmp(ty_name,PREP)==0 ) {
- if ( strcmp(bol,"always")==0 ) {
- if ( new->t_prep ) twice=YES ;
- new->t_prep=YES ;
- } else
- if ( strcmp(bol,"cond")==0 ) {
- if ( new->t_prep ) twice=YES ;
- new->t_prep=MAYBE ;
- } else
- if ( strcmp(bol,"is")==0 ) {
- if ( new->t_isprep ) twice=YES ;
- new->t_isprep= YES ;
- } else
- {
- fuerror("illegal preprocessor spec in %s: %s",
- inname,bol) ;
- }
- } else
- if ( strcmp(ty_name,OPT)==0 ) {
- if ( new->t_optim ) twice=YES ;
- new->t_optim= atoi(bol) ;
- if (new->t_optim <= 0) new->t_optim = 1;
- } else
- if ( strcmp(ty_name,LINKER)==0 ) {
- if ( new->t_linker ) twice=YES ;
- new->t_linker= YES ;
- new->t_combine= YES ;
- } else
- if ( strcmp(ty_name,COMBINER)==0 ) {
- if ( new->t_combine ) twice=YES ;
- new->t_combine= YES ;
- } else
- if ( strcmp(ty_name,PRIO)==0 ) {
- new->t_priority= atoi(bol) ;
- } else
- if ( strcmp(ty_name,RUNT)==0 ) {
- if ( new->t_rts ) twice=YES ;
- new->t_rts= keeps(bol) ;
- } else
- if ( strcmp(ty_name,NEEDT)==0 ) {
- if ( new->t_needed ) twice=YES ;
- new->t_needed= keeps(bol) ;
- } else
- if ( strcmp(ty_name,RES)==0 ) {
- if ( new->t_outfile ) twice=YES ;
- new->t_outfile= keeps(bol) ;
- } else
- if ( strcmp(ty_name,CALL)==0 ) {
- if ( callname && strcmp(bol,callname)==0 ) {
- name_seen=1 ;
- callname= (char *)0 ;
- #ifdef DEBUG
- if ( debug>=3 ) {
- vprint("found call name in %s\n",
- new->t_name) ;
- }
- #endif
- }
- } else
- if ( strcmp(ty_name,END)==0 ) {
- break ;
- } else {
- fuerror("illegal keyword %s %s",ty_name,bol);
- }
- if ( twice ) {
- werror("%s: specified twice for %s",
- ty_name, new->t_name) ;
- }
- }
- if ( ! ( new->t_name && new->t_out && new->t_prog ) ) {
- fuerror("insufficient specification for %s in %s",
- new->t_name,inname) ;
- }
- if ( ! new->t_argd ) new->t_argd="" ;
- /* Warning, side effect */
- if ( name_seen && new->t_rts ) {
- if ( rts && strcmp(rts,new->t_rts)!=0 ) {
- error("Attempt to use two run-time systems, %s and %s",
- rts, new->t_rts) ;
- }
- rts= new->t_rts ;
- keephead(rts) ; keeptail(rts) ;
- }
- #ifdef DEBUG
- if ( debug>=3 ) {
- register list_elem *elem ;
- vprint("%s: from %s to %s '%s'\n",
- new->t_name,new->t_in ? new->t_in : "(null)",new->t_out,new->t_prog) ;
- vprint("\targs: ") ; prns(new->t_argd) ;
- scanlist( l_first(new->t_mapf), elem ) {
- vprint("\t%s\n",l_content(*elem)) ;
- }
- if ( new->t_rts ) vprint("\trts: %s\n",new->t_rts) ;
- if ( new->t_needed ) vprint("\tneeded: %s\n",new->t_needed) ;
- }
- #endif
- if ( new->t_optim &&
- ( new->t_optim <= Optlevel || inoptlist(new->t_name) ) ) {
- new->t_optim = Optlevel;
- }
- l_add(&tr_list,(char *)new) ;
- }
- /************************** IO from core or file *******************/
- static int incore ;
- static growstring rline ;
- static FILE *infile ;
- static char *inptr ;
- char *em_dir = EM_DIR;
- void open_in(char *name)
- {
- register dmach *cmac ;
- gr_init(&rline) ;
- for ( cmac= massoc ; cmac->ma_index!= -1 ; cmac++ ) {
- if ( strcmp(name,cmac->ma_name)==0 ) {
- incore=YES ;
- inptr= &intable[cmac->ma_index] ;
- return ;
- }
- }
- /* Not in core */
- incore= NO ;
- /* Try to read EM_DIR/lib/MACH/descr */
- gr_cat(&rline,em_dir) ;
- gr_cat(&rline,"/lib/") ; gr_cat(&rline,name) ;
- gr_cat(&rline,"/descr") ;
- infile= fopen(gr_start(rline),"r") ;
- if ( !infile ) {
- gr_throw(&rline) ;
- gr_cat(&rline,em_dir) ; gr_cat(&rline,"/") ;
- gr_cat(&rline,ACK_PATH); gr_cat(&rline,"/") ;
- gr_cat(&rline,name) ;
- infile= fopen(gr_start(rline),"r") ;
- }
- if ( !infile ) {
- infile= fopen(name,"r") ;
- }
- if ( infile==NULL ) {
- fuerror("Cannot find description for %s",name) ;
- }
- }
- void close_in()
- {
- if ( !incore ) fclose(infile) ;
- gr_throw(&rline) ;
- }
- char *readline()
- {
- /* Get a line from the input,
- return 0 if at end,
- The line is stored in a volatile buffer,
- a pointer to the line is returned.
- */
- register int nchar ;
- enum { BOL, ESCAPE, SKIPPING, MOL } state = BOL ;
- gr_throw(&rline) ;
- for (;;) {
- nchar= getinchar() ;
- if ( nchar==EOF ) {
- if ( state!=BOL ) {
- werror("incomplete line in %s", inname) ;
- }
- return 0 ;
- }
- if ( state==SKIPPING ) {
- if ( nchar=='\n' ) {
- state= MOL ;
- } else {
- continue ;
- }
- }
- if ( state==ESCAPE ) {
- switch( nchar ) {
- case '\n' :
- break ;
- default :
- gr_add(&rline,BSLASH) ;
- case COMMENT :
- case BSLASH :
- gr_add(&rline,nchar) ;
- break ;
- }
- state= MOL ;
- continue ;
- }
- switch ( nchar ) {
- case '\n' : gr_add(&rline,0) ;
- return gr_start(rline) ;
- case COMMENT : state= SKIPPING ;
- break ;
- case BSLASH : state= ESCAPE ;
- break ;
- default : gr_add(&rline,nchar) ;
- state= MOL ;
- }
- }
- }
- int getinchar()
- {
- int token ;
- if ( incore ) {
- if ( *inptr==0 ) return EOF ;
- return *inptr++ ;
- }
- token= getc(infile) ;
- if ( (token>=0177 || token <=0 ) && token !=EOF ) {
- fuerror("Non-ascii character in description file %s",inname);
- }
- return token ;
- }
- int getln()
- {
- char *c_ptr ;
- do {
- if ( (c_ptr=readline())==(char *)0 ) return 0 ;
- ty_name= skipblank(c_ptr) ;
- } while ( *ty_name==0 ) ;
- c_ptr= firstblank(ty_name) ;
- if ( *c_ptr ) {
- *c_ptr++ =0 ;
- c_ptr= skipblank(c_ptr) ;
- }
- bol= c_ptr ;
- return 1 ;
- }
|