#! /bin/bash
# a script to generate externals.h
# the latter is included by all LoopTools code, with the purpose
# of making internal symbols "invisible" from the outside
# this file is part of LoopTools
# last modified 28 Aug 20 th


base="${0%/*}/../.."
ext="$base/src/include/externals.h"
cext="$base/src/include/cexternals.h"
lib="$base/build/libooptools.a"
prefix=lj

shopt -s nullglob

set -- `nm "$lib" | awk '
  /\.o:$/ {
    file = $1;
    sub(".o:$", "", file);
  }
  /\.o\):$/ {
    file = $1;
    sub("^.*\\\\(", "", file);
    sub("\\\\.o\\\\):$", "", file);
  }
  $2 ~ /^(T|C)$/ && $3 !~ /^_*('"$prefix"')*(\
a00c|a00|a0ic|a0i|a0c|a0|\
agetc|aget|aputnocachec|aputnocache|aputc|aput|\
b001c|b001|b00c|b00|b0c|b0ic|b0i|b0|b111c|b111|b11c|b11|b1c|b1|\
bgetc|bget|bputnocachec|bputnocache|bputc|bput|bcoeffc|bcoeff|\
db001c|db001|db00c|db00|db0c|db0|db11c|db11|db1c|db1|\
c0ic|c0i|c0nocachec|c0nocache|c0c|c0|\
cgetc|cget|cputnocachec|cputnocache|cputc|cput|ccoeffc|ccoeff|\
d0ic|d0i|d0nocachec|d0nocache|d0c|d0|\
dgetc|dget|dputnocachec|dputnocache|dputc|dput|dcoeffc|dcoeff|\
e0ic|e0i|e0nocachec|e0nocache|e0c|e0|\
egetc|eget|eputnocachec|eputnocache|eputc|eput|ecoeffc|ecoeff|\
li2c|li2csub|li2|li2sub|li2omxc|li2omxcsub|li2omx|li2omxsub|\
ltini|ltexi|ltcache|ltvars|ltregul|\
clearcache|markcache|restorecache|getcachelast|setcachelast|\
setmudim|getmudim|\
setdelta|getdelta|\
setuvdiv|getuvdiv|\
setlambda|getlambda|getepsi|\
setminmass|getminmass|\
setmaxdev|getmaxdev|\
setdiffeps|getdiffeps|\
setzeroeps|getzeroeps|\
setwarndigits|getwarndigits|\
seterrdigits|geterrdigits|\
setversionkey|getversionkey|\
setdebugkey|getdebugkey|setdebugrange|\
setcmpbits|getcmpbits)_$/ {
    sub("^_", "", $3);
    sub("^" PREFIX, "", $3);
    sub("_*$", "", $3);
    print file " " $3;
  }
' PREFIX="$prefix"`

fdefs=
cdefs=
c_defs=

test -f "$ext" && mv -f "$ext"{,.old}
touch "$ext"
test -f "$cext" && mv -f "$cext"{,.old}
touch "$cext"

cd build

while test $# -gt 1; do
  file=
  cppflags=
  for file in "$1".[Fc]; do
    break
  done
  test -z "$file" && case "$1" in
  *C)
	file=`echo "$1.F" | sed 's/C\.F$/\.F/'`
	cppflags="-DCOMPLEXPARA"
	;;
  esac
  case "$file" in
  *.c)	sym=`gcc -E -P "$file" | sed -n "
	  s|^[^ ]* *\($2\)_*(.*|\1|pI
	  s|} \($2\)_*;|\1|pI
	  T
	  q"`
	test ${sym}x = x && {
	  echo "$0 bug for file $file sym $2"
	  exit 1
	}
	c_defs+="
#define ${sym}_ $prefix${sym}_"
	cdefs+="
#define $sym $prefix$sym"
	fdefs+="
#define $sym $prefix$sym"
	;;
  *)	sym=${2:0:29}
	sym=`gfortran -E -P $cppflags "$file" | sed -n "
	  s|^[^c*].*subroutine *\($sym\).*|\1|pI
	  s|^[^c*].*function *\($sym\).*|\1|pI
	  s|^[^c*].*entry *\($sym\).*|\1|pI
	  s|^[^c*].*block data *\($sym\).*|\1|pI
	  s|^[^c*].*common */\($sym\).*|\1|pI
	  T
	  q"`
	test "${sym}x" = x && {
	  echo "$0 bug for file $file sym $2"
	  exit 1
	}
	fdefs+="
#define $sym $prefix$sym"
	;;
  esac
  echo "$sym"
  test -z "$sym" && echo "Symbol $2 not found in $file." 1>&2
  shift 2
done


cat > "$ext" << _EOF_
#if 0
This file was generated by ${0##*/} on `date`.
Do not edit.
#endif
`echo "$fdefs" | sort -u`
_EOF_


cat > "$cext" << _EOF_
#if 0
This file was generated by ${0##*/} on `date`.
Do not edit.
#endif

#if NOUNDERSCORE
`echo "$cdefs" | sort -u`

#else
`echo "$c_defs" | sort -u`

#endif
_EOF_

