[comp.lang.c] mso: Make structure offsets from C source

nw@vaxine.UUCP (Neil Webber) (12/02/86)

The following shar archive contains a script called "mso", which
stands for "make structure offsets".  What this does is take a
set of C .h files and make a file containing #define statements
for the offsets of the fields within the structures declared in
the .h files.

For example, consider this:

        struct blatz {
                short   bozo;
                char    frammis;
                struct  blatz *dweeb;
        };

The output of mso will look like this (4.2BSD/cc/VAX):

        #define BOZO            0
        #define FRAMMIS         2
        #define DWEEB           4

There are some painfully obvious limitations.  First of all, the script
and the entire concept is excruciatingly machine/compiler dependent.
Second, the script is written in a rather kludgy fashion, and in C-shell
to boot.  I apologize for this; I know better now.  Third, it relies
on you choosing unique names for your structure field names.  This is
a dubious assumption; you'll probably have to massage the output by
hand to make any use of it.

This is only known to work for certain with the 4.2BSD "cc" compiler,
and the GreenHills M68000 family cross compiler.  Since it uses the
so-called "old" (sdb-style) symbolic output of the 4.2BSD compiler,
I suspect it may work on other flavors of UNIX -- but I don't guarantee it.

Flames to /dev/null, useful comments or improvements welcome.  Around
here, we've used mso as a *starting point* for generating assembly language
equates for C data structures, and we've also used it to ease the pain
of machine-level debugging.

Enough already.  Here's the shar archive, including a man page.

Neil Webber     Automatix Inc. (or current resident)    Billerica MA
        {decvax,ihnp4,allegra}!encore!vaxine!nw

---------------------- cut here -------------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the result in a file
# 3. Execute the file with /bin/sh (not csh)
echo extracting - mso
sed 's/^X//' > mso << 'FRIDAY_NIGHT'
X#!/bin/csh -f
X#
X# SCCSID = @(#)mso.sh	1.1  2/26/85
X#
X# mso [-c<compiler> -f<compiler_flags> -o<output> ] files
X#
X# Make structure offsets from C header source.  Since this is a shell script,
X# note that no spaces may be present between an option and its value.
X#
X# mso takes a set of .h files, concatenates them all togethers, cc's them with
X# a debugging option (normally -g or -go), and makes a file containing #defines
X# for structure offsets from the result.
X#
X# By default, mso will use /bin/cc as the C compiler, and "-go" as the compiler
X# flags.  If no output file is given then stdout is used.
X#
X
Xset files = ()
Xset compiler = /bin/cc
Xset compiler_flags = -go
Xunset output_file
Xunset aborting
X
Xforeach arg ( $*:q )
X  switch ( "$arg" )
X
X#
X# -c: select compiler
X#
X    case -c*:
X      set compiler = `echo $arg | sed -e 's/^..//'`
X      breaksw
X
X#
X# -f: select compiler flags (besides -S)
X#
X    case -f*:
X      set compiler_flags = -`echo $arg | sed -e 's/^..//'`
X      breaksw
X
X#
X# -o: output file
X#
X    case -o*:
X      set output_file = `echo $arg | sed -e 's/^..//'`
X      breaksw
X
X#
X# other flags
X#
X    case -*:
X      echo "mso: unknown option <$arg>"
X      set aborting
X      breaksw
X
X#
X# files
X#
X    default:
X      set files = ($files $arg)
X      breaksw
X  endsw
Xend
X
Xif ($?aborting) exit 1
X
X#
X# Make a .c file
X#
X
Xrm -f mso$$.{c,s,q} mso$$a.c
Xforeach file ($files)
X  echo "#include '$file'" >> mso$$a.c
Xend
X
X# because csh makes it so hard to quote quotes ...
Xtr "'" '"' < mso$$a.c > mso$$.c
X
X$compiler -S $compiler_flags mso$$.c
X
X# see 'as' reference manual for details.  Basically, the output of the cc
X# will be a bunch of ".stabs" directives -- the ones which are type "0140,0"
X# are the ones we want; the last field in the "0140" .stabs is the size.
X
X# upper case, blow away comma and double quote
Xtr 'a-z,"' 'A-Z  ' < mso$$.s > mso$$.q
X
X# awk program looks for 0140,0 types, and makes a #define line.
X
Xif ($?output_file) then
X  awk '/ *.\.STABS/ { if (($3 == 0140) && ($4 == 0)) printf "#define %-40s%d\n",$2,$6 }' > $output_file < mso$$.q
Xelse
X  awk '/ *.\.STABS/ { if (($3 == 0140) && ($4 == 0)) printf "#define %-40s%d\n",$2,$6 }' < mso$$.q
Xendif
X
Xrm -f mso$$.{c,s,q} mso$$a.c
FRIDAY_NIGHT
echo extracting - mso.l
sed 's/^X//' > mso.l << 'FRIDAY_NIGHT'
X.XX @(#)mso.l	1.1  1/25/85  \" SCCS ID
X.TH MSO 1 local
X.SH NAME
Xmso -- make structure offsets
X.SH SYNOPSIS
X.B mso
X[ -c<compiler> -f<compiler-flags> -o<output> ] files
X.SH DESCRIPTION
X.I mso
Xgenerates C-preprocessor #define statements for offset values of
XC structures.
X.I mso
Xfirst concatenates the
X.B files
Xtogether into a temporary file.
XThis temporary file is then passed
Xthrough the C compiler with the "generate debug symbols" option set.
XThe resulting assembly language output is massaged to give the final output.
X.PP
XThe options are described below.
XNo spaces are permitted between an option and its value.
X.TP 5
X.B \-c
Xselects the compiler that will be used.
XThe default is
X.B /bin/cc\c
X\&.
X.TP
X.B \-f
Xselects the compiler flags that will be
Xused.
XThe default is
X.B \-go
X(you would specify this on the command line as "-fgo").
XNote that
X.I mso
Xonly works with the "obsolete" symbol formats, as used by the old
Xsymbolic debugger,
X.I sdb\c
X\&.
X.TP
X.B \-o
Xselects the output file.  By default,
X.I mso
Xwill write to standard output.
X.T
X.PP
XThe convention used by
X.I mso
Xis that a structure field member called "flortz" will generate
Xa "#define FLORTZ xxx"
Xstatement; xxx being the offset of "flortz" within the structure.
X.SH DIAGNOSTICS
XThe C compiler will print the usual diagnostics if there are
Xsyntax errors in the
X.B files.
X.SH SEE ALSO
Xcc(1)
FRIDAY_NIGHT