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".
17 static char rcs_id[] = "$Id: rmach.c,v 2.17 1994/06/24 10:13:02 ceriel Exp $" ;
18 static char rcs_dmach[] = RCS_DMACH ;
21 /************************************************************************/
23 /* Read machine definitions and transformations */
25 /************************************************************************/
34 #define PROG "program"
35 #define MAPF "mapflag"
37 #define STD_IN "stdin"
38 #define STD_OUT "stdout"
40 #define OPT "optimizer"
41 #define LINKER "linker"
42 #define COMBINER "combiner"
43 #define PRIO "priority"
46 #define CALL "callname"
49 extern growstring scanb();
50 extern growstring scanvars();
54 static char *ty_name ;
60 setlist(name) char *name ; {
61 /* Name is sought in the internal tables,
62 if not present, the a file of that name is sought
63 in first the current and then the EM Lib directory
68 while ( _getline() ) {
69 if ( strcmp(VAR,ty_name)==0 ) {
70 doassign(bol,(char *)0,0) ;
72 if ( strcmp(CALL,ty_name)==0 ) {
73 if ( callname && strcmp(bol,callname)==0 ) {
77 vprint("found call name\n");
82 if ( strcmp(PASS,ty_name)==0 ) {
85 error("unknown keyword %s",ty_name) ;
89 if ( debug>=3 ) vprint("End %s\n",name) ;
93 static int inoptlist(nm)
96 register char *p=Optlist ;
101 while ( *q!='\0' && *q++==*p ) p++ ;
102 if ( *q=='\0' && ( *p=='\0' || *p==',' ) ) return 1 ;
103 while ( *p!='\0' && *p++!=',' ) /* nothing */ ;
114 new= (trf *)getcore(sizeof *new) ;
115 new->t_name= keeps(bol) ;
118 fuerror("unexpected EOF on %s",inname) ;
121 if ( strcmp(ty_name,IN)==0 ) {
122 if ( new->t_in ) twice=YES ;
123 new->t_in= keeps(bol);
125 if ( strcmp(ty_name,OUT)==0 ) {
126 if ( new->t_out ) twice=YES ;
127 new->t_out= keeps(bol);
129 if ( strcmp(ty_name,PROG)==0 ) {
130 if ( new->t_prog ) twice=YES ;
131 bline= scanb(bol); /* Scan for \ */
132 new->t_prog= gr_final(&bline);
134 if ( strcmp(ty_name,MAPF)==0 ) {
135 /* First read the mapflags line
136 and scan for backslashes */
138 l_add(&new->t_mapf,gr_final(&bline)) ;
140 if ( strcmp(ty_name,ARGS)==0 ) {
141 if ( new->t_argd ) twice=YES ;
143 new->t_argd= keeps(gr_start(bline)) ;
146 if ( strcmp(ty_name,STD_IN)==0 ) {
147 if ( new->t_stdin ) twice=YES ;
150 if ( strcmp(ty_name,STD_OUT)==0 ) {
151 if ( new->t_stdout ) twice=YES ;
154 if ( strcmp(ty_name,PREP)==0 ) {
155 if ( strcmp(bol,"always")==0 ) {
156 if ( new->t_prep ) twice=YES ;
159 if ( strcmp(bol,"cond")==0 ) {
160 if ( new->t_prep ) twice=YES ;
163 if ( strcmp(bol,"is")==0 ) {
164 if ( new->t_isprep ) twice=YES ;
168 fuerror("illegal preprocessor spec in %s: %s",
172 if ( strcmp(ty_name,OPT)==0 ) {
173 if ( new->t_optim ) twice=YES ;
174 new->t_optim= atoi(bol) ;
175 if (new->t_optim <= 0) new->t_optim = 1;
177 if ( strcmp(ty_name,LINKER)==0 ) {
178 if ( new->t_linker ) twice=YES ;
180 new->t_combine= YES ;
182 if ( strcmp(ty_name,COMBINER)==0 ) {
183 if ( new->t_combine ) twice=YES ;
184 new->t_combine= YES ;
186 if ( strcmp(ty_name,PRIO)==0 ) {
187 new->t_priority= atoi(bol) ;
189 if ( strcmp(ty_name,RUNT)==0 ) {
190 if ( new->t_rts ) twice=YES ;
191 new->t_rts= keeps(bol) ;
193 if ( strcmp(ty_name,NEEDT)==0 ) {
194 if ( new->t_needed ) twice=YES ;
195 new->t_needed= keeps(bol) ;
197 if ( strcmp(ty_name,RES)==0 ) {
198 if ( new->t_outfile ) twice=YES ;
199 new->t_outfile= keeps(bol) ;
201 if ( strcmp(ty_name,CALL)==0 ) {
202 if ( callname && strcmp(bol,callname)==0 ) {
204 callname= (char *)0 ;
207 vprint("found call name in %s\n",
213 if ( strcmp(ty_name,END)==0 ) {
216 fuerror("illegal keyword %s %s",ty_name,bol);
219 werror("%s: specified twice for %s",
220 ty_name, new->t_name) ;
223 if ( ! ( new->t_name && new->t_out && new->t_prog ) ) {
224 fuerror("insufficient specification for %s in %s",
225 new->t_name,inname) ;
227 if ( ! new->t_argd ) new->t_argd="" ;
228 /* Warning, side effect */
229 if ( name_seen && new->t_rts ) {
230 if ( rts && strcmp(rts,new->t_rts)!=0 ) {
231 error("Attempt to use two run-time systems, %s and %s",
235 keephead(rts) ; keeptail(rts) ;
239 register list_elem *elem ;
240 vprint("%s: from %s to %s '%s'\n",
241 new->t_name,new->t_in ? new->t_in : "(null)",new->t_out,new->t_prog) ;
242 vprint("\targs: ") ; prns(new->t_argd) ;
243 scanlist( l_first(new->t_mapf), elem ) {
244 vprint("\t%s\n",l_content(*elem)) ;
246 if ( new->t_rts ) vprint("\trts: %s\n",new->t_rts) ;
247 if ( new->t_needed ) vprint("\tneeded: %s\n",new->t_needed) ;
251 ( new->t_optim <= Optlevel || inoptlist(new->t_name) ) ) {
252 new->t_optim = Optlevel;
254 l_add(&tr_list,(char *)new) ;
257 /************************** IO from core or file *******************/
260 static growstring rline ;
261 static FILE *infile ;
263 char *em_dir = EM_DIR;
265 open_in(name) register char *name ; {
266 register dmach *cmac ;
269 for ( cmac= massoc ; cmac->ma_index!= -1 ; cmac++ ) {
270 if ( strcmp(name,cmac->ma_name)==0 ) {
272 inptr= &intable[cmac->ma_index] ;
278 /* Try to read EM_DIR/lib/MACH/descr */
279 gr_cat(&rline,em_dir) ;
280 gr_cat(&rline,"/lib/") ; gr_cat(&rline,name) ;
281 gr_cat(&rline,"/descr") ;
282 infile= fopen(gr_start(rline),"r") ;
285 gr_cat(&rline,em_dir) ; gr_cat(&rline,"/") ;
286 gr_cat(&rline,ACK_PATH); gr_cat(&rline,"/") ;
287 gr_cat(&rline,name) ;
288 infile= fopen(gr_start(rline),"r") ;
291 infile= fopen(name,"r") ;
293 if ( infile==NULL ) {
294 fuerror("Cannot find description for %s",name) ;
299 if ( !incore ) fclose(infile) ;
304 /* Get a line from the input,
306 The line is stored in a volatile buffer,
307 a pointer to the line is returned.
310 enum { BOL, ESCAPE, SKIPPING, MOL } state = BOL ;
317 werror("incomplete line in %s", inname) ;
321 if ( state==SKIPPING ) {
328 if ( state==ESCAPE ) {
333 gr_add(&rline,BSLASH) ;
336 gr_add(&rline,nchar) ;
343 case '\n' : gr_add(&rline,0) ;
344 return gr_start(rline) ;
345 case COMMENT : state= SKIPPING ;
347 case BSLASH : state= ESCAPE ;
349 default : gr_add(&rline,nchar) ;
359 if ( *inptr==0 ) return EOF ;
362 token= getc(infile) ;
363 if ( (token>=0177 || token <=0 ) && token !=EOF ) {
364 fuerror("Non-ascii character in description file %s",inname);
370 register char *c_ptr ;
373 if ( (c_ptr=readline())==(char *)0 ) return 0 ;
374 ty_name= skipblank(c_ptr) ;
375 } while ( *ty_name==0 ) ;
376 c_ptr= firstblank(ty_name) ;
379 c_ptr= skipblank(c_ptr) ;