scan.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. *
  4. * This product is part of the Amsterdam Compiler Kit.
  5. *
  6. * Permission to use, sell, duplicate or disclose this software must be
  7. * obtained in writing. Requests for such permissions may be sent to
  8. *
  9. * Dr. Andrew S. Tanenbaum
  10. * Wiskundig Seminarium
  11. * Vrije Universiteit
  12. * Postbox 7161
  13. * 1007 MC Amsterdam
  14. * The Netherlands
  15. *
  16. */
  17. #include "ack.h"
  18. #include "list.h"
  19. #include "trans.h"
  20. #include "data.h"
  21. #ifndef NORCSID
  22. static char rcs_id[] = "$Header$" ;
  23. #endif
  24. enum f_path setpath() { /* Try to find a transformation path */
  25. start_scan();
  26. /*
  27. The end result is the setting of the t_do flags
  28. in the transformation list.
  29. The list is scanned for possible transformations
  30. stopping at stopsuffix or a combine transformation.
  31. The scan flags are set by this process.
  32. When a transformation is found, it is compared with
  33. the last transformation found, if better (or the first)
  34. the scan bits are copied to the t_do bits, except for
  35. the combiner which is remembered in a global pointer.
  36. At the end of all transformations for all files, the combiner
  37. is called, unless errors occurred.
  38. */
  39. try(l_first(tr_list),p_suffix);
  40. return scan_end();
  41. }
  42. /******************** data used only while scanning *******************/
  43. static int last_ncount; /* The # of non-optimizing transformations
  44. in the best path sofar */
  45. static int last_ocount; /* The # of optimizing transformations in the
  46. best path sofar */
  47. static int com_err; /* Complain only once about multiple linkers*/
  48. static trf *final; /* The last non-combining transformation */
  49. static int suf_found; /* Was the suffix at least recognized ? */
  50. /******************** The hard work ********************/
  51. start_scan() {
  52. register list_elem *scan ;
  53. scanlist(l_first(tr_list),scan) {
  54. t_cont(*scan)->t_do=NO ; t_cont(*scan)->t_scan=NO ;
  55. t_cont(*scan)->t_keep=NO ;
  56. }
  57. final= (trf *)0 ;
  58. suf_found= 0 ;
  59. #ifdef DEBUG
  60. if ( debug>=3 ) vprint("Scan_start\n");
  61. #endif
  62. last_ncount= -1 ;
  63. last_ocount= 0 ;
  64. }
  65. try(f_scan,suffix) list_elem *f_scan; char *suffix; {
  66. register list_elem *scan ;
  67. register trf *trafo ;
  68. /* Try to find a transformation path starting at f_scan for a
  69. file with the indicated suffix.
  70. If the suffix is already reached or the combiner is found
  71. call scan_found() to OK the scan.
  72. If a transformation is found it calls itself recursively
  73. with as starting point the next transformation in the list.
  74. */
  75. if ( stopsuffix && *stopsuffix && strcmp(stopsuffix,suffix)==0 ) {
  76. scan_found();
  77. return ;
  78. }
  79. scanlist(f_scan, scan) {
  80. trafo= t_cont(*scan) ;
  81. if ( satisfy(trafo,suffix) ) {
  82. /* Found a transformation */
  83. suf_found= 1;
  84. #ifdef DEBUG
  85. if ( debug>=4 ) {
  86. vprint("Found %s for %s: result %s\n",
  87. trafo->t_name,suffix,trafo->t_out);
  88. }
  89. #endif
  90. trafo->t_scan=YES ;
  91. if ( trafo->t_prep ) {
  92. if ( !cpp_trafo ) {
  93. find_cpp() ;
  94. }
  95. if ( stopsuffix &&
  96. strcmp(stopsuffix,
  97. cpp_trafo->t_out)==0 )
  98. {
  99. scan_found() ;
  100. return ;
  101. }
  102. }
  103. if ( trafo->t_combine ) {
  104. if ( stopsuffix ) {
  105. trafo->t_scan=NO;
  106. if ( *stopsuffix ) return ;
  107. } else {
  108. if( combiner &&
  109. combiner!=trafo && !com_err ){
  110. com_err++ ;
  111. werror("Multiple linkers present %s and %s",
  112. trafo->t_name,combiner->t_name) ;
  113. } else {
  114. combiner=trafo;
  115. }
  116. }
  117. scan_found() ;
  118. } else {
  119. try(l_next(*scan),trafo->t_out);
  120. }
  121. trafo->t_scan= NO ;
  122. }
  123. }
  124. }
  125. scan_found() {
  126. register list_elem *scan;
  127. int ncount, ocount ;
  128. register trf *keepit ;
  129. keepit= (trf *)0 ;
  130. suf_found= 1;
  131. #ifdef DEBUG
  132. if ( debug>=3 ) vprint("Scan found\n") ;
  133. #endif
  134. /* Gather data used in comparison */
  135. ncount=0; ocount=0;
  136. scanlist(l_first(tr_list),scan) {
  137. if (t_cont(*scan)->t_scan) {
  138. #ifdef DEBUG
  139. if ( debug>=4 ) vprint("%s-",t_cont(*scan)->t_name) ;
  140. #endif
  141. if( t_cont(*scan)->t_optim ) ocount++ ;else ncount++ ;
  142. if ( !(t_cont(*scan)->t_combine) ) {
  143. keepit= t_cont(*scan) ;
  144. }
  145. }
  146. }
  147. #ifdef DEBUG
  148. if ( debug>=4 ) vprint("\n");
  149. #endif
  150. /* Is this transformation better then any found yet ? */
  151. #ifdef DEBUG
  152. if ( debug>=3 ) {
  153. vprint("old n:%d, o:%d - new n:%d, o:%d\n",
  154. last_ncount,last_ocount,ncount,ocount) ;
  155. }
  156. #endif
  157. if ( last_ncount== -1 || /* None found yet */
  158. last_ncount>ncount || /* Shorter nec. path */
  159. (last_ncount==ncount && /* Same nec. path, optimize?*/
  160. (Optflag? last_ocount<ocount : last_ocount>ocount ) ) ) {
  161. /* Yes it is */
  162. #ifdef DEBUG
  163. if ( debug>=3 ) vprint("Better\n");
  164. #endif
  165. scanlist(l_first(tr_list),scan) {
  166. t_cont(*scan)->t_do=t_cont(*scan)->t_scan;
  167. }
  168. last_ncount=ncount; last_ocount=ocount;
  169. if ( keepit ) final=keepit ;
  170. }
  171. }
  172. int satisfy(trafo,suffix) register trf *trafo; char *suffix ; {
  173. register char *f_char, *l_char ;
  174. /* Check whether this transformation is present for
  175. the current machine and the parameter suffix is among
  176. the input suffices. If so, return 1. 0 otherwise
  177. */
  178. if ( trafo->t_isprep ) return 0 ;
  179. l_char=trafo->t_in ;
  180. while ( l_char ) {
  181. f_char= l_char ;
  182. if ( *f_char!=SUFCHAR || ! *(f_char+1) ) {
  183. fuerror("Illegal input suffix entry for %s",
  184. trafo->t_name) ;
  185. }
  186. l_char=index(f_char+1,SUFCHAR);
  187. if ( l_char ? strncmp(f_char,suffix,l_char-f_char)==0 :
  188. strcmp(f_char,suffix)==0 ) {
  189. return 1 ;
  190. }
  191. }
  192. return 0 ;
  193. }
  194. enum f_path scan_end() { /* Finalization */
  195. /* Return value indicating whether a transformation was found */
  196. /* Set the flags for the transformation up to, but not including,
  197. the combiner
  198. */
  199. #ifdef DEBUG
  200. if ( debug>=3 ) vprint("End_scan\n");
  201. #endif
  202. if ( last_ncount== -1 ) return suf_found ? F_NOPATH : F_NOMATCH ;
  203. #ifdef DEBUG
  204. if ( debug>=2 ) vprint("Transformation found\n");
  205. #endif
  206. if ( cpp_trafo && stopsuffix &&
  207. strcmp(stopsuffix,cpp_trafo->t_out)==0 ) {
  208. final= cpp_trafo ;
  209. }
  210. /* There might not be a final when the file can be eaten
  211. by the combiner
  212. */
  213. if ( final ) final->t_keep=YES ;
  214. if ( combiner ) {
  215. if ( !combiner->t_do ) error("Combiner YES/NO");
  216. combiner->t_do=NO ;
  217. }
  218. return F_OK ;
  219. }
  220. find_cpp() {
  221. register list_elem *elem ;
  222. scanlist( l_first(tr_list), elem ) {
  223. if ( t_cont(*elem)->t_isprep ) {
  224. if ( cpp_trafo ) fuerror("Multiple cpp's present") ;
  225. cpp_trafo= t_cont(*elem) ;
  226. }
  227. }
  228. if ( !cpp_trafo ) fuerror("No cpp present") ;
  229. }