scan.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  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".
  4. *
  5. */
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "ack.h"
  9. #include "list.h"
  10. #include "data.h"
  11. #ifndef NORCSID
  12. static char rcs_id[] = "$Id$" ;
  13. #endif
  14. void start_scan();
  15. void scan_found();
  16. void find_cpp();
  17. void try(list_elem *f_scan, char *suffix);
  18. enum f_path getpath(trf **first)
  19. {
  20. /* Try to find a transformation path */
  21. start_scan();
  22. /*
  23. The end result is the chaining of
  24. the consequtive phases with the t_next field.
  25. The list is scanned for possible transformations
  26. stopping at stopsuffix or the last transformation in the list.
  27. The scan flags are set by this process.
  28. When a transformation is found, it is compared with
  29. the last transformation found.
  30. */
  31. try(l_first(tr_list),p_suffix);
  32. return scan_end(first);
  33. }
  34. /******************** data used only while scanning *******************/
  35. static int last_pcount; /* The added priority of
  36. the best path so far */
  37. static int last_ncount; /* The # of non-optimizing transformations
  38. in the best path sofar */
  39. static int last_ocount; /* The # of optimizing transformations in the
  40. best path sofar */
  41. static int suf_found; /* Was the suffix at least recognized ? */
  42. /******************** The hard work ********************/
  43. void start_scan()
  44. {
  45. register list_elem *scan ;
  46. scanlist(l_first(tr_list),scan) {
  47. t_cont(*scan)->t_scan=NO ;
  48. }
  49. suf_found= 0 ;
  50. #ifdef DEBUG
  51. if ( debug>=3 ) vprint("Scan_start\n");
  52. #endif
  53. last_ncount= -1 ;
  54. last_ocount= 0 ;
  55. }
  56. void try(list_elem *f_scan, char *suffix)
  57. {
  58. register list_elem *scan ;
  59. register trf *trafo ;
  60. /* Try to find a transformation path starting at f_scan for a
  61. file with the indicated suffix.
  62. If the suffix is already reached or a combiner is found
  63. call scan_found() to OK the scan.
  64. If a transformation is found it calls itself recursively
  65. with as starting point the next transformation in the list.
  66. */
  67. if ( stopsuffix && *stopsuffix && strcmp(stopsuffix,suffix)==0 ) {
  68. scan_found();
  69. return ;
  70. }
  71. if (! f_scan) return;
  72. scanlist(f_scan, scan) {
  73. trafo= t_cont(*scan) ;
  74. if ( satisfy(trafo,suffix) ) {
  75. /* Found a transformation */
  76. suf_found= 1;
  77. #ifdef DEBUG
  78. if ( debug>=4 ) {
  79. vprint("Found %s for %s: result %s\n",
  80. trafo->t_name,suffix,trafo->t_out);
  81. }
  82. #endif
  83. trafo->t_scan=YES ;
  84. if ( trafo->t_prep ) {
  85. if ( !cpp_trafo ) {
  86. find_cpp() ;
  87. }
  88. if ( stopsuffix &&
  89. strcmp(stopsuffix,
  90. cpp_trafo->t_out)==0 )
  91. {
  92. scan_found() ;
  93. return ;
  94. }
  95. }
  96. if ( trafo->t_next ) {
  97. /* We know what happens from this phase on,
  98. so take a shortcut.
  99. */
  100. register trf *sneak ;
  101. sneak= trafo ;
  102. while( (sneak=sneak->t_next) ) {
  103. sneak->t_scan=YES ;
  104. }
  105. scan_found() ;
  106. sneak= trafo ;
  107. while( (sneak=sneak->t_next) ) {
  108. sneak->t_scan=NO ;
  109. }
  110. return ;
  111. }
  112. if ( trafo->t_linker && stopsuffix && !*stopsuffix ) {
  113. trafo->t_scan=NO ;
  114. scan_found() ;
  115. return ;
  116. }
  117. if (! l_next(*scan) && !stopsuffix) {
  118. scan_found() ;
  119. } else {
  120. try(l_next(*scan),trafo->t_out);
  121. }
  122. trafo->t_scan= NO ;
  123. }
  124. }
  125. }
  126. void scan_found()
  127. {
  128. register list_elem *scan;
  129. int ncount, ocount, pcount ;
  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; pcount=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_optim>Optlevel ) pcount-- ;
  143. pcount += t_cont(*scan)->t_priority ;
  144. }
  145. }
  146. #ifdef DEBUG
  147. if ( debug>=4 ) vprint("\n");
  148. #endif
  149. /* Is this transformation better then any found yet ? */
  150. #ifdef DEBUG
  151. if ( debug>=3 ) {
  152. vprint("old n:%d, o:%d, p:%d - new n:%d, o:%d, p:%d\n",
  153. last_ncount,last_ocount,last_pcount,
  154. ncount,ocount,pcount) ;
  155. }
  156. #endif
  157. if ( last_ncount== -1 || /* None found yet */
  158. last_pcount<pcount || /* Better priority */
  159. ( last_pcount==pcount && /* Same prio, and */
  160. ( last_ncount>ncount || /* Shorter nec. path */
  161. (last_ncount==ncount && /* Same nec. path, optimize?*/
  162. (Optlevel? last_ocount<ocount : last_ocount>ocount ))))) {
  163. /* Yes it is */
  164. #ifdef DEBUG
  165. if ( debug>=3 ) vprint("Better\n");
  166. #endif
  167. scanlist(l_first(tr_list),scan) {
  168. t_cont(*scan)->t_bscan=t_cont(*scan)->t_scan;
  169. }
  170. last_ncount=ncount; last_ocount=ocount; last_pcount=pcount;
  171. }
  172. }
  173. int satisfy(trf *trafo, char *suffix)
  174. {
  175. register char *f_char, *l_char ;
  176. /* Check whether this transformation is present for
  177. the current machine and the parameter suffix is among
  178. the input suffices. If so, return 1. 0 otherwise
  179. */
  180. if ( trafo->t_isprep ) return 0 ;
  181. l_char=trafo->t_in ;
  182. while ( l_char ) {
  183. f_char= l_char ;
  184. if ( *f_char!=SUFCHAR || ! *(f_char+1) ) {
  185. fuerror("Illegal input suffix entry for %s",
  186. trafo->t_name) ;
  187. }
  188. l_char=strchr(f_char+1,SUFCHAR);
  189. if ( l_char ) *l_char = 0;
  190. if ( strcmp(f_char,suffix)==0 ) {
  191. if ( l_char ) *l_char = SUFCHAR;
  192. return 1;
  193. }
  194. if ( l_char ) *l_char = SUFCHAR;
  195. }
  196. return 0 ;
  197. }
  198. enum f_path scan_end(trf **first)
  199. { /* Finalization */
  200. /* Return value indicating whether a transformation was found */
  201. /* Set the flags for the transformation up to, but not including,
  202. the combiner
  203. */
  204. register trf *prev, *curr ;
  205. register list_elem *scan;
  206. #ifdef DEBUG
  207. if ( debug>=3 ) vprint("End_scan\n");
  208. #endif
  209. if ( last_ncount== -1 ) return suf_found ? F_NOPATH : F_NOMATCH ;
  210. #ifdef DEBUG
  211. if ( debug>=2 ) vprint("Transformation found\n");
  212. #endif
  213. prev= (trf *)0 ; *first= prev ;
  214. scanlist(l_first(tr_list),scan) {
  215. curr= t_cont(*scan) ;
  216. if ( curr->t_bscan ) {
  217. if ( prev ) {
  218. prev->t_next= curr ;
  219. if ( curr->t_linker ) prev->t_keep=YES ;
  220. } else {
  221. *first= curr ;
  222. }
  223. if ( curr->t_next ) {
  224. return F_OK ;
  225. }
  226. prev=curr ;
  227. }
  228. }
  229. if ( cpp_trafo && stopsuffix &&
  230. strcmp(stopsuffix,cpp_trafo->t_out)==0 ) {
  231. cpp_trafo->t_keep=YES ;
  232. }
  233. if ( prev ) {
  234. prev->t_keep=YES ;
  235. }
  236. return F_OK ;
  237. }
  238. void find_cpp()
  239. {
  240. register list_elem *elem ;
  241. scanlist( l_first(tr_list), elem ) {
  242. if ( t_cont(*elem)->t_isprep ) {
  243. if ( cpp_trafo ) fuerror("Multiple cpp's present") ;
  244. cpp_trafo= t_cont(*elem) ;
  245. }
  246. }
  247. if ( !cpp_trafo ) fuerror("No cpp present") ;
  248. }