From 4b5e5d0cc823f44aba7f12c5c215b06903ee3d99 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 21 Apr 2016 00:35:00 +0200 Subject: [PATCH] Allow to use the original name of the global functions It is impossible to have two functions with the same name inside the same program, but it is possible to provide a #define to allow the user code to use the original function name for the wrapper function, so do it for convenience. Remove the old changes adding explicit "_wrap_" prefix to the examples and the tests and remove the few more now passing tests from the list of failing tests. --- Doc/Manual/C.html | 2 +- Examples/c/simple/runme.c | 2 +- Examples/test-suite/c/Makefile.in | 3 --- Examples/test-suite/c/cpp_basic_runme.c | 8 +++--- .../c/cpp_basic_template_function_runme.c | 2 +- Source/Modules/c.cxx | 27 ++++++++++++++++++- 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Doc/Manual/C.html b/Doc/Manual/C.html index dee6f73f4..c8859f208 100644 --- a/Doc/Manual/C.html +++ b/Doc/Manual/C.html @@ -192,7 +192,7 @@ Wrapping C functions and variables is obviously performed in a straightforward w

-For each C function declared in the interface file a wrapper function is created. Basically, the wrapper function performs a call to the original function, and returns its result. +For each C function declared in the interface file a wrapper function with the prefix _wrap_ is created. Basically, the wrapper function performs a call to the original function, and returns its result. For convenience, a #define func _wrap_func is also provided in the generated header file to make it possible to call the function under its original name. If this is undesirable, SWIG_NO_WRAPPER_ALIASES can be predefined before including the wrapper header to disable these defines.

diff --git a/Examples/c/simple/runme.c b/Examples/c/simple/runme.c index fff159dfc..dd01a209c 100644 --- a/Examples/c/simple/runme.c +++ b/Examples/c/simple/runme.c @@ -5,7 +5,7 @@ int main(int argc, char **argv) { int a = 42; int b = 105; - int g = _wrap_gcd(a, b); + int g = gcd(a, b); printf("The gcd of %d and %d is %d\n", a, b, g); printf("Foo = %f\n", Foo); Foo = 3.1415926; diff --git a/Examples/test-suite/c/Makefile.in b/Examples/test-suite/c/Makefile.in index 85eeb420a..5e4a30365 100644 --- a/Examples/test-suite/c/Makefile.in +++ b/Examples/test-suite/c/Makefile.in @@ -54,8 +54,6 @@ FAILING_CPP_TESTS := \ arrays_global_twodim \ char_strings \ constant_pointers \ - c_backend_cpp_natural_std_string \ - c_backend_cpp_exception \ default_arg_values \ default_args \ default_constructor \ @@ -89,7 +87,6 @@ FAILING_CPP_TESTS := \ nested_class \ nested_scope \ nested_template_base \ - operator_overload \ overload_arrays \ smart_pointer_extend \ smart_pointer_not \ diff --git a/Examples/test-suite/c/cpp_basic_runme.c b/Examples/test-suite/c/cpp_basic_runme.c index 20aec75ab..ff16981b1 100644 --- a/Examples/test-suite/c/cpp_basic_runme.c +++ b/Examples/test-suite/c/cpp_basic_runme.c @@ -85,12 +85,12 @@ int main(int argc, const char *argv[]) { // getting, setting and calling function pointers isn't supported yet #if 0 - SomeTypeForMemFnPtr func1 = _wrap_get_func1_ptr(); + SomeTypeForMemFnPtr func1 = get_func1_ptr(); Foo_func_ptr_set(f, func1); - assert(_wrap_test_func_ptr(f, 2) == 28); - SomeTypeForMemFnPtr func2 = _wrap_get_func2_ptr(); + assert(test_func_ptr(f, 2) == 28); + SomeTypeForMemFnPtr func2 = get_func2_ptr(); Foo_func_ptr_set(f, func2); - assert(_wrap_test_func_ptr(f, 2) == -14); + assert(test_func_ptr(f, 2) == -14); #endif delete_Bar(b); diff --git a/Examples/test-suite/c/cpp_basic_template_function_runme.c b/Examples/test-suite/c/cpp_basic_template_function_runme.c index 920d35a7e..51ccdb0cf 100644 --- a/Examples/test-suite/c/cpp_basic_template_function_runme.c +++ b/Examples/test-suite/c/cpp_basic_template_function_runme.c @@ -2,7 +2,7 @@ #include "cpp_basic_template_function/cpp_basic_template_function_wrap.h" int main() { - assert(_wrap_GetMaxInt(3, 5) == 5); + assert(GetMaxInt(3, 5) == 5); return 0; } diff --git a/Source/Modules/c.cxx b/Source/Modules/c.cxx index 4e879f39d..7231afe39 100644 --- a/Source/Modules/c.cxx +++ b/Source/Modules/c.cxx @@ -107,6 +107,7 @@ class C:public Language { File *f_wrappers_cxx; File *f_wrappers_types; File *f_wrappers_decl; + File *f_wrappers_aliases; File *f_init; String *empty_string; @@ -416,6 +417,11 @@ public: f_wrappers_types = NewString(""); f_wrappers_decl = NewString(""); + // We also define aliases for the global wrapper functions to allow calling them using their original names, but as this can result in problems (as usual + // when using the preprocessor), we provide a way to disable this by defining SWIG_NO_WRAPPER_ALIASES when compiling the generated code and so we use a + // separate section for this too. + f_wrappers_aliases = NIL; + { cplusplus_output_guard @@ -434,6 +440,13 @@ public: Dump(f_wrappers_h_body, f_wrappers_h); Delete(f_wrappers_h_body); + + if (f_wrappers_aliases) { + Dump(f_wrappers_aliases, f_wrappers_h); + Delete(f_wrappers_aliases); + + Printv(f_wrappers_h, "#endif /* SWIG_NO_WRAPPER_ALIASES */\n", NIL); + } } // close wrapper header guard // write all to the file @@ -928,12 +941,14 @@ ready: * emit_wrapper_func_decl() * * Declares the wrapper function, using the C types used for it, in the header. + * Also emits a define allowing to use the function without the "_wrap_" prefix. * The node here is a function declaration. * ---------------------------------------------------------------------- */ void emit_wrapper_func_decl(Node *n, String *name) { // C++ function wrapper proxy code - String *wname = IS_SET_TO_ONE(n, "c:globalfun") ? Swig_name_wrapper(name) : Copy(name); + bool const is_global = IS_SET_TO_ONE(n, "c:globalfun"); + String *wname = is_global ? Swig_name_wrapper(name) : Copy(name); String *preturn_type = get_wrapper_func_return_type(n); String *pproto = get_wrapper_func_proto(n); String *wrapper_call = NewString(""); @@ -941,6 +956,16 @@ ready: // add function declaration to the proxy header file Printv(f_wrappers_decl, preturn_type, " ", wname, "(", pproto, ");\n\n", NIL); + if (is_global) { + if (!f_wrappers_aliases) { + // Allocate it on demand. + f_wrappers_aliases = NewStringEmpty(); + Printv(f_wrappers_aliases, "#ifndef SWIG_NO_WRAPPER_ALIASES\n", NIL); + } + + Printf(f_wrappers_aliases, "#define %s %s\n", name, wname); + } + // cleanup Delete(wname); Delete(pproto);