home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / gcc / genmultilib < prev    next >
Text File  |  1995-10-20  |  8KB  |  232 lines

  1. #!/bin/sh 
  2. # Generates multilib.h.
  3. #   Copyright (C) 1994, 1995 Free Software Foundation, Inc.
  4.  
  5. #This file is part of GNU CC.
  6.  
  7. #GNU CC is free software; you can redistribute it and/or modify
  8. #it under the terms of the GNU General Public License as published by
  9. #the Free Software Foundation; either version 2, or (at your option)
  10. #any later version.
  11.  
  12. #GNU CC is distributed in the hope that it will be useful,
  13. #but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. #GNU General Public License for more details.
  16.  
  17. #You should have received a copy of the GNU General Public License
  18. #along with GNU CC; see the file COPYING.  If not, write to
  19. #the Free Software Foundation, 59 Temple Place - Suite 330,
  20. #Boston, MA 02111-1307, USA.
  21.  
  22. # This shell script produces a header file which the gcc driver
  23. # program uses to pick which library to use based on the machine
  24. # specific options that it is given.
  25.  
  26. # The first argument is a list of sets of options.  The elements in
  27. # the list are separated by spaces.  Within an element, the options
  28. # are separated by slashes.  No leading dash is used on the options.
  29. # Each option in a set is mutually incompatible with all other options
  30. # in the set.
  31.  
  32. # The optional second argument is a list of subdirectory names.  If
  33. # the second argument is non-empty, there must be as many elements in
  34. # the second argument as there are options in the first argument.  The
  35. # elements in the second list are separated by spaces.  If the second
  36. # argument is empty, the option names will be used as the directory
  37. # names.
  38.  
  39. # The optional third argument is a list of options which are
  40. # identical.  The elements in the list are separated by spaces.  Each
  41. # element must be of the form OPTION=OPTION.  The first OPTION should
  42. # appear in the first argument, and the second should be a synonym for
  43. # it.  Question marks are replaced with equal signs in both options.
  44.  
  45. # The output looks like
  46. #   #define MULTILIB_MATCHES "\
  47. #   SUBDIRECTORY OPTIONS;\
  48. #   ...
  49. #   "
  50. # The SUBDIRECTORY is the subdirectory to use.  The OPTIONS are
  51. # multiple options separated by spaces.  Each option may start with an
  52. # exclamation point.  gcc will consider each line in turn.  If none of
  53. # the options beginning with an exclamation point are present, and all
  54. # of the other options are present, that subdirectory will be used.
  55. # The order of the subdirectories is such that they can be created in
  56. # order; that is, a subdirectory is preceded by all its parents.
  57.  
  58. # Here is a example (this is simplified from the actual 680x0 case):
  59. #   genmultilib "m68000/m68020 msoft-float" "m68000 m68020 msoft-float"
  60. #        "m68000=mc68000"
  61. # This produces:
  62. #   #define MULTILIB_SELECT "\
  63. #   . !m68000 !mc68000 !m68020 !msoft-float;\
  64. #   m68000 m68000 !m68020 !msoft-float;\
  65. #   m68000 mc60000 !m68020 !msoft-float;\
  66. #   m68020 !m68000 !mc68000 m68020 !msoft-float;\
  67. #   msoft-float !m68000 !mc68000 !m68020 msoft-float;\
  68. #   m68000/msoft-float m68000 !m68020 msoft-float;\
  69. #   m68000/msoft-float mc68000 !m68020 msoft-float;\
  70. #   m68020/msoft-float !m68000 !mc68000 m68020 msoft-float;\
  71. #   "
  72. # The effect is that `gcc -msoft-float' (for example) will append
  73. # msoft-float to the directory name when searching for libraries or
  74. # startup files, and `gcc -m68000 -msoft-float' (for example) will
  75. # append m68000/msoft-float.
  76.  
  77. # Copy the positional parameters into variables.
  78. options=$1
  79. dirnames=$2
  80. matches=$3
  81.  
  82. # What we want to do is select all combinations of the sets in
  83. # options.  Each combination which includes a set of mutually
  84. # exclusive options must then be output multiple times, once for each
  85. # item in the set.  Selecting combinations is a recursive process.
  86. # Since not all versions of sh support functions, we achieve recursion
  87. # by creating a temporary shell script which invokes itself.
  88. rm -f tmpmultilib
  89. cat >tmpmultilib <<\EOF
  90. #!/bin/sh
  91. # This recursive script basically outputs all combinations of its
  92. # input arguments, handling mutually exclusive sets of options by
  93. # repetition.  When the script is called, ${initial} is the list of
  94. # options which should appear before all combinations this will
  95. # output.  The output looks like a list of subdirectory names with
  96. # leading and trailing slashes.
  97. if [ "$#" != "0" ]; then
  98.   first=$1
  99.   shift
  100.   for opt in `echo $first | sed -e 's|/| |'g`; do
  101.     echo ${initial}${opt}/
  102.   done
  103.   ./tmpmultilib $@
  104.   for opt in `echo $first | sed -e 's|/| |'g`; do
  105.     initial="${initial}${opt}/" ./tmpmultilib $@
  106.   done
  107. fi
  108. EOF
  109. chmod +x tmpmultilib
  110.  
  111. combinations=`initial=/ ./tmpmultilib ${options}`
  112.  
  113. rm -f tmpmultilib
  114.  
  115. # Construct a sed pattern which will convert option names to directory
  116. # names.
  117. todirnames=
  118. if [ -n "${dirnames}" ]; then
  119.   set x ${dirnames}
  120.   shift
  121.   for set in ${options}; do
  122.     for opt in `echo ${set} | sed -e 's|/| |'g`; do
  123.       if [ "$1" != "${opt}" ]; then
  124.         todirnames="${todirnames} -e s|/${opt}/|/${1}/|g"
  125.       fi
  126.       shift
  127.     done
  128.   done
  129. fi
  130.  
  131. # Construct a sed pattern which will add negations based on the
  132. # matches.  The semicolons are easier than getting the shell to accept
  133. # quoted spaces when expanding a variable.
  134. matchnegations=
  135. for i in ${matches}; do
  136.   l=`echo $i | sed -e 's/=.*$//' -e 's/?/=/g'`
  137.   r=`echo $i | sed -e 's/^.*=//' -e 's/?/=/g'`
  138.   matchnegations="${matchnegations} -e s/;!${l};/;!${l};!${r};/"
  139. done
  140.  
  141. # We need another recursive shell script to correctly handle positive
  142. # matches.  If we are invoked as
  143. #   genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2"
  144. # we must output
  145. #   opt1/opt2 opt1 opt2
  146. #   opt1/opt2 nopt1 opt2
  147. #   opt1/opt2 opt1 nopt2
  148. #   opt1/opt2 nopt1 nopt2
  149. # In other words, we must output all combinations of matches.
  150. rm -f tmpmultilib2
  151. cat >tmpmultilib2 <<\EOF
  152. #!/bin/sh
  153. # The positional parameters are a list of matches to consider.
  154. # ${dirout} is the directory name and ${optout} is the current list of
  155. # options.
  156. if [ "$#" = "0" ]; then
  157.   echo "${dirout} ${optout};\\"
  158. else
  159.   first=$1
  160.   shift
  161.   dirout="${dirout}" optout="${optout}" ./tmpmultilib2 $@
  162.   l=`echo ${first} | sed -e 's/=.*$//' -e 's/?/=/g'`
  163.   r=`echo ${first} | sed -e 's/^.*=//' -e 's/?/=/g'`
  164.   if expr " ${optout} " : ".* ${l} .*" > /dev/null; then
  165.     newopt=`echo " ${optout} " | sed -e "s/ ${l} / ${r} /" -e 's/^ //' -e 's/ $//'`
  166.     dirout="${dirout}" optout="${newopt}" ./tmpmultilib2 $@
  167.   fi
  168. fi
  169. EOF
  170. chmod +x tmpmultilib2
  171.  
  172. # We are ready to start output.
  173. echo '#define MULTILIB_SELECT "\'
  174.  
  175. # Start with the current directory, which includes only negations.
  176. optout=
  177. for set in ${options}; do
  178.   for opt in `echo ${set} | sed -e 's|/| |'g`; do
  179.     optout="${optout} !${opt}"
  180.   done
  181. done
  182. optout=`echo ${optout} | sed -e 's/^ //'`
  183. if [ -n "${matchnegations}" ]; then
  184.   optout=`echo ";${optout};" | sed -e 's/ /;/g' ${matchnegations} -e 's/^;//' -e 's/;$//' -e 's/;/ /g'`
  185. fi
  186. echo ". ${optout};\\"
  187.  
  188. # Work over the list of combinations.  We have to translate each one
  189. # to use the directory names rather than the option names, we have to
  190. # include the information in matches, and we have to generate the
  191. # correct list of options and negations.
  192. for combo in ${combinations}; do
  193.   # Use the directory names rather than the option names.
  194.   if [ -n "${todirnames}" ]; then
  195.     dirout=`echo ${combo} | sed ${todirnames}`
  196.   else
  197.     dirout=${combo}
  198.   fi
  199.   # Remove the leading and trailing slashes.
  200.   dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'`
  201.  
  202.   # Look through the options.  We must output each option that is
  203.   # present, and negate each option that is not present.
  204.   optout=
  205.   for set in ${options}; do
  206.     setopts=`echo ${set} | sed -e 's|/| |g'`
  207.     for opt in ${setopts}; do
  208.       if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then
  209.     optout="${optout} ${opt}"
  210.       else
  211.     optout="${optout} !${opt}"
  212.       fi
  213.     done
  214.   done
  215.   optout=`echo ${optout} | sed -e 's/^ //'`
  216.  
  217.   # Add any negations of matches.
  218.   if [ -n "${matchnegations}" ]; then
  219.     optout=`echo ";${optout};" | sed -e 's/ /;/g' ${matchnegations} -e 's/^;//' -e 's/;$//' -e 's/;/ /g'`
  220.   fi
  221.  
  222.   # Output the line with all appropriate matches.
  223.   dirout="${dirout}" optout="${optout}" ./tmpmultilib2 ${matches}
  224. done
  225.  
  226. rm -f tmpmultilib2
  227.  
  228. # That's it.
  229. echo '"'
  230.  
  231. exit 0
  232.