# --------------------------------------------------------------------
#    Copyright (C) 1999,  Daniel Schulz	   
# 
#    This file is part of the TDI library. The TDI library implements  
#    the generic part of the Thread Debug Interface for POSIX Threads
#    Implementations - TDI.
#
#    This library is free software; you can redistribute it and/or
#    modify it under the terms of the GNU Library General Public
#    License as published by the Free Software Foundation; either
#    version 2 of the License, or (at your option) any later version.
#
#    This library 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
#    Library General Public License for more details.
#
#    You should have received a copy of the GNU Library General Public
#    License along with this library; if not, write to the Free
#    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#    Report problems and direct all questions to:
#
#    tdi-bugs@informatik.hu-berlin.de
#	
# $Author: dschulz $ $Date: 1999/05/03 23:04:08 $ $Name: TDI-alpha-release-2 $ 
#
# File: tdi-dlgen (generates the unshading stuff in tdi-dlgen.[ch])	 
#
# ---------------------------------------------------------------------

# this is a bash script (see the SHELL entry in the Makefile)

#########################################################
# File         : tdi-dlgen (shell-script)
# Description  : Code generation for shared library usage
# Author       : Daniel Schulz 
# Creation Date: 98-11-26
#########################################################



# a) we generate the header file
#    - get all include entries
#    - get all prototypes and substitute $ with the function-name


echo -n Creating tdi-dlgen.h ...

cat <<End > tdi-dlgen.h
/* 

  this file was generated by `basename $0` on `date`           
                                                               
  !! DON'T EDIT THIS FILE, IT WILL BE OVERWRITTEN NEXT TIME !!

*/ 

/* following open and close functions are provided */

/* returns 0 if no error occurred */ 
extern int tdi_libopen();
/* returns 0 if no error occurred */ 
extern int tdi_libclose();

/* return 1 if libs are open */
extern int tdi_islibopen();

/* include */

End

# generate the sequence of includes
awk 'BEGIN {FS="#";} END {print "\n/* end of include part */\n"} /^#/ {next;} /^$/ { next;} { print "#include "$4;}' < $1 >> tdi-dlgen.h

#generate the sequence of func_ptr declarations
sort $1 | awk 'BEGIN {FS="#"; print "/* function pointer declaration */\n"} /^#/ {next;} /include#/ {next;} { if (NF < 4) next; gsub("[$]","tdi_"$1); print "extern "$2";"}' >> tdi-dlgen.h

#generate the define sequence

cat <<End >> tdi-dlgen.h
/* redefine the standard calls */

#ifndef DONT_REDEFINE_STANDARD_CALLS

End

sort $1 | awk 'BEGIN {FS="#";} /^#/ {next;} /include#/ {next;} { if (NF < 4) next; print "#define " $1 " tdi_" $1 }' >> tdi-dlgen.h

cat <<End >> tdi-dlgen.h

#endif /* DONT_REDEFINE_STANDARD_CALLS */

End
echo done.

# b) we generate the .c-file
#    - include the generated include file
#    - define the function pointers
#    - assemble the libopen and libclose functions 

echo -n Creating tdi-dlgen.c ...

cat <<End > tdi-dlgen.ca 
/* 

  this file was generated by `basename $0` on `date`           
                                                               
  !! DON'T EDIT THIS FILE, IT WILL BE OVERWRITTEN NEXT TIME !!

*/

End

#generate the sequence of func_ptr definitions
sort $1 | awk 'BEGIN {FS="#"; print "#define DONT_REDEFINE_STANDARD_CALLS\n#include \"tdi-dlgen.h\"\n#include <dlfcn.h>\n/* function pointer definition */\n"} /^#/ {next;} { if (NF < 3) next; gsub("[$]","tdi_"$1); print $2";"}' >> tdi-dlgen.ca

#generate the tdi_libopen

MAX_LIB=30

cat <<End >> tdi-dlgen.ca

/* library array */

#define MAXLIB $MAX_LIB

void* tdi_libhandle[MAXLIB];
int lib_open = 0;

int
tdi_islibopen() {
  return lib_open;
}

int
tdi_libopen() {
End


LIBS=`sort -t# -k3 $1 | awk 'BEGIN {FS="#";LASTLIB="";LIBNR=0;} /^#/ {next;} { if ($3 != LASTLIB) { print $3;LASTLIB=$3;}}'` 

LIBNR=0

for i in $LIBS 
 do
  if test '$i == "/usr/lib/libc.so"'; then libopen=$2; else libopen=$i; fi
  #generate the sequence of func_ptr declarations
  cat $1 | awk 'BEGIN {FS="#"; PRE=0} /^#/ {next;} { if (PRE==0) {print "\n/* function pointer assignment */\n\n\ttdi_libhandle[" LIBNO "] = dlopen(\"" LIBOPEN "\",RTLD_LAZY);\n";PRE=1;}; if (NF < 4 || $3!=LIB) next; gsub("[$]",""); print "\ttdi_"$1 "= ("$2") dlsym(tdi_libhandle["LIBNO"],\""$1"\"); if (dlerror()!=NULL) return -1;"}' LIB=$i LIBOPEN=$libopen LIBNO=$LIBNR  >> tdi-dlgen.ca
  LIBNR=`expr $LIBNR + 1`
 done

# the tail of the libopen function and libclose
cat <<End >> tdi-dlgen.ca

  lib_open=1;

  return 0;

}

int 
tdi_libclose() { 

/* 0  means O.K., -1 means error */

int libclose_error = 0;

End


LIBNR=0

for i in $LIBS
 do
  echo "     dlclose(tdi_libhandle[$LIBNR]); if (dlerror()!=NULL) libclose_error = -1;" >> tdi-dlgen.ca
  LIBNR=`expr $LIBNR + 1`
 done

cat <<End >> tdi-dlgen.ca

 lib_open=0;

 return libclose_error;

}
/* end of tdi-dlgen.c */ 
End

mv tdi-dlgen.ca tdi-dlgen.c

echo done.


















