From 9a3e12fe127d1f66139ae5014fde70310b83aa5d Mon Sep 17 00:00:00 2001 From: manus Date: Fri, 7 Dec 2007 01:08:12 +0000 Subject: [PATCH] Ensured that the library also works in finalized mode. The issue is that in finalized mode more than one copy of `eiffel_curl.h' could be present, meaning that multiple values of each static declared variables could be present at run-time and in one case, one was properly initialized, but not the other. Fixes bug#13671. git-svn-id: https://svn.origo.ethz.ch/eiffelstudio/trunk/Src/library/cURL@71399 8089f293-4706-0410-a29e-feb5c42a2edf --- Clib/Makefile-win.SH | 67 +++++++++++++++++ Clib/Makefile.SH | 94 +++++++++++++++++++++++ Clib/eiffel_curl.c | 149 ++++++++++++++++++++++++++++++++++++ cURL.ecf | 32 ++++++++ spec/include/eiffel_curl.h | 150 +++++-------------------------------- 5 files changed, 361 insertions(+), 131 deletions(-) create mode 100644 Clib/Makefile-win.SH create mode 100644 Clib/Makefile.SH create mode 100644 Clib/eiffel_curl.c diff --git a/Clib/Makefile-win.SH b/Clib/Makefile-win.SH new file mode 100644 index 00000000..11f90ca1 --- /dev/null +++ b/Clib/Makefile-win.SH @@ -0,0 +1,67 @@ +TOP = .. +DIR = $dir_sep +OUTDIR= . +INDIR= . +CC = $cc +OUTPUT_CMD = $output_cmd +CFLAGS = -I"$rt_include" -I..$(DIR)spec$(DIR)include -I. \ + -I..$(DIR)..$(DIR)..$(DIR)C_library$(DIR)libpng -I..$(DIR)..$(DIR)..$(DIR)C_library$(DIR)zlib +JCFLAGS = $(CFLAGS) $ccflags $optimize +JMTCFLAGS = $(CFLAGS) $mtccflags $optimize +JILCFLAGS = $(CFLAGS) $mtccflags $optimize -DEIF_IL_DLL +LN = copy +MV = $mv +RM = $del +MKDIR_TARGET = $mkdir_target +LINK = $link32 +DLL_FLAGS = $dll_flags +DLL_LIBS = $dll_libs +OBJECTS = eiffel_curl.$obj +MT_OBJECTS = MTeiffel_curl.$obj +IL_OBJECTS = ILeiffel_curl.$obj + +.c.$obj: + $(CC) -c $(JCFLAGS) $< + +all:: lib_dir $output_libraries clean + +standard:: eiffel_curl.lib ileiffel_curl.lib +mtstandard:: mteiffel_curl.lib + +..$(DIR)spec: + $(MKDIR_TARGET) + +..$(DIR)spec$(DIR)$(ISE_C_COMPILER): ..$(DIR)spec + $(MKDIR_TARGET) + +..$(DIR)spec$(DIR)$(ISE_C_COMPILER)$(DIR)$(ISE_PLATFORM): ..$(DIR)spec$(DIR)$(ISE_C_COMPILER) + $(MKDIR_TARGET) + +..$(DIR)spec$(DIR)$(ISE_C_COMPILER)$(DIR)$(ISE_PLATFORM)$(DIR)lib: ..$(DIR)spec$(DIR)$(ISE_C_COMPILER)$(DIR)$(ISE_PLATFORM) + $(MKDIR_TARGET) + +lib_dir: ..$(DIR)spec$(DIR)$(ISE_C_COMPILER)$(DIR)$(ISE_PLATFORM)$(DIR)lib + +clean: + $(RM) *.$obj + $(RM) *.lib + +eiffel_curl.lib: $(OBJECTS) + $alib_line + $(MV) $@ ..$(DIR)spec$(DIR)$(ISE_C_COMPILER)$(DIR)$(ISE_PLATFORM)$(DIR)lib$(DIR)$@ + +mteiffel_curl.lib: $(MT_OBJECTS) + $alib_line + $(MV) $@ ..$(DIR)spec$(DIR)$(ISE_C_COMPILER)$(DIR)$(ISE_PLATFORM)$(DIR)lib$(DIR)$@ + +ileiffel_curl.lib: $(IL_OBJECTS) + $alib_line + $(MV) $@ ..$(DIR)spec$(DIR)$(ISE_C_COMPILER)$(DIR)$(ISE_PLATFORM)$(DIR)lib$(DIR)$@ + +#Multithreaded targets. +MTeiffel_curl.$obj: eiffel_curl.c + $(CC) $(JMTCFLAGS) $(OUTPUT_CMD)$@ -c $? + +#.NET targets. +ILeiffel_curl.$obj: eiffel_curl.c + $(CC) $(JILCFLAGS) $(OUTPUT_CMD)$@ -c $? diff --git a/Clib/Makefile.SH b/Clib/Makefile.SH new file mode 100644 index 00000000..325dbfe8 --- /dev/null +++ b/Clib/Makefile.SH @@ -0,0 +1,94 @@ +case $CONFIG in +'') + if test ! -f config.sh; then + (echo "Can't find config.sh."; exit 1) + fi 2>/dev/null + . ./config.sh + ;; +esac +case "$0" in +*/*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac +echo "Extracting "."/Makefile (with variable substitutions)" +$spitshell >Makefile <>Makefile <<'!NO!SUBS!' + +MT_OBJECTS = MTeiffel_curl.o +OBJECTS = eiffel_curl.o + +ALL_OBJECTS = $(OBJECTS) $(MT_OBJECTS) + +all: $(ALL_OBJECTS) + $(MKDIR) ../spec/$(PLATFORM)/lib + $(MV) $? ../spec/$(PLATFORM)/lib + $(MAKE) clobber + +MTeiffel_curl.o: eiffel_curl.c + $(CC) -c $(MTCFLAGS) $? -o $@ + +local_realclean:: + $(RM) $(ALL_OBJECTS) +######################################################################## +# Common rules for all Makefiles -- do not edit + +emptyrule:: + +clean: local_clean +realclean: local_realclean +clobber: local_clobber + +local_clean:: + $(RM) core *~ *.o + +local_realclean:: local_clean + +local_clobber:: local_realclean + $(RM) Makefile config.sh + +Makefile: Makefile.SH + /bin/sh Makefile.SH + +tags:: + $(CTAGS) -w *.[ch] + $(CTAGS) -xw *.[ch] > tags + +local_clobber:: + $(RM) tags + +######################################################################## +# Dependencies generated by make depend +# DO NOT DELETE THIS LINE -- make depend relies on it + +# Put nothing here or make depend will gobble it up +.FORCE_DEPEND:: + @echo "You must run 'make depend' in $(TOP) first."; exit 1 +!NO!SUBS! +chmod 644 Makefile +$eunicefix Makefile + diff --git a/Clib/eiffel_curl.c b/Clib/eiffel_curl.c new file mode 100644 index 00000000..a3ea435d --- /dev/null +++ b/Clib/eiffel_curl.c @@ -0,0 +1,149 @@ +/* +indexing + description: "Functions used by the class CURL_FUNCTION." + copyright: "Copyright (c) 1984-2006, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 356 Storke Road, Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +*/ + +#include "eiffel_curl.h" + +typedef EIF_INTEGER (* EIF_CURL_PROGRESS_PROC) ( +#ifndef EIF_IL_DLL + EIF_REFERENCE, /* CURL_FUNCTION Eiffel object */ +#endif + EIF_POINTER, /* a_user_pointer */ + EIF_REAL_64, /* a_dltotal */ + EIF_REAL_64, /* a_dlnow */ + EIF_REAL_64, /* a_ultotal */ + EIF_REAL_64 /* a_ulnow */ + ); + +typedef EIF_INTEGER (* EIF_CURL_WRITE_PROC) ( +#ifndef EIF_IL_DLL + EIF_REFERENCE, /* CURL_FUNCTION Eiffel object */ +#endif + EIF_POINTER, /* a_data_pointer */ + EIF_INTEGER, /* a_size */ + EIF_INTEGER, /* a_nmemb */ + EIF_POINTER /* a_write_pointer */ + ); + +typedef EIF_INTEGER (* EIF_CURL_DEBUG_PROC) ( +#ifndef EIF_IL_DLL + EIF_REFERENCE, /* CURL_FUNCTION Eiffel object */ +#endif + EIF_POINTER, /* a_curl_handle */ + EIF_INTEGER, /* a_curl_infotype */ + EIF_POINTER, /* a_char_pointer */ + EIF_INTEGER, /* a_size */ + EIF_POINTER /* a_user_pointer */ + ); + +static EIF_OBJECT eiffel_function_object = NULL; + /* Address of Eiffel object CURL_FUNCTION */ + +static EIF_CURL_PROGRESS_PROC eiffel_progress_function = NULL; + /* Address of Eiffel CURL_FUNCTION.progress_function */ + +static EIF_CURL_WRITE_PROC eiffel_write_function = NULL; + /* Address of Eiffel CURL_FUNCTION.write_function */ + +static EIF_CURL_DEBUG_PROC eiffel_debug_function = NULL; + /* Address of Eiffel CURL_FUNCTION.debug_function */ + +/* Set Eiffel CURL_FUNCTION object address */ +void c_set_object(EIF_REFERENCE a_address) +{ + if (a_address) { + eiffel_function_object = eif_protect (a_address); + } else { + eiffel_function_object = NULL; + } +} + +/* Release Eiffel CURL_FUNCTION object address */ +void c_release_object() +{ + eif_wean (eiffel_function_object); +} + +/* Set CURL_FUNCTOIN.progress_function address */ +void c_set_progress_function_address( EIF_POINTER a_address) +{ + eiffel_progress_function = (EIF_CURL_PROGRESS_PROC) a_address; +} + +/* Set CURL_FUNCTOIN.write_function address */ +void c_set_write_function_address( EIF_POINTER a_address) +{ + eiffel_write_function = (EIF_CURL_WRITE_PROC) a_address; +} + +/* Set CURL_FUNCTOIN.debug_function address */ +void c_set_debug_function_address (EIF_POINTER a_address) +{ + eiffel_debug_function = (EIF_CURL_DEBUG_PROC) a_address; +} + +/* Eiffel adapter function for CURLOPT_WRITEFUNCTION + We need this function since Eiffel function call need first parameter is EIF_REFERENCE. */ +size_t curl_write_function (void *ptr, size_t size, size_t nmemb, void *data) +{ + if (eiffel_function_object) { + return (size_t) ((eiffel_write_function) ( +#ifndef EIF_IL_DLL + (EIF_REFERENCE) eif_access (eiffel_function_object), +#endif + (EIF_POINTER) ptr, + (EIF_INTEGER) size, + (EIF_INTEGER) nmemb, + (EIF_POINTER) data)); + } else { + return 0; + } +} + +/* Eiffel adapter function for CURLOPT_PROGRESSFUNCTION + We need this function since Eiffel function call need first parameter is EIF_REFERENCE. */ +size_t curl_progress_function (void * a_object_id, double a_dltotal, double a_dlnow, double a_ultotal, double a_ulnow) + { + if (eiffel_function_object) { + return (size_t) ((eiffel_progress_function) ( +#ifndef EIF_IL_DLL + (EIF_REFERENCE) eif_access (eiffel_function_object), +#endif + (EIF_POINTER) a_object_id, + (EIF_REAL_64) a_dltotal, + (EIF_REAL_64) a_dlnow, + (EIF_REAL_64) a_ultotal, + (EIF_REAL_64) a_ulnow)); + } else { + return 0; + } + } + +/* Eiffel adapter function for CURLOPT_DEBUGFUNCTION + We need this function since Eiffel function call need first parameter is EIF_REFERENCE. */ +size_t curl_debug_function (CURL * a_curl_handle, curl_infotype a_curl_infotype, unsigned char * a_char_pointer, size_t a_size, void * a_object_id) + { + if (eiffel_function_object) { + return (size_t) ((eiffel_debug_function) ( +#ifndef EIF_IL_DLL + (EIF_REFERENCE) eif_access (eiffel_function_object), +#endif + (EIF_POINTER) a_curl_handle, + (EIF_INTEGER) a_curl_infotype, + (EIF_POINTER) a_char_pointer, + (EIF_INTEGER) a_size, + (EIF_POINTER) a_object_id)); + } else { + return 0; + } + } diff --git a/cURL.ecf b/cURL.ecf index b92ba6cd..0ba49079 100644 --- a/cURL.ecf +++ b/cURL.ecf @@ -23,6 +23,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spec/include/eiffel_curl.h b/spec/include/eiffel_curl.h index 95fb3f0c..e9138e2e 100644 --- a/spec/include/eiffel_curl.h +++ b/spec/include/eiffel_curl.h @@ -12,146 +12,34 @@ indexing ]" */ -#include -#include +#ifndef _eiffel_curl_h_ +#define _eiffel_curl_h_ + +#include "eif_eiffel.h" /* unix-specific */ -#ifndef EIF_WINNT +#ifndef EIF_WINDOWS #include #include #endif #include -#include "eif_main.h" - -#ifdef EIF_THREADS -#include "eif_threads.h" +#ifdef __cplusplus +extern "C" { #endif -#ifndef eiffel_curl -#define eiffel_curl - -typedef EIF_INTEGER (* EIF_CURL_PROGRESS_PROC) ( - EIF_REFERENCE, /* CURL_FUNCTION Eiffel object */ - EIF_POINTER, /* a_user_pointer */ - EIF_REAL_64, /* a_dltotal */ - EIF_REAL_64, /* a_dlnow */ - EIF_REAL_64, /* a_ultotal */ - EIF_REAL_64 /* a_ulnow */ - ); - -typedef EIF_INTEGER (* EIF_CURL_WRITE_PROC) ( - EIF_REFERENCE, /* CURL_FUNCTION Eiffel object */ - EIF_POINTER, /* a_data_pointer */ - EIF_INTEGER, /* a_size */ - EIF_INTEGER, /* a_nmemb */ - EIF_POINTER /* a_write_pointer */ - ); - -typedef EIF_INTEGER (* EIF_CURL_DEBUG_PROC) ( - EIF_REFERENCE, /* CURL_FUNCTION Eiffel object */ - EIF_POINTER, /* a_curl_handle */ - EIF_INTEGER, /* a_curl_infotype */ - EIF_POINTER, /* a_char_pointer */ - EIF_INTEGER, /* a_size */ - EIF_POINTER /* a_user_pointer */ - ); - -static EIF_OBJECT eiffel_function_object = NULL; - /* Address of Eiffel object CURL_FUNCTION */ - -static EIF_CURL_PROGRESS_PROC eiffel_progress_function = NULL; - /* Address of Eiffel CURL_FUNCTION.progress_function */ - -static EIF_CURL_WRITE_PROC eiffel_write_function = NULL; - /* Address of Eiffel CURL_FUNCTION.write_function */ - -static EIF_CURL_DEBUG_PROC eiffel_debug_function = NULL; - /* Address of Eiffel CURL_FUNCTION.debug_function */ - -/* Set Eiffel CURL_FUNCTION object address */ -static void c_set_object(EIF_REFERENCE a_address) -{ - if (a_address) { - eiffel_function_object = eif_protect (a_address); - } else { - eiffel_function_object = NULL; - } -} - -/* Release Eiffel CURL_FUNCTION object address */ -static void c_release_object() -{ - eif_wean (eiffel_function_object); -} - -/* Set CURL_FUNCTOIN.progress_function address */ -static void c_set_progress_function_address( EIF_POINTER a_address) -{ - eiffel_progress_function = (EIF_CURL_PROGRESS_PROC) a_address; -} - -/* Set CURL_FUNCTOIN.write_function address */ -static void c_set_write_function_address( EIF_POINTER a_address) -{ - eiffel_write_function = (EIF_CURL_WRITE_PROC) a_address; -} - -/* Set CURL_FUNCTOIN.debug_function address */ -static void c_set_debug_function_address (EIF_POINTER a_address) -{ - eiffel_debug_function = (EIF_CURL_DEBUG_PROC) a_address; -} - -/* Eiffel adapter function for CURLOPT_WRITEFUNCTION - We need this function since Eiffel function call need first parameter is EIF_REFERENCE. */ -static size_t curl_write_function (void *ptr, size_t size, size_t nmemb, void *data) -{ - if (eiffel_function_object) { - return (size_t) ((eiffel_write_function) ( - (EIF_REFERENCE) eif_access (eiffel_function_object), - (EIF_POINTER) ptr, - (EIF_INTEGER) size, - (EIF_INTEGER) nmemb, - (EIF_POINTER) data)); - } else { - return 0; - } -} - -/* Eiffel adapter function for CURLOPT_PROGRESSFUNCTION - We need this function since Eiffel function call need first parameter is EIF_REFERENCE. */ -static size_t curl_progress_function (void * a_object_id, double a_dltotal, double a_dlnow, double a_ultotal, double a_ulnow) - { - if (eiffel_function_object) { - return (size_t) ((eiffel_progress_function) ( - (EIF_REFERENCE) eif_access (eiffel_function_object), - (EIF_POINTER) a_object_id, - (EIF_REAL_64) a_dltotal, - (EIF_REAL_64) a_dlnow, - (EIF_REAL_64) a_ultotal, - (EIF_REAL_64) a_ulnow)); - } else { - return 0; - } - } - -/* Eiffel adapter function for CURLOPT_DEBUGFUNCTION - We need this function since Eiffel function call need first parameter is EIF_REFERENCE. */ -static size_t curl_debug_function (CURL * a_curl_handle, curl_infotype a_curl_infotype, unsigned char * a_char_pointer, size_t a_size, void * a_object_id) - { - if (eiffel_function_object) { - return (size_t) ((eiffel_debug_function) ( - (EIF_REFERENCE) eif_access (eiffel_function_object), - (EIF_POINTER) a_curl_handle, - (EIF_INTEGER) a_curl_infotype, - (EIF_POINTER) a_char_pointer, - (EIF_INTEGER) a_size, - (EIF_POINTER) a_object_id)); - } else { - return 0; - } - } +extern void c_set_object(EIF_REFERENCE a_address); +extern void c_release_object(void); +extern void c_set_progress_function_address( EIF_POINTER a_address); +extern void c_set_write_function_address( EIF_POINTER a_address); +extern void c_set_debug_function_address (EIF_POINTER a_address); +extern size_t curl_write_function (void *ptr, size_t size, size_t nmemb, void *data); +extern size_t curl_progress_function (void * a_object_id, double a_dltotal, double a_dlnow, double a_ultotal, double a_ulnow); +extern size_t curl_debug_function (CURL * a_curl_handle, curl_infotype a_curl_infotype, unsigned char * a_char_pointer, size_t a_size, void * a_object_id); +#ifdef __cplusplus +} +#endif + #endif