#!/bin/sh

# Create a Pascal library interface from a template and the
# interfaces of the units that the library consists of. The units
# and their comments must be formatted in a certain way. This is no
# completely general tool. (The more general solution would be to
# have the compiler write a GPI file for the library, but until GPC
# can do that, this script is better than nothing.) }
#
# Copyright (C) 2001-2002 Free Software Foundation, Inc.
#
# Author: Frank Heckenbach <frank@pascal.gnu.de>
#
# This file is part of GNU Pascal.
#
# GNU Pascal is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# GNU Pascal is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Pascal; see the file COPYING. If not, write to the
# Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.

# This script requires bash. Since bash cannot be assumed to be in
# /bin, /usr/bin or any other certain place, we cannot use it in the
# first line. So we use /bin/sh, which can be assumed to exist. Then
# we check if it's actually bash, and if not, try to re-run the
# script with bash.
if [ x"$BASH" = x ]; then
  if [ x"$RERUN_BASH_TRIED" != x ]; then
    echo "`basename "$0"`: cannot run, \`bash' is either not bash or a very old version" >&2
    exit 1
  else
    RERUN_BASH_TRIED=1; export RERUN_BASH_TRIED
    exec bash "$0" "$@"
    echo "`basename "$0"`: cannot run bash" >&2
    exit 1
  fi
fi

if [ $# -ne 3 ]; then
  echo "Usage: `basename $0` template dest version" >&2
  exit 1
fi

# Find a good awk.
if test -z "$AWK"; then
  for AWK in gawk nawk awk ""; do
    if type "$AWK" 2>&1 | grep 'not found' > /dev/null 2>&1; then
      :
    else
      break
    fi
  done
fi
if test -z "$AWK"; then
  echo 'No awk found.' >&2
  exit 1
fi

{
  echo "{ This file was generated automatically from $1."
  echo "  DO NOT CHANGE THIS FILE MANUALLY! }"
  echo ""
  # Instead of the following bash/awk combination, we could do it
  # all within awk, but only GNU awk. Other versions of awk don't
  # support getline from secondary files, for instance...
  ORIG_IFS="$IFS"
  while IFS=""; read -r line; do
    IFS="$ORIG_IFS"
    case "$line" in
      @interface*)
        unit="`echo "$line" | sed -e 's/^@interface *//'`"
        # This awk script should be DAU-awk safe... :-/
        "$AWK" '
          BEGIN { d = ""; empty = 0; state = 0 }
          # Handle states in reversed order, so that after state++
          # the new state is not handled for the same line.
          state == 2 && /^implementation$/ { exit 0 }
          state == 2 && /^ *{@internal}$/ { state = - state }
          state == 2 && !/^uses/ {
            line = $0
            # Remove variable initializers and make the declarations external
            i = index (line, ":")
            j = index (line, "=")
            l = index (line, "(")  # no schema types
            if (i > 0 && j > i && (l == 0 || l > j))
              {
                while (j > 1 && substr (line, j - 1, 1) == " ") j--
                while ((k = index (line, ";")) == 0)
                  {
                    getline
                    line = line " " $0
                  }
                if (k > j)
                  line = substr (line, 1, j - 1) substr (line, k) " external;"
              }
            # Do not print multiple empty lines in a row
            if (!empty || line != "") print line
            if (line == "")
              empty = 1
            else
              empty = 0
          }
          state < 0 && /^ *{@endinternal}$/ { state = - state }
          state == 1 && /^interface$/ { state++ }
          state == 0 {
            sub ("^{ *", "")
            if ($0 != "")
              {
                if (d != "") d = d "\n"
                d = d $0
              }
          }
          state == 0 && /^$/ {
            print "{ " d ", from '"$unit"' }"
            state++;
          }
        ' < "$unit";;
      *) echo "$line";;
    esac
  done < "$1" | sed -e "s/@VERSION@/$3/"
} > "$2" || { rm -f "$2"; exit 1; }
