home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / gcc / listing < prev    next >
Text File  |  1994-08-31  |  6KB  |  228 lines

  1. #!/bin/sh -f
  2. # Generate a source code listing for C or C++ code with assembler code. The
  3. # listing is always written to stdout.
  4. # Author: Igor Metz <metz@iam.unibe.ch>
  5.  
  6. # Revision 1.4  94/08/26  13:58:27  coxs <coxs@dg-rtp.dg.com>
  7. # lister now guesses how to should be configured. Added elf and coff support.
  8. #
  9. # Revision 1.3  89/12/18  13:58:27  metz
  10. # lister must now be configured before it can be used. This is done in the
  11. # /bin/sh part of the code.
  12. # Revision 1.2  89/08/16  17:35:02  metz
  13. # Support for SPARC added.
  14. # Revision 1.1  89/08/16  16:49:22  metz
  15. # Initial revision
  16.  
  17. # Requires: gawk (may be it works also with nawk)
  18.  
  19. # usage:  lister filename [compiler-options]
  20.  
  21. # Method:
  22. # compile the source with -g option to assembler code, then merge the
  23. # generated assembler code with the source code. Compiler options
  24. # can be supplied on the command line (for example -O)
  25.  
  26. # To install lister, assign one of the supported values to the variable MYSYS:
  27. # mc68020  for Motorola 68020 (Sun-3, ..)
  28. # mc68030  for Motorola 68030 (Sun-3, ..)
  29. # sparc    for SPARC (SUN-4, ..)
  30. # i386     for i386 (Sun i386, ...)
  31. # i386-linux for i386 (Linux, ...)
  32.  
  33. # Guess what kind of objects we are creating and thus what type of assembler
  34. # symbols to look for
  35.  
  36. ex /tmp/$$.c <<END >/dev/null
  37. a
  38. main (){}
  39. .
  40. w
  41. q
  42. END
  43. WD=`pwd`
  44. cd /tmp
  45. gcc -c $$.c
  46. case "`file $$.o`" in 
  47. *ELF*) MYSYS=elf ;;
  48. *COFF*|*BCS*) MYSYS=coff ;;
  49. *mc68k*|*M68000*) MYSYS=mc68030 ;;
  50. *SPARC*) MYSYS=sparc ;;
  51. *386*) MYSYS=i386 ;;
  52. esac
  53. rm $$.c $$.o
  54. cd $WD
  55.  
  56. # uncomment the line you need if the above guesses incorrectly:
  57. # MYSYS=mc68020
  58. # MYSYS=mc68030
  59. # MYSYS=sparc
  60. # MYSYS=i386
  61. # MYSYS=i386-linux
  62. # MYSYS=`mach`  # this will work on Suns with SunOS > 4.0.0
  63. # MYSYS=elf
  64. # MYSYS=coff
  65.  
  66. WHOAMI=$0
  67. if [ $# -gt 0 ] ; then
  68. FILENAME=$1
  69. shift
  70. fi
  71.  
  72. exec gawk -v whoami=$WHOAMI -vsys=$MYSYS -voptions="$*" '
  73. # commandline arguments:
  74. #  ARGV[0] = "gawk"
  75. #  ARGV[1] = processid
  76. #  ARGV[2] = filename
  77. BEGIN {
  78.   if (ARGC != 3) {
  79.     usage()
  80.     exit 1
  81.   }
  82.  
  83.   # Declaration of global variables
  84.   c_filename = ""
  85.   asm_filename = ""
  86.   cmdline = ""
  87.   asm_code = ""
  88.   c_code = ""
  89.   c_lineno = 0
  90.   oldlineno = 0
  91.   newlineno = 0
  92.   ignore_stabd = 0
  93.   num_of_fields = 0
  94.  
  95.   # check processor architecture and set sourcecode line_hint accordingly
  96.   if (sys == "sparc" || sys == "i386") {
  97.     line_hint = "^[ \t]*\.stabn.*"
  98.     line_field = 3;
  99.     line_delimiter = ",";
  100.     line_offset = 0;
  101.   }
  102.   else if (sys == "mc68020" || sys == "mc68030" || sys == "i386-linux") {
  103.     line_hint = "^[ \t]*\.stabd.*"
  104.     line_field = 3;
  105.     line_delimiter = ",";
  106.     line_offset = 0;
  107.   }
  108.   else if (sys == "elf") {
  109.     line_hint = "section.*\.line"
  110.     line_field = 3;
  111.     line_delimiter = "\t";
  112.     line_offset = 0;
  113.   }
  114.   else if (sys == "coff") {
  115.     line_hint = "^[ \t]*ln"
  116.     line_field = 3;
  117.     line_delimiter = "\t";
  118.   }
  119.   else {
  120.     error("Processor type " sys " is not supported yet, sorry")
  121.   }
  122.  
  123.   parse_cmdline()
  124.  
  125.   printf("compiling %s to asm code\n", c_filename ) > "/dev/stderr"
  126.  
  127.   if (system(cmdline) != 0 ) {
  128.     error("Compilation of " c_filename " failed")
  129.   }
  130.  
  131.   printf("generating listing\n") > "/dev/stderr"
  132.  
  133.  
  134.   while ( getline asm_code < asm_filename > 0 ) {
  135.     if ( (ignore_stabd==0) && (asm_code ~ line_hint)) {
  136.       while ( sys == "elf" && (asm_code !~ "word" && asm_code !~ "byte") && 
  137.         getline asm_code < asm_filename > 0);
  138.       # source line hint found. Split the line into fields separated by commas.
  139.       # num_of_fields is 4 for sparc, 3 for m68k
  140.       num_of_fields = split(asm_code, fields, line_delimiter)
  141.       newlineno = fields[line_field] + line_offset;
  142.  
  143.       if (newlineno > oldlineno) {
  144.         while ( newlineno > c_lineno && getline c_code < c_filename > 0) {
  145.       c_lineno++
  146.       printf("%4d %s\n", c_lineno, c_code)
  147.     }
  148.     oldlineno = newlineno
  149.       }
  150.     }
  151.     else if ( asm_code ~ ".*Ltext[ \t]*$" ) {
  152.       # filename hint found
  153.       if ( match(asm_code, c_filename)) {
  154.         ignore_stabd = 0
  155.       }
  156.       else {
  157.         ignore_stabd = 1
  158.       }
  159.     }
  160.     else if ( sys == "elf" && asm_code ~ "section.*\.debug" ) {
  161.       while ( asm_code !~ "^[ \t]*[.]*previous" &&
  162.           asm_code !~ "\.popsection" && 
  163.               getline asm_code < asm_filename > 0 );
  164.       if ( ! (getline asm_code < asm_filename > 0)) break;
  165.     }
  166.     else if ( sys == "coff" && asm_code ~ "^[ \t]*sdef" ) {
  167.       if ( asm_code ~ "\.bf" ) {
  168.          while ( asm_code !~ "^[ \t]*line" && 
  169.                  getline asm_code < asm_filename > 0 ) {
  170.            num_of_fields = split(asm_code, fields, "\t")
  171.            line_offset = fields[line_field] - 1;
  172.          }
  173.       }
  174.       while ( asm_code !~ "^[ \t]*endef" && 
  175.               getline asm_code < asm_filename > 0 ) {
  176.       }
  177.       if ( ! (getline asm_code < asm_filename > 0)) break;
  178.     }
  179.     printf("\t\t\t%s\n", asm_code)
  180.   }
  181.  
  182.   # general cleanup
  183.   system("/bin/rm " asm_filename)
  184. }
  185.  
  186. function usage() {
  187.     printf("usage: %s filename compiler-options\n", whoami) > "/dev/stderr"
  188. }
  189.  
  190. function error(s) {
  191.     printf("error: %s\n", s) > "/dev/stderr"
  192.     exit 1
  193. }
  194.  
  195. function parse_cmdline(    i) {
  196.   # construct filenames to use
  197.   asm_filename = "/tmp/lister" ARGV[1] ".s"
  198.   ARGV[1] = ""
  199.   c_filename = ARGV[2]
  200.   ARGV[2] = ""
  201.  
  202.   # construct commandline to use
  203.   if ( match(c_filename, ".C") || match(c_filename, ".cc") ) {
  204.     cmdline = "g++"
  205.   }
  206.   else if (match(c_filename, ".c") || match(c_filename, ".i")) {
  207.     cmdline = "gcc"
  208.   }
  209.   else {
  210.     error("unknown extension for file " c_filename)
  211.   }
  212.  
  213.   cmdline = cmdline " -g -S -o " asm_filename
  214.  
  215.   # now we append the compiler options specified by the user
  216.   cmdline = cmdline " " options
  217.  
  218.   # last but not least: the name of the file to compile
  219.   cmdline = cmdline " " c_filename
  220. }
  221.  
  222. ' $$ $FILENAME
  223.  
  224.