head	1.4;
access;
symbols
	gcc-2_8_1-990325:1.4
	gcc-2_8_1-990319:1.4
	gcc-2_8_1-990302:1.4
	gcc_2_8_1-990302:1.4
	gcc_2_8_1-990222:1.4
	gcc-2_8_1-990109:1.4
	gcc-2_8_1-981210:1.4
	gcc-2_8_1-981208:1.4
	gcc-2_8_1-980929:1.4
	gcc_2_8_1-980929:1.4
	gcc-2_8_1-980928:1.4
	gcc-2_8_1-980813:1.4
	gcc-2_8_1-980811:1.4
	gcc-2_8_1-980718:1.4
	gcc-2_8_1-980705:1.4
	gcc-2_8_1-980627:1.4
	gcc-2_8_1-980609:1.4
	gcc-2_8_1-980608:1.4
	gcc-2_8_1-980529:1.4
	gcc-2_8_1-980525:1.4
	gcc-2_8_1-980513:1.4
	gcc-2_8_1-980502:1.4
	gcc-2_8_1-980402:1.4
	gcc-2_8_1-980426:1.4
	gcc-2_8_1-980419:1.4
	gcc-2_8_1-980413:1.4
	gcc-2_8_1-980412:1.4
	gcc-2_8_1-980407:1.4
	gcc-2_8_1-980401:1.4
	gcc_2_8_1-980315:1.4
	gcc-2_8_1-RELEASE:1.4;
locks; strict;
comment	@# @;


1.4
date	97.12.05.12.06.39;	author kenner;	state Exp;
branches;
next	1.3;

1.3
date	94.08.31.13.53.39;	author coxs;	state Exp;
branches;
next	1.2;

1.2
date	94.08.29.21.43.34;	author coxs;	state Exp;
branches;
next	1.1;

1.1
date	94.08.29.19.25.21;	author coxs;	state Exp;
branches;
next	;


desc
@Initial version
@


1.4
log
@Change linux to gnu-linux.
@
text
@#!/bin/sh -f
# Generate a source code listing for C or C++ code with assembler code. The
# listing is always written to stdout.
# Author: Igor Metz <metz@@iam.unibe.ch>

# Revision 1.4  94/08/26  13:58:27  coxs <coxs@@dg-rtp.dg.com>
# lister now guesses how to should be configured. Added elf and coff support.
#
# Revision 1.3  89/12/18  13:58:27  metz
# lister must now be configured before it can be used. This is done in the
# /bin/sh part of the code.
# 
# 
# Revision 1.2  89/08/16  17:35:02  metz
# Support for SPARC added.
# 
# Revision 1.1  89/08/16  16:49:22  metz
# Initial revision
# 

# Requires: gawk (may be it works also with nawk)

# usage:  lister filename [compiler-options]

# Method:
# compile the source with -g option to assembler code, then merge the
# generated assembler code with the source code. Compiler options
# can be supplied on the command line (for example -O)

# To install lister, assign one of the supported values to the variable MYSYS:
# mc68020  for Motorola 68020 (Sun-3, ..)
# mc68030  for Motorola 68030 (Sun-3, ..)
# sparc    for SPARC (SUN-4, ..)
# i386     for i386 (Sun i386, ...)
# i386-gnu-linux for i386 (GNU/Linux, ...)

# Guess what kind of objects we are creating and thus what type of assembler
# symbols to look for

ex /tmp/$$.c <<END >/dev/null
a
main (){}
.
w
q
END
WD=`pwd`
cd /tmp
gcc -c $$.c
case "`file $$.o`" in 
*ELF*) MYSYS=elf ;;
*COFF*|*BCS*) MYSYS=coff ;;
*mc68k*|*M68000*) MYSYS=mc68030 ;;
*SPARC*) MYSYS=sparc ;;
*386*) MYSYS=i386 ;;
esac
rm $$.c $$.o
cd $WD

# uncomment the line you need if the above guesses incorrectly:
# MYSYS=mc68020
# MYSYS=mc68030
# MYSYS=sparc
# MYSYS=i386
# MYSYS=i386-gnu-linux
# MYSYS=`mach`  # this will work on Suns with SunOS > 4.0.0
# MYSYS=elf
# MYSYS=coff

WHOAMI=$0
if [ $# -gt 0 ] ; then
FILENAME=$1
shift
fi

exec gawk -v whoami=$WHOAMI -vsys=$MYSYS -voptions="$*" '
# commandline arguments:
#  ARGV[0] = "gawk"
#  ARGV[1] = processid
#  ARGV[2] = filename
BEGIN {
  if (ARGC != 3) {
    usage()
    exit 1
  }

  # Declaration of global variables
  c_filename = ""
  asm_filename = ""
  cmdline = ""
  asm_code = ""
  c_code = ""
  c_lineno = 0
  oldlineno = 0
  newlineno = 0
  ignore_stabd = 0
  num_of_fields = 0

  # check processor architecture and set sourcecode line_hint accordingly
  if (sys == "sparc" || sys == "i386") {
    line_hint = "^[ \t]*\.stabn.*"
    line_field = 3;
    line_delimiter = ",";
    line_offset = 0;
  }
  else if (sys == "mc68020" || sys == "mc68030" || sys == "i386-gnu-linux") {
    line_hint = "^[ \t]*\.stabd.*"
    line_field = 3;
    line_delimiter = ",";
    line_offset = 0;
  }
  else if (sys == "elf") {
    line_hint = "section.*\.line"
    line_field = 3;
    line_delimiter = "\t";
    line_offset = 0;
  }
  else if (sys == "coff") {
    line_hint = "^[ \t]*ln"
    line_field = 3;
    line_delimiter = "\t";
  }
  else {
    error("Processor type " sys " is not supported yet, sorry")
  }

  parse_cmdline()

  printf("compiling %s to asm code\n", c_filename ) > "/dev/stderr"

  if (system(cmdline) != 0 ) {
    error("Compilation of " c_filename " failed")
  }

  printf("generating listing\n") > "/dev/stderr"


  while ( getline asm_code < asm_filename > 0 ) {
    if ( (ignore_stabd==0) && (asm_code ~ line_hint)) {
      while ( sys == "elf" && (asm_code !~ "word" && asm_code !~ "byte") && 
        getline asm_code < asm_filename > 0);
      # source line hint found. Split the line into fields separated by commas.
      # num_of_fields is 4 for sparc, 3 for m68k
      num_of_fields = split(asm_code, fields, line_delimiter)
      newlineno = fields[line_field] + line_offset;

      if (newlineno > oldlineno) {
        while ( newlineno > c_lineno && getline c_code < c_filename > 0) {
	  c_lineno++
	  printf("%4d %s\n", c_lineno, c_code)
	}
	oldlineno = newlineno
      }
    }
    else if ( asm_code ~ ".*Ltext[ \t]*$" ) {
      # filename hint found
      if ( match(asm_code, c_filename)) {
        ignore_stabd = 0
      }
      else {
        ignore_stabd = 1
      }
    }
    else if ( sys == "elf" && asm_code ~ "section.*\.debug" ) {
      while ( asm_code !~ "^[ \t]*[.]*previous" &&
	      asm_code !~ "\.popsection" && 
              getline asm_code < asm_filename > 0 );
      if ( ! (getline asm_code < asm_filename > 0)) break;
    }
    else if ( sys == "coff" && asm_code ~ "^[ \t]*sdef" ) {
      if ( asm_code ~ "\.bf" ) {
         while ( asm_code !~ "^[ \t]*line" && 
                 getline asm_code < asm_filename > 0 ) {
           num_of_fields = split(asm_code, fields, "\t")
           line_offset = fields[line_field] - 1;
         }
      }
      while ( asm_code !~ "^[ \t]*endef" && 
              getline asm_code < asm_filename > 0 ) {
      }
      if ( ! (getline asm_code < asm_filename > 0)) break;
    }
    printf("\t\t\t%s\n", asm_code)
  }

  # general cleanup
  system("/bin/rm " asm_filename)
}

function usage() {
    printf("usage: %s filename compiler-options\n", whoami) > "/dev/stderr"
}

function error(s) {
    printf("error: %s\n", s) > "/dev/stderr"
    exit 1
}

function parse_cmdline(    i) {
  # construct filenames to use
  asm_filename = "/tmp/lister" ARGV[1] ".s"
  ARGV[1] = ""
  c_filename = ARGV[2]
  ARGV[2] = ""

  # construct commandline to use
  if ( match(c_filename, ".C") || match(c_filename, ".cc") ) {
    cmdline = "g++"
  }
  else if (match(c_filename, ".c") || match(c_filename, ".i")) {
    cmdline = "gcc"
  }
  else {
    error("unknown extension for file " c_filename)
  }

  cmdline = cmdline " -g -S -o " asm_filename

  # now we append the compiler options specified by the user
  cmdline = cmdline " " options

  # last but not least: the name of the file to compile
  cmdline = cmdline " " c_filename
}

' $$ $FILENAME

@


1.3
log
@Some assemblers put a "." before pseudo-ops
@
text
@d35 1
a35 1
# i386-linux for i386 (Linux, ...)
d65 1
a65 1
# MYSYS=i386-linux
d106 1
a106 1
  else if (sys == "mc68020" || sys == "mc68030" || sys == "i386-linux") {
@


1.2
log
@Added coff and elf support.
@
text
@d165 1
a165 1
      while ( asm_code !~ "^[ \t]*previous" &&
@


1.1
log
@Initial revision
@
text
@d6 3
d37 24
a60 1
# uncomment the line you need:
d67 2
d70 2
d74 1
d76 1
a76 1
exec gawk -vsys=$MYSYS -voptions="$*" '
d102 3
d108 14
d140 2
d144 2
a145 2
      num_of_fields = split(asm_code, fields, ",")
      newlineno = fields[3] + 0 # the line number we are looking for is field 3
d148 1
a148 2
        while ( newlineno > c_lineno ) {
	  getline c_code < c_filename
d164 19
d191 1
a191 1
    printf("usage: %s filename compiler-options\n", argv[0]) > "/dev/stderr"
d210 1
a210 1
  else if (match(c_filename, ".c")) {
@
