245 lines
6.3 KiB
C
245 lines
6.3 KiB
C
/*
|
|
* (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
*
|
|
* This product is part of the Amsterdam Compiler Kit.
|
|
*
|
|
* Permission to use, sell, duplicate or disclose this software must be
|
|
* obtained in writing. Requests for such permissions may be sent to
|
|
*
|
|
* Dr. Andrew S. Tanenbaum
|
|
* Wiskundig Seminarium
|
|
* Vrije Universiteit
|
|
* Postbox 7161
|
|
* 1007 MC Amsterdam
|
|
* The Netherlands
|
|
*
|
|
*/
|
|
|
|
#include "ack.h"
|
|
#include "list.h"
|
|
#include "trans.h"
|
|
#include "data.h"
|
|
|
|
enum f_path setpath() { /* Try to find a transformation path */
|
|
|
|
start_scan();
|
|
/*
|
|
The end result is the setting of the t_do flags
|
|
in the transformation list.
|
|
The list is scanned for possible transformations
|
|
stopping at stopsuffix or a combine transformation.
|
|
The scan flags are set by this process.
|
|
When a transformation is found, it is compared with
|
|
the last transformation found, if better (or the first)
|
|
the scan bits are copied to the t_do bits, except for
|
|
the combiner which is remembered in a global pointer.
|
|
At the end of all transformations for all files, the combiner
|
|
is called, unless errors occurred.
|
|
*/
|
|
try(l_first(tr_list),p_suffix);
|
|
return scan_end();
|
|
}
|
|
|
|
/******************** data used only while scanning *******************/
|
|
|
|
static int last_ncount; /* The # of non-optimizing transformations
|
|
in the best path sofar */
|
|
|
|
static int last_ocount; /* The # of optimizing transformations in the
|
|
best path sofar */
|
|
static int com_err; /* Complain only once about multiple linkers*/
|
|
|
|
static trf *final; /* The last non-combining transformation */
|
|
|
|
static int suf_found; /* Was the suffix at least recognized ? */
|
|
|
|
/******************** The hard work ********************/
|
|
|
|
start_scan() {
|
|
register list_elem *scan ;
|
|
|
|
scanlist(l_first(tr_list),scan) {
|
|
t_cont(*scan)->t_do=NO ; t_cont(*scan)->t_scan=NO ;
|
|
t_cont(*scan)->t_keep=NO ;
|
|
}
|
|
final= (trf *)0 ;
|
|
suf_found= 0 ;
|
|
#ifdef DEBUG
|
|
if ( debug>=3 ) vprint("Scan_start\n");
|
|
#endif
|
|
last_ncount= -1 ;
|
|
last_ocount= 0 ;
|
|
}
|
|
|
|
try(f_scan,suffix) list_elem *f_scan; char *suffix; {
|
|
register list_elem *scan ;
|
|
register trf *trafo ;
|
|
/* Try to find a transformation path starting at f_scan for a
|
|
file with the indicated suffix.
|
|
If the suffix is already reached or the combiner is found
|
|
call scan_found() to OK the scan.
|
|
If a transformation is found it calls itself recursively
|
|
with as starting point the next transformation in the list.
|
|
*/
|
|
if ( stopsuffix && *stopsuffix && strcmp(stopsuffix,suffix)==0 ) {
|
|
scan_found();
|
|
return ;
|
|
}
|
|
scanlist(f_scan, scan) {
|
|
trafo= t_cont(*scan) ;
|
|
if ( satisfy(trafo,suffix) ) {
|
|
/* Found a transformation */
|
|
suf_found= 1;
|
|
#ifdef DEBUG
|
|
if ( debug>=4 ) {
|
|
vprint("Found %s for %s: result %s\n",
|
|
trafo->t_name,suffix,trafo->t_out);
|
|
}
|
|
#endif
|
|
trafo->t_scan=YES ;
|
|
if ( trafo->t_prep ) {
|
|
if ( !cpp_trafo ) {
|
|
find_cpp() ;
|
|
}
|
|
if ( stopsuffix &&
|
|
strcmp(stopsuffix,
|
|
cpp_trafo->t_out)==0 )
|
|
{
|
|
scan_found() ;
|
|
return ;
|
|
}
|
|
}
|
|
if ( trafo->t_combine ) {
|
|
if ( stopsuffix ) {
|
|
trafo->t_scan=NO;
|
|
if ( *stopsuffix ) return ;
|
|
} else {
|
|
if( combiner &&
|
|
combiner!=trafo && !com_err ){
|
|
com_err++ ;
|
|
werror("Multiple linkers present %s and %s",
|
|
trafo->t_name,combiner->t_name) ;
|
|
} else {
|
|
combiner=trafo;
|
|
}
|
|
}
|
|
scan_found() ;
|
|
} else {
|
|
try(l_next(*scan),trafo->t_out);
|
|
}
|
|
trafo->t_scan= NO ;
|
|
}
|
|
}
|
|
}
|
|
|
|
scan_found() {
|
|
register list_elem *scan;
|
|
int ncount, ocount ;
|
|
register trf *keepit ;
|
|
|
|
keepit= (trf *)0 ;
|
|
suf_found= 1;
|
|
#ifdef DEBUG
|
|
if ( debug>=3 ) vprint("Scan found\n") ;
|
|
#endif
|
|
/* Gather data used in comparison */
|
|
ncount=0; ocount=0;
|
|
scanlist(l_first(tr_list),scan) {
|
|
if (t_cont(*scan)->t_scan) {
|
|
#ifdef DEBUG
|
|
if ( debug>=4 ) vprint("%s-",t_cont(*scan)->t_name) ;
|
|
#endif
|
|
if( t_cont(*scan)->t_optim ) ocount++ ;else ncount++ ;
|
|
if ( !(t_cont(*scan)->t_combine) ) {
|
|
keepit= t_cont(*scan) ;
|
|
}
|
|
}
|
|
}
|
|
#ifdef DEBUG
|
|
if ( debug>=4 ) vprint("\n");
|
|
#endif
|
|
/* Is this transformation better then any found yet ? */
|
|
#ifdef DEBUG
|
|
if ( debug>=3 ) {
|
|
vprint("old n:%d, o:%d - new n:%d, o:%d\n",
|
|
last_ncount,last_ocount,ncount,ocount) ;
|
|
}
|
|
#endif
|
|
if ( last_ncount== -1 || /* None found yet */
|
|
last_ncount>ncount || /* Shorter nec. path */
|
|
(last_ncount==ncount && /* Same nec. path, optimize?*/
|
|
(Optflag? last_ocount<ocount : last_ocount>ocount ) ) ) {
|
|
/* Yes it is */
|
|
#ifdef DEBUG
|
|
if ( debug>=3 ) vprint("Better\n");
|
|
#endif
|
|
scanlist(l_first(tr_list),scan) {
|
|
t_cont(*scan)->t_do=t_cont(*scan)->t_scan;
|
|
}
|
|
last_ncount=ncount; last_ocount=ocount;
|
|
if ( keepit ) final=keepit ;
|
|
}
|
|
}
|
|
|
|
int satisfy(trafo,suffix) register trf *trafo; char *suffix ; {
|
|
register char *f_char, *l_char ;
|
|
/* Check whether this transformation is present for
|
|
the current machine and the parameter suffix is among
|
|
the input suffices. If so, return 1. 0 otherwise
|
|
*/
|
|
if ( trafo->t_isprep ) return 0 ;
|
|
l_char=trafo->t_in ;
|
|
while ( l_char ) {
|
|
f_char= l_char ;
|
|
if ( *f_char!=SUFCHAR || ! *(f_char+1) ) {
|
|
fuerror("Illegal input suffix entry for %s",
|
|
trafo->t_name) ;
|
|
}
|
|
l_char=index(f_char+1,SUFCHAR);
|
|
if ( l_char ? strncmp(f_char,suffix,l_char-f_char)==0 :
|
|
strcmp(f_char,suffix)==0 ) {
|
|
return 1 ;
|
|
}
|
|
}
|
|
return 0 ;
|
|
}
|
|
|
|
enum f_path scan_end() { /* Finalization */
|
|
/* Return value indicating whether a transformation was found */
|
|
/* Set the flags for the transformation up to, but not including,
|
|
the combiner
|
|
*/
|
|
|
|
#ifdef DEBUG
|
|
if ( debug>=3 ) vprint("End_scan\n");
|
|
#endif
|
|
if ( last_ncount== -1 ) return suf_found ? F_NOPATH : F_NOMATCH ;
|
|
#ifdef DEBUG
|
|
if ( debug>=2 ) vprint("Transformation found\n");
|
|
#endif
|
|
if ( cpp_trafo && stopsuffix &&
|
|
strcmp(stopsuffix,cpp_trafo->t_out)==0 ) {
|
|
final= cpp_trafo ;
|
|
}
|
|
/* There might not be a final when the file can be eaten
|
|
by the combiner
|
|
*/
|
|
if ( final ) final->t_keep=YES ;
|
|
if ( combiner ) {
|
|
if ( !combiner->t_do ) error("Combiner YES/NO");
|
|
combiner->t_do=NO ;
|
|
}
|
|
return F_OK ;
|
|
}
|
|
|
|
find_cpp() {
|
|
register list_elem *elem ;
|
|
scanlist( l_first(tr_list), elem ) {
|
|
if ( t_cont(*elem)->t_isprep ) {
|
|
if ( cpp_trafo ) fuerror("Multiple cpp's present") ;
|
|
cpp_trafo= t_cont(*elem) ;
|
|
}
|
|
}
|
|
if ( !cpp_trafo ) fuerror("No cpp present") ;
|
|
}
|