#!/bin/sh
# $Header: //info.ravenbrook.com/project/mps/version/1.105/code/expgen.sh#1 $
#
# Copyright (C) 2004 Ravenbrook Limited.  All rights reserved.
#
# expgen.sh
#
# Export Generator
#
# This is a script to generate the a list of exports that is required
# for Windows DLL creation.
#
# It processed the mps header files and produces a .DEF file that is
# suitable for use with the linker when producing a DLL file on Windows.
#
# When run, this script produces the following output files:
# expgen - a plain text list of functions declared in the header files.
# w3gen.def - a .def file suitable for use in the linker stage when
# building a Windows .DLL.
#
# Procedure for rebuilding a new w3gen.def
#
# This procedure should be carried out when the contents of w3gen.def
# would change.  This is a bit tricky to say exactly when, but certainly
# when:
# a) new functions are declared in public header files.
# b) different header files are released to a client.
#
# Procedure:
#
# 1) Ensure that the sources for w3gen.def are submitted.  w3gen.def
# must be built from versioned sources.
# The sources are:
# expgen.sh
# w3build.bat
# all the headers that get included.
# For safety's sake better to ensure that no files are open:
# p4 opened ...
# should say '... - file(s) not opened on this client.'
#
# 2) Open w3gen.def for edit (making it writable)
# p4 open w3gen.def
#
# 3) Run this script.
# sh expgen.sh
# There should be no output when successful.
#
# 4) Eyeball the diff.
# p4 diff ...
# Check the that resulting diff is sane.  For most changes it should
# just consist of a new symbol being included (plus some Header related
# junk).
#
# 5) Submit the change.
# p4 submit ...
#
#
# Design
#
# The script works by using the -fdump-translation-unit option of gcc.
# This produces a more easily parseable rendering of the header files.
# A fairly simple awk script is used to process the output.
#
#
# Dependencies
#
# This script currently depends fairly heavily on being run in a
# Unix-like environment with access to the GNU compiler.
#
# It's also fairly sensitive to changes in the undocumented format
# produced by gcc -fdump-translation-unit.  Hopefully it is fairly easy
# to adapt to changes in this output.
#
# Assumes it can freely write to the files "fun", "name-s".
#
#
# Awk crash course
#
# Awk processes files line-by-line, thus the entire script is executed
# for each line of the input file (more complex awk scripts can control
# this using "next" and "getline" and so on).
#
# In awk $exp identifies a field within the line.  $1 is the first
# field, $2 is the second and so on.  $0 is the whole line.  By default
# fields are separated by whitespace.
#
# string ~ RE is a matching expression and evaulated to true iff the
# string is matched by the regular expression.
#
# REFERENCES
#
# [SUSV3] Single UNIX Specification Version 3,
# http://www.unix.org/single_unix_specification/
#
# For documenation of the standard utilities: sh, awk, join, sort, sed
#
# [MSDN-LINKER-DEF] Module-Definition (.def) files,
# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_module.2d.definition_files.asp
#
# For documentation on the format of .def files.

tu () {
  # if invoked on a file called spong.h will produce a file named
  # spong.h.tu
  gcc -fdump-translation-unit -o /dev/null "$@"
}

# This list of header files is produced by
# awk '/^copy.*\.h/{print $2}' w3build.bat
# followed by manual removal of mpsw3.h mpswin.h (which gcc on UNIX
# cannot parse).  Also removed are mpsio.h mpslib.h as they defined
# interfaces that mps _uses_ not defines.  Also removed is mpscmvff.h as
# it does not get included in mps.lib
# The functions declared in mpsw3.h have to be added to the .def file by
# hand later in this script.
f='mps.h
mpsavm.h
mpsacl.h
mpscamc.h
mpscams.h
mpscawl.h
mpsclo.h
mpscmv.h
mpscsnc.h
mpslibcb.h
mpstd.h'

tu $f

>expgen

for a in $f
do
  >fun
  awk '
    $2=="function_decl" && $7=="srcp:" && $8 ~ /^'$a':/ {print $4 >"fun"}
    $2=="identifier_node"{print $1,$4}
  ' $a.tu |
  sort -k 1 >name-s

  echo ';' $a >>expgen
  sort -k 1 fun |
    join -o 2.2 - name-s >>expgen
done

{
  printf '; %sHeader%s\n' '$' '$'
  echo '; DO NOT EDIT.  Automatically generated by $Header: //info.ravenbrook.com/project/mps/version/1.105/code/expgen.sh#1 $' | sed 's/\$/!/g'
  echo 'EXPORTS'
  cat expgen
  # This is where we manually the functions declared in mpsw3.h
  echo ';' mpsw3.h - by hand
  echo mps_SEH_filter
  echo mps_SEH_handler
} > w3gen.def