diff --git a/Examples/Makefile.in b/Examples/Makefile.in index b6a457b4d..3edb75f8d 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -1105,11 +1105,9 @@ c: $(SRCS) $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(CLIBPREFIX)$(TARGET)$(SO) $(CC) $(MAIN) $(TARGET)_proxy.c -L. -l$(TARGET) - LD_LIBRARY_PATH=`pwd`:LD_LIBRARY_PATH; export LD_LIBRARY_PATH c_cpp: $(SRCS) $(SWIG) -c++ -c $(SWIGOPT) $(INTERFACE) $(CXX) -c $(CCSHARED) $(CXXFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(CLIBPREFIX)$(TARGET)$(SO) $(CC) $(MAIN) $(TARGET)_proxy.c -L. -l$(TARGET) - LD_LIBRARY_PATH=`pwd`:LD_LIBRARY_PATH; export LD_LIBRARY_PATH diff --git a/Examples/c/class/Makefile b/Examples/c/class/Makefile index 0dbbb5c18..c19797921 100644 --- a/Examples/c/class/Makefile +++ b/Examples/c/class/Makefile @@ -10,5 +10,5 @@ all:: TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' MAIN='$(MAIN)' c_cpp clean: - rm -f *.o *.out *.so *.a + rm -f *.o *.out *.so *.a *.dll *.exe *_wrap* *_proxy* *~ diff --git a/Examples/c/reference/Makefile b/Examples/c/reference/Makefile new file mode 100644 index 000000000..499888730 --- /dev/null +++ b/Examples/c/reference/Makefile @@ -0,0 +1,14 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig -debug-module 4 +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +MAIN = main.c + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' MAIN='$(MAIN)' c_cpp + +clean: + rm -f *.o *.out *.so *.a *.dll *.exe *_wrap* *_proxy* *~ + diff --git a/Examples/c/reference/example.cxx b/Examples/c/reference/example.cxx new file mode 100644 index 000000000..7dfb9054d --- /dev/null +++ b/Examples/c/reference/example.cxx @@ -0,0 +1,19 @@ +#include + +#include "example.h" + +void foo_by_val(Bar foo) { + foo.set(123); + printf("inside foo_by_val: %d\n", foo.get()); +} + +void foo_by_ref(Bar& foo) { + foo.set(123); + printf("inside foo_by_ref: %d\n", foo.get()); +} + +void foo_by_ptr(Bar* foo) { + foo->set(123); + printf("inside foo_by_ptr: %d\n", foo->get()); +} + diff --git a/Examples/c/reference/example.h b/Examples/c/reference/example.h new file mode 100644 index 000000000..bef5a765e --- /dev/null +++ b/Examples/c/reference/example.h @@ -0,0 +1,16 @@ +#include + +class Bar { +private: + int x; +public: + Bar() : x(0) {} + ~Bar() {} + void set(int x) { this->x = x; } + int get() { return x; } +}; + +/*void foo_by_val(Bar bar); +void foo_by_ref(Bar& bar);*/ +void foo_by_ptr(Bar* bar); + diff --git a/Examples/c/reference/example.i b/Examples/c/reference/example.i new file mode 100644 index 000000000..aed792dce --- /dev/null +++ b/Examples/c/reference/example.i @@ -0,0 +1,8 @@ +%module example + +%{ +#include "example.h" +%} + +%include "example.h" + diff --git a/Examples/c/reference/main.c b/Examples/c/reference/main.c new file mode 100644 index 000000000..ae1cab34e --- /dev/null +++ b/Examples/c/reference/main.c @@ -0,0 +1,12 @@ +#include + +#include "example_proxy.h" + +int main(int argc, char** argv) { + Bar * bar = new_Bar(); + foo_by_ptr(bar); + + delete_Bar(bar); + return 0; +} + diff --git a/Examples/c/simple/Makefile b/Examples/c/simple/Makefile index 2b0f5e47a..03eaf3d28 100644 --- a/Examples/c/simple/Makefile +++ b/Examples/c/simple/Makefile @@ -1,5 +1,5 @@ TOP = ../.. -SWIG = $(TOP)/../preinst-swig +SWIG = $(TOP)/../preinst-swig -debug-module 4 > tree.txt SRCS = example.c TARGET = example INTERFACE = example.i @@ -10,5 +10,5 @@ all:: TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' MAIN='$(MAIN)' c clean: - rm -f *.o *.so *.out *.a *~ + rm -f *.o *.so *.out *.a *.exe *.dll *_wrap* *_proxy* *~ diff --git a/Examples/c/simple/example.c b/Examples/c/simple/example.c index 6bd36a3d6..56be8799e 100644 --- a/Examples/c/simple/example.c +++ b/Examples/c/simple/example.c @@ -22,5 +22,3 @@ int gcd(int x, int y) { } return g; } - - diff --git a/Examples/python/class/example.i b/Examples/python/class/example.i index 75700b305..0bf3285ca 100644 --- a/Examples/python/class/example.i +++ b/Examples/python/class/example.i @@ -5,6 +5,10 @@ #include "example.h" %} +%typemap(in) double { + /* hello */ +} + /* Let's just grab the original header file here */ %include "example.h" diff --git a/Lib/c/c.swg b/Lib/c/c.swg index e69de29bb..aa9fcc279 100644 --- a/Lib/c/c.swg +++ b/Lib/c/c.swg @@ -0,0 +1,22 @@ +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * c.swg + * ----------------------------------------------------------------------------- */ + +%typemap(ctype) short "short" +%typemap(ctype) int "int" +%typemap(ctype) long "long" +%typemap(ctype) char "char" +%typemap(ctype) float "float" +%typemap(ctype) double "double" +%typemap(ctype) bool "_Bool" +%typemap(ctype) SWIGTYPE "struct $*1_typeObj *" + +%typemap(in) short, int, long, char, float, double, bool "$1 = $input;" + +%typemap(in) SWIGTYPE { + $1 = ($1_type) $input->obj; +} + diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h index 174e8b001..72e394c98 100644 --- a/Source/Include/swigwarn.h +++ b/Source/Include/swigwarn.h @@ -252,6 +252,10 @@ /* please leave 870-889 free for Php */ +#define WARN_C_TYPEMAP_CTYPE_UNDEF 890 + +/* please leave 890-909 free for C */ + /* Feel free to claim any number in this space that's not currently being used. Just make sure you add an entry here */ diff --git a/Source/Modules/c.cxx b/Source/Modules/c.cxx index 020954bb1..89fe955a3 100644 --- a/Source/Modules/c.cxx +++ b/Source/Modules/c.cxx @@ -72,12 +72,12 @@ public: void emitSwigProtectSymbols(File *f) { Printf(f, "#ifndef SWIGPROTECT\n"); Printf(f, "# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)\n"); - Printf(f, "# define SWIGPROTECT //\n"); + Printf(f, "# define SWIGPROTECT(x)\n"); Printf(f, "# else\n"); Printf(f, "# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)\n"); - Printf(f, "# define SWIGPROTECT __attribute__ ((visibility(\"protected\")))\n"); + Printf(f, "# define SWIGPROTECT(x) __attribute__ ((visibility(\"protected\"))) x\n"); Printf(f, "# else\n"); - Printf(f, "# define SWIGPROTECT //\n"); + Printf(f, "# define SWIGPROTECT(x)\n"); Printf(f, "# endif\n"); Printf(f, "# endif\n"); Printf(f, "#endif\n\n"); @@ -226,6 +226,26 @@ public: return SWIG_OK; } + /* ----------------------------------------------------------------------- + * globalfunctionHandler() + * ------------------------------------------------------------------------ */ + + virtual int globalfunctionHandler(Node *n ) { + String* vis_hint = NewString(""); + String* return_type_str = SwigType_str(Getattr(n, "type"), 0); + String* name = Getattr(n, "sym:name"); + ParmList* parms = Getattr(n, "parms"); + + Language::globalfunctionHandler(n); + + // add visibility hint for the compiler (do not override this symbol) + Printv(vis_hint, "SWIGPROTECT(", return_type_str, " ", name, "(", ParmList_str(parms), ");)\n\n", NIL); + Printv(f_wrappers, vis_hint, NIL); + + Delete(vis_hint); + return SWIG_OK; + } + /* ---------------------------------------------------------------------- * functionWrapper() * ---------------------------------------------------------------------- */ @@ -236,6 +256,8 @@ public: String *return_type_str = SwigType_str(return_type, 0); String *arg_names = NewString(""); ParmList *parms = Getattr(n, "parms"); + Parm *p; + String* tm; // create new function wrapper object Wrapper *wrapper = NewWrapper(); @@ -250,16 +272,66 @@ public: // attach the standard typemaps emit_attach_parmmaps(parms, wrapper); - // prepare parameter list - Parm *p, *np; + // attach 'ctype' typemaps + Swig_typemap_attach_parms("ctype", parms, wrapper); + + Setattr(n, "wrap:parms", parms); + + // emit variables for holding parameters + emit_parameter_variables(parms, wrapper); + + // prepare function definition + int gencomma = 0; for (p = parms; p; ) { - np = nextSibling(p); - SwigType *type = Getattr(p, "type"); - Printv(wrapper->def, SwigType_str(type, 0), " ", Getattr(p, "lname"), np ? ", " : "", NIL); - Printv(arg_names, Getattr(p, "name"), np ? ", " : "", NIL); - p = np; + + while (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + } + + SwigType* type = Getattr(p, "type"); + String* lname = Getattr(p, "lname"); + String* c_parm_type = NewString(""); + String* arg_name = NewString(""); + + Printf(arg_name, "c%s", lname); + + if ((tm = Getattr(p, "tmap:ctype"))) { + if (Cmp(Getattr(p, "c:immutable"), "1") == 0) { + Printv(c_parm_type, SwigType_str(type, 0), NIL); + } + else { + Printv(c_parm_type, tm, NIL); + } + } + else { + Swig_warning(WARN_C_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(type, 0)); + } + + Printv(arg_names, gencomma ? ", " : "", Getattr(p, "name"), NIL); + Printv(wrapper->def, gencomma ? ", " : "", c_parm_type, " ", arg_name, NIL); + gencomma = 1; + + if ((tm = Getattr(p, "tmap:in"))) { + if (Cmp(Getattr(p, "c:immutable"), "1") == 0) { + // FIXME + Printv(wrapper->code, lname, " = ", arg_name, ";\n", NIL); + } + else { + Replaceall(tm, "$input", arg_name); + Setattr(p, "emit:input", arg_name); + Printf(wrapper->code, "%s\n", tm); + } + p = Getattr(p, "tmap:in:next"); + } + else { + Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(type, 0)); + p = nextSibling(p); + } + Delete(arg_name); + Delete(c_parm_type); } - Printv(wrapper->def, ") {", NIL); + + Printf(wrapper->def, ") {"); // declare wrapper function local variables emit_return_variable(n, return_type, wrapper); @@ -277,19 +349,24 @@ public: if (shadow_flag) { // use shadow-type for parameter if supplied String* proto; - String* stype = Getattr(parms, "stype"); - if (stype) { - Swig_save("temp", parms, "type", NIL); - Setattr(parms, "type", stype); - proto = ParmList_str(parms); - Swig_restore(parms); + if (parms) { + String* stype = Getattr(parms, "c:stype"); + if (stype) { + Swig_save("temp", parms, "type", NIL); + Setattr(parms, "type", stype); + proto = ParmList_str(parms); + Swig_restore(parms); + } + else { + proto = ParmList_str(parms); + } } else { - proto = ParmList_str(parms); + proto = empty_string; } // use shadow-type for return type if supplied - SwigType* shadow_type = Getattr(n, "stype"); + SwigType* shadow_type = Getattr(n, "c:stype"); if (shadow_type) { return_type_str = SwigType_str(shadow_type, 0); } @@ -329,12 +406,6 @@ public: Printv(f_shadow_header, return_type_str, " ", name, "(", proto, ");\n"); } - // add visibility hint for the compiler - String* vis_hint = NewString(""); - Printv(vis_hint, "SWIGPROTECT ", return_type_str, " ", name, "(", ParmList_str(parms), ");\n", NIL); - Printv(f_init, vis_hint, NIL); - Delete(vis_hint); - // cleanup Delete(arg_names); Delete(wname); @@ -395,7 +466,8 @@ public: Parm* p = NewParm(ctype, "self"); stype = Copy(classname); SwigType_add_pointer(stype); - Setattr(p, "stype", stype); + Setattr(p, "c:stype", stype); + Setattr(p, "c:immutable", "1"); if (parms) set_nextSibling(p, parms); Setattr(n, "parms", p); @@ -461,7 +533,8 @@ public: Parm* p = NewParm(ctype, "self"); stype = Copy(classname); SwigType_add_pointer(stype); - Setattr(p, "stype", stype); + Setattr(p, "c:stype", stype); + Setattr(p, "c:immutable", "1"); Setattr(p, "lname", "arg1"); // create second argument @@ -533,7 +606,7 @@ public: Setattr(n, "type", ctype); stype = Copy(name); SwigType_add_pointer(stype); - Setattr(n, "stype", stype); + Setattr(n, "c:stype", stype); // generate action code Printv(code, "result = (", sobj_name, "*) malloc(sizeof(", sobj_name, "));\n", NIL); @@ -576,7 +649,8 @@ public: Setattr(p, "lname", "arg1"); stype = Copy(name); SwigType_add_pointer(stype); - Setattr(p, "stype", stype); + Setattr(p, "c:stype", stype); + Setattr(p, "c:immutable", "1"); Setattr(n, "parms", p); Setattr(n, "type", "void");