diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2012-04-27 18:55:37 +0000 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2012-04-27 18:55:37 +0000 |
commit | af1c6ac3c326d0ee9c5cc526e5537918d7e309f8 (patch) | |
tree | cf7c9e3af6244b8126c978c301b29159aaee9de4 /Source/Swig | |
parent | 02fbe37ae6147b64e21c153b45a9a09313668438 (diff) | |
parent | e464aa021b456425cd6c568cb7407fc0349919a5 (diff) | |
download | swig-af1c6ac3c326d0ee9c5cc526e5537918d7e309f8.tar.gz |
Merge trunk (up to just after swig 2.0.5 release - rev 13009) to gsoc2008-cherylfoil
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-cherylfoil@13017 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Diffstat (limited to 'Source/Swig')
-rw-r--r-- | Source/Swig/cwrap.c | 240 | ||||
-rw-r--r-- | Source/Swig/deprecate.c | 2 | ||||
-rw-r--r-- | Source/Swig/error.c | 85 | ||||
-rw-r--r-- | Source/Swig/fragment.c | 4 | ||||
-rw-r--r-- | Source/Swig/getopt.c | 2 | ||||
-rw-r--r-- | Source/Swig/include.c | 73 | ||||
-rw-r--r-- | Source/Swig/misc.c | 412 | ||||
-rw-r--r-- | Source/Swig/naming.c | 324 | ||||
-rw-r--r-- | Source/Swig/parms.c | 54 | ||||
-rw-r--r-- | Source/Swig/scanner.c | 210 | ||||
-rw-r--r-- | Source/Swig/stype.c | 620 | ||||
-rw-r--r-- | Source/Swig/swig.h | 247 | ||||
-rw-r--r-- | Source/Swig/swigfile.h | 34 | ||||
-rw-r--r-- | Source/Swig/swigopt.h | 4 | ||||
-rw-r--r-- | Source/Swig/swigparm.h | 6 | ||||
-rw-r--r-- | Source/Swig/swigscan.h | 9 | ||||
-rw-r--r-- | Source/Swig/swigtree.h | 4 | ||||
-rw-r--r-- | Source/Swig/swigwrap.h | 14 | ||||
-rw-r--r-- | Source/Swig/symbol.c | 184 | ||||
-rw-r--r-- | Source/Swig/tree.c | 14 | ||||
-rw-r--r-- | Source/Swig/typemap.c | 1103 | ||||
-rw-r--r-- | Source/Swig/typeobj.c | 159 | ||||
-rw-r--r-- | Source/Swig/typesys.c | 186 | ||||
-rw-r--r-- | Source/Swig/warn.c | 38 | ||||
-rw-r--r-- | Source/Swig/wrapfunc.c | 12 |
25 files changed, 2607 insertions, 1433 deletions
diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index 714613d81..5e2e6367d 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -17,6 +17,7 @@ char cvsroot_cwrap_c[] = "$Id$"; #include "swig.h" extern int cparse_cplusplus; +static const char *cresult_variable_name = "result"; static Parm *nonvoid_parms(Parm *p) { if (p) { @@ -28,7 +29,28 @@ static Parm *nonvoid_parms(Parm *p) { } /* ----------------------------------------------------------------------------- - * Swig_parm_name() + * Swig_cresult_name_set() + * + * Change the name of the variable used to hold the return value from C/C++ wrapper functions + * from the default "result". + * ----------------------------------------------------------------------------- */ + +void Swig_cresult_name_set(const char *new_name) { + cresult_variable_name = new_name; +} + +/* ----------------------------------------------------------------------------- + * Swig_cresult_name() + * + * Get the name of the variable used to hold the return value from C/C++ wrapper functions + * ----------------------------------------------------------------------------- */ + +const char *Swig_cresult_name(void) { + return cresult_variable_name; +} + +/* ----------------------------------------------------------------------------- + * Swig_cparm_name() * * Generates a name for the ith argument in an argument list * ----------------------------------------------------------------------------- */ @@ -49,7 +71,7 @@ String *Swig_cparm_name(Parm *p, int i) { * and user defined types to pointers. * ----------------------------------------------------------------------------- */ -static String *Swig_clocal(SwigType *t, const String_or_char *name, const String_or_char *value) { +static String *Swig_clocal(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr value) { String *decl; decl = NewStringEmpty(); @@ -151,7 +173,7 @@ String *Swig_wrapped_member_var_type(SwigType *t, int varcref) { } -static String *Swig_wrapped_var_deref(SwigType *t, String_or_char *name, int varcref) { +static String *Swig_wrapped_var_deref(SwigType *t, const_String_or_char_ptr name, int varcref) { if (SwigType_isclass(t)) { if (varcref) { if (cparse_cplusplus) { @@ -167,7 +189,7 @@ static String *Swig_wrapped_var_deref(SwigType *t, String_or_char *name, int var } } -static String *Swig_wrapped_var_assign(SwigType *t, const String_or_char *name, int varcref) { +static String *Swig_wrapped_var_assign(SwigType *t, const_String_or_char_ptr name, int varcref) { if (SwigType_isclass(t)) { if (varcref) { return NewStringf("%s", name); @@ -199,7 +221,11 @@ int Swig_cargs(Wrapper *w, ParmList *p) { String *type = Getattr(p, "type"); /* default values only emitted if in compact default args mode */ String *pvalue = (compactdefargs) ? Getattr(p, "value") : 0; - SwigType *altty = SwigType_alttype(type, 0); + + /* When using compactdefaultargs, the code generated initialises a variable via a constructor call that accepts the + * default value as a parameter. The default constructor is not called and therefore SwigValueWrapper is not needed. */ + SwigType *altty = pvalue ? 0 : SwigType_alttype(type, 0); + int tycode = SwigType_type(type); if (tycode == T_REFERENCE) { if (pvalue) { @@ -212,7 +238,7 @@ int Swig_cargs(Wrapper *w, ParmList *p) { SwigType_del_reference(tvalue); tycode = SwigType_type(tvalue); if (tycode != T_USER) { - /* plain primitive type, we copy the the def value */ + /* plain primitive type, we copy the def value */ String *lstr = SwigType_lstr(tvalue, defname); defvalue = NewStringf("%s = %s", lstr, qvalue); Delete(lstr); @@ -255,7 +281,7 @@ int Swig_cargs(Wrapper *w, ParmList *p) { * function call. * ----------------------------------------------------------------------------- */ -String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_char *decl) { +String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr decl) { String *fcall; fcall = NewStringEmpty(); @@ -264,10 +290,9 @@ String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_ch break; case T_REFERENCE: { - String *str = SwigType_str(t, "_result_ref"); - Printf(fcall, "{\n"); - Printf(fcall, "%s = ", str); - Delete(str); + String *lstr = SwigType_lstr(t, 0); + Printf(fcall, "%s = (%s) &", name, lstr); + Delete(lstr); } break; case T_USER: @@ -294,12 +319,6 @@ String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_ch Append(fcall, ";"); } - if (SwigType_type(t) == T_REFERENCE) { - String *lstr = SwigType_lstr(t, 0); - Printf(fcall, "\n%s = (%s) &_result_ref;\n", name, lstr); - Append(fcall, "}"); - Delete(lstr); - } return fcall; } @@ -313,7 +332,7 @@ String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_ch * * ----------------------------------------------------------------------------- */ -String *Swig_cfunction_call(String_or_char *name, ParmList *parms) { +String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms) { String *func; int i = 0; int comma = 0; @@ -380,7 +399,7 @@ String *Swig_cfunction_call(String_or_char *name, ParmList *parms) { * set to "(*this)->" or some similar sequence. * ----------------------------------------------------------------------------- */ -static String *Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self, String *explicit_qualifier, SwigType *director_type) { +static String *Swig_cmethod_call(const_String_or_char_ptr name, ParmList *parms, const_String_or_char_ptr self, String *explicit_qualifier, SwigType *director_type) { String *func, *nname; int i = 0; Parm *p = parms; @@ -472,7 +491,7 @@ static String *Swig_cmethod_call(String_or_char *name, ParmList *parms, String_o * calloc(1,sizeof(name)); * ----------------------------------------------------------------------------- */ -String *Swig_cconstructor_call(String_or_char *name) { +String *Swig_cconstructor_call(const_String_or_char_ptr name) { DOH *func; func = NewStringEmpty(); @@ -491,7 +510,7 @@ String *Swig_cconstructor_call(String_or_char *name) { * * ----------------------------------------------------------------------------- */ -String *Swig_cppconstructor_base_call(String_or_char *name, ParmList *parms, int skip_self) { +String *Swig_cppconstructor_base_call(const_String_or_char_ptr name, ParmList *parms, int skip_self) { String *func; String *nname; int i = 0; @@ -536,20 +555,20 @@ String *Swig_cppconstructor_base_call(String_or_char *name, ParmList *parms, int return func; } -String *Swig_cppconstructor_call(String_or_char *name, ParmList *parms) { +String *Swig_cppconstructor_call(const_String_or_char_ptr name, ParmList *parms) { return Swig_cppconstructor_base_call(name, parms, 0); } -String *Swig_cppconstructor_nodirector_call(String_or_char *name, ParmList *parms) { +String *Swig_cppconstructor_nodirector_call(const_String_or_char_ptr name, ParmList *parms) { return Swig_cppconstructor_base_call(name, parms, 1); } -String *Swig_cppconstructor_director_call(String_or_char *name, ParmList *parms) { +String *Swig_cppconstructor_director_call(const_String_or_char_ptr name, ParmList *parms) { return Swig_cppconstructor_base_call(name, parms, 0); } /* ----------------------------------------------------------------------------- - * Swig_rflag_search() + * recursive_flag_search() * * This function searches for the class attribute 'attr' in the class * 'n' or recursively in its bases. @@ -570,7 +589,7 @@ String *Swig_cppconstructor_director_call(String_or_char *name, ParmList *parms) * ----------------------------------------------------------------------------- */ /* #define SWIG_FAST_REC_SEARCH 1 */ -String *Swig_rflag_search(Node *n, const String *attr, const String *noattr) { +static String *recursive_flag_search(Node *n, const String *attr, const String *noattr) { String *f = 0; n = Swig_methodclass(n); if (GetFlag(n, noattr)) { @@ -584,7 +603,7 @@ String *Swig_rflag_search(Node *n, const String *attr, const String *noattr) { if (bl) { Iterator bi; for (bi = First(bl); bi.item; bi = Next(bi)) { - f = Swig_rflag_search(bi.item, attr, noattr); + f = recursive_flag_search(bi.item, attr, noattr); if (f) { #ifdef SWIG_FAST_REC_SEARCH SetFlagAttr(n, attr, f); @@ -603,12 +622,11 @@ String *Swig_rflag_search(Node *n, const String *attr, const String *noattr) { /* ----------------------------------------------------------------------------- * Swig_unref_call() * - * find the unref call, if any. + * Find the "feature:unref" call, if any. * ----------------------------------------------------------------------------- */ String *Swig_unref_call(Node *n) { - Node *cn = Swig_methodclass(n); - String *unref = Swig_rflag_search(cn, "feature:unref", "feature:nounref"); + String *unref = recursive_flag_search(n, "feature:unref", "feature:nounref"); if (unref) { String *pname = Swig_cparm_name(0, 0); unref = NewString(unref); @@ -622,12 +640,11 @@ String *Swig_unref_call(Node *n) { /* ----------------------------------------------------------------------------- * Swig_ref_call() * - * find the ref call, if any. + * Find the "feature:ref" call, if any. * ----------------------------------------------------------------------------- */ String *Swig_ref_call(Node *n, const String *lname) { - Node *cn = Swig_methodclass(n); - String *ref = Swig_rflag_search(cn, "feature:ref", "feature:noref"); + String *ref = recursive_flag_search(n, "feature:ref", "feature:noref"); if (ref) { ref = NewString(ref); Replaceall(ref, "$this", lname); @@ -645,7 +662,8 @@ String *Swig_ref_call(Node *n, const String *lname) { * ----------------------------------------------------------------------------- */ String *Swig_cdestructor_call(Node *n) { - String *unref = Swig_unref_call(n); + Node *cn = Swig_methodclass(n); + String *unref = Swig_unref_call(cn); if (unref) { return unref; @@ -667,7 +685,8 @@ String *Swig_cdestructor_call(Node *n) { * ----------------------------------------------------------------------------- */ String *Swig_cppdestructor_call(Node *n) { - String *unref = Swig_unref_call(n); + Node *cn = Swig_methodclass(n); + String *unref = Swig_unref_call(cn); if (unref) { return unref; } else { @@ -687,7 +706,7 @@ String *Swig_cppdestructor_call(Node *n) { * * ----------------------------------------------------------------------------- */ -String *Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self, int varcref) { +String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, String *self, int varcref) { String *func; String *pname0 = Swig_cparm_name(0, 0); String *pname1 = Swig_cparm_name(0, 1); @@ -722,7 +741,7 @@ String *Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_cha * * ----------------------------------------------------------------------------- */ -String *Swig_cmemberget_call(const String_or_char *name, SwigType *t, String_or_char *self, int varcref) { +String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String *self, int varcref) { String *func; String *call; String *pname0 = Swig_cparm_name(0, 0); @@ -785,16 +804,35 @@ int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parm * Converts a C++ method node to a function accessor function. * ----------------------------------------------------------------------------- */ -int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *director_type, int is_director) { - String *name, *qualifier; +int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int flags, SwigType *director_type, int is_director) { + String *name; ParmList *parms; SwigType *type; Parm *p; String *self = 0; - - /* If smart pointer, change self dereferencing */ + int is_smart_pointer_overload = 0; + String *qualifier = Getattr(n, "qualifier"); + + /* If smart pointer without const overload or mutable method, change self dereferencing */ if (flags & CWRAP_SMART_POINTER) { - self = NewString("(*this)->"); + if (flags & CWRAP_SMART_POINTER_OVERLOAD) { + if (qualifier && strncmp(Char(qualifier), "q(const)", 8) == 0) { + self = NewString("(*(this))->"); + is_smart_pointer_overload = 1; + } + else if (Cmp(Getattr(n, "storage"), "static") == 0) { + String *cname = Getattr(n, "classname") ? Getattr(n, "classname") : classname; + String *ctname = SwigType_namestr(cname); + self = NewStringf("(*(%s const *)this)->", ctname); + is_smart_pointer_overload = 1; + Delete(ctname); + } + else { + self = NewString("(*this)->"); + } + } else { + self = NewString("(*this)->"); + } } /* If node is a member template expansion, we don't allow added code */ @@ -802,7 +840,6 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc flags &= ~(CWRAP_EXTEND); name = Getattr(n, "name"); - qualifier = Getattr(n, "qualifier"); parms = CopyParmList(nonvoid_parms(Getattr(n, "parms"))); type = NewString(classname); @@ -810,7 +847,7 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc SwigType_push(type, qualifier); } SwigType_add_pointer(type); - p = NewParm(type, "self"); + p = NewParm(type, "self", n); Setattr(p, "self", "1"); Setattr(p, "hidden","1"); /* @@ -833,7 +870,7 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc These two lines just transfer the ownership of the 'this' pointer from the input to the output wrapping object. - This happens in python, but may also happens in other target + This happens in python, but may also happen in other target languages. */ if (GetFlag(n, "feature:self:disown")) { @@ -865,7 +902,7 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc } call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type); - cres = Swig_cresult(Getattr(n, "type"), "result", call); + cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call); if (pure_virtual && is_director && (flags & CWRAP_DIRECTOR_TWO_CALLS)) { String *qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname")); @@ -878,7 +915,7 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc /* Create two method calls, one to call the explicit method, the other a normal polymorphic function call */ String *cres_both_calls = NewStringf(""); String *call_extra = Swig_cmethod_call(name, p, self, 0, director_type); - String *cres_extra = Swig_cresult(Getattr(n, "type"), "result", call_extra); + String *cres_extra = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call_extra); Printv(cres_both_calls, "if (upcall) {\n", cres, "\n", "} else {", cres_extra, "\n}", NIL); Setattr(n, "wrap:action", cres_both_calls); Delete(cres_extra); @@ -899,7 +936,7 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc String *defaultargs = Getattr(n, "defaultargs"); String *code = Getattr(n, "code"); String *cname = Getattr(n, "classname") ? Getattr(n, "classname") : classname; - String *membername = Swig_name_member(cname, name); + String *membername = Swig_name_member(nspace, cname, name); String *mangled = Swig_name_mangle(membername); int is_smart_pointer = flags & CWRAP_SMART_POINTER; @@ -924,10 +961,18 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc if (Cmp(Getattr(n, "storage"), "static") != 0) { String *pname = Swig_cparm_name(pp, i); - String *ctname = SwigType_namestr(cname); - String *fadd = NewStringf("(%s*)(%s)->operator ->()", ctname, pname); + String *ctname = SwigType_namestr(cname); + String *fadd = 0; + if (is_smart_pointer_overload) { + String *nclassname = SwigType_namestr(classname); + fadd = NewStringf("(%s const *)((%s const *)%s)->operator ->()", ctname, nclassname, pname); + Delete(nclassname); + } + else { + fadd = NewStringf("(%s*)(%s)->operator ->()", ctname, pname); + } Append(func, fadd); - Delete(ctname); + Delete(ctname); Delete(fadd); Delete(pname); pp = nextSibling(pp); @@ -951,12 +996,12 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc } } Append(func, ")"); - cres = Swig_cresult(Getattr(n, "type"), "result", func); + cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), func); Setattr(n, "wrap:action", cres); Delete(cres); } else { String *call = Swig_cfunction_call(mangled, p); - String *cres = Swig_cresult(Getattr(n, "type"), "result", call); + String *cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call); Setattr(n, "wrap:action", cres); Delete(call); Delete(cres); @@ -1012,16 +1057,14 @@ Node *Swig_directormap(Node *module, String *type) { * This function creates a C wrapper for a C constructor function. * ----------------------------------------------------------------------------- */ -int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags) { +int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags) { ParmList *parms; Parm *prefix_args; Parm *p; ParmList *directorparms; SwigType *type; - Node *classNode; int use_director; - classNode = Swig_methodclass(n); use_director = Swig_directorclass(n); parms = CopyParmList(nonvoid_parms(Getattr(n, "parms"))); @@ -1052,7 +1095,7 @@ int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparis String *cres; String *defaultargs = Getattr(n, "defaultargs"); String *code = Getattr(n, "code"); - String *membername = Swig_name_construct(classname); + String *membername = Swig_name_construct(nspace, classname); String *mangled = Swig_name_mangle(membername); /* Check if the constructor is overloaded. If so, and it has code attached, we append an extra suffix @@ -1068,7 +1111,7 @@ int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparis } call = Swig_cfunction_call(mangled, parms); - cres = Swig_cresult(type, "result", call); + cres = Swig_cresult(type, Swig_cresult_name(), call); Setattr(n, "wrap:action", cres); Delete(cres); Delete(call); @@ -1099,7 +1142,7 @@ int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparis * implemented in the target language, calls to those methods will * generate Swig::DirectorPureVirtualException exceptions. */ - String *cres = Swig_cresult(type, "result", director_call); + String *cres = Swig_cresult(type, Swig_cresult_name(), director_call); Append(action, cres); Delete(cres); } else { @@ -1114,11 +1157,11 @@ int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparis Append(action, director_ctor); Replaceall(action, "$comparison", tmp_none_comparison); - cres = Swig_cresult(type, "result", director_call); + cres = Swig_cresult(type, Swig_cresult_name(), director_call); Replaceall(action, "$director_new", cres); Delete(cres); - cres = Swig_cresult(type, "result", nodirector_call); + cres = Swig_cresult(type, Swig_cresult_name(), nodirector_call); Replaceall(action, "$nondirector_new", cres); Delete(cres); } @@ -1128,14 +1171,14 @@ int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparis Delete(directorname); } else { String *call = Swig_cppconstructor_call(classname, parms); - String *cres = Swig_cresult(type, "result", call); + String *cres = Swig_cresult(type, Swig_cresult_name(), call); Setattr(n, "wrap:action", cres); Delete(cres); Delete(call); } } else { String *call = Swig_cconstructor_call(classname); - String *cres = Swig_cresult(type, "result", call); + String *cres = Swig_cresult(type, Swig_cresult_name(), call); Setattr(n, "wrap:action", cres); Delete(cres); Delete(call); @@ -1156,13 +1199,13 @@ int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparis * This function creates a C wrapper for a destructor function. * ----------------------------------------------------------------------------- */ -int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags) { +int Swig_DestructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int cplus, int flags) { SwigType *type; Parm *p; type = NewString(classname); SwigType_add_pointer(type); - p = NewParm(type, "self"); + p = NewParm(type, "self", n); Setattr(p, "self", "1"); Setattr(p, "hidden", "1"); Setattr(p, "wrap:disown", "1"); @@ -1173,7 +1216,7 @@ int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags) String *cres; String *call; String *membername, *mangled, *code; - membername = Swig_name_destroy(classname); + membername = Swig_name_destroy(nspace, classname); mangled = Swig_name_mangle(membername); code = Getattr(n, "code"); if (code) { @@ -1222,10 +1265,7 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { SwigType *ty; SwigType *type; SwigType *void_type = NewString("void"); - String *membername; - String *mangled; String *self = 0; - String *sname; int varcref = flags & CWRAP_NATURAL_VAR; @@ -1239,19 +1279,15 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { name = Getattr(n, "name"); type = Getattr(n, "type"); - sname = Swig_name_set(name); - membername = Swig_name_member(classname, sname); - mangled = Swig_name_mangle(membername); - t = NewString(classname); SwigType_add_pointer(t); - parms = NewParm(t, "self"); + parms = NewParm(t, "self", n); Setattr(parms, "self", "1"); Setattr(parms, "hidden","1"); Delete(t); ty = Swig_wrapped_member_var_type(type, varcref); - p = NewParm(ty, name); + p = NewParm(ty, name, n); Setattr(parms, "hidden", "1"); set_nextSibling(parms, p); @@ -1265,6 +1301,11 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { String *call; String *cres; String *code = Getattr(n, "code"); + + String *sname = Swig_name_set(0, name); + String *membername = Swig_name_member(0, classname, sname); + String *mangled = Swig_name_mangle(membername); + if (code) { /* I don't think this ever gets run - WSF */ Swig_add_extension_code(n, mangled, parms, void_type, code, cparse_cplusplus, "self"); @@ -1272,8 +1313,12 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { call = Swig_cfunction_call(mangled, parms); cres = NewStringf("%s;", call); Setattr(n, "wrap:action", cres); - Delete(call); + Delete(cres); + Delete(call); + Delete(mangled); + Delete(membername); + Delete(sname); } else { String *call = Swig_cmemberset_call(name, type, self, varcref); String *cres = NewStringf("%s;", call); @@ -1286,9 +1331,6 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { Delete(parms); Delete(ty); Delete(void_type); - Delete(membername); - Delete(sname); - Delete(mangled); Delete(self); return SWIG_OK; } @@ -1305,10 +1347,7 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { SwigType *t; SwigType *ty; SwigType *type; - String *membername; - String *mangled; String *self = 0; - String *gname; int varcref = flags & CWRAP_NATURAL_VAR; @@ -1317,6 +1356,10 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { Node *sn = Getattr(n, "cplus:staticbase"); String *base = Getattr(sn, "name"); self = NewStringf("%s::", base); + } else if (flags & CWRAP_SMART_POINTER_OVERLOAD) { + String *nclassname = SwigType_namestr(classname); + self = NewStringf("(*(%s const *)this)->", nclassname); + Delete(nclassname); } else { self = NewString("(*this)->"); } @@ -1328,13 +1371,9 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { name = Getattr(n, "name"); type = Getattr(n, "type"); - gname = Swig_name_get(name); - membername = Swig_name_member(classname, gname); - mangled = Swig_name_mangle(membername); - t = NewString(classname); SwigType_add_pointer(t); - parms = NewParm(t, "self"); + parms = NewParm(t, "self", n); Setattr(parms, "self", "1"); Setattr(parms, "hidden","1"); Delete(t); @@ -1343,20 +1382,28 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { if (flags & CWRAP_EXTEND) { String *call; String *cres; - String *code = Getattr(n, "code"); + + String *gname = Swig_name_get(0, name); + String *membername = Swig_name_member(0, classname, gname); + String *mangled = Swig_name_mangle(membername); + if (code) { /* I don't think this ever gets run - WSF */ Swig_add_extension_code(n, mangled, parms, ty, code, cparse_cplusplus, "self"); } call = Swig_cfunction_call(mangled, parms); - cres = Swig_cresult(ty, "result", call); + cres = Swig_cresult(ty, Swig_cresult_name(), call); Setattr(n, "wrap:action", cres); + Delete(cres); Delete(call); + Delete(mangled); + Delete(membername); + Delete(gname); } else { String *call = Swig_cmemberget_call(name, type, self, varcref); - String *cres = Swig_cresult(ty, "result", call); + String *cres = Swig_cresult(ty, Swig_cresult_name(), call); Setattr(n, "wrap:action", cres); Delete(call); Delete(cres); @@ -1365,9 +1412,6 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { Setattr(n, "parms", parms); Delete(parms); Delete(ty); - Delete(membername); - Delete(gname); - Delete(mangled); return SWIG_OK; } @@ -1390,10 +1434,10 @@ int Swig_VarsetToFunction(Node *n, int flags) { type = Getattr(n, "type"); nname = SwigType_namestr(name); ty = Swig_wrapped_var_type(type, varcref); - parms = NewParm(ty, name); + parms = NewParm(ty, name, n); if (flags & CWRAP_EXTEND) { - String *sname = Swig_name_set(name); + String *sname = Swig_name_set(0, name); String *mangled = Swig_name_mangle(sname); String *call = Swig_cfunction_call(mangled, parms); String *cres = NewStringf("%s;", call); @@ -1447,17 +1491,17 @@ int Swig_VargetToFunction(Node *n, int flags) { ty = Swig_wrapped_var_type(type, varcref); if (flags & CWRAP_EXTEND) { - String *sname = Swig_name_get(name); + String *sname = Swig_name_get(0, name); String *mangled = Swig_name_mangle(sname); call = Swig_cfunction_call(mangled, 0); - cres = Swig_cresult(ty, "result", call); + cres = Swig_cresult(ty, Swig_cresult_name(), call); Setattr(n, "wrap:action", cres); Delete(mangled); Delete(sname); } else { String *nname = SwigType_namestr(name); call = Swig_wrapped_var_assign(type, nname, varcref); - cres = Swig_cresult(ty, "result", call); + cres = Swig_cresult(ty, Swig_cresult_name(), call); Setattr(n, "wrap:action", cres); Delete(nname); } diff --git a/Source/Swig/deprecate.c b/Source/Swig/deprecate.c index f25b9a650..ead4d5bd6 100644 --- a/Source/Swig/deprecate.c +++ b/Source/Swig/deprecate.c @@ -77,7 +77,7 @@ int ParmList_is_compactdefargs(ParmList *p) { * ParmList_errorstr() * * Generate a prototype string suitable for use in error/warning messages. - * This function is aware of hidden parameters. + * Similar to ParmList_protostr() but is also aware of hidden parameters. * ---------------------------------------------------------------------- */ /* Discussion. This function is used to generate error messages, but take diff --git a/Source/Swig/error.c b/Source/Swig/error.c index 0ce53dd5b..5dfcf605b 100644 --- a/Source/Swig/error.c +++ b/Source/Swig/error.c @@ -53,16 +53,18 @@ static char wrn_wnum_fmt[64]; static char wrn_nnum_fmt[64]; static char err_line_fmt[64]; static char err_eof_fmt[64]; +static char diag_line_fmt[64]; +static char diag_eof_fmt[64]; -static String *format_filename(const String_or_char *filename); +static String *format_filename(const_String_or_char_ptr filename); /* ----------------------------------------------------------------------------- * Swig_warning() * - * Issue a warning message + * Issue a warning message on stderr. * ----------------------------------------------------------------------------- */ -void Swig_warning(int wnum, const String_or_char *filename, int line, const char *fmt, ...) { +void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const char *fmt, ...) { String *out; char *msg; int wrn = 1; @@ -122,10 +124,10 @@ void Swig_warning(int wnum, const String_or_char *filename, int line, const char /* ----------------------------------------------------------------------------- * Swig_error() * - * Issue an error message + * Issue an error message on stderr. * ----------------------------------------------------------------------------- */ -void Swig_error(const String_or_char *filename, int line, const char *fmt, ...) { +void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...) { va_list ap; String *formatted_filename = NULL; @@ -174,7 +176,7 @@ void Swig_error_silent(int s) { * Takes a comma separate list of warning numbers and puts in the filter. * ----------------------------------------------------------------------------- */ -void Swig_warnfilter(const String_or_char *wlist, int add) { +void Swig_warnfilter(const_String_or_char_ptr wlist, int add) { char *c; char *cw; String *s; @@ -249,8 +251,8 @@ void Swig_error_msg_format(ErrorMessageFormat format) { by now a switch is used to translated into one. */ switch (format) { case EMF_MICROSOFT: - fmt_line = "%s(%d)"; - fmt_eof = "%s(999999)"; /* Is there a special character for EOF? Just use a large number. */ + fmt_line = "%s(%d) "; + fmt_eof = "%s(999999) "; /* Is there a special character for EOF? Just use a large number. */ break; case EMF_STANDARD: default: @@ -258,10 +260,12 @@ void Swig_error_msg_format(ErrorMessageFormat format) { fmt_eof = "%s:EOF"; } - sprintf(wrn_wnum_fmt, "%s: %s(%%d): ", fmt_line, warning); + sprintf(wrn_wnum_fmt, "%s: %s %%d: ", fmt_line, warning); sprintf(wrn_nnum_fmt, "%s: %s: ", fmt_line, warning); sprintf(err_line_fmt, "%s: %s: ", fmt_line, error); sprintf(err_eof_fmt, "%s: %s: ", fmt_eof, error); + sprintf(diag_line_fmt, "%s: ", fmt_line); + sprintf(diag_eof_fmt, "%s: ", fmt_eof); msg_format = format; init_fmt = 1; @@ -272,10 +276,71 @@ void Swig_error_msg_format(ErrorMessageFormat format) { * * Remove double backslashes in Windows filename paths for display * ----------------------------------------------------------------------------- */ -static String *format_filename(const String_or_char *filename) { +static String *format_filename(const_String_or_char_ptr filename) { String *formatted_filename = NewString(filename); #if defined(_WIN32) Replaceall(formatted_filename, "\\\\", "\\"); #endif return formatted_filename; } + +/* ----------------------------------------------------------------------------- + * Swig_stringify_with_location() + * + * Return a string representation of any DOH object with line and file location + * information in the appropriate error message format. The string representation + * is enclosed within [] brackets after the line and file information. + * ----------------------------------------------------------------------------- */ + +String *Swig_stringify_with_location(DOH *object) { + String *str = NewStringEmpty(); + + if (!init_fmt) + Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); + + if (object) { + int line = Getline(object); + String *formatted_filename = format_filename(Getfile(object)); + if (line > 0) { + Printf(str, diag_line_fmt, formatted_filename, line); + } else { + Printf(str, diag_eof_fmt, formatted_filename); + } + if (Len(object) == 0) { + Printf(str, "[EMPTY]"); + } else { + Printf(str, "[%s]", object); + } + Delete(formatted_filename); + } else { + Printf(str, "[NULL]"); + } + + return str; +} + +/* ----------------------------------------------------------------------------- + * Swig_diagnostic() + * + * Issue a diagnostic message on stdout. + * ----------------------------------------------------------------------------- */ + +void Swig_diagnostic(const_String_or_char_ptr filename, int line, const char *fmt, ...) { + va_list ap; + String *formatted_filename = NULL; + + if (!init_fmt) + Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); + + va_start(ap, fmt); + formatted_filename = format_filename(filename); + if (line > 0) { + Printf(stdout, diag_line_fmt, formatted_filename, line); + } else { + Printf(stdout, diag_eof_fmt, formatted_filename); + } + vPrintf(stdout, fmt, ap); + va_end(ap); + Delete(formatted_filename); +} + diff --git a/Source/Swig/fragment.c b/Source/Swig/fragment.c index 896461b30..4a3fea5a2 100644 --- a/Source/Swig/fragment.c +++ b/Source/Swig/fragment.c @@ -60,6 +60,8 @@ void Swig_fragment_register(Node *fragment) { if (kwargs) { Setmeta(ccode, "kwargs", kwargs); } + Setfile(ccode, Getfile(fragment)); + Setline(ccode, Getline(fragment)); Setattr(fragments, name, ccode); if (debug) Printf(stdout, "registering fragment %s %s\n", name, section); @@ -142,7 +144,7 @@ void Swig_fragment_emit(Node *n) { if (section) { File *f = Swig_filebyname(section); if (!f) { - Swig_error(Getfile(code), Getline(code), "Bad section '%s' for code fragment '%s'\n", section, name); + Swig_error(Getfile(code), Getline(code), "Bad section '%s' in %%fragment declaration for code fragment '%s'\n", section, name); } else { if (debug) Printf(stdout, "emitting subfragment %s %s\n", name, section); diff --git a/Source/Swig/getopt.c b/Source/Swig/getopt.c index b8389b476..f6f196bfd 100644 --- a/Source/Swig/getopt.c +++ b/Source/Swig/getopt.c @@ -104,7 +104,7 @@ void Swig_check_options(int check_input) { * Generates a generic error message and exits. * ----------------------------------------------------------------------------- */ -void Swig_arg_error() { +void Swig_arg_error(void) { Printf(stderr, "SWIG : Unable to parse command line options.\n"); Printf(stderr, "Use 'swig -help' for available options.\n"); exit(1); diff --git a/Source/Swig/include.c b/Source/Swig/include.c index 79b97b4d6..3766894ae 100644 --- a/Source/Swig/include.c +++ b/Source/Swig/include.c @@ -21,6 +21,7 @@ static List *directories = 0; /* List of include directories */ static String *lastpath = 0; /* Last file that was included */ static List *pdirectories = 0; /* List of pushed directories */ static int dopush = 1; /* Whether to push directories */ +static int file_debug = 0; /* This functions determine whether to push/pop dirs in the preprocessor */ void Swig_set_push_dir(int push) { @@ -37,7 +38,7 @@ int Swig_get_push_dir(void) { * Adds a directory to the SWIG search path. * ----------------------------------------------------------------------------- */ -List *Swig_add_directory(const String_or_char *dirname) { +List *Swig_add_directory(const_String_or_char_ptr dirname) { String *adirname; if (!directories) directories = NewList(); @@ -57,7 +58,7 @@ List *Swig_add_directory(const String_or_char *dirname) { * the preprocessor to grab files in the same directory as other included files. * ----------------------------------------------------------------------------- */ -void Swig_push_directory(const String_or_char *dirname) { +void Swig_push_directory(const_String_or_char_ptr dirname) { String *pdirname; if (!Swig_get_push_dir()) return; @@ -77,7 +78,7 @@ void Swig_push_directory(const String_or_char *dirname) { * the preprocessor. * ----------------------------------------------------------------------------- */ -void Swig_pop_directory() { +void Swig_pop_directory(void) { if (!Swig_get_push_dir()) return; if (!pdirectories) @@ -91,13 +92,13 @@ void Swig_pop_directory() { * Returns the full pathname of the last file opened. * ----------------------------------------------------------------------------- */ -String *Swig_last_file() { +String *Swig_last_file(void) { assert(lastpath); return lastpath; } /* ----------------------------------------------------------------------------- - * Swig_search_path() + * Swig_search_path_any() * * Returns a list of the current search paths. * ----------------------------------------------------------------------------- */ @@ -155,10 +156,11 @@ List *Swig_search_path() { /* ----------------------------------------------------------------------------- * Swig_open() * - * Looks for a file and open it. Returns an open FILE * on success. + * open a file, optionally looking for it in the include path. Returns an open + * FILE * on success. * ----------------------------------------------------------------------------- */ -static FILE *Swig_open_any(const String_or_char *name, int sysfile) { +static FILE *Swig_open_file(const_String_or_char_ptr name, int sysfile, int use_include_path) { FILE *f; String *filename; List *spath = 0; @@ -172,8 +174,11 @@ static FILE *Swig_open_any(const String_or_char *name, int sysfile) { cname = Char(name); filename = NewString(cname); assert(filename); + if (file_debug) { + Printf(stdout, " Open: %s\n", filename); + } f = fopen(Char(filename), "r"); - if (!f) { + if (!f && use_include_path) { spath = Swig_search_path_any(sysfile); ilen = Len(spath); for (i = 0; i < ilen; i++) { @@ -186,19 +191,20 @@ static FILE *Swig_open_any(const String_or_char *name, int sysfile) { Delete(spath); } if (f) { -#if defined(_WIN32) /* Note not on Cygwin else filename is displayed with double '/' */ - Replaceall(filename, "\\\\", "\\"); /* remove double '\' in case any already present */ - Replaceall(filename, "\\", "\\\\"); -#endif Delete(lastpath); - lastpath = Copy(filename); + lastpath = filename; } - Delete(filename); return f; } -FILE *Swig_open(const String_or_char *name) { - return Swig_open_any(name, 0); +/* Open a file - searching the include paths to find it */ +FILE *Swig_include_open(const_String_or_char_ptr name) { + return Swig_open_file(name, 0, 1); +} + +/* Open a file - does not use include paths to find it */ +FILE *Swig_open(const_String_or_char_ptr name) { + return Swig_open_file(name, 0, 0); } @@ -219,6 +225,8 @@ String *Swig_read_file(FILE *f) { Append(str, buffer); } len = Len(str); + /* Add a newline if not present on last line -- the preprocessor seems to + * rely on \n and not EOF terminating lines */ if (len) { char *cstr = Char(str); if (cstr[len - 1] != '\n') { @@ -234,29 +242,29 @@ String *Swig_read_file(FILE *f) { * Opens a file and returns it as a string. * ----------------------------------------------------------------------------- */ -static String *Swig_include_any(const String_or_char *name, int sysfile) { +static String *Swig_include_any(const_String_or_char_ptr name, int sysfile) { FILE *f; String *str; String *file; - f = Swig_open_any(name, sysfile); + f = Swig_open_file(name, sysfile, 1); if (!f) return 0; str = Swig_read_file(f); fclose(f); Seek(str, 0, SEEK_SET); - file = Copy(lastpath); + file = Copy(Swig_last_file()); Setfile(str, file); Delete(file); Setline(str, 1); return str; } -String *Swig_include(const String_or_char *name) { +String *Swig_include(const_String_or_char_ptr name) { return Swig_include_any(name, 0); } -String *Swig_include_sys(const String_or_char *name) { +String *Swig_include_sys(const_String_or_char_ptr name) { return Swig_include_any(name, 1); } @@ -266,10 +274,10 @@ String *Swig_include_sys(const String_or_char *name) { * Copies the contents of a file into another file * ----------------------------------------------------------------------------- */ -int Swig_insert_file(const String_or_char *filename, File *outfile) { +int Swig_insert_file(const_String_or_char_ptr filename, File *outfile) { char buffer[4096]; int nbytes; - FILE *f = Swig_open(filename); + FILE *f = Swig_include_open(filename); if (!f) return -1; @@ -290,7 +298,7 @@ int Swig_insert_file(const String_or_char *filename, File *outfile) { static Hash *named_files = 0; -void Swig_register_filebyname(const String_or_char *filename, File *outfile) { +void Swig_register_filebyname(const_String_or_char_ptr filename, File *outfile) { if (!named_files) named_files = NewHash(); Setattr(named_files, filename, outfile); @@ -302,7 +310,7 @@ void Swig_register_filebyname(const String_or_char *filename, File *outfile) { * Get a named file * ----------------------------------------------------------------------------- */ -File *Swig_filebyname(const String_or_char *filename) { +File *Swig_filebyname(const_String_or_char_ptr filename) { if (!named_files) return 0; return Getattr(named_files, filename); @@ -314,7 +322,7 @@ File *Swig_filebyname(const String_or_char *filename) { * Returns the suffix of a file * ----------------------------------------------------------------------------- */ -char *Swig_file_suffix(const String_or_char *filename) { +char *Swig_file_suffix(const_String_or_char_ptr filename) { char *d; char *c = Char(filename); int len = Len(filename); @@ -336,7 +344,7 @@ char *Swig_file_suffix(const String_or_char *filename) { * Returns the filename with no suffix attached. * ----------------------------------------------------------------------------- */ -char *Swig_file_basename(const String_or_char *filename) { +char *Swig_file_basename(const_String_or_char_ptr filename) { static char tmp[1024]; char *c; strcpy(tmp, Char(filename)); @@ -350,7 +358,7 @@ char *Swig_file_basename(const String_or_char *filename) { * * Return the file with any leading path stripped off * ----------------------------------------------------------------------------- */ -char *Swig_file_filename(const String_or_char *filename) { +char *Swig_file_filename(const_String_or_char_ptr filename) { static char tmp[1024]; const char *delim = SWIG_FILE_DELIMITER; char *c; @@ -368,7 +376,7 @@ char *Swig_file_filename(const String_or_char *filename) { * * Return the name of the directory associated with a file * ----------------------------------------------------------------------------- */ -char *Swig_file_dirname(const String_or_char *filename) { +char *Swig_file_dirname(const_String_or_char_ptr filename) { static char tmp[1024]; const char *delim = SWIG_FILE_DELIMITER; char *c; @@ -382,3 +390,10 @@ char *Swig_file_dirname(const String_or_char *filename) { *(++c) = 0; return tmp; } + +/* + * Swig_file_debug() + */ +void Swig_file_debug_set() { + file_debug = 1; +} diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index 03dc28d2a..82af7a31a 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -17,6 +17,15 @@ char cvsroot_misc_c[] = "$Id$"; #include <errno.h> #include <ctype.h> #include <limits.h> +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef _WIN32 +#include <direct.h> +#ifndef S_ISDIR +#define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR) +#endif +#endif static char *fake_version = 0; @@ -58,7 +67,7 @@ const char *Swig_package_version(void) { /* ----------------------------------------------------------------------------- * Swig_banner() * - * Emits the SWIG identifying banner. + * Emits the SWIG identifying banner for the C/C++ wrapper file. * ----------------------------------------------------------------------------- */ void Swig_banner(File *f) { @@ -71,15 +80,29 @@ void Swig_banner(File *f) { * changes to this file unless you know what you are doing--modify the SWIG \n\ * interface file instead. \n", Swig_package_version()); /* String too long for ISO compliance */ - Printf(f, " * ----------------------------------------------------------------------------- */\n\n"); + Printf(f, " * ----------------------------------------------------------------------------- */\n"); + +} + +/* ----------------------------------------------------------------------------- + * Swig_banner_target_lang() + * + * Emits a SWIG identifying banner in the target language + * ----------------------------------------------------------------------------- */ +void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar) { + Printf(f, "%s This file was automatically generated by SWIG (http://www.swig.org).\n", commentchar); + Printf(f, "%s Version %s\n", commentchar, Swig_package_version()); + Printf(f, "%s\n", commentchar); + Printf(f, "%s Do not make changes to this file unless you know what you are doing--modify\n", commentchar); + Printf(f, "%s the SWIG interface file instead.\n", commentchar); } /* ----------------------------------------------------------------------------- * Swig_strip_c_comments() * - * Return a new string with C comments stripped from the input string. Null is - * returned if there aren't any. + * Return a new string with C comments stripped from the input string. NULL is + * returned if there aren't any comments. * ----------------------------------------------------------------------------- */ String *Swig_strip_c_comments(const String *s) { @@ -97,9 +120,10 @@ String *Swig_strip_c_comments(const String *s) { comment_begin = c-1; } else if (comment_begin && !comment_end && *c == '*') { ++c; - if (*c == '/') + if (*c == '/') { comment_end = c; - break; + break; + } } ++c; } @@ -120,6 +144,133 @@ String *Swig_strip_c_comments(const String *s) { return stripped; } +/* ----------------------------------------------------------------------------- + * is_directory() + * ----------------------------------------------------------------------------- */ +static int is_directory(String *directory) { + int last = Len(directory) - 1; + int statres; + struct stat st; + char *dir = Char(directory); + if (dir[last] == SWIG_FILE_DELIMITER[0]) { + /* remove trailing slash - can cause S_ISDIR to fail on Windows, at least */ + dir[last] = 0; + statres = stat(dir, &st); + dir[last] = SWIG_FILE_DELIMITER[0]; + } else { + statres = stat(dir, &st); + } + return (statres == 0 && S_ISDIR(st.st_mode)); +} + +/* ----------------------------------------------------------------------------- + * Swig_new_subdirectory() + * + * Create the subdirectory only if the basedirectory already exists as a directory. + * basedirectory can be NULL or empty to indicate current directory. + * ----------------------------------------------------------------------------- */ + +String *Swig_new_subdirectory(String *basedirectory, String *subdirectory) { + String *error = 0; + struct stat st; + int current_directory = basedirectory ? (Len(basedirectory) == 0 ? 1 : 0) : 0; + + if (current_directory || is_directory(basedirectory)) { + Iterator it; + String *dir = basedirectory ? NewString(basedirectory) : NewString(""); + List *subdirs = Split(subdirectory, SWIG_FILE_DELIMITER[0], INT_MAX); + + for (it = First(subdirs); it.item; it = Next(it)) { + int statdir; + String *subdirectory = it.item; + Printf(dir, "%s", subdirectory); + statdir = stat(Char(dir), &st); + if (statdir == 0) { + Printf(dir, SWIG_FILE_DELIMITER); + if (S_ISDIR(st.st_mode)) { + continue; + } else { + error = NewStringf("Cannot create directory %s", dir); + break; + } + } else { +#ifdef _WIN32 + int result = _mkdir(Char(dir)); +#else + int result = mkdir(Char(dir), 0777); +#endif + Printf(dir, SWIG_FILE_DELIMITER); + if (result != 0 && errno != EEXIST) { + error = NewStringf("Cannot create directory %s", dir); + break; + } + } + } + } else { + error = NewStringf("Cannot create subdirectory %s under the base directory %s. Either the base does not exist as a directory or it is not readable.", subdirectory, basedirectory); + } + return error; +} + +/* ----------------------------------------------------------------------------- + * Swig_filename_correct() + * + * Corrects filename paths by removing duplicate delimeters and on non-unix + * systems use the correct delimeter across the whole name. + * ----------------------------------------------------------------------------- */ + +void Swig_filename_correct(String *filename) { + int network_path = 0; + if (Len(filename) >= 2) { + const char *fname = Char(filename); + if (fname[0] == '\\' && fname[1] == '\\') + network_path = 1; + if (fname[0] == '/' && fname[1] == '/') + network_path = 1; + } +#if defined(_WIN32) || defined(MACSWIG) + /* accept Unix path separator on non-Unix systems */ + Replaceall(filename, "/", SWIG_FILE_DELIMITER); +#endif +#if defined(__CYGWIN__) + /* accept Windows path separator in addition to Unix path separator */ + Replaceall(filename, "\\", SWIG_FILE_DELIMITER); +#endif + /* remove all duplicate file name delimiters */ + while (Replaceall(filename, SWIG_FILE_DELIMITER SWIG_FILE_DELIMITER, SWIG_FILE_DELIMITER)) { + } + /* Network paths can start with a double slash on Windows - unremove the duplicate slash we just removed */ + if (network_path) + Insert(filename, 0, SWIG_FILE_DELIMITER); +} + +/* ----------------------------------------------------------------------------- + * Swig_filename_escape() + * + * Escapes backslashes in filename - for Windows + * ----------------------------------------------------------------------------- */ + +String *Swig_filename_escape(String *filename) { + String *adjusted_filename = Copy(filename); + Swig_filename_correct(adjusted_filename); +#if defined(_WIN32) /* Note not on Cygwin else filename is displayed with double '/' */ + Replaceall(adjusted_filename, "\\", "\\\\"); +#endif + return adjusted_filename; +} + +/* ----------------------------------------------------------------------------- + * Swig_filename_unescape() + * + * Remove double backslash escaping in filename - for Windows + * ----------------------------------------------------------------------------- */ + +void Swig_filename_unescape(String *filename) { + (void)filename; +#if defined(_WIN32) + Replaceall(filename, "\\\\", "\\"); +#endif +} /* ----------------------------------------------------------------------------- * Swig_string_escape() @@ -384,7 +535,6 @@ String *Swig_string_schemify(String *s) { return ns; } - /* ----------------------------------------------------------------------------- * Swig_string_typecode() * @@ -608,7 +758,7 @@ String *Swig_string_emangle(String *s) { * In this case, "A::B". Returns NULL if there is no base. * ----------------------------------------------------------------------------- */ -void Swig_scopename_split(String *s, String **rprefix, String **rlast) { +void Swig_scopename_split(const String *s, String **rprefix, String **rlast) { char *tmp = Char(s); char *c = tmp; char *cc = c; @@ -662,7 +812,7 @@ void Swig_scopename_split(String *s, String **rprefix, String **rlast) { } -String *Swig_scopename_prefix(String *s) { +String *Swig_scopename_prefix(const String *s) { char *tmp = Char(s); char *c = tmp; char *cc = c; @@ -714,7 +864,7 @@ String *Swig_scopename_prefix(String *s) { * case, "C". * ----------------------------------------------------------------------------- */ -String *Swig_scopename_last(String *s) { +String *Swig_scopename_last(const String *s) { char *tmp = Char(s); char *c = tmp; char *cc = c; @@ -758,7 +908,7 @@ String *Swig_scopename_last(String *s) { * In this case, "A". Returns NULL if there is no base. * ----------------------------------------------------------------------------- */ -String *Swig_scopename_first(String *s) { +String *Swig_scopename_first(const String *s) { char *tmp = Char(s); char *c = tmp; char *co = 0; @@ -808,7 +958,7 @@ String *Swig_scopename_first(String *s) { * In this case, "B::C". Returns NULL if there is no suffix. * ----------------------------------------------------------------------------- */ -String *Swig_scopename_suffix(String *s) { +String *Swig_scopename_suffix(const String *s) { char *tmp = Char(s); char *c = tmp; char *co = 0; @@ -849,10 +999,14 @@ String *Swig_scopename_suffix(String *s) { /* ----------------------------------------------------------------------------- * Swig_scopename_check() * - * Checks to see if a name is qualified with a scope name + * Checks to see if a name is qualified with a scope name, examples: + * foo -> 0 + * ::foo -> 1 + * foo::bar -> 1 + * foo< ::bar > -> 0 * ----------------------------------------------------------------------------- */ -int Swig_scopename_check(String *s) { +int Swig_scopename_check(const String *s) { char *c = Char(s); char *co = strstr(c, "operator "); @@ -931,118 +1085,169 @@ String *Swig_string_command(String *s) { /* ----------------------------------------------------------------------------- - * Swig_string_rxspencer() + * Swig_string_strip() * - * Executes a regexp substitution via the RxSpencer library. For example: + * Strip given prefix from identifiers * - * Printf(stderr,"gsl%(rxspencer:[GSL_.*_][@1])s","GSL_Hello_") -> gslHello + * Printf(stderr,"%(strip:[wx])s","wxHello") -> Hello * ----------------------------------------------------------------------------- */ -#if defined(HAVE_RXSPENCER) -#include <sys/types.h> -#include <rxspencer/regex.h> -#define USE_RXSPENCER -#endif -const char *skip_delim(char pb, char pe, const char *ce) { - int end = 0; - int lb = 0; - while (!end && *ce != '\0') { - if (*ce == pb) { - ++lb; - } - if (*ce == pe) { - if (!lb) { - end = 1; - --ce; +String *Swig_string_strip(String *s) { + String *ns; + if (!Len(s)) { + ns = NewString(s); + } else { + const char *cs = Char(s); + const char *ce = Strchr(cs, ']'); + if (*cs != '[' || !ce) { + ns = NewString(s); + } else { + String *fmt = NewStringf("%%.%ds", ce-cs-1); + String *prefix = NewStringf(fmt, cs+1); + if (0 == Strncmp(ce+1, prefix, Len(prefix))) { + ns = NewString(ce+1+Len(prefix)); } else { - --lb; + ns = NewString(ce+1); } } - ++ce; } - return end ? ce : 0; + return ns; } -#if defined(USE_RXSPENCER) -String *Swig_string_rxspencer(String *s) { - String *res = 0; - if (Len(s)) { - const char *cs = Char(s); - const char *cb; - const char *ce; - if (*cs == '[') { - int retval; - regex_t compiled; - cb = ++cs; - ce = skip_delim('[', ']', cb); - if (ce) { - char bregexp[512]; - strncpy(bregexp, cb, ce - cb); - bregexp[ce - cb] = '\0'; - ++ce; - retval = regcomp(&compiled, bregexp, REG_EXTENDED); - if (retval == 0) { - cs = ce; - if (*cs == '[') { - cb = ++cs; - ce = skip_delim('[', ']', cb); - if (ce) { - const char *cvalue = ce + 1; - int nsub = (int) compiled.re_nsub + 1; - regmatch_t *pmatch = (regmatch_t *) malloc(sizeof(regmatch_t) * (nsub)); - retval = regexec(&compiled, cvalue, nsub, pmatch, 0); - if (retval != REG_NOMATCH) { - char *spos = 0; - res = NewStringWithSize(cb, ce - cb); - spos = Strchr(res, '@'); - while (spos) { - char cd = *(++spos); - if (isdigit(cd)) { - char arg[8]; - size_t len; - int i = cd - '0'; - sprintf(arg, "@%d", i); - if (i < nsub && (len = pmatch[i].rm_eo - pmatch[i].rm_so)) { - char value[256]; - strncpy(value, cvalue + pmatch[i].rm_so, len); - value[len] = 0; - Replaceall(res, arg, value); - } else { - Replaceall(res, arg, ""); - } - spos = Strchr(res, '@'); - } else if (cd == '@') { - spos = strchr(spos + 1, '@'); - } - } - } - free(pmatch); - } - } +#ifdef HAVE_PCRE +#include <pcre.h> + +static int split_regex_pattern_subst(String *s, String **pattern, String **subst, const char **input) +{ + const char *pats, *pate; + const char *subs, *sube; + + /* Locate the search pattern */ + const char *p = Char(s); + if (*p++ != '/') goto err_out; + pats = p; + p = strchr(p, '/'); + if (!p) goto err_out; + pate = p; + + /* Locate the substitution string */ + subs = ++p; + p = strchr(p, '/'); + if (!p) goto err_out; + sube = p; + + *pattern = NewStringWithSize(pats, pate - pats); + *subst = NewStringWithSize(subs, sube - subs); + *input = p + 1; + return 1; + +err_out: + Swig_error("SWIG", Getline(s), "Invalid regex substitution: '%s'.\n", s); + exit(1); +} + +String *replace_captures(int num_captures, const char *input, String *subst, int captures[], String *pattern, String *s) +{ + String *result = NewStringEmpty(); + const char *p = Char(subst); + + while (*p) { + /* Copy part without substitutions */ + const char *q = strchr(p, '\\'); + if (!q) { + Write(result, p, strlen(p)); + break; + } + Write(result, p, q - p); + p = q + 1; + + /* Handle substitution */ + if (*p == '\0') { + Putc('\\', result); + } else if (isdigit((unsigned char)*p)) { + int group = *p++ - '0'; + if (group < num_captures) { + int l = captures[group*2], r = captures[group*2 + 1]; + if (l != -1) { + Write(result, input + l, r - l); } - regfree(&compiled); + } else { + Swig_error("SWIG", Getline(s), "PCRE capture replacement failed while matching \"%s\" using \"%s\" - request for group %d is greater than the number of captures %d.\n", + Char(pattern), input, group, num_captures-1); } } } - if (!res) - res = NewStringEmpty(); - return res; + + return result; } + +/* ----------------------------------------------------------------------------- + * Swig_string_regex() + * + * Executes a regular expression substitution. For example: + * + * Printf(stderr,"gsl%(regex:/GSL_.*_/\\1/)s","GSL_Hello_") -> gslHello + * ----------------------------------------------------------------------------- */ +String *Swig_string_regex(String *s) { + const int pcre_options = 0; + + String *res = 0; + pcre *compiled_pat = 0; + const char *pcre_error, *input; + int pcre_errorpos; + String *pattern = 0, *subst = 0; + int captures[30]; + + if (split_regex_pattern_subst(s, &pattern, &subst, &input)) { + int rc; + + compiled_pat = pcre_compile( + Char(pattern), pcre_options, &pcre_error, &pcre_errorpos, NULL); + if (!compiled_pat) { + Swig_error("SWIG", Getline(s), "PCRE compilation failed: '%s' in '%s':%i.\n", + pcre_error, Char(pattern), pcre_errorpos); + exit(1); + } + rc = pcre_exec(compiled_pat, NULL, input, strlen(input), 0, 0, captures, 30); + if (rc >= 0) { + res = replace_captures(rc, input, subst, captures, pattern, s); + } else if (rc != PCRE_ERROR_NOMATCH) { + Swig_error("SWIG", Getline(s), "PCRE execution failed: error %d while matching \"%s\" using \"%s\".\n", + rc, Char(pattern), input); + exit(1); + } + } + + DohDelete(pattern); + DohDelete(subst); + pcre_free(compiled_pat); + return res ? res : NewStringEmpty(); +} + +String *Swig_pcre_version(void) { + return NewStringf("PCRE Version: %s", pcre_version()); +} + #else -String *Swig_string_rxspencer(String *s) { - (void) s; - return NewStringEmpty(); + +String *Swig_string_regex(String *s) { + Swig_error("SWIG", Getline(s), "PCRE regex support not enabled in this SWIG build.\n"); + exit(1); +} + +String *Swig_pcre_version(void) { + return NewStringf("PCRE not used"); } + #endif /* ------------------------------------------------------------ - * is_generated_overload() + * Swig_is_generated_overload() * Check if the function is an automatically generated * overload created because a method has default parameters. * ------------------------------------------------------------ */ -int Swig_is_generated_overload(Node *n) -{ +int Swig_is_generated_overload(Node *n) { Node *base_method = Getattr(n, "sym:overloaded"); Node *default_args = Getattr(n, "defaultargs"); return ((base_method != NULL) && (default_args != NULL) && (base_method == default_args)); @@ -1066,8 +1271,9 @@ void Swig_init() { DohEncoding("typecode", Swig_string_typecode); DohEncoding("mangle", Swig_string_emangle); DohEncoding("command", Swig_string_command); - DohEncoding("rxspencer", Swig_string_rxspencer); DohEncoding("schemify", Swig_string_schemify); + DohEncoding("strip", Swig_string_strip); + DohEncoding("regex", Swig_string_regex); /* aliases for the case encoders */ DohEncoding("uppercase", Swig_string_upper); diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index 31cf116dc..1be1405a3 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -9,6 +9,15 @@ * naming.c * * Functions for generating various kinds of names during code generation. + * + * Swig_name_register is used to register a format string for generating names. + * The format string makes use of the following format specifiers: + * + * %c - class name is substituted + * %f - function name is substituted + * %m - member name is substituted + * %n - namespace is substituted + * %v - variable name is substituted * ----------------------------------------------------------------------------- */ char cvsroot_naming_c[] = "$Id$"; @@ -31,13 +40,13 @@ static Hash *naming_hash = 0; * Register a new naming format. * ----------------------------------------------------------------------------- */ -void Swig_name_register(const String_or_char *method, const String_or_char *format) { +void Swig_name_register(const_String_or_char_ptr method, const_String_or_char_ptr format) { if (!naming_hash) naming_hash = NewHash(); Setattr(naming_hash, method, format); } -void Swig_name_unregister(const String_or_char *method) { +void Swig_name_unregister(const_String_or_char_ptr method) { if (naming_hash) { Delattr(naming_hash, method); } @@ -126,12 +135,29 @@ static int name_mangle(String *r) { } /* ----------------------------------------------------------------------------- + * replace_nspace() + * + * Mangles in the namespace from nspace by replacing %n in name if nspace feature required. + * ----------------------------------------------------------------------------- */ + +static void replace_nspace(String *name, const_String_or_char_ptr nspace) { + if (nspace) { + String *namspace = NewStringf("%s_", nspace); + Replaceall(namspace, NSPACE_SEPARATOR, "_"); + Replace(name, "%n", namspace, DOH_REPLACE_ANY); + Delete(namspace); + } else { + Replace(name, "%n", "", DOH_REPLACE_ANY); + } +} + +/* ----------------------------------------------------------------------------- * Swig_name_mangle() * * Converts all of the non-identifier characters of a string to underscores. * ----------------------------------------------------------------------------- */ -String *Swig_name_mangle(const String_or_char *s) { +String *Swig_name_mangle(const_String_or_char_ptr s) { #if 0 String *r = NewString(s); name_mangle(r); @@ -147,7 +173,7 @@ String *Swig_name_mangle(const String_or_char *s) { * Returns the name of a wrapper function. * ----------------------------------------------------------------------------- */ -String *Swig_name_wrapper(const String_or_char *fname) { +String *Swig_name_wrapper(const_String_or_char_ptr fname) { String *r; String *f; @@ -172,7 +198,7 @@ String *Swig_name_wrapper(const String_or_char *fname) { * Returns the name of a class method. * ----------------------------------------------------------------------------- */ -String *Swig_name_member(const String_or_char *classname, const String_or_char *mname) { +String *Swig_name_member(const_String_or_char_ptr nspace, const_String_or_char_ptr classname, const_String_or_char_ptr membername) { String *r; String *f; String *rclassname; @@ -184,7 +210,7 @@ String *Swig_name_member(const String_or_char *classname, const String_or_char * naming_hash = NewHash(); f = Getattr(naming_hash, "member"); if (!f) { - Append(r, "%c_%m"); + Append(r, "%n%c_%m"); } else { Append(r, f); } @@ -192,8 +218,9 @@ String *Swig_name_member(const String_or_char *classname, const String_or_char * if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { cname = strchr(cname, ' ') + 1; } + replace_nspace(r, nspace); Replace(r, "%c", cname, DOH_REPLACE_ANY); - Replace(r, "%m", mname, DOH_REPLACE_ANY); + Replace(r, "%m", membername, DOH_REPLACE_ANY); /* name_mangle(r); */ Delete(rclassname); return r; @@ -205,7 +232,7 @@ String *Swig_name_member(const String_or_char *classname, const String_or_char * * Returns the name of the accessor function used to get a variable. * ----------------------------------------------------------------------------- */ -String *Swig_name_get(const String_or_char *vname) { +String *Swig_name_get(const_String_or_char_ptr nspace, const_String_or_char_ptr vname) { String *r; String *f; @@ -218,10 +245,12 @@ String *Swig_name_get(const String_or_char *vname) { naming_hash = NewHash(); f = Getattr(naming_hash, "get"); if (!f) { - Append(r, "%v_get"); + Append(r, "%n%v_get"); } else { Append(r, f); } + + replace_nspace(r, nspace); Replace(r, "%v", vname, DOH_REPLACE_ANY); /* name_mangle(r); */ return r; @@ -233,7 +262,7 @@ String *Swig_name_get(const String_or_char *vname) { * Returns the name of the accessor function used to set a variable. * ----------------------------------------------------------------------------- */ -String *Swig_name_set(const String_or_char *vname) { +String *Swig_name_set(const_String_or_char_ptr nspace, const_String_or_char_ptr vname) { String *r; String *f; @@ -242,10 +271,12 @@ String *Swig_name_set(const String_or_char *vname) { naming_hash = NewHash(); f = Getattr(naming_hash, "set"); if (!f) { - Append(r, "%v_set"); + Append(r, "%n%v_set"); } else { Append(r, f); } + + replace_nspace(r, nspace); Replace(r, "%v", vname, DOH_REPLACE_ANY); /* name_mangle(r); */ return r; @@ -257,7 +288,7 @@ String *Swig_name_set(const String_or_char *vname) { * Returns the name of the accessor function used to create an object. * ----------------------------------------------------------------------------- */ -String *Swig_name_construct(const String_or_char *classname) { +String *Swig_name_construct(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { String *r; String *f; String *rclassname; @@ -269,7 +300,7 @@ String *Swig_name_construct(const String_or_char *classname) { naming_hash = NewHash(); f = Getattr(naming_hash, "construct"); if (!f) { - Append(r, "new_%c"); + Append(r, "new_%n%c"); } else { Append(r, f); } @@ -278,6 +309,8 @@ String *Swig_name_construct(const String_or_char *classname) { if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { cname = strchr(cname, ' ') + 1; } + + replace_nspace(r, nspace); Replace(r, "%c", cname, DOH_REPLACE_ANY); Delete(rclassname); return r; @@ -290,7 +323,7 @@ String *Swig_name_construct(const String_or_char *classname) { * Returns the name of the accessor function used to copy an object. * ----------------------------------------------------------------------------- */ -String *Swig_name_copyconstructor(const String_or_char *classname) { +String *Swig_name_copyconstructor(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { String *r; String *f; String *rclassname; @@ -302,7 +335,7 @@ String *Swig_name_copyconstructor(const String_or_char *classname) { naming_hash = NewHash(); f = Getattr(naming_hash, "copy"); if (!f) { - Append(r, "copy_%c"); + Append(r, "copy_%n%c"); } else { Append(r, f); } @@ -312,6 +345,7 @@ String *Swig_name_copyconstructor(const String_or_char *classname) { cname = strchr(cname, ' ') + 1; } + replace_nspace(r, nspace); Replace(r, "%c", cname, DOH_REPLACE_ANY); Delete(rclassname); return r; @@ -323,7 +357,7 @@ String *Swig_name_copyconstructor(const String_or_char *classname) { * Returns the name of the accessor function used to destroy an object. * ----------------------------------------------------------------------------- */ -String *Swig_name_destroy(const String_or_char *classname) { +String *Swig_name_destroy(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { String *r; String *f; String *rclassname; @@ -334,7 +368,7 @@ String *Swig_name_destroy(const String_or_char *classname) { naming_hash = NewHash(); f = Getattr(naming_hash, "destroy"); if (!f) { - Append(r, "delete_%c"); + Append(r, "delete_%n%c"); } else { Append(r, f); } @@ -343,6 +377,8 @@ String *Swig_name_destroy(const String_or_char *classname) { if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { cname = strchr(cname, ' ') + 1; } + + replace_nspace(r, nspace); Replace(r, "%c", cname, DOH_REPLACE_ANY); Delete(rclassname); return r; @@ -355,7 +391,7 @@ String *Swig_name_destroy(const String_or_char *classname) { * Returns the name of the accessor function used to disown an object. * ----------------------------------------------------------------------------- */ -String *Swig_name_disown(const String_or_char *classname) { +String *Swig_name_disown(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { String *r; String *f; String *rclassname; @@ -366,7 +402,7 @@ String *Swig_name_disown(const String_or_char *classname) { naming_hash = NewHash(); f = Getattr(naming_hash, "disown"); if (!f) { - Append(r, "disown_%c"); + Append(r, "disown_%n%c"); } else { Append(r, f); } @@ -375,6 +411,8 @@ String *Swig_name_disown(const String_or_char *classname) { if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { cname = strchr(cname, ' ') + 1; } + + replace_nspace(r, nspace); Replace(r, "%c", cname, DOH_REPLACE_ANY); Delete(rclassname); return r; @@ -478,25 +516,12 @@ DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType Delete(cls); } /* A template-based class lookup, check name first */ - if (!rn && SwigType_istemplate(name)) { - String *t_name = SwigType_templateprefix(name); - if (!Equal(t_name, name)) { + if (!rn) { + String *t_name = SwigType_istemplate_templateprefix(name); + if (t_name) rn = Swig_name_object_get(namehash, prefix, t_name, decl); - } Delete(t_name); } - /* A template-based class lookup */ - /* - if (!rn && SwigType_istemplate(prefix)) { - String *t_prefix = SwigType_templateprefix(prefix); - if (Strcmp(t_prefix, prefix) != 0) { - String *t_name = SwigType_templateprefix(name); - rn = Swig_name_object_get(namehash, t_prefix, t_name, decl); - Delete(t_name); - } - Delete(t_prefix); - } - */ } /* A wildcard-based class lookup */ if (!rn) { @@ -540,6 +565,7 @@ DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) { Iterator ki; + Hash *derh; String *bprefix; String *dprefix; char *cbprefix; @@ -548,6 +574,9 @@ void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) { if (!namehash) return; + /* Temporary hash holding all the entries we add while we iterate over + namehash itself as we can't modify the latter while iterating over it. */ + derh = NULL; bprefix = NewStringf("%s::", base); dprefix = NewStringf("%s::", derived); cbprefix = Char(bprefix); @@ -555,13 +584,20 @@ void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) { for (ki = First(namehash); ki.key; ki = Next(ki)) { char *k = Char(ki.key); if (strncmp(k, cbprefix, plen) == 0) { + /* Copy, adjusting name, this element to the derived hash. */ Iterator oi; String *nkey = NewStringf("%s%s", dprefix, k + plen); Hash *n = ki.item; - Hash *newh = Getattr(namehash, nkey); + Hash *newh; + + /* Don't overwrite an existing value for the derived class, if any. */ + newh = Getattr(namehash, nkey); if (!newh) { + if (!derh) + derh = NewHash(); + newh = NewHash(); - Setattr(namehash, nkey, newh); + Setattr(derh, nkey, newh); Delete(newh); } for (oi = First(n); oi.key; oi = Next(oi)) { @@ -574,8 +610,17 @@ void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) { Delete(nkey); } } + + /* Merge the contents of derived hash into the main hash. */ + if (derh) { + for (ki = First(derh); ki.key; ki = Next(ki)) { + Setattr(namehash, ki.key, ki.item); + } + } + Delete(bprefix); Delete(dprefix); + Delete(derh); } /* ----------------------------------------------------------------------------- @@ -604,7 +649,7 @@ static void merge_features(Hash *features, Node *n) { * ----------------------------------------------------------------------------- */ static -void features_get(Hash *features, String *tname, SwigType *decl, SwigType *ncdecl, Node *node) { +void features_get(Hash *features, const String *tname, SwigType *decl, SwigType *ncdecl, Node *node) { Node *n = Getattr(features, tname); #ifdef SWIG_DEBUG Printf(stdout, " features_get: %s\n", tname); @@ -659,7 +704,7 @@ void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *d } #ifdef SWIG_DEBUG - Printf(stdout, "Swig_features_get: %s %s %s\n", prefix, name, decl); + Printf(stdout, "Swig_features_get: '%s' '%s' '%s'\n", prefix, name, decl); #endif /* Global features */ @@ -667,10 +712,9 @@ void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *d if (name) { String *tname = NewStringEmpty(); /* add features for 'root' template */ - if (SwigType_istemplate(name)) { - String *dname = SwigType_templateprefix(name); + String *dname = SwigType_istemplate_templateprefix(name); + if (dname) { features_get(features, dname, decl, ncdecl, node); - Delete(dname); } /* Catch-all */ features_get(features, name, decl, ncdecl, node); @@ -688,16 +732,16 @@ void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *d /* A specific class lookup */ if (Len(prefix)) { /* A template-based class lookup */ - if (SwigType_istemplate(prefix)) { - String *tprefix = SwigType_templateprefix(prefix); + String *tprefix = SwigType_istemplate_templateprefix(prefix); + if (tprefix) { Clear(tname); Printf(tname, "%s::%s", tprefix, name); features_get(features, tname, decl, ncdecl, node); - Delete(tprefix); } Clear(tname); Printf(tname, "%s::%s", prefix, name); features_get(features, tname, decl, ncdecl, node); + Delete(tprefix); } } else { /* Lookup in the global namespace only */ @@ -706,6 +750,7 @@ void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *d features_get(features, tname, decl, ncdecl, node); } Delete(tname); + Delete(dname); } if (name && SwigType_istemplate(name)) { /* add features for complete template type */ @@ -731,12 +776,12 @@ void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *d * concatenating the feature name plus ':' plus the attribute name. * ----------------------------------------------------------------------------- */ -void Swig_feature_set(Hash *features, const String_or_char *name, SwigType *decl, const String_or_char *featurename, String *value, Hash *featureattribs) { +void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs) { Hash *n; Hash *fhash; #ifdef SWIG_DEBUG - Printf(stdout, "Swig_feature_set: %s %s %s %s\n", name, decl, featurename, value); + Printf(stdout, "Swig_feature_set: '%s' '%s' '%s' '%s'\n", name, decl, featurename, value); #endif n = Getattr(features, name); @@ -868,11 +913,14 @@ static int nodes_are_equivalent(Node *a, Node *b, int a_inclass) { /* they must have the same type */ String *ta = nodeType(a); String *tb = nodeType(b); - if (Cmp(ta, tb) != 0) - return 0; + if (!Equal(ta, tb)) { + if (!(Equal(ta, "using") && Equal(tb, "cdecl"))) { + return 0; + } + } - /* cdecl case */ if (Cmp(ta, "cdecl") == 0) { + /* both cdecl case */ /* typedef */ String *a_storage = Getattr(a, "storage"); String *b_storage = Getattr(b, "storage"); @@ -931,8 +979,17 @@ static int nodes_are_equivalent(Node *a, Node *b, int a_inclass) { } } } + } else if (Equal(ta, "using")) { + /* using and cdecl case */ + String *b_storage = Getattr(b, "storage"); + if (Equal(b_storage, "typedef")) { + String *a_name = Getattr(a, "name"); + String *b_name = Getattr(b, "name"); + if (Equal(a_name, b_name)) + return 1; + } } else { - /* %constant case */ + /* both %constant case */ String *a_storage = Getattr(a, "storage"); String *b_storage = Getattr(b, "storage"); if ((Cmp(a_storage, "%constant") == 0) @@ -975,7 +1032,7 @@ int Swig_need_redefined_warn(Node *a, Node *b, int InClass) { * This is basically any protected members when the allprotected mode is set. * Otherwise we take just the protected virtual methods and non-static methods * (potentially virtual methods) as well as constructors/destructors. - * + * Also any "using" statements in a class may potentially be virtual. * ----------------------------------------------------------------------------- */ int Swig_need_protected(Node *n) { @@ -992,6 +1049,8 @@ int Swig_need_protected(Node *n) { } } else if (Equal(nodetype, "constructor") || Equal(nodetype, "destructor")) { return 1; + } else if (Equal(nodetype, "using") && !Getattr(n, "namespace")) { + return 1; } } return 0; @@ -1036,25 +1095,21 @@ static void Swig_name_object_attach_keys(const char *keys[], Hash *nameobj) { if (ckey) { const char **rkey; int isnotmatch = 0; - int isrxsmatch = 0; + int isregexmatch = 0; if ((strncmp(ckey, "match", 5) == 0) || (isnotmatch = (strncmp(ckey, "notmatch", 8) == 0)) - || (isrxsmatch = (strncmp(ckey, "rxsmatch", 8) == 0)) - || (isnotmatch = isrxsmatch = (strncmp(ckey, "notrxsmatch", 11) == 0))) { + || (isregexmatch = (strncmp(ckey, "regexmatch", 10) == 0)) + || (isnotmatch = isregexmatch = (strncmp(ckey, "notregexmatch", 13) == 0))) { Hash *mi = NewHash(); List *attrlist = Swig_make_attrlist(ckey); if (!matchlist) matchlist = NewList(); Setattr(mi, "value", Getattr(kw, "value")); Setattr(mi, "attrlist", attrlist); -#ifdef SWIG_DEBUG - if (isrxsmatch) - Printf(stdout, "rxsmatch to use: %s %s %s\n", ckey, Getattr(kw, "value"), attrlist); -#endif if (isnotmatch) SetFlag(mi, "notmatch"); - if (isrxsmatch) - SetFlag(mi, "rxsmatch"); + if (isregexmatch) + SetFlag(mi, "regexmatch"); Delete(attrlist); Append(matchlist, mi); Delete(mi); @@ -1089,7 +1144,7 @@ void Swig_name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, Str } if (!nname || !Len(nname) || Getattr(nameobj, "fullname") || /* any of these options trigger a 'list' nameobj */ - Getattr(nameobj, "sourcefmt") || Getattr(nameobj, "matchlist")) { + Getattr(nameobj, "sourcefmt") || Getattr(nameobj, "matchlist") || Getattr(nameobj, "regextarget")) { if (decl) Setattr(nameobj, "decl", decl); if (nname && Len(nname)) @@ -1130,36 +1185,50 @@ static DOH *Swig_get_lattr(Node *n, List *lattr) { return res; } -#if defined(HAVE_RXSPENCER) -#include <sys/types.h> -#include <rxspencer/regex.h> -#define USE_RXSPENCER -#endif +#ifdef HAVE_PCRE +#include <pcre.h> + +int Swig_name_regexmatch_value(Node *n, String *pattern, String *s) { + pcre *compiled_pat; + const char *err; + int errpos; + int rc; + + compiled_pat = pcre_compile(Char(pattern), 0, &err, &errpos, NULL); + if (!compiled_pat) { + Swig_error("SWIG", Getline(n), + "Invalid regex \"%s\": compilation failed at %d: %s\n", + Char(pattern), errpos, err); + exit(1); + } -#if defined(USE_RXSPENCER) -int Swig_name_rxsmatch_value(String *mvalue, String *value) { - int match = 0; - char *cvalue = Char(value); - char *cmvalue = Char(mvalue); - regex_t compiled; - int retval = regcomp(&compiled, cmvalue, REG_EXTENDED | REG_NOSUB); - if (retval != 0) + rc = pcre_exec(compiled_pat, NULL, Char(s), Len(s), 0, 0, NULL, 0); + pcre_free(compiled_pat); + + if (rc == PCRE_ERROR_NOMATCH) return 0; - retval = regexec(&compiled, cvalue, 0, 0, 0); - match = (retval == REG_NOMATCH) ? 0 : 1; -#ifdef SWIG_DEBUG - Printf(stdout, "rxsmatch_value: %s %s %d\n", cvalue, cmvalue, match); -#endif - regfree(&compiled); - return match; + + if (rc < 0 ) { + Swig_error("SWIG", Getline(n), + "Matching \"%s\" against regex \"%s\" failed: %d\n", + Char(s), Char(pattern), rc); + exit(1); + } + + return 1; } -#else -int Swig_name_rxsmatch_value(String *mvalue, String *value) { - (void) mvalue; - (void) value; - return 0; + +#else /* !HAVE_PCRE */ + +int Swig_name_regexmatch_value(Node *n, String *pattern, String *s) { + (void)pattern; + (void)s; + Swig_error("SWIG", Getline(n), + "PCRE regex matching is not available in this SWIG build.\n"); + exit(1); } -#endif + +#endif /* HAVE_PCRE/!HAVE_PCRE */ int Swig_name_match_value(String *mvalue, String *value) { #if defined(SWIG_USE_SIMPLE_MATCHOR) @@ -1202,17 +1271,11 @@ int Swig_name_match_nameobj(Hash *rn, Node *n) { List *lattr = Getattr(mi, "attrlist"); String *nval = Swig_get_lattr(n, lattr); int notmatch = GetFlag(mi, "notmatch"); - int rxsmatch = GetFlag(mi, "rxsmatch"); -#ifdef SWIG_DEBUG - Printf(stdout, "mi %d %s re %d not %d \n", i, nval, notmatch, rxsmatch); - if (rxsmatch) { - Printf(stdout, "rxsmatch %s\n", lattr); - } -#endif + int regexmatch = GetFlag(mi, "regexmatch"); match = 0; if (nval) { String *kwval = Getattr(mi, "value"); - match = rxsmatch ? Swig_name_rxsmatch_value(kwval, nval) + match = regexmatch ? Swig_name_regexmatch_value(n, kwval, nval) : Swig_name_match_value(kwval, nval); #ifdef SWIG_DEBUG Printf(stdout, "val %s %s %d %d \n", nval, kwval, match, ilen); @@ -1252,7 +1315,7 @@ Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *na String *sfmt = Getattr(rn, "sourcefmt"); String *sname = 0; int fullname = GetFlag(rn, "fullname"); - int rxstarget = GetFlag(rn, "rxstarget"); + int regextarget = GetFlag(rn, "regextarget"); if (sfmt) { if (fullname && prefix) { String *pname = NewStringf("%s::%s", prefix, name); @@ -1269,10 +1332,17 @@ Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *na DohIncref(name); } } - match = rxstarget ? Swig_name_rxsmatch_value(tname, sname) : Swig_name_match_value(tname, sname); + match = regextarget ? Swig_name_regexmatch_value(n, tname, sname) + : Swig_name_match_value(tname, sname); Delete(sname); } else { - match = 1; + /* Applying the renaming rule may fail if it contains a %(regex)s expression that doesn't match the given name. */ + String *sname = NewStringf(Getattr(rn, "name"), name); + if (sname) { + if (Len(sname)) + match = 1; + Delete(sname); + } } } if (match) { @@ -1368,7 +1438,7 @@ void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *ne ParmList *declparms = declaratorparms; - const char *rename_keys[] = { "fullname", "sourcefmt", "targetfmt", "continue", "rxstarget", 0 }; + const char *rename_keys[] = { "fullname", "sourcefmt", "targetfmt", "continue", "regextarget", 0 }; Swig_name_object_attach_keys(rename_keys, newname); /* Add the name */ @@ -1440,7 +1510,7 @@ static String *apply_rename(String *newname, int fullname, String *prefix, Strin * * ----------------------------------------------------------------------------- */ -String *Swig_name_make(Node *n, String *prefix, String_or_char *cname, SwigType *decl, String *oldname) { +String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, SwigType *decl, String *oldname) { String *nname = 0; String *result = 0; String *name = NewString(cname); @@ -1579,19 +1649,20 @@ void Swig_name_inherit(String *base, String *derived) { } /* ----------------------------------------------------------------------------- - * void Swig_name_decl() + * void Swig_name_str() * - * Return a stringified version of a C/C++ declaration without the return type. - * The node passed in is expected to be a function. Some example return values: - * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()" - * "MyNameSpace::ABC::ABC(int,double)" - * "MyNameSpace::ABC::constmethod(int) const" + * Return a stringified version of a C/C++ symbol from a node. + * The node passed in is expected to be a function, constructor, destructor or + * variable. Some example return values: + * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate" + * "MyNameSpace::ABC::ABC" + * "MyNameSpace::ABC::constmethod" + * "MyNameSpace::ABC::variablename" * * ----------------------------------------------------------------------------- */ -String *Swig_name_decl(Node *n) { +String *Swig_name_str(Node *n) { String *qname; - String *decl; String *qualifier = Swig_symbol_qualified(n); String *name = Swig_scopename_last(Getattr(n, "name")); if (qualifier) @@ -1615,12 +1686,38 @@ String *Swig_name_decl(Node *n) { qname = NewString(""); if (qualifier && Len(qualifier) > 0) Printf(qname, "%s::", qualifier); - Printf(qname, "%s", name); - - decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : ""); + Printf(qname, "%s", SwigType_str(name, 0)); Delete(name); Delete(qualifier); + + return qname; +} + +/* ----------------------------------------------------------------------------- + * void Swig_name_decl() + * + * Return a stringified version of a C/C++ declaration without the return type. + * The node passed in is expected to be a function, constructor, destructor or + * variable. Some example return values: + * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()" + * "MyNameSpace::ABC::ABC(int,double)" + * "MyNameSpace::ABC::constmethod(int) const" + * "MyNameSpace::ABC::variablename" + * + * ----------------------------------------------------------------------------- */ + +String *Swig_name_decl(Node *n) { + String *qname; + String *decl; + + qname = Swig_name_str(n); + + if (checkAttribute(n, "kind", "variable")) + decl = NewStringf("%s", qname); + else + decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : ""); + Delete(qname); return decl; @@ -1630,7 +1727,8 @@ String *Swig_name_decl(Node *n) { * void Swig_name_fulldecl() * * Return a stringified version of a C/C++ declaration including the return type. - * The node passed in is expected to be a function. Some example return values: + * The node passed in is expected to be a function, constructor or destructor. + * Some example return values: * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()" * "MyNameSpace::ABC::ABC(int,double)" * "int * MyNameSpace::ABC::constmethod(int) const" diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c index 267852cf0..283a2f5c2 100644 --- a/Source/Swig/parms.c +++ b/Source/Swig/parms.c @@ -18,10 +18,25 @@ char cvsroot_parms_c[] = "$Id$"; /* ------------------------------------------------------------------------ * NewParm() * - * Create a new parameter from datatype 'type' and name 'name'. + * Create a new parameter from datatype 'type' and name 'name' copying + * the file and line number from the Node file_line_node. * ------------------------------------------------------------------------ */ -Parm *NewParm(SwigType *type, const String_or_char *name) { +Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *file_line_node) { + Parm *p = NewParmWithoutFileLineInfo(type, name); + Setfile(p, Getfile(file_line_node)); + Setline(p, Getline(file_line_node)); + return p; +} + +/* ------------------------------------------------------------------------ + * NewParmWithoutFileLineInfo() + * + * Create a new parameter from datatype 'type' and name 'name' without any + * file / line numbering information. + * ------------------------------------------------------------------------ */ + +Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name) { Parm *p = NewHash(); set_nodeType(p, "parm"); if (type) { @@ -119,6 +134,14 @@ int ParmList_len(ParmList *p) { } /* --------------------------------------------------------------------- + * get_empty_type() + * ---------------------------------------------------------------------- */ + +static SwigType *get_empty_type() { + return NewStringEmpty(); +} + +/* --------------------------------------------------------------------- * ParmList_str() * * Generates a string of parameters @@ -127,7 +150,8 @@ int ParmList_len(ParmList *p) { String *ParmList_str(ParmList *p) { String *out = NewStringEmpty(); while (p) { - String *pstr = SwigType_str(Getattr(p, "type"), Getattr(p, "name")); + String *type = Getattr(p, "type"); + String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name")); Append(out, pstr); p = nextSibling(p); if (p) { @@ -148,7 +172,8 @@ String *ParmList_str_defaultargs(ParmList *p) { String *out = NewStringEmpty(); while (p) { String *value = Getattr(p, "value"); - String *pstr = SwigType_str(Getattr(p, "type"), Getattr(p, "name")); + String *type = Getattr(p, "type"); + String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name")); Append(out, pstr); if (value) { Printf(out, "=%s", value); @@ -162,6 +187,24 @@ String *ParmList_str_defaultargs(ParmList *p) { return out; } +/* ----------------------------------------------------------------------------- + * ParmList_str_multibrackets() + * + * Generates a string of parameters including default arguments adding brackets + * if more than one parameter + * ----------------------------------------------------------------------------- */ + +String *ParmList_str_multibrackets(ParmList *p) { + String *out; + String *parm_str = ParmList_str_defaultargs(p); + if (ParmList_len(p) > 1) + out = NewStringf("(%s)", parm_str); + else + out = NewStringf("%s", parm_str); + Delete(parm_str); + return out; +} + /* --------------------------------------------------------------------- * ParmList_protostr() * @@ -171,7 +214,8 @@ String *ParmList_str_defaultargs(ParmList *p) { String *ParmList_protostr(ParmList *p) { String *out = NewStringEmpty(); while (p) { - String *pstr = SwigType_str(Getattr(p, "type"), 0); + String *type = Getattr(p, "type"); + String *pstr = SwigType_str(type ? type : get_empty_type(), 0); Append(out, pstr); p = nextSibling(p); if (p) { diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c index a082036a5..31dc7522f 100644 --- a/Source/Swig/scanner.c +++ b/Source/Swig/scanner.c @@ -19,6 +19,11 @@ char cvsroot_scanner_c[] = "$Id$"; #include "swig.h" #include <ctype.h> +extern String *cparse_file; +extern int cparse_line; +extern int cparse_cplusplus; +extern int cparse_start_line; + struct Scanner { String *text; /* Current token value */ List *scanobjs; /* Objects being scanned */ @@ -34,13 +39,20 @@ struct Scanner { int freeze_line; /* Suspend line number updates */ }; +typedef struct Locator { + String *filename; + int line_number; + struct Locator *next; +} Locator; +static int follow_locators = 0; + /* ----------------------------------------------------------------------------- * NewScanner() * * Create a new scanner object * ----------------------------------------------------------------------------- */ -Scanner *NewScanner() { +Scanner *NewScanner(void) { Scanner *s; s = (Scanner *) malloc(sizeof(Scanner)); s->line = 1; @@ -86,6 +98,7 @@ void Scanner_clear(Scanner * s) { Clear(s->text); Clear(s->scanobjs); Delete(s->error); + s->str = 0; s->error = 0; s->line = 1; s->nexttoken = -1; @@ -119,11 +132,11 @@ void Scanner_push(Scanner * s, String *txt) { * call to Scanner_token(). * ----------------------------------------------------------------------------- */ -void Scanner_pushtoken(Scanner * s, int nt, const String_or_char *val) { +void Scanner_pushtoken(Scanner * s, int nt, const_String_or_char_ptr val) { assert(s); assert((nt >= 0) && (nt < SWIG_MAXTOKENS)); s->nexttoken = nt; - if (val != s->text) { + if ( Char(val) != Char(s->text) ) { Clear(s->text); Append(s->text,val); } @@ -213,7 +226,7 @@ static char nextchar(Scanner * s) { * Sets error information on the scanner. * ----------------------------------------------------------------------------- */ -static void set_error(Scanner *s, int line, String_or_char *msg) { +static void set_error(Scanner *s, int line, const_String_or_char_ptr msg) { s->error_line = line; s->error = NewString(msg); } @@ -225,8 +238,7 @@ static void set_error(Scanner *s, int line, String_or_char *msg) { * Returns error information (if any) * ----------------------------------------------------------------------------- */ -String * -Scanner_errmsg(Scanner *s) { +String *Scanner_errmsg(Scanner *s) { return s->error; } @@ -236,13 +248,12 @@ Scanner_errline(Scanner *s) { } /* ----------------------------------------------------------------------------- - * Scanner_freeze_line() + * freeze_line() * * Freezes the current line number. * ----------------------------------------------------------------------------- */ -void -Scanner_freeze_line(Scanner *s, int val) { +static void freeze_line(Scanner *s, int val) { s->freeze_line = val; } @@ -540,7 +551,7 @@ static int look(Scanner * s) { break; case 10: /* C++ style comment */ if ((c = nextchar(s)) == 0) { - set_error(s,s->start_line,"Unterminated comment"); + Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n"); return SWIG_TOKEN_ERROR; } if (c == '\n') { @@ -552,7 +563,7 @@ static int look(Scanner * s) { break; case 11: /* C style comment block */ if ((c = nextchar(s)) == 0) { - set_error(s,s->start_line,"Unterminated comment"); + Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n"); return SWIG_TOKEN_ERROR; } if (c == '*') { @@ -563,7 +574,7 @@ static int look(Scanner * s) { break; case 12: /* Still in C style comment */ if ((c = nextchar(s)) == 0) { - set_error(s,s->start_line,"Unterminated comment"); + Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n"); return SWIG_TOKEN_ERROR; } if (c == '*') { @@ -577,7 +588,7 @@ static int look(Scanner * s) { case 2: /* Processing a string */ if ((c = nextchar(s)) == 0) { - set_error(s,s->start_line, "Unterminated string"); + Swig_error(cparse_file, cparse_start_line, "Unterminated string\n"); return SWIG_TOKEN_ERROR; } if (c == '\"') { @@ -660,7 +671,7 @@ static int look(Scanner * s) { case 40: /* Process an include block */ if ((c = nextchar(s)) == 0) { - set_error(s,s->start_line,"Unterminated code block"); + Swig_error(cparse_file, cparse_start_line, "Unterminated block\n"); return SWIG_TOKEN_ERROR; } if (c == '%') @@ -730,15 +741,25 @@ static int look(Scanner * s) { break; case 7: /* Identifier */ if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_ID; - if (isalnum(c) || (c == '_') || (c == '$')) { + state = 71; + else if (isalnum(c) || (c == '_') || (c == '$')) { state = 7; } else { retract(s, 1); - return SWIG_TOKEN_ID; + state = 71; } break; + case 71: /* Identifier or true/false */ + if (cparse_cplusplus) { + if (Strcmp(s->text, "true") == 0) + return SWIG_TOKEN_BOOL; + else if (Strcmp(s->text, "false") == 0) + return SWIG_TOKEN_BOOL; + } + return SWIG_TOKEN_ID; + break; + case 75: /* Special identifier $ */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_DOLLAR; @@ -747,7 +768,7 @@ static int look(Scanner * s) { } else { retract(s,1); if (Len(s->text) == 1) return SWIG_TOKEN_DOLLAR; - return SWIG_TOKEN_ID; + state = 71; } break; @@ -937,7 +958,7 @@ static int look(Scanner * s) { /* A character constant */ case 9: if ((c = nextchar(s)) == 0) { - set_error(s,s->start_line,"Unterminated character constant"); + Swig_error(cparse_file, cparse_start_line, "Unterminated character constant\n"); return SWIG_TOKEN_ERROR; } if (c == '\'') { @@ -1052,7 +1073,7 @@ static int look(Scanner * s) { /* Reverse string */ case 900: if ((c = nextchar(s)) == 0) { - set_error(s,s->start_line,"Unterminated character constant"); + Swig_error(cparse_file, cparse_start_line, "Unterminated character constant\n"); return SWIG_TOKEN_ERROR; } if (c == '`') { @@ -1135,10 +1156,9 @@ void Scanner_skip_line(Scanner * s) { int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) { char c; int num_levels = 1; - int l; int state = 0; char temp[2] = { 0, 0 }; - l = s->line; + String *locator = 0; temp[0] = (char) startchar; Clear(s->text); Setfile(s->text, Getfile(s->str)); @@ -1147,6 +1167,7 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) { Append(s->text, temp); while (num_levels > 0) { if ((c = nextchar(s)) == 0) { + Delete(locator); return -1; } switch (state) { @@ -1167,6 +1188,10 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) { state = 11; else if (c == '*') state = 12; + else if (c == startchar) { + state = 0; + num_levels++; + } else state = 0; break; @@ -1176,17 +1201,25 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) { else state = 11; break; - case 12: + case 12: /* first character inside C comment */ if (c == '*') + state = 14; + else if (c == '@') + state = 40; + else state = 13; break; case 13: if (c == '*') - state = 13; + state = 14; + break; + case 14: /* possible end of C comment */ + if (c == '*') + state = 14; else if (c == '/') state = 0; else - state = 12; + state = 13; break; case 20: if (c == '\"') @@ -1206,10 +1239,43 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) { case 31: state = 30; break; + /* 40-45 SWIG locator checks - a C comment with contents starting: @SWIG */ + case 40: + state = (c == 'S') ? 41 : (c == '*') ? 14 : 13; + break; + case 41: + state = (c == 'W') ? 42 : (c == '*') ? 14 : 13; + break; + case 42: + state = (c == 'I') ? 43 : (c == '*') ? 14 : 13; + break; + case 43: + state = (c == 'G') ? 44 : (c == '*') ? 14 : 13; + if (c == 'G') { + Delete(locator); + locator = NewString("/*@SWIG"); + } + break; + case 44: + if (c == '*') + state = 45; + Putc(c, locator); + break; + case 45: /* end of SWIG locator in C comment */ + if (c == '/') { + state = 0; + Putc(c, locator); + Scanner_locator(s, locator); + } else { + /* malformed locator */ + state = (c == '*') ? 14 : 13; + } + break; default: break; } } + Delete(locator); return 0; } @@ -1220,8 +1286,98 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) { * operator. * ----------------------------------------------------------------------------- */ -int -Scanner_isoperator(int tokval) { +int Scanner_isoperator(int tokval) { if (tokval >= 100) return 1; return 0; } + +/* ---------------------------------------------------------------------- + * locator() + * + * Support for locator strings. These are strings of the form + * @SWIG:filename,line,id@ emitted by the SWIG preprocessor. They + * are primarily used for macro line number reporting. + * We just use the locator to mark when to activate/deactivate linecounting. + * ---------------------------------------------------------------------- */ + + +void Scanner_locator(Scanner *s, String *loc) { + static Locator *locs = 0; + static int expanding_macro = 0; + + if (!follow_locators) { + if (Equal(loc, "/*@SWIG@*/")) { + /* End locator. */ + if (expanding_macro) + --expanding_macro; + } else { + /* Begin locator. */ + ++expanding_macro; + } + /* Freeze line number processing in Scanner */ + freeze_line(s,expanding_macro); + } else { + int c; + Locator *l; + Seek(loc, 7, SEEK_SET); + c = Getc(loc); + if (c == '@') { + /* Empty locator. We pop the last location off */ + if (locs) { + Scanner_set_location(s, locs->filename, locs->line_number); + cparse_file = locs->filename; + cparse_line = locs->line_number; + l = locs->next; + free(locs); + locs = l; + } + return; + } + + /* We're going to push a new location */ + l = (Locator *) malloc(sizeof(Locator)); + l->filename = cparse_file; + l->line_number = cparse_line; + l->next = locs; + locs = l; + + /* Now, parse the new location out of the locator string */ + { + String *fn = NewStringEmpty(); + /* Putc(c, fn); */ + + while ((c = Getc(loc)) != EOF) { + if ((c == '@') || (c == ',')) + break; + Putc(c, fn); + } + cparse_file = Swig_copy_string(Char(fn)); + Clear(fn); + cparse_line = 1; + /* Get the line number */ + while ((c = Getc(loc)) != EOF) { + if ((c == '@') || (c == ',')) + break; + Putc(c, fn); + } + cparse_line = atoi(Char(fn)); + Clear(fn); + + /* Get the rest of it */ + while ((c = Getc(loc)) != EOF) { + if (c == '@') + break; + Putc(c, fn); + } + /* Swig_diagnostic(cparse_file, cparse_line, "Scanner_set_location\n"); */ + Scanner_set_location(s, cparse_file, cparse_line); + Delete(fn); + } + } +} + +void Swig_cparse_follow_locators(int v) { + follow_locators = v; +} + + diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index 30a80b4bd..5b9708b9a 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -177,7 +177,7 @@ void SwigType_push(SwigType *t, String *cons) { * Testing functions for querying a raw datatype * ----------------------------------------------------------------------------- */ -int SwigType_ispointer_return(SwigType *t) { +int SwigType_ispointer_return(const SwigType *t) { char *c; int idx; if (!t) @@ -190,7 +190,7 @@ int SwigType_ispointer_return(SwigType *t) { return 0; } -int SwigType_isreference_return(SwigType *t) { +int SwigType_isreference_return(const SwigType *t) { char *c; int idx; if (!t) @@ -203,7 +203,7 @@ int SwigType_isreference_return(SwigType *t) { return 0; } -int SwigType_isconst(SwigType *t) { +int SwigType_isconst(const SwigType *t) { char *c; if (!t) return 0; @@ -229,7 +229,7 @@ int SwigType_isconst(SwigType *t) { return 0; } -int SwigType_ismutable(SwigType *t) { +int SwigType_ismutable(const SwigType *t) { int r; SwigType *qt = SwigType_typedef_resolve_all(t); if (SwigType_isreference(qt) || SwigType_isarray(qt)) { @@ -240,7 +240,7 @@ int SwigType_ismutable(SwigType *t) { return r ? 0 : 1; } -int SwigType_isenum(SwigType *t) { +int SwigType_isenum(const SwigType *t) { char *c = Char(t); if (!t) return 0; @@ -250,7 +250,7 @@ int SwigType_isenum(SwigType *t) { return 0; } -int SwigType_issimple(SwigType *t) { +int SwigType_issimple(const SwigType *t) { char *c = Char(t); if (!t) return 0; @@ -275,223 +275,187 @@ int SwigType_issimple(SwigType *t) { } /* ----------------------------------------------------------------------------- - * SwigType_default() + * SwigType_default_create() * - * Create the default string for this datatype. This takes a type and strips it - * down to its most primitive form--resolving all typedefs and removing operators. + * Create the default type for this datatype. This takes a type and strips it + * down to a generic form first by resolving all typedefs. * * Rules: - * Pointers: p.SWIGTYPE - * References: r.SWIGTYPE - * Arrays: a().SWIGTYPE - * Types: SWIGTYPE - * MemberPointer: m(CLASS).SWIGTYPE - * Enums: enum SWIGTYPE + * Pointers: p.SWIGTYPE + * References: r.SWIGTYPE + * Arrays no dimension: a().SWIGTYPE + * Arrays with dimension: a(ANY).SWIGTYPE + * Member pointer: m(CLASS).SWIGTYPE + * Function pointer: f(ANY).SWIGTYPE + * Enums: enum SWIGTYPE + * Types: SWIGTYPE * - * Note: if this function is applied to a primitive type, it returns NULL. This - * allows recursive application for special types like arrays. + * Examples (also see SwigType_default_deduce): + * + * int [2][4] + * a(2).a(4).int + * a(ANY).a(ANY).SWIGTYPE + * + * struct A {}; + * typedef A *Aptr; + * Aptr const & + * r.q(const).Aptr + * r.q(const).p.SWIGTYPE + * + * enum E {e1, e2}; + * enum E const & + * r.q(const).enum E + * r.q(const).enum SWIGTYPE * ----------------------------------------------------------------------------- */ -#ifdef SWIG_DEFAULT_CACHE -static Hash *default_cache = 0; -#endif - -#define SWIG_NEW_TYPE_DEFAULT -/* The new default type resolution method: - -1.- It preserves the original mixed types, then it goes 'backward' - first deleting the qualifier, then the inner types - - typedef A *Aptr; - const Aptr&; - r.q(const).Aptr -> r.q(const).p.SWIGTYPE - r.q(const).p.SWIGTYPE -> r.p.SWIGTYPE - r.p.SWIGTYPE -> r.SWIGTYPE - r.SWIGTYPE -> SWIGTYPE - - - enum Hello {}; - const Hello& hi; - r.q(const).Hello -> r.q(const).enum SWIGTYPE - r.q(const).enum SWIGTYPE -> r.enum SWIGTYPE - r.enum SWIGTYPE -> r.SWIGTYPE - r.SWIGTYPE -> SWIGTYPE - - int a[2][4]; - a(2).a(4).int -> a(ANY).a(ANY).SWIGTYPE - a(ANY).a(ANY).SWIGTYPE -> a(ANY).a().SWIGTYPE - a(ANY).a().SWIGTYPE -> a(ANY).p.SWIGTYPE - a(ANY).p.SWIGTYPE -> a(ANY).SWIGTYPE - a(ANY).SWIGTYPE -> a().SWIGTYPE - a().SWIGTYPE -> p.SWIGTYPE - p.SWIGTYPE -> SWIGTYPE -*/ +SwigType *SwigType_default_create(const SwigType *ty) { + SwigType *r = 0; + List *l; + Iterator it; + int numitems; + + if (!SwigType_isvarargs(ty)) { + SwigType *t = SwigType_typedef_resolve_all(ty); + r = NewStringEmpty(); + l = SwigType_split(t); + numitems = Len(l); + + if (numitems >= 1) { + String *last_subtype = Getitem(l, numitems-1); + if (SwigType_isenum(last_subtype)) + Setitem(l, numitems-1, NewString("enum SWIGTYPE")); + else + Setitem(l, numitems-1, NewString("SWIGTYPE")); + } -static -void SwigType_add_default(String *def, SwigType *nr) { - if (Strcmp(nr, "SWIGTYPE") == 0) { - Append(def, "SWIGTYPE"); - } else { - String *q = SwigType_isqualifier(nr) ? SwigType_pop(nr) : 0; - if (q && strstr(Char(nr), "SWIGTYPE")) { - Append(def, nr); - } else { - String *nd = SwigType_default(nr); - if (nd) { - String *bdef = nd; - if (q) { - bdef = NewStringf("%s%s", q, nd); - if ((Strcmp(nr, bdef) == 0)) { - Delete(bdef); - bdef = nd; - } else { - Delete(nd); - } - } - Append(def, bdef); - Delete(bdef); + for (it = First(l); it.item; it = Next(it)) { + String *subtype = it.item; + if (SwigType_isarray(subtype)) { + if (Equal(subtype, "a().")) + Append(r, NewString("a().")); + else + Append(r, NewString("a(ANY).")); + } else if (SwigType_isfunction(subtype)) { + Append(r, NewString("f(ANY).SWIGTYPE")); + break; + } else if (SwigType_ismemberpointer(subtype)) { + Append(r, NewString("m(CLASS).SWIGTYPE")); + break; } else { - Append(def, nr); + Append(r, subtype); } } - Delete(q); - } -} - - -SwigType *SwigType_default(SwigType *t) { - String *r1, *def; - String *r = 0; - char *cr; - -#ifdef SWIG_DEFAULT_CACHE - if (!default_cache) - default_cache = NewHash(); - r = Getattr(default_cache, t); - if (r) { - return Copy(r); + Delete(l); + Delete(t); } -#endif - if (SwigType_isvarargs(t)) { - return 0; - } + return r; +} - r = t; - while ((r1 = SwigType_typedef_resolve(r))) { - if (r != t) - Delete(r); - r = r1; - } - if (SwigType_isqualifier(r)) { - String *q; - if (r == t) - r = Copy(t); - q = SwigType_pop(r); - if (strstr(Char(r), "SWIGTYPE")) { - Delete(q); - def = r; - return def; - } - Delete(q); - } - cr = Char(r); - if (strcmp(cr, "p.SWIGTYPE") == 0) { - def = NewString("SWIGTYPE"); - } else if (SwigType_ispointer(r)) { -#ifdef SWIG_NEW_TYPE_DEFAULT - SwigType *nr = Copy(r); - SwigType_del_pointer(nr); - def = SwigType_isfunction(nr) ? NewStringEmpty() : NewString("p."); - SwigType_add_default(def, nr); - Delete(nr); -#else - def = NewString("p.SWIGTYPE"); -#endif - } else if (strcmp(cr, "r.SWIGTYPE") == 0) { - def = NewString("SWIGTYPE"); - } else if (SwigType_isreference(r)) { -#ifdef SWIG_NEW_TYPE_DEFAULT - SwigType *nr = Copy(r); - SwigType_del_reference(nr); - def = NewString("r."); - SwigType_add_default(def, nr); - Delete(nr); -#else - def = NewString("r.SWIGTYPE"); -#endif - } else if (SwigType_isarray(r)) { - if (strcmp(cr, "a().SWIGTYPE") == 0) { - def = NewString("p.SWIGTYPE"); - } else if (strcmp(cr, "a(ANY).SWIGTYPE") == 0) { - def = NewString("a().SWIGTYPE"); - } else { - int i, empty = 0; - int ndim = SwigType_array_ndim(r); - SwigType *nr = Copy(r); - for (i = 0; i < ndim; i++) { - String *dim = SwigType_array_getdim(r, i); - if (!Len(dim)) { - char *c = Char(nr); - empty = strstr(c, "a(ANY).") != c; +/* ----------------------------------------------------------------------------- + * SwigType_default_deduce() + * + * This function implements type deduction used in the typemap matching rules + * and is very close to the type deduction used in partial template class + * specialization matching in that the most specialized type is always chosen. + * SWIGTYPE is used as the generic type. The basic idea is to repeatedly call + * this function to find a deduced type unless until nothing matches. + * + * The type t must have already been converted to the default type via a call to + * SwigType_default_create() before calling this function. + * + * Example deductions (matching the examples described in SwigType_default_create), + * where the most specialized matches are highest in the list: + * + * a(ANY).a(ANY).SWIGTYPE + * a(ANY).a().SWIGTYPE + * a(ANY).p.SWIGTYPE + * a(ANY).SWIGTYPE + * a().SWIGTYPE + * p.SWIGTYPE + * SWIGTYPE + * + * r.q(const).p.SWIGTYPE + * r.q(const).SWIGTYPE + * r.SWIGTYPE + * SWIGTYPE + * + * r.q(const).enum SWIGTYPE + * r.enum SWIGTYPE + * r.SWIGTYPE + * SWIGTYPE + * ----------------------------------------------------------------------------- */ + +SwigType *SwigType_default_deduce(const SwigType *t) { + SwigType *r = NewStringEmpty(); + List *l; + Iterator it; + int numitems; + + l = SwigType_split(t); + + numitems = Len(l); + if (numitems >= 1) { + String *last_subtype = Getitem(l, numitems-1); + int is_enum = SwigType_isenum(last_subtype); + + if (numitems >=2 ) { + String *subtype = Getitem(l, numitems-2); /* last but one */ + if (SwigType_isarray(subtype)) { + if (is_enum) { + /* enum deduction, enum SWIGTYPE => SWIGTYPE */ + Setitem(l, numitems-1, NewString("SWIGTYPE")); + } else { + /* array deduction, a(ANY). => a(). => p. */ + String *deduced_subtype = 0; + if (Strcmp(subtype, "a().") == 0) { + deduced_subtype = NewString("p."); + } else if (Strcmp(subtype, "a(ANY).") == 0) { + deduced_subtype = NewString("a()."); + } else { + assert(0); + } + Setitem(l, numitems-2, deduced_subtype); } - Delete(dim); - } - if (empty) { - def = NewString("a()."); + } else if (SwigType_ismemberpointer(subtype)) { + /* member pointer deduction, m(CLASS). => p. */ + Setitem(l, numitems-2, NewString("p.")); + } else if (is_enum && !SwigType_isqualifier(subtype)) { + /* enum deduction, enum SWIGTYPE => SWIGTYPE */ + Setitem(l, numitems-1, NewString("SWIGTYPE")); } else { - def = NewString("a(ANY)."); + /* simple type deduction, eg, r.p.p. => r.p. */ + /* also function pointers eg, p.f(ANY). => p. */ + Delitem(l, numitems-2); } -#ifdef SWIG_NEW_TYPE_DEFAULT - SwigType_del_array(nr); - SwigType_add_default(def, nr); -#else - Append(def, "SWIGTYPE"); -#endif - Delete(nr); - } - } else if (SwigType_ismemberpointer(r)) { - if (strcmp(cr, "m(CLASS).SWIGTYPE") == 0) { - def = NewString("p.SWIGTYPE"); - } else { - def = NewString("m(CLASS).SWIGTYPE"); - } - } else if (SwigType_isenum(r)) { - if (strcmp(cr, "enum SWIGTYPE") == 0) { - def = NewString("SWIGTYPE"); } else { - def = NewString("enum SWIGTYPE"); - } - } else if (SwigType_isfunction(r)) { - if (strcmp(cr, "f(ANY).SWIGTYPE") == 0) { - def = NewString("p.SWIGTYPE"); - } else { - def = NewString("p.f(ANY).SWIGTYPE"); + if (is_enum) { + /* enum deduction, enum SWIGTYPE => SWIGTYPE */ + Setitem(l, numitems-1, NewString("SWIGTYPE")); + } else { + /* delete the only item, we are done with deduction */ + Delitem(l, 0); + } } } else { - def = NewString("SWIGTYPE"); + assert(0); } - if (r != t) - Delete(r); - if (Equal(def, t)) { - Delete(def); - def = 0; - } -#ifdef SWIG_DEFAULT_CACHE - /* The cache produces strange results, see enum_template.i case */ - if (def) { - String *cdef = Copy(def); - Setattr(default_cache, t, cdef); - Delete(cdef); + + for (it = First(l); it.item; it = Next(it)) { + Append(r, it.item); } -#endif - /* Printf(stderr,"type : def %s : %s\n", t, def); */ + if (Len(r) == 0) { + Delete(r); + r = 0; + } - return def; + Delete(l); + return r; } + /* ----------------------------------------------------------------------------- * SwigType_namestr() * @@ -529,7 +493,13 @@ String *SwigType_namestr(const SwigType *t) { Putc(' ', r); Putc('>', r); suffix = SwigType_templatesuffix(t); - Append(r, suffix); + if (Len(suffix) > 0) { + String *suffix_namestr = SwigType_namestr(suffix); + Append(r, suffix_namestr); + Delete(suffix_namestr); + } else { + Append(r, suffix); + } Delete(suffix); Delete(p); return r; @@ -541,14 +511,19 @@ String *SwigType_namestr(const SwigType *t) { * Create a C string representation of a datatype. * ----------------------------------------------------------------------------- */ -String *SwigType_str(SwigType *s, const String_or_char *id) { +String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) { String *result; - String *element = 0, *nextelement; + String *element = 0; + String *nextelement; + String *forwardelement; List *elements; int nelements, i; if (id) { - result = NewString(id); + /* stringify the id expanding templates, for example when the id is a fully qualified templated class name */ + String *id_str = NewString(id); /* unfortunate copy due to current const limitations */ + result = SwigType_str(id_str, 0); + Delete(id_str); } else { result = NewStringEmpty(); } @@ -563,8 +538,14 @@ String *SwigType_str(SwigType *s, const String_or_char *id) { for (i = 0; i < nelements; i++) { if (i < (nelements - 1)) { nextelement = Getitem(elements, i + 1); + forwardelement = nextelement; + if (SwigType_isqualifier(nextelement)) { + if (i < (nelements - 2)) + forwardelement = Getitem(elements, i + 2); + } } else { nextelement = 0; + forwardelement = 0; } if (SwigType_isqualifier(element)) { DOH *q = 0; @@ -574,7 +555,7 @@ String *SwigType_str(SwigType *s, const String_or_char *id) { Delete(q); } else if (SwigType_ispointer(element)) { Insert(result, 0, "*"); - if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { + if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } @@ -583,14 +564,14 @@ String *SwigType_str(SwigType *s, const String_or_char *id) { q = SwigType_parm(element); Insert(result, 0, "::*"); Insert(result, 0, q); - if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { + if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } Delete(q); } else if (SwigType_isreference(element)) { Insert(result, 0, "&"); - if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { + if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } @@ -633,12 +614,12 @@ String *SwigType_str(SwigType *s, const String_or_char *id) { } /* ----------------------------------------------------------------------------- - * SwigType_ltype(SwigType *ty) + * SwigType_ltype(const SwigType *ty) * * Create a locally assignable type * ----------------------------------------------------------------------------- */ -SwigType *SwigType_ltype(SwigType *s) { +SwigType *SwigType_ltype(const SwigType *s) { String *result; String *element; SwigType *td, *tc = 0; @@ -736,7 +717,7 @@ SwigType *SwigType_ltype(SwigType *s) { * with an equivalent assignable version. * -------------------------------------------------------------------- */ -String *SwigType_lstr(SwigType *s, const String_or_char *id) { +String *SwigType_lstr(const SwigType *s, const_String_or_char_ptr id) { String *result; SwigType *tc; @@ -753,16 +734,19 @@ String *SwigType_lstr(SwigType *s, const String_or_char *id) { * datatype printed by str(). * ----------------------------------------------------------------------------- */ -String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { +String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) { String *result, *cast; - String *element = 0, *nextelement; - SwigType *td, *rs, *tc = 0; + String *element = 0; + String *nextelement; + String *forwardelement; + SwigType *td, *tc = 0; + const SwigType *rs; List *elements; int nelements, i; int clear = 1; int firstarray = 1; int isreference = 0; - int isarray = 0; + int isfunction = 0; result = NewStringEmpty(); @@ -798,8 +782,14 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { for (i = 0; i < nelements; i++) { if (i < (nelements - 1)) { nextelement = Getitem(elements, i + 1); + forwardelement = nextelement; + if (SwigType_isqualifier(nextelement)) { + if (i < (nelements - 2)) + forwardelement = Getitem(elements, i + 2); + } } else { nextelement = 0; + forwardelement = 0; } if (SwigType_isqualifier(element)) { DOH *q = 0; @@ -810,7 +800,7 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { clear = 0; } else if (SwigType_ispointer(element)) { Insert(result, 0, "*"); - if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { + if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } @@ -821,18 +811,19 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { q = SwigType_parm(element); Insert(result, 0, q); Delete(q); - if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { + if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } firstarray = 0; } else if (SwigType_isreference(element)) { Insert(result, 0, "&"); - if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { + if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } - isreference = 1; + if (!isfunction) + isreference = 1; } else if (SwigType_isarray(element)) { DOH *size; if (firstarray && !isreference) { @@ -846,7 +837,6 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { Delete(size); clear = 0; } - isarray = 1; } else if (SwigType_isfunction(element)) { DOH *parms, *p; int j, plen; @@ -862,6 +852,7 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { } Append(result, ")"); Delete(parms); + isfunction = 1; } else { String *bs = SwigType_namestr(element); Insert(result, 0, " "); @@ -878,8 +869,6 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { } if (name) { if (isreference) { - if (isarray) - Clear(cast); Append(cast, "*"); } Append(cast, name); @@ -896,7 +885,7 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { * Casts a variable from the real type to the local datatype. * ----------------------------------------------------------------------------- */ -String *SwigType_lcaststr(SwigType *s, const String_or_char *name) { +String *SwigType_lcaststr(const SwigType *s, const_String_or_char_ptr name) { String *result; result = NewStringEmpty(); @@ -922,27 +911,163 @@ String *SwigType_lcaststr(SwigType *s, const String_or_char *name) { return result; } +#if 0 +/* Alternative implementation for manglestr_default. Mangling is similar to the original + except for a few subtle differences for example in templates: + namespace foo { + template<class T> class bar {}; + typedef int Integer; + void test2(bar<Integer *> *x); + } + Mangling is more consistent and changes from + _p_foo__barT_int_p_t to + _p_foo__barT_p_int_t. +*/ +static void mangle_stringcopy(String *destination, const char *source, int count) { + while (count-- > 0) { + char newc = '_'; + if (!(*source == '.' || *source == ':' || *source == ' ')) + newc = *source; + /* TODO: occasionally '*' or numerics need converting to '_', eg in array dimensions and template expressions */ + Putc(newc, destination); + source++; + } +} + +static void mangle_subtype(String *mangled, SwigType *s); + +/* ----------------------------------------------------------------------------- + * mangle_namestr() + * + * Mangles a type taking care of template expansions. Similar to SwigType_namestr(). + * The type may include a trailing '.', for example "p." + * ----------------------------------------------------------------------------- */ + +static void mangle_namestr(String *mangled, SwigType *t) { + int length = Len(t); + if (SwigType_isqualifier(t)) { + Append(mangled, "q_"); + mangle_stringcopy(mangled, Char(t)+2, length-4); + Append(mangled, "__"); + } else if (SwigType_ismemberpointer(t)) { + Append(mangled, "m_"); + mangle_stringcopy(mangled, Char(t)+2, length-4); + Append(mangled, "__"); + } else if (SwigType_isarray(t)) { + Append(mangled, "a_"); + mangle_stringcopy(mangled, Char(t)+2, length-4); + Append(mangled, "__"); + } else if (SwigType_isfunction(t)) { + List *p = SwigType_parmlist(t); + int sz = Len(p); + int i; + Append(mangled, "f_"); + for (i = 0; i < sz; i++) { + mangle_subtype(mangled, Getitem(p, i)); + Putc('_', mangled); + } + Append(mangled, (sz > 0) ? "_" : "__"); + } else if (SwigType_isvarargs(t)) { + Append(mangled, "___"); + } else { + char *d = Char(t); + char *c = strstr(d, "<("); + if (!c || !strstr(c + 2, ")>")) { + /* not a template type */ + mangle_stringcopy(mangled, Char(t), Len(t)); + } else { + /* a template type */ + String *suffix; + List *p; + int i, sz; + mangle_stringcopy(mangled, d, c-d); + Putc('T', mangled); + Putc('_', mangled); + + p = SwigType_parmlist(c + 1); + sz = Len(p); + for (i = 0; i < sz; i++) { + mangle_subtype(mangled, Getitem(p, i)); + Putc('_', mangled); + } + Putc('t', mangled); + suffix = SwigType_templatesuffix(t); + if (Len(suffix) > 0) { + mangle_namestr(mangled, suffix); + } else { + Append(mangled, suffix); + } + Delete(suffix); + Delete(p); + } + } +} + +static void mangle_subtype(String *mangled, SwigType *s) { + List *elements; + int nelements, i; + + assert(s); + elements = SwigType_split(s); + nelements = Len(elements); + for (i = 0; i < nelements; i++) { + SwigType *element = Getitem(elements, i); + mangle_namestr(mangled, element); + } + Delete(elements); +} + +static String *manglestr_default(const SwigType *s) { + String *mangled = NewString("_"); + SwigType *sr = SwigType_typedef_resolve_all(s); + SwigType *sq = SwigType_typedef_qualified(sr); + SwigType *ss = SwigType_remove_global_scope_prefix(sq); + SwigType *type = ss; + SwigType *lt; + + if (SwigType_istemplate(ss)) { + SwigType *ty = Swig_symbol_template_deftype(ss, 0); + Delete(ss); + ss = ty; + type = ss; + } + + lt = SwigType_ltype(type); + + Replace(lt, "struct ", "", DOH_REPLACE_ANY); + Replace(lt, "class ", "", DOH_REPLACE_ANY); + Replace(lt, "union ", "", DOH_REPLACE_ANY); + Replace(lt, "enum ", "", DOH_REPLACE_ANY); + + mangle_subtype(mangled, lt); + + Delete(ss); + Delete(sq); + Delete(sr); + + return mangled; +} + +#else -/* keep old mangling since Java codes need it */ -String *SwigType_manglestr_default(SwigType *s) { +static String *manglestr_default(const SwigType *s) { char *c; String *result = 0; String *base = 0; SwigType *lt; - SwigType *sr = SwigType_typedef_qualified(s); - SwigType *ss = SwigType_typedef_resolve_all(sr); - - s = ss; + SwigType *sr = SwigType_typedef_resolve_all(s); + SwigType *sq = SwigType_typedef_qualified(sr); + SwigType *ss = SwigType_remove_global_scope_prefix(sq); + SwigType *type = ss; if (SwigType_istemplate(ss)) { SwigType *ty = Swig_symbol_template_deftype(ss, 0); Delete(ss); ss = ty; - s = ss; + type = ss; } - Delete(sr); - lt = SwigType_ltype(s); + lt = SwigType_ltype(type); result = SwigType_prefix(lt); base = SwigType_base(lt); @@ -989,13 +1114,23 @@ String *SwigType_manglestr_default(SwigType *s) { Insert(result, 0, "_"); Delete(lt); Delete(base); - if (ss) - Delete(ss); + Delete(ss); + Delete(sq); + Delete(sr); return result; } +#endif -String *SwigType_manglestr(SwigType *s) { - return SwigType_manglestr_default(s); +String *SwigType_manglestr(const SwigType *s) { +#if 0 + /* Debugging checks to ensure a proper SwigType is passed in and not a stringified type */ + String *angle = Strstr(s, "<"); + if (angle && Strncmp(angle, "<(", 2) != 0) + Printf(stderr, "SwigType_manglestr error: %s\n", s); + else if (Strstr(s, "*") || Strstr(s, "&") || Strstr(s, "[")) + Printf(stderr, "SwigType_manglestr error: %s\n", s); +#endif + return manglestr_default(s); } /* ----------------------------------------------------------------------------- @@ -1090,12 +1225,31 @@ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) { } /* ----------------------------------------------------------------------------- + * SwigType_remove_global_scope_prefix() + * + * Removes the unary scope operator (::) prefix indicating global scope in all + * components of the type + * ----------------------------------------------------------------------------- */ + +SwigType *SwigType_remove_global_scope_prefix(const SwigType *t) { + SwigType *result; + const char *type = Char(t); + if (strncmp(type, "::", 2) == 0) + type += 2; + result = NewString(type); + Replaceall(result, ".::", "."); + Replaceall(result, "(::", "("); + Replaceall(result, "enum ::", "enum "); + return result; +} + +/* ----------------------------------------------------------------------------- * SwigType_check_decl() * * Checks type declarators for a match * ----------------------------------------------------------------------------- */ -int SwigType_check_decl(SwigType *ty, const SwigType *decl) { +int SwigType_check_decl(const SwigType *ty, const SwigType *decl) { SwigType *t, *t1, *t2; int r; t = SwigType_typedef_resolve_all(ty); diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 9501eaa55..3a44452ed 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -11,8 +11,6 @@ * Header file for the SWIG core. * ----------------------------------------------------------------------------- */ -/* $Id$ */ - #ifndef SWIGCORE_H_ #define SWIGCORE_H_ @@ -37,6 +35,10 @@ extern "C" { #define SWIG_ERROR 0 #define SWIG_NOWRAP 0 +/* Global macros */ +#define NSPACE_SEPARATOR "." /* Namespace separator for the nspace feature - this should be changed to a target language configurable variable */ +#define NSPACE_TODO 0 /* Languages that still need to implement and test the nspace feature use this */ + /* Short names for common data types */ typedef DOH String; @@ -114,120 +116,128 @@ extern "C" { extern SwigType *NewSwigType(int typecode); extern SwigType *SwigType_del_element(SwigType *t); extern SwigType *SwigType_add_pointer(SwigType *t); - extern SwigType *SwigType_add_memberpointer(SwigType *t, const String_or_char *qual); + extern SwigType *SwigType_add_memberpointer(SwigType *t, const_String_or_char_ptr qual); extern SwigType *SwigType_del_memberpointer(SwigType *t); extern SwigType *SwigType_del_pointer(SwigType *t); - extern SwigType *SwigType_add_array(SwigType *t, const String_or_char *size); + extern SwigType *SwigType_add_array(SwigType *t, const_String_or_char_ptr size); extern SwigType *SwigType_del_array(SwigType *t); extern SwigType *SwigType_pop_arrays(SwigType *t); extern SwigType *SwigType_add_reference(SwigType *t); extern SwigType *SwigType_del_reference(SwigType *t); - extern SwigType *SwigType_add_qualifier(SwigType *t, const String_or_char *qual); + extern SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual); extern SwigType *SwigType_del_qualifier(SwigType *t); extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms); extern SwigType *SwigType_add_template(SwigType *t, ParmList *parms); extern SwigType *SwigType_pop_function(SwigType *t); - extern ParmList *SwigType_function_parms(SwigType *t); + extern ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node); extern List *SwigType_split(const SwigType *t); extern String *SwigType_pop(SwigType *t); - extern void SwigType_push(SwigType *t, SwigType *s); + extern void SwigType_push(SwigType *t, String *s); extern List *SwigType_parmlist(const SwigType *p); - extern String *SwigType_parm(String *p); - extern String *SwigType_str(SwigType *s, const String_or_char *id); - extern String *SwigType_lstr(SwigType *s, const String_or_char *id); - extern String *SwigType_rcaststr(SwigType *s, const String_or_char *id); - extern String *SwigType_lcaststr(SwigType *s, const String_or_char *id); - extern String *SwigType_manglestr(SwigType *t); - extern SwigType *SwigType_ltype(SwigType *t); - extern int SwigType_ispointer(SwigType *t); - extern int SwigType_ispointer_return(SwigType *t); - extern int SwigType_isfunctionpointer(SwigType *t); - extern int SwigType_ismemberpointer(SwigType *t); - extern int SwigType_isreference(SwigType *t); - extern int SwigType_isreference_return(SwigType *t); - extern int SwigType_isarray(SwigType *t); - extern int SwigType_prefix_is_simple_1D_array(SwigType *t); - extern int SwigType_isfunction(SwigType *t); - extern int SwigType_isqualifier(SwigType *t); - extern int SwigType_isconst(SwigType *t); - extern int SwigType_issimple(SwigType *t); - extern int SwigType_ismutable(SwigType *t); + extern String *SwigType_parm(const SwigType *p); + extern String *SwigType_str(const SwigType *s, const_String_or_char_ptr id); + extern String *SwigType_lstr(const SwigType *s, const_String_or_char_ptr id); + extern String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr id); + extern String *SwigType_lcaststr(const SwigType *s, const_String_or_char_ptr id); + extern String *SwigType_manglestr(const SwigType *t); + extern SwigType *SwigType_ltype(const SwigType *t); + extern int SwigType_ispointer(const SwigType *t); + extern int SwigType_ispointer_return(const SwigType *t); + extern int SwigType_isfunctionpointer(const SwigType *t); + extern int SwigType_ismemberpointer(const SwigType *t); + extern int SwigType_isreference(const SwigType *t); + extern int SwigType_isreference_return(const SwigType *t); + extern int SwigType_isarray(const SwigType *t); + extern int SwigType_prefix_is_simple_1D_array(const SwigType *t); + extern int SwigType_isfunction(const SwigType *t); + extern int SwigType_isqualifier(const SwigType *t); + extern int SwigType_isconst(const SwigType *t); + extern int SwigType_issimple(const SwigType *t); + extern int SwigType_ismutable(const SwigType *t); extern int SwigType_isvarargs(const SwigType *t); extern int SwigType_istemplate(const SwigType *t); - extern int SwigType_isenum(SwigType *t); - extern int SwigType_check_decl(SwigType *t, const String_or_char *decl); - extern SwigType *SwigType_strip_qualifiers(SwigType *t); + extern int SwigType_isenum(const SwigType *t); + extern int SwigType_check_decl(const SwigType *t, const_String_or_char_ptr decl); + extern SwigType *SwigType_strip_qualifiers(const SwigType *t); + extern SwigType *SwigType_strip_single_qualifier(const SwigType *t); extern SwigType *SwigType_functionpointer_decompose(SwigType *t); extern String *SwigType_base(const SwigType *t); extern String *SwigType_namestr(const SwigType *t); extern String *SwigType_templateprefix(const SwigType *t); extern String *SwigType_templatesuffix(const SwigType *t); + extern String *SwigType_istemplate_templateprefix(const SwigType *t); + extern String *SwigType_istemplate_only_templateprefix(const SwigType *t); extern String *SwigType_templateargs(const SwigType *t); extern String *SwigType_prefix(const SwigType *t); - extern int SwigType_array_ndim(SwigType *t); - extern String *SwigType_array_getdim(SwigType *t, int n); - extern void SwigType_array_setdim(SwigType *t, int n, const String_or_char *rep); - extern SwigType *SwigType_array_type(SwigType *t); - extern String *SwigType_default(SwigType *t); + extern int SwigType_array_ndim(const SwigType *t); + extern String *SwigType_array_getdim(const SwigType *t, int n); + extern void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep); + extern SwigType *SwigType_array_type(const SwigType *t); + extern SwigType *SwigType_default_create(const SwigType *ty); + extern SwigType *SwigType_default_deduce(const SwigType *t); extern void SwigType_typename_replace(SwigType *t, String *pat, String *rep); - extern SwigType *SwigType_alttype(SwigType *t, int ltmap); - - extern void SwigType_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl); - extern SwigType *SwigType_template_deftype(const SwigType *type, Symtab *tscope); + extern SwigType *SwigType_remove_global_scope_prefix(const SwigType *t); + extern SwigType *SwigType_alttype(const SwigType *t, int ltmap); /* --- Type-system managment --- */ extern void SwigType_typesystem_init(void); - extern int SwigType_typedef(SwigType *type, String_or_char *name); - extern int SwigType_typedef_class(String_or_char *name); - extern int SwigType_typedef_using(String_or_char *qname); + extern int SwigType_typedef(const SwigType *type, const_String_or_char_ptr name); + extern int SwigType_typedef_class(const_String_or_char_ptr name); + extern int SwigType_typedef_using(const_String_or_char_ptr qname); extern void SwigType_inherit(String *subclass, String *baseclass, String *cast, String *conversioncode); - extern int SwigType_issubtype(SwigType *subtype, SwigType *basetype); + extern int SwigType_issubtype(const SwigType *subtype, const SwigType *basetype); extern void SwigType_scope_alias(String *aliasname, Typetab *t); extern void SwigType_using_scope(Typetab *t); - extern void SwigType_new_scope(const String_or_char *name); + extern void SwigType_new_scope(const_String_or_char_ptr name); extern void SwigType_inherit_scope(Typetab *scope); extern Typetab *SwigType_pop_scope(void); extern Typetab *SwigType_set_scope(Typetab *h); - extern void SwigType_print_scope(Typetab *t); - extern SwigType *SwigType_typedef_resolve(SwigType *t); - extern SwigType *SwigType_typedef_resolve_all(SwigType *t); - extern SwigType *SwigType_typedef_qualified(SwigType *t); - extern int SwigType_istypedef(SwigType *t); - extern int SwigType_isclass(SwigType *t); + extern void SwigType_print_scope(void); + extern SwigType *SwigType_typedef_resolve(const SwigType *t); + extern SwigType *SwigType_typedef_resolve_all(const SwigType *t); + extern SwigType *SwigType_typedef_qualified(const SwigType *t); + extern int SwigType_istypedef(const SwigType *t); + extern int SwigType_isclass(const SwigType *t); extern void SwigType_attach_symtab(Symtab *syms); - extern void SwigType_remember(SwigType *t); - extern void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata); - extern void SwigType_remember_mangleddata(String *mangled, const String_or_char *clientdata); - extern void (*SwigType_remember_trace(void (*tf) (SwigType *, String *, String *))) (SwigType *, String *, String *); + extern void SwigType_remember(const SwigType *t); + extern void SwigType_remember_clientdata(const SwigType *t, const_String_or_char_ptr clientdata); + extern void SwigType_remember_mangleddata(String *mangled, const_String_or_char_ptr clientdata); + extern void (*SwigType_remember_trace(void (*tf) (const SwigType *, String *, String *))) (const SwigType *, String *, String *); extern void SwigType_emit_type_table(File *f_headers, File *f_table); - extern int SwigType_type(SwigType *t); + extern int SwigType_type(const SwigType *t); /* --- Symbol table module --- */ + extern void Swig_symbol_print_tables(Symtab *symtab); + extern void Swig_symbol_print_tables_summary(void); + extern void Swig_symbol_print_symbols(void); + extern void Swig_symbol_print_csymbols(void); extern void Swig_symbol_init(void); - extern void Swig_symbol_setscopename(const String_or_char *name); + extern void Swig_symbol_setscopename(const_String_or_char_ptr name); extern String *Swig_symbol_getscopename(void); extern String *Swig_symbol_qualifiedscopename(Symtab *symtab); + extern String *Swig_symbol_qualified_language_scopename(Symtab *symtab); extern Symtab *Swig_symbol_newscope(void); extern Symtab *Swig_symbol_setscope(Symtab *); - extern Symtab *Swig_symbol_getscope(const String_or_char *symname); + extern Symtab *Swig_symbol_getscope(const_String_or_char_ptr symname); + extern Symtab *Swig_symbol_global_scope(void); extern Symtab *Swig_symbol_current(void); extern Symtab *Swig_symbol_popscope(void); - extern Node *Swig_symbol_add(String_or_char *symname, Node *node); - extern void Swig_symbol_cadd(String_or_char *symname, Node *node); - extern Node *Swig_symbol_clookup(String_or_char *symname, Symtab *tab); - extern Node *Swig_symbol_clookup_check(String_or_char *symname, Symtab *tab, int (*check) (Node *)); - extern Symtab *Swig_symbol_cscope(String_or_char *symname, Symtab *tab); - extern Node *Swig_symbol_clookup_local(String_or_char *symname, Symtab *tab); - extern Node *Swig_symbol_clookup_local_check(String_or_char *symname, Symtab *tab, int (*check) (Node *)); + extern Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *node); + extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *node); + extern Node *Swig_symbol_clookup(const_String_or_char_ptr symname, Symtab *tab); + extern Node *Swig_symbol_clookup_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *)); + extern Symtab *Swig_symbol_cscope(const_String_or_char_ptr symname, Symtab *tab); + extern Node *Swig_symbol_clookup_local(const_String_or_char_ptr symname, Symtab *tab); + extern Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *)); extern String *Swig_symbol_qualified(Node *node); extern Node *Swig_symbol_isoverloaded(Node *node); extern void Swig_symbol_remove(Node *node); - extern void Swig_symbol_alias(String_or_char *aliasname, Symtab *tab); + extern void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *tab); extern void Swig_symbol_inherit(Symtab *tab); extern SwigType *Swig_symbol_type_qualify(const SwigType *ty, Symtab *tab); extern String *Swig_symbol_string_qualify(String *s, Symtab *tab); - extern SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab); + extern SwigType *Swig_symbol_typedef_reduce(const SwigType *ty, Symtab *tab); extern ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl); extern SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope); @@ -250,17 +260,17 @@ extern int ParmList_is_compactdefargs(ParmList *p); /* --- Naming functions --- */ - extern void Swig_name_register(const String_or_char *method, const String_or_char *format); - extern void Swig_name_unregister(const String_or_char *method); - extern String *Swig_name_mangle(const String_or_char *s); - extern String *Swig_name_wrapper(const String_or_char *fname); - extern String *Swig_name_member(const String_or_char *classname, const String_or_char *mname); - extern String *Swig_name_get(const String_or_char *vname); - extern String *Swig_name_set(const String_or_char *vname); - extern String *Swig_name_construct(const String_or_char *classname); - extern String *Swig_name_copyconstructor(const String_or_char *classname); - extern String *Swig_name_destroy(const String_or_char *classname); - extern String *Swig_name_disown(const String_or_char *classname); + extern void Swig_name_register(const_String_or_char_ptr method, const_String_or_char_ptr format); + extern void Swig_name_unregister(const_String_or_char_ptr method); + extern String *Swig_name_mangle(const_String_or_char_ptr s); + extern String *Swig_name_wrapper(const_String_or_char_ptr fname); + extern String *Swig_name_member(const_String_or_char_ptr nspace, const_String_or_char_ptr classname, const_String_or_char_ptr membername); + extern String *Swig_name_get(const_String_or_char_ptr nspace, const_String_or_char_ptr vname); + extern String *Swig_name_set(const_String_or_char_ptr nspace, const_String_or_char_ptr vname); + extern String *Swig_name_construct(const_String_or_char_ptr nspace, const_String_or_char_ptr classname); + extern String *Swig_name_copyconstructor(const_String_or_char_ptr nspace, const_String_or_char_ptr classname); + extern String *Swig_name_destroy(const_String_or_char_ptr nspace, const_String_or_char_ptr classname); + extern String *Swig_name_disown(const_String_or_char_ptr nspace, const_String_or_char_ptr classname); extern void Swig_naming_init(void); extern void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn); @@ -271,80 +281,87 @@ extern int ParmList_is_compactdefargs(ParmList *p); extern int Swig_need_name_warning(Node *n); extern int Swig_need_redefined_warn(Node *a, Node *b, int InClass); - extern String *Swig_name_make(Node *n, String *prefix, String_or_char *cname, SwigType *decl, String *oldname); + extern String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, SwigType *decl, String *oldname); extern String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl); + extern String *Swig_name_str(Node *n); extern String *Swig_name_decl(Node *n); extern String *Swig_name_fulldecl(Node *n); /* --- parameterized rename functions --- */ - extern void Swig_name_object_set(Hash *namehash, String_or_char *name, SwigType *decl, DOH *object); - extern DOH *Swig_name_object_get(Hash *namehash, String_or_char *prefix, String_or_char *name, SwigType *decl); + extern void Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object); + extern DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl); extern void Swig_name_object_inherit(Hash *namehash, String *base, String *derived); - extern void Swig_features_get(Hash *features, String_or_char *prefix, String_or_char *name, SwigType *decl, Node *n); - extern void Swig_feature_set(Hash *features, const String_or_char *name, SwigType *decl, const String_or_char *featurename, String *value, Hash *featureattribs); + extern void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *n); + extern void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs); /* --- Misc --- */ extern char *Swig_copy_string(const char *c); extern void Swig_set_fakeversion(const char *version); extern const char *Swig_package_version(void); extern void Swig_banner(File *f); + extern void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar); extern String *Swig_strip_c_comments(const String *s); + extern String *Swig_new_subdirectory(String *basedirectory, String *subdirectory); + extern void Swig_filename_correct(String *filename); + extern String *Swig_filename_escape(String *filename); + extern void Swig_filename_unescape(String *filename); extern String *Swig_string_escape(String *s); extern String *Swig_string_mangle(const String *s); - extern void Swig_scopename_split(String *s, String **prefix, String **last); - extern String *Swig_scopename_prefix(String *s); - extern String *Swig_scopename_last(String *s); - extern String *Swig_scopename_first(String *s); - extern String *Swig_scopename_suffix(String *s); - extern int Swig_scopename_check(String *s); + extern void Swig_scopename_split(const String *s, String **prefix, String **last); + extern String *Swig_scopename_prefix(const String *s); + extern String *Swig_scopename_last(const String *s); + extern String *Swig_scopename_first(const String *s); + extern String *Swig_scopename_suffix(const String *s); + extern int Swig_scopename_check(const String *s); extern String *Swig_string_lower(String *s); extern String *Swig_string_upper(String *s); extern String *Swig_string_title(String *s); - + extern String *Swig_pcre_version(void); extern void Swig_init(void); extern void Swig_warn(const char *filename, int line, const char *msg); extern int Swig_value_wrapper_mode(int mode); extern int Swig_is_generated_overload(Node *n); - -#define WARNING(msg) Swig_warn(__FILE__,__LINE__,msg) - typedef enum { EMF_STANDARD, EMF_MICROSOFT } ErrorMessageFormat; - extern void Swig_warning(int num, const String_or_char *filename, int line, const char *fmt, ...); - extern void Swig_error(const String_or_char *filename, int line, const char *fmt, ...); + extern void Swig_warning(int num, const_String_or_char_ptr filename, int line, const char *fmt, ...); + extern void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...); extern int Swig_error_count(void); extern void Swig_error_silent(int s); - extern void Swig_warnfilter(const String_or_char *wlist, int val); + extern void Swig_warnfilter(const_String_or_char_ptr wlist, int val); extern void Swig_warnall(void); extern int Swig_warn_count(void); extern void Swig_error_msg_format(ErrorMessageFormat format); + extern void Swig_diagnostic(const_String_or_char_ptr filename, int line, const char *fmt, ...); + extern String *Swig_stringify_with_location(DOH *object); /* --- C Wrappers --- */ + extern void Swig_cresult_name_set(const char *new_name); + extern const char *Swig_cresult_name(void); extern String *Swig_cparm_name(Parm *p, int i); extern String *Swig_wrapped_var_type(SwigType *t, int varcref); extern int Swig_cargs(Wrapper *w, ParmList *l); - extern String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_char *decl); + extern String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr decl); - extern String *Swig_cfunction_call(String_or_char *name, ParmList *parms); - extern String *Swig_cconstructor_call(String_or_char *name); - extern String *Swig_cppconstructor_call(String_or_char *name, ParmList *parms); + extern String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms); + extern String *Swig_cconstructor_call(const_String_or_char_ptr name); + extern String *Swig_cppconstructor_call(const_String_or_char_ptr name, ParmList *parms); extern String *Swig_unref_call(Node *n); extern String *Swig_ref_call(Node *n, const String *lname); extern String *Swig_cdestructor_call(Node *n); extern String *Swig_cppdestructor_call(Node *n); - extern String *Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self, int varcref); - extern String *Swig_cmemberget_call(const String_or_char *name, SwigType *t, String_or_char *self, int varcref); + extern String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, String *self, int varcref); + extern String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String *self, int varcref); extern int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self); /* --- Transformations --- */ - extern int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *director_type, int is_director); - extern int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags); - extern int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags); + extern int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int flags, SwigType *director_type, int is_director); + extern int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags); + extern int Swig_DestructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int cplus, int flags); extern int Swig_MembersetToFunction(Node *n, String *classname, int flags); extern int Swig_MembergetToFunction(Node *n, String *classname, int flags); extern int Swig_VargetToFunction(Node *n, int flags); @@ -356,6 +373,7 @@ extern int ParmList_is_compactdefargs(ParmList *p); #define CWRAP_DIRECTOR_ONE_CALL 0x08 #define CWRAP_DIRECTOR_TWO_CALLS 0x10 #define CWRAP_ALL_PROTECTED_ACCESS 0x20 +#define CWRAP_SMART_POINTER_OVERLOAD 0x40 /* --- Director Helpers --- */ extern Node *Swig_methodclass(Node *n); @@ -365,22 +383,22 @@ extern int ParmList_is_compactdefargs(ParmList *p); /* --- Legacy Typemap API (somewhat simplified, ha!) --- */ extern void Swig_typemap_init(void); - extern void Swig_typemap_register(const String_or_char *op, ParmList *pattern, String_or_char *code, ParmList *locals, ParmList *kwargs); - extern int Swig_typemap_copy(const String_or_char *op, ParmList *srcpattern, ParmList *pattern); - extern void Swig_typemap_clear(const String_or_char *op, ParmList *pattern); + extern void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *pattern, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs); + extern int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcpattern, ParmList *pattern); + extern void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *pattern); extern int Swig_typemap_apply(ParmList *srcpat, ParmList *destpat); extern void Swig_typemap_clear_apply(ParmList *pattern); extern void Swig_typemap_debug(void); + extern void Swig_typemap_search_debug_set(void); + extern void Swig_typemap_used_debug_set(void); + extern void Swig_typemap_register_debug_set(void); - extern Hash *Swig_typemap_search(const String_or_char *op, SwigType *type, const String_or_char *pname, SwigType **matchtype); - extern Hash *Swig_typemap_search_multi(const String_or_char *op, ParmList *parms, int *nmatch); - extern String *Swig_typemap_lookup(const String_or_char *op, Node *n, const String_or_char *lname, Wrapper *f); - extern String *Swig_typemap_lookup_out(const String_or_char *op, Node *n, const String_or_char *lname, Wrapper *f, String *actioncode); - extern void Swig_typemap_attach_kwargs(Hash *tm, const String_or_char *op, Parm *p); + extern String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f); + extern String *Swig_typemap_lookup_out(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f, String *actioncode); extern void Swig_typemap_new_scope(void); extern Hash *Swig_typemap_pop_scope(void); - extern void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrapper *f); + extern void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f); /* --- Code fragment support --- */ @@ -395,6 +413,9 @@ extern int ParmList_is_compactdefargs(ParmList *p); extern void Wrapper_director_mode_set(int); extern void Wrapper_director_protected_mode_set(int); extern void Wrapper_all_protected_mode_set(int); + extern void Language_replace_special_variables(String *method, String *tm, Parm *parm); + extern void Swig_print(DOH *object, int count); + extern void Swig_print_with_location(DOH *object, int count); /* -- template init -- */ diff --git a/Source/Swig/swigfile.h b/Source/Swig/swigfile.h index 4f6869109..158243c04 100644 --- a/Source/Swig/swigfile.h +++ b/Source/Swig/swigfile.h @@ -11,26 +11,26 @@ * File handling functions in the SWIG core * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9603 2006-12-05 21:47:01Z beazley $ */ - -extern List *Swig_add_directory(const String_or_char *dirname); -extern void Swig_push_directory(const String_or_char *dirname); -extern void Swig_pop_directory(); -extern String *Swig_last_file(); -extern List *Swig_search_path(); -extern FILE *Swig_open(const String_or_char *name); +extern List *Swig_add_directory(const_String_or_char_ptr dirname); +extern void Swig_push_directory(const_String_or_char_ptr dirname); +extern void Swig_pop_directory(void); +extern String *Swig_last_file(void); +extern List *Swig_search_path(void); +extern FILE *Swig_include_open(const_String_or_char_ptr name); +extern FILE *Swig_open(const_String_or_char_ptr name); extern String *Swig_read_file(FILE *f); -extern String *Swig_include(const String_or_char *name); -extern String *Swig_include_sys(const String_or_char *name); -extern int Swig_insert_file(const String_or_char *name, File *outfile); +extern String *Swig_include(const_String_or_char_ptr name); +extern String *Swig_include_sys(const_String_or_char_ptr name); +extern int Swig_insert_file(const_String_or_char_ptr name, File *outfile); extern void Swig_set_push_dir(int dopush); extern int Swig_get_push_dir(void); -extern void Swig_register_filebyname(const String_or_char *filename, File *outfile); -extern File *Swig_filebyname(const String_or_char *filename); -extern char *Swig_file_suffix(const String_or_char *filename); -extern char *Swig_file_basename(const String_or_char *filename); -extern char *Swig_file_filename(const String_or_char *filename); -extern char *Swig_file_dirname(const String_or_char *filename); +extern void Swig_register_filebyname(const_String_or_char_ptr filename, File *outfile); +extern File *Swig_filebyname(const_String_or_char_ptr filename); +extern char *Swig_file_suffix(const_String_or_char_ptr filename); +extern char *Swig_file_basename(const_String_or_char_ptr filename); +extern char *Swig_file_filename(const_String_or_char_ptr filename); +extern char *Swig_file_dirname(const_String_or_char_ptr filename); +extern void Swig_file_debug_set(); /* Delimiter used in accessing files and directories */ diff --git a/Source/Swig/swigopt.h b/Source/Swig/swigopt.h index 433ca07e5..543bfb819 100644 --- a/Source/Swig/swigopt.h +++ b/Source/Swig/swigopt.h @@ -11,10 +11,8 @@ * Header file for the SWIG command line processing functions * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9622 2006-12-19 03:49:17Z beazley $ */ - extern void Swig_init_args(int argc, char **argv); extern void Swig_mark_arg(int n); extern int Swig_check_marked(int n); extern void Swig_check_options(int check_input); - extern void Swig_arg_error(); + extern void Swig_arg_error(void); diff --git a/Source/Swig/swigparm.h b/Source/Swig/swigparm.h index 6ea849424..70a39390e 100644 --- a/Source/Swig/swigparm.h +++ b/Source/Swig/swigparm.h @@ -12,10 +12,9 @@ * parameter lists. * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9629 2006-12-30 18:27:47Z beazley $ */ - /* Individual parameters */ -extern Parm *NewParm(SwigType *type, const String_or_char *name); +extern Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *file_line_node); +extern Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name); extern Parm *CopyParm(Parm *p); /* Parameter lists */ @@ -28,6 +27,7 @@ extern int ParmList_has_defaultargs(ParmList *p); /* Output functions */ extern String *ParmList_str(ParmList *); extern String *ParmList_str_defaultargs(ParmList *); +extern String *ParmList_str_multibrackets(ParmList *); extern String *ParmList_protostr(ParmList *); diff --git a/Source/Swig/swigscan.h b/Source/Swig/swigscan.h index 31b0c2705..a2d5911bd 100644 --- a/Source/Swig/swigscan.h +++ b/Source/Swig/swigscan.h @@ -11,15 +11,13 @@ * C/C++ scanner. * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9633 2007-01-10 23:43:07Z beazley $ */ - typedef struct Scanner Scanner; -extern Scanner *NewScanner(); +extern Scanner *NewScanner(void); extern void DelScanner(Scanner *); extern void Scanner_clear(Scanner *); extern void Scanner_push(Scanner *, String *); -extern void Scanner_pushtoken(Scanner *, int, const String_or_char *value); +extern void Scanner_pushtoken(Scanner *, int, const_String_or_char_ptr value); extern int Scanner_token(Scanner *); extern String *Scanner_text(Scanner *); extern void Scanner_skip_line(Scanner *); @@ -32,7 +30,7 @@ extern void Scanner_idstart(Scanner *, const char *idchar); extern String *Scanner_errmsg(Scanner *); extern int Scanner_errline(Scanner *); extern int Scanner_isoperator(int tokval); -extern void Scanner_freeze_line(Scanner *s, int val); +extern void Scanner_locator(Scanner *, String *loc); /* Note: Tokens in range 100+ are for C/C++ operators */ @@ -68,6 +66,7 @@ extern void Scanner_freeze_line(Scanner *s, int val); #define SWIG_TOKEN_ULONGLONG 29 /* 314ULL */ #define SWIG_TOKEN_QUESTION 30 /* ? */ #define SWIG_TOKEN_COMMENT 31 /* C or C++ comment */ +#define SWIG_TOKEN_BOOL 32 /* true or false */ #define SWIG_TOKEN_ILLEGAL 99 #define SWIG_TOKEN_ERROR -1 diff --git a/Source/Swig/swigtree.h b/Source/Swig/swigtree.h index d4221207c..5decb79e3 100644 --- a/Source/Swig/swigtree.h +++ b/Source/Swig/swigtree.h @@ -13,8 +13,6 @@ * and function names are meant to be similar. * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9622 2006-12-19 03:49:17Z beazley $ */ - /* Macros to traverse the DOM tree */ #define nodeType(x) Getattr(x,"nodeType") @@ -35,7 +33,7 @@ /* Utility functions */ -extern int checkAttribute(Node *obj, const String_or_char *name, const String_or_char *value); +extern int checkAttribute(Node *obj, const_String_or_char_ptr name, const_String_or_char_ptr value); extern void appendChild(Node *node, Node *child); extern void prependChild(Node *node, Node *child); extern void removeNode(Node *node); diff --git a/Source/Swig/swigwrap.h b/Source/Swig/swigwrap.h index bd1009d0e..e44cb5344 100644 --- a/Source/Swig/swigwrap.h +++ b/Source/Swig/swigwrap.h @@ -11,8 +11,6 @@ * Functions related to wrapper objects. * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9635 2007-01-12 01:44:16Z beazley $ */ - typedef struct Wrapper { Hash *localh; String *def; @@ -20,14 +18,14 @@ typedef struct Wrapper { String *code; } Wrapper; -extern Wrapper *NewWrapper(); +extern Wrapper *NewWrapper(void); extern void DelWrapper(Wrapper *w); extern void Wrapper_compact_print_mode_set(int flag); extern void Wrapper_pretty_print(String *str, File *f); extern void Wrapper_compact_print(String *str, File *f); extern void Wrapper_print(Wrapper *w, File *f); -extern int Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_char *decl); -extern int Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...); -extern int Wrapper_check_local(Wrapper *w, const String_or_char *name); -extern char *Wrapper_new_local(Wrapper *w, const String_or_char *name, const String_or_char *decl); -extern char *Wrapper_new_localv(Wrapper *w, const String_or_char *name, ...); +extern int Wrapper_add_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl); +extern int Wrapper_add_localv(Wrapper *w, const_String_or_char_ptr name, ...); +extern int Wrapper_check_local(Wrapper *w, const_String_or_char_ptr name); +extern char *Wrapper_new_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl); +extern char *Wrapper_new_localv(Wrapper *w, const_String_or_char_ptr name, ...); diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index 3d6eb508b..5ee6c3ec0 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -179,20 +179,83 @@ static Hash *global_scope = 0; /* Global scope */ /* common attribute keys, to avoid calling find_key all the times */ +/* ----------------------------------------------------------------------------- + * Swig_symbol_print_tables() + * + * Debug display of symbol tables + * ----------------------------------------------------------------------------- */ -#if 0 -void Swig_symbol_dump_symtable() { - Printf(stdout, "DUMPING SYMTABLE start =======================================\n"); - { - Hash *cst = Getattr(current_symtab, "csymtab"); - Swig_print_tree(cst); - /* - Swig_print_tree(Getattr(cst, "NumSpace")); - */ +void Swig_symbol_print_tables(Symtab *symtab) { + if (!symtab) + symtab = current_symtab; + + Printf(stdout, "SYMBOL TABLES start =======================================\n"); + Swig_print_tree(symtab); + Printf(stdout, "SYMBOL TABLES finish =======================================\n"); +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_print_tables_summary() + * + * Debug summary display of all symbol tables by fully-qualified name + * ----------------------------------------------------------------------------- */ + +void Swig_symbol_print_tables_summary(void) { + Printf(stdout, "SYMBOL TABLES SUMMARY start =======================================\n"); + Swig_print_node(symtabs); + Printf(stdout, "SYMBOL TABLES SUMMARY finish =======================================\n"); +} + +/* ----------------------------------------------------------------------------- + * symbol_print_symbols() + * ----------------------------------------------------------------------------- */ + +static void symbol_print_symbols(const char *symboltabletype) { + Node *table = symtabs; + Iterator ki = First(table); + while (ki.key) { + String *k = ki.key; + Printf(stdout, "===================================================\n"); + Printf(stdout, "%s -\n", k); + { + Symtab *symtab = Getattr(Getattr(table, k), symboltabletype); + Iterator it = First(symtab); + while (it.key) { + String *symname = it.key; + Printf(stdout, " %s\n", symname); + /* + Printf(stdout, " %s - %p (%s)\n", symname, it.item, Getattr(it.item, "name")); + */ + it = Next(it); + } + } + ki = Next(ki); } - Printf(stdout, "DUMPING SYMTABLE end =======================================\n"); } -#endif + +/* ----------------------------------------------------------------------------- + * Swig_symbol_print_symbols() + * + * Debug display of all the target language symbols + * ----------------------------------------------------------------------------- */ + +void Swig_symbol_print_symbols(void) { + Printf(stdout, "SYMBOLS start =======================================\n"); + symbol_print_symbols("symtab"); + Printf(stdout, "SYMBOLS finish =======================================\n"); +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_print_csymbols() + * + * Debug display of all the C symbols + * ----------------------------------------------------------------------------- */ + +void Swig_symbol_print_csymbols(void) { + Printf(stdout, "CSYMBOLS start =======================================\n"); + symbol_print_symbols("csymtab"); + Printf(stdout, "CSYMBOLS finish =======================================\n"); +} /* ----------------------------------------------------------------------------- * Swig_symbol_init() @@ -200,7 +263,7 @@ void Swig_symbol_dump_symtable() { * Create a new symbol table object * ----------------------------------------------------------------------------- */ -void Swig_symbol_init() { +void Swig_symbol_init(void) { current = NewHash(); current_symtab = NewHash(); @@ -224,7 +287,7 @@ void Swig_symbol_init() { * Set the C scopename of the current symbol table. * ----------------------------------------------------------------------------- */ -void Swig_symbol_setscopename(const String_or_char *name) { +void Swig_symbol_setscopename(const_String_or_char_ptr name) { String *qname; /* assert(!Getattr(current_symtab,"name")); */ Setattr(current_symtab, "name", name); @@ -244,7 +307,7 @@ void Swig_symbol_setscopename(const String_or_char *name) { * Get the C scopename of the current symbol table * ----------------------------------------------------------------------------- */ -String *Swig_symbol_getscopename() { +String *Swig_symbol_getscopename(void) { return Getattr(current_symtab, "name"); } @@ -254,10 +317,10 @@ String *Swig_symbol_getscopename() { * Given a fully qualified C scopename, this function returns a symbol table * ----------------------------------------------------------------------------- */ -Symtab *Swig_symbol_getscope(const String_or_char *name) { +Symtab *Swig_symbol_getscope(const_String_or_char_ptr name) { if (!symtabs) return 0; - if (Equal("::", (String_or_char *) name)) + if (Equal("::", (const_String_or_char_ptr ) name)) name = ""; return Getattr(symtabs, name); } @@ -293,13 +356,28 @@ String *Swig_symbol_qualifiedscopename(Symtab *symtab) { return result; } +/* ----------------------------------------------------------------------------- + * Swig_symbol_qualified_language_scopename() + * + * Get the fully qualified C scopename of a symbol table but using a language + * specific separator for the scopenames. Basically the same as + * Swig_symbol_qualifiedscopename() but using the different separator. + * ----------------------------------------------------------------------------- */ + +String *Swig_symbol_qualified_language_scopename(Symtab *n) { + /* TODO: fix for %rename to work */ + String *result = Swig_symbol_qualifiedscopename(n); + Replaceall(result, "::", NSPACE_SEPARATOR); + return result; +} + /* ----------------------------------------------------------------------------- * Swig_symbol_newscope() * * Create a new scope. Returns the newly created scope. * ----------------------------------------------------------------------------- */ -Symtab *Swig_symbol_newscope() { +Symtab *Swig_symbol_newscope(void) { Hash *n; Hash *hsyms, *h; @@ -350,7 +428,7 @@ Symtab *Swig_symbol_setscope(Symtab *sym) { * scope to the parent scope. * ----------------------------------------------------------------------------- */ -Symtab *Swig_symbol_popscope() { +Symtab *Swig_symbol_popscope(void) { Hash *h = current_symtab; current_symtab = Getattr(current_symtab, "parentNode"); assert(current_symtab); @@ -362,12 +440,22 @@ Symtab *Swig_symbol_popscope() { } /* ----------------------------------------------------------------------------- + * Swig_symbol_global_scope() + * + * Return the symbol table for the global scope. + * ----------------------------------------------------------------------------- */ + +Symtab *Swig_symbol_global_scope(void) { + return global_scope; +} + +/* ----------------------------------------------------------------------------- * Swig_symbol_current() * * Return the current symbol table. * ----------------------------------------------------------------------------- */ -Symtab *Swig_symbol_current() { +Symtab *Swig_symbol_current(void) { return current_symtab; } @@ -377,7 +465,7 @@ Symtab *Swig_symbol_current() { * Makes an alias for a symbol in the global symbol table. * ----------------------------------------------------------------------------- */ -void Swig_symbol_alias(String_or_char *aliasname, Symtab *s) { +void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *s) { String *qname = Swig_symbol_qualifiedscopename(current_symtab); if (qname) { Printf(qname, "::%s", aliasname); @@ -425,7 +513,7 @@ void Swig_symbol_inherit(Symtab *s) { * Adds a node to the C symbol table only. * ----------------------------------------------------------------------------- */ -void Swig_symbol_cadd(String_or_char *name, Node *n) { +void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) { Node *append = 0; Node *cn; @@ -598,7 +686,7 @@ void Swig_symbol_cadd(String_or_char *name, Node *n) { * for namespace support, type resolution, and other issues. * ----------------------------------------------------------------------------- */ -Node *Swig_symbol_add(String_or_char *symname, Node *n) { +Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) { Hash *c, *cn, *cl = 0; SwigType *decl, *ndecl; String *cstorage, *nstorage; @@ -831,7 +919,7 @@ Node *Swig_symbol_add(String_or_char *symname, Node *n) { * verifying that a class hierarchy implements all pure virtual methods. * ----------------------------------------------------------------------------- */ -static Node *_symbol_lookup(String *name, Symtab *symtab, int (*check) (Node *n)) { +static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (Node *n)) { Node *n; List *inherit; Hash *sym = Getattr(symtab, "csymtab"); @@ -875,6 +963,7 @@ static Node *_symbol_lookup(String *name, Symtab *symtab, int (*check) (Node *n) Delete(dname); if (n) return n; + Setmark(symtab, 1); } inherit = Getattr(symtab, "inherit"); @@ -894,7 +983,7 @@ static Node *_symbol_lookup(String *name, Symtab *symtab, int (*check) (Node *n) return 0; } -static Node *symbol_lookup(String_or_char *name, Symtab *symtab, int (*check) (Node *n)) { +static Node *symbol_lookup(const_String_or_char_ptr name, Symtab *symtab, int (*check) (Node *n)) { Node *n = 0; if (DohCheck(name)) { n = _symbol_lookup(name, symtab, check); @@ -912,7 +1001,7 @@ static Node *symbol_lookup(String_or_char *name, Symtab *symtab, int (*check) (N * symbol_lookup_qualified() * ----------------------------------------------------------------------------- */ -static Node *symbol_lookup_qualified(String_or_char *name, Symtab *symtab, String *prefix, int local, int (*checkfunc) (Node *n)) { +static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symtab, const String *prefix, int local, int (*checkfunc) (Node *n)) { /* This is a little funky, we search by fully qualified names */ if (!symtab) @@ -932,6 +1021,7 @@ static Node *symbol_lookup_qualified(String_or_char *name, Symtab *symtab, Strin /* Make qualified name of current scope */ String *qalloc = 0; String *qname = Swig_symbol_qualifiedscopename(symtab); + const String *cqname; if (qname) { if (Len(qname)) { if (prefix && Len(prefix)) { @@ -941,10 +1031,11 @@ static Node *symbol_lookup_qualified(String_or_char *name, Symtab *symtab, Strin Append(qname, prefix); } qalloc = qname; + cqname = qname; } else { - qname = prefix; + cqname = prefix; } - st = Getattr(symtabs, qname); + st = Getattr(symtabs, cqname); /* Found a scope match */ if (st) { if (!name) { @@ -978,7 +1069,7 @@ static Node *symbol_lookup_qualified(String_or_char *name, Symtab *symtab, Strin * to get the real node. * ----------------------------------------------------------------------------- */ -Node *Swig_symbol_clookup(String_or_char *name, Symtab *n) { +Node *Swig_symbol_clookup(const_String_or_char_ptr name, Symtab *n) { Hash *hsym = 0; Node *s = 0; @@ -1000,6 +1091,8 @@ Node *Swig_symbol_clookup(String_or_char *name, Symtab *n) { String *nname = NewString(cname + 2); if (Swig_scopename_check(nname)) { s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0); + } else { + s = symbol_lookup(nname, global_scope, 0); } Delete(nname); } else { @@ -1050,7 +1143,7 @@ Node *Swig_symbol_clookup(String_or_char *name, Symtab *n) { * inheritance hierarchy. * ----------------------------------------------------------------------------- */ -Node *Swig_symbol_clookup_check(String_or_char *name, Symtab *n, int (*checkfunc) (Node *n)) { +Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *n)) { Hash *hsym = 0; Node *s = 0; @@ -1072,6 +1165,8 @@ Node *Swig_symbol_clookup_check(String_or_char *name, Symtab *n, int (*checkfunc String *nname = NewString(cname + 2); if (Swig_scopename_check(nname)) { s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc); + } else { + s = symbol_lookup(nname, global_scope, checkfunc); } Delete(nname); } else { @@ -1114,20 +1209,18 @@ Node *Swig_symbol_clookup_check(String_or_char *name, Symtab *n, int (*checkfunc * Swig_symbol_clookup_local() * ----------------------------------------------------------------------------- */ -Node *Swig_symbol_clookup_local(String_or_char *name, Symtab *n) { - Hash *h, *hsym; +Node *Swig_symbol_clookup_local(const_String_or_char_ptr name, Symtab *n) { + Hash *hsym; Node *s = 0; if (!n) { hsym = current_symtab; - h = ccurrent; } else { if (!Checkattr(n, "nodeType", "symboltable")) { n = Getattr(n, "sym:symtab"); } assert(n); hsym = n; - h = Getattr(n, "csymtab"); } if (Swig_scopename_check(name)) { @@ -1136,6 +1229,8 @@ Node *Swig_symbol_clookup_local(String_or_char *name, Symtab *n) { String *nname = NewString(cname + 2); if (Swig_scopename_check(nname)) { s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0); + } else { + s = symbol_lookup(nname, global_scope, 0); } Delete(nname); } else { @@ -1162,20 +1257,18 @@ Node *Swig_symbol_clookup_local(String_or_char *name, Symtab *n) { * Swig_symbol_clookup_local_check() * ----------------------------------------------------------------------------- */ -Node *Swig_symbol_clookup_local_check(String_or_char *name, Symtab *n, int (*checkfunc) (Node *)) { - Hash *h, *hsym; +Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *)) { + Hash *hsym; Node *s = 0; if (!n) { hsym = current_symtab; - h = ccurrent; } else { if (!Checkattr(n, "nodeType", "symboltable")) { n = Getattr(n, "sym:symtab"); } assert(n); hsym = n; - h = Getattr(n, "csymtab"); } if (Swig_scopename_check(name)) { @@ -1184,6 +1277,8 @@ Node *Swig_symbol_clookup_local_check(String_or_char *name, Symtab *n, int (*che String *nname = NewString(cname + 2); if (Swig_scopename_check(nname)) { s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc); + } else { + s = symbol_lookup(nname, global_scope, checkfunc); } Delete(nname); } else { @@ -1213,7 +1308,7 @@ Node *Swig_symbol_clookup_local_check(String_or_char *name, Symtab *n, int (*che * Look up a scope name. * ----------------------------------------------------------------------------- */ -Symtab *Swig_symbol_cscope(String_or_char *name, Symtab *symtab) { +Symtab *Swig_symbol_cscope(const_String_or_char_ptr name, Symtab *symtab) { char *cname = Char(name); if (strncmp(cname, "::", 2) == 0) return symbol_lookup_qualified(0, global_scope, name, 0, 0); @@ -1255,7 +1350,8 @@ void Swig_symbol_remove(Node *n) { Setattr(symtab, symname, symnext); fixovername = symnext; /* fix as symbol to remove is at head of linked list */ } else { - Delattr(symtab, symname); + if (symname) + Delattr(symtab, symname); } } if (symnext) { @@ -1546,7 +1642,7 @@ SwigType *Swig_symbol_template_reduce(SwigType *qt, Symtab *ntab) { * Chase a typedef through symbol tables looking for a match. * ----------------------------------------------------------------------------- */ -SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab) { +SwigType *Swig_symbol_typedef_reduce(const SwigType *ty, Symtab *tab) { SwigType *prefix, *base; Node *n; String *nt; @@ -1653,8 +1749,9 @@ String *Swig_symbol_string_qualify(String *s, Symtab *st) { String *id = NewStringEmpty(); String *r = NewStringEmpty(); char *c = Char(s); + int first_char = 1; while (*c) { - if (isalpha((int) *c) || (*c == '_') || (*c == ':')) { + if (isalpha((int) *c) || (*c == '_') || (*c == ':') || (isdigit((int) *c) && !first_char)) { Putc(*c, id); have_id = 1; } else { @@ -1667,6 +1764,7 @@ String *Swig_symbol_string_qualify(String *s, Symtab *st) { } Putc(*c, r); } + first_char = (*c == ':'); c++; } if (have_id) { @@ -1730,7 +1828,7 @@ ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, ntq = ty; } /* Printf(stderr,"value %s %s %s\n",value,ntr,ntq); */ - cp = NewParm(ntq, 0); + cp = NewParmWithoutFileLineInfo(ntq, 0); if (lp) set_nextSibling(lp, cp); else @@ -1807,7 +1905,7 @@ SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) { String *tprefix = SwigType_templateprefix(base); String *targs = SwigType_templateargs(base); String *tsuffix = SwigType_templatesuffix(base); - ParmList *tparms = SwigType_function_parms(targs); + ParmList *tparms = SwigType_function_parms(targs, 0); Node *tempn = Swig_symbol_clookup_local(tprefix, tscope); if (!tempn && tsuffix && Len(tsuffix)) { tempn = Swig_symbol_clookup(tprefix, 0); diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c index b6cbca352..e66670c7c 100644 --- a/Source/Swig/tree.c +++ b/Source/Swig/tree.c @@ -34,7 +34,7 @@ void Swig_print_tags(DOH *obj, DOH *root) { croot = root; while (obj) { - Printf(stdout, "%s . %s (%s:%d)\n", croot, nodeType(obj), Getfile(obj), Getline(obj)); + Swig_diagnostic(Getfile(obj), Getline(obj), "%s . %s\n", croot, nodeType(obj)); cobj = firstChild(obj); if (cobj) { newroot = NewStringf("%s . %s", croot, nodeType(obj)); @@ -233,7 +233,7 @@ Node *copyNode(Node *n) { * checkAttribute() * ----------------------------------------------------------------------------- */ -int checkAttribute(Node *n, const String_or_char *name, const String_or_char *value) { +int checkAttribute(Node *n, const_String_or_char_ptr name, const_String_or_char_ptr value) { String *v = Getattr(n, name); return v ? Equal(v, value) : 0; } @@ -272,7 +272,7 @@ void Swig_require(const char *ns, Node *n, ...) { } obj = Getattr(n, name); if (!opt && !obj) { - Printf(stderr, "%s:%d. Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n", Getfile(n), Getline(n), name, nodeType(n)); + Swig_error(Getfile(n), Getline(n), "Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n", name, nodeType(n)); assert(obj); } if (!obj) @@ -291,10 +291,10 @@ void Swig_require(const char *ns, Node *n, ...) { if (view) { if (Strcmp(view, ns) != 0) { Setattr(n, NewStringf("%s:view", ns), view); - Setattr(n, "view", ns); + Setattr(n, "view", NewString(ns)); } } else { - Setattr(n, "view", ns); + Setattr(n, "view", NewString(ns)); } } } @@ -337,10 +337,10 @@ void Swig_save(const char *ns, Node *n, ...) { if (view) { if (Strcmp(view, ns) != 0) { Setattr(n, NewStringf("%s:view", ns), view); - Setattr(n, "view", ns); + Setattr(n, "view", NewString(ns)); } } else { - Setattr(n, "view", ns); + Setattr(n, "view", NewString(ns)); } } } diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 5ee74b629..1b2150c3c 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -21,7 +21,12 @@ char cvsroot_typemap_c[] = "$Id$"; #define SWIG_DEBUG #endif -static void replace_embedded_typemap(String *s); +static int typemap_search_debug = 0; +static int typemaps_used_debug = 0; +static int typemap_register_debug = 0; +static int in_typemap_search_multi = 0; + +static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f, Node *file_line_node); /* ----------------------------------------------------------------------------- * Typemaps are stored in a collection of nested hash tables. Something like @@ -35,14 +40,24 @@ static void replace_embedded_typemap(String *s); * different typemap methods. These are referenced by names such as * "tmap:in", "tmap:out", "tmap:argout", and so forth. * - * The object corresponding to a specific method has the following - * attributes: + * The object corresponding to a specific typemap method has the following attributes: * * "type" - Typemap type * "pname" - Parameter name * "code" - Typemap code - * "typemap" - Descriptive text describing the actual map + * "source" - Source directive (%apply or %typemap) for the typemap * "locals" - Local variables (if any) + * "kwargs" - Typemap attributes + * + * Example for a typemap method named "in": + * %typemap(in, warning="987:my warning", noblock=1) int &my_int (int tmp) "$1 = $input;" + * + * "type" - r.int + * "pname" - my_int + * "code" - $1 = $input; + * "source" - typemap(in) int &my_int + * "locals" - int tmp + * "kwargs" - warning="987:my typemap warning", foo=123 * * ----------------------------------------------------------------------------- */ @@ -52,47 +67,46 @@ static void replace_embedded_typemap(String *s); static Hash *typemaps[MAX_SCOPE]; static int tm_scope = 0; -static Hash *get_typemap(int tm_scope, SwigType *type) { +static Hash *get_typemap(int tm_scope, const SwigType *type) { Hash *tm = 0; SwigType *dtype = 0; + SwigType *hashtype; + if (SwigType_istemplate(type)) { String *ty = Swig_symbol_template_deftype(type, 0); dtype = Swig_symbol_type_qualify(ty, 0); - /* Printf(stderr,"gettm %s %s\n", type, dtype); */ type = dtype; Delete(ty); } - tm = Getattr(typemaps[tm_scope], type); + /* remove unary scope operator (::) prefix indicating global scope for looking up in the hashmap */ + hashtype = SwigType_remove_global_scope_prefix(type); + tm = Getattr(typemaps[tm_scope], hashtype); - if (dtype) { - if (!tm) { - String *t_name = SwigType_templateprefix(type); - if (!Equal(t_name, type)) { - tm = Getattr(typemaps[tm_scope], t_name); - } - Delete(t_name); - } - Delete(dtype); - } + Delete(dtype); + Delete(hashtype); return tm; } -static void set_typemap(int tm_scope, SwigType *type, Hash *tm) { - SwigType *dtype = 0; +static void set_typemap(int tm_scope, const SwigType *type, Hash *tm) { + SwigType *hashtype = 0; if (SwigType_istemplate(type)) { - String *ty = Swig_symbol_template_deftype(type, 0); - dtype = Swig_symbol_type_qualify(ty, 0); - /* Printf(stderr,"settm %s %s\n", type, dtype); */ - type = dtype; + SwigType *rty = SwigType_typedef_resolve_all(type); + String *ty = Swig_symbol_template_deftype(rty, 0); + String *tyq = Swig_symbol_type_qualify(ty, 0); + hashtype = SwigType_remove_global_scope_prefix(tyq); + Delete(rty); + Delete(tyq); Delete(ty); } else { - dtype = Copy(type); - type = dtype; + hashtype = SwigType_remove_global_scope_prefix(type); } - Setattr(typemaps[tm_scope], type, tm); - Delete(dtype); + + /* note that the unary scope operator (::) prefix indicating global scope has been removed from the type */ + Setattr(typemaps[tm_scope], hashtype, tm); + + Delete(hashtype); } @@ -111,33 +125,34 @@ void Swig_typemap_init() { tm_scope = 0; } -static String *tmop_name(const String_or_char *op) { +static String *typemap_method_name(const_String_or_char_ptr tmap_method) { static Hash *names = 0; String *s; /* Due to "interesting" object-identity semantics of DOH, we have to make sure that we only intern strings without object identity into the hash table. - (Swig_typemap_attach_kwargs calls tmop_name several times with - the "same" String *op (i.e., same object identity) but differing + (typemap_attach_kwargs calls typemap_method_name several times with + the "same" String *tmap_method (i.e., same object identity) but differing string values.) Most other callers work around this by using char* rather than String *. -- mkoeppe, Jun 17, 2003 */ - const char *op_without_object_identity = Char(op); + const char *method_without_object_identity = Char(tmap_method); if (!names) names = NewHash(); - s = Getattr(names, op_without_object_identity); + s = Getattr(names, method_without_object_identity); if (s) return s; - s = NewStringf("tmap:%s", op); - Setattr(names, op_without_object_identity, s); + s = NewStringf("tmap:%s", tmap_method); + Setattr(names, method_without_object_identity, s); Delete(s); return s; } +#if 0 /* ----------------------------------------------------------------------------- * Swig_typemap_new_scope() * @@ -161,25 +176,31 @@ Hash *Swig_typemap_pop_scope() { } return 0; } +#endif /* ----------------------------------------------------------------------------- - * Swig_typemap_register() + * typemap_register() * - * Add a new multi-valued typemap + * Internal implementation for Swig_typemap_register() * ----------------------------------------------------------------------------- */ -void Swig_typemap_register(const String_or_char *op, ParmList *parms, String_or_char *code, ParmList *locals, ParmList *kwargs) { +static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs, String *source_directive) { Hash *tm; Hash *tm1; Hash *tm2; Parm *np; - String *tmop; + String *tm_method; SwigType *type; String *pname; - if (!parms) return; - tmop = tmop_name(op); + + if (typemap_register_debug) { + Printf(stdout, "Registering - %s\n", tmap_method); + Swig_print_node(parms); + } + + tm_method = typemap_method_name(tmap_method); /* Register the first type in the parameter list */ @@ -204,18 +225,18 @@ void Swig_typemap_register(const String_or_char *op, ParmList *parms, String_or_ tm = tm1; } - /* Now see if this typemap op has been seen before */ - tm2 = Getattr(tm, tmop); + /* Now see if this typemap method has been seen before */ + tm2 = Getattr(tm, tm_method); if (!tm2) { tm2 = NewHash(); - Setattr(tm, tmop, tm2); + Setattr(tm, tm_method, tm2); Delete(tm2); } - /* For a multi-valued typemap, the typemap code and information + /* For a multi-argument typemap, the typemap code and information is really only stored in the last argument. However, to make this work, we perform a really neat trick using - the typemap operator name. + the typemap method name. For example, consider this typemap @@ -225,35 +246,35 @@ void Swig_typemap_register(const String_or_char *op, ParmList *parms, String_or_ To store it, we look at typemaps for the following: - operator type-name + typemap method type-name ---------------------------------------------- "in" int foo "in-int+foo:" int *bar "in-int+foo:-p.int+bar: char *blah[] - Notice how the operator expands to encode information about + Notice how the typemap method name expands to encode information about previous arguments. */ np = nextSibling(parms); if (np) { - /* Make an entirely new operator key */ - String *newop = NewStringf("%s-%s+%s:", op, type, pname); + /* Make an entirely new typemap method key */ + String *multi_tmap_method = NewStringf("%s-%s+%s:", tmap_method, type, pname); + /* Now reregister on the remaining arguments */ - Swig_typemap_register(newop, np, code, locals, kwargs); + typemap_register(multi_tmap_method, np, code, locals, kwargs, source_directive); - /* Setattr(tm2,newop,newop); */ - Delete(newop); + Delete(multi_tmap_method); } else { - String *str = SwigType_str(type, pname); - String *typemap = NewStringf("typemap(%s) %s", op, str); ParmList *clocals = CopyParmList(locals); ParmList *ckwargs = CopyParmList(kwargs); + Setfile(tm2, Getfile(code)); + Setline(tm2, Getline(code)); Setattr(tm2, "code", code); Setattr(tm2, "type", type); - Setattr(tm2, "typemap", typemap); + Setattr(tm2, "source", source_directive); if (pname) { Setattr(tm2, "pname", pname); } @@ -262,19 +283,32 @@ void Swig_typemap_register(const String_or_char *op, ParmList *parms, String_or_ Delete(clocals); Delete(ckwargs); - - Delete(str); - Delete(typemap); } } +/* ----------------------------------------------------------------------------- + * Swig_typemap_register() + * + * Add a new, possibly multi-argument, typemap + * ----------------------------------------------------------------------------- */ + +void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs) { + String *parms_str = ParmList_str_multibrackets(parms); + String *source_directive = NewStringf("typemap(%s) %s", tmap_method, parms_str); + + typemap_register(tmap_method, parms, code, locals, kwargs, source_directive); + + Delete(source_directive); + Delete(parms_str); +} + /* ----------------------------------------------------------------------------- - * Swig_typemap_get() + * typemap_get() * * Retrieve typemap information from current scope. * ----------------------------------------------------------------------------- */ -static Hash *Swig_typemap_get(SwigType *type, String_or_char *name, int scope) { +static Hash *typemap_get(SwigType *type, const_String_or_char_ptr name, int scope) { Hash *tm, *tm1; /* See if this type has been seen before */ if ((scope < 0) || (scope > tm_scope)) @@ -296,46 +330,53 @@ static Hash *Swig_typemap_get(SwigType *type, String_or_char *name, int scope) { * Copy a typemap * ----------------------------------------------------------------------------- */ -int Swig_typemap_copy(const String_or_char *op, ParmList *srcparms, ParmList *parms) { +int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcparms, ParmList *parms) { Hash *tm = 0; - String *tmop; + String *tm_method; Parm *p; String *pname; SwigType *ptype; int ts = tm_scope; - String *tmops, *newop; + String *tm_methods, *multi_tmap_method; if (ParmList_len(parms) != ParmList_len(srcparms)) return -1; - tmop = tmop_name(op); + tm_method = typemap_method_name(tmap_method); while (ts >= 0) { p = srcparms; - tmops = NewString(tmop); + tm_methods = NewString(tm_method); while (p) { ptype = Getattr(p, "type"); pname = Getattr(p, "name"); /* Lookup the type */ - tm = Swig_typemap_get(ptype, pname, ts); + tm = typemap_get(ptype, pname, ts); if (!tm) break; - tm = Getattr(tm, tmops); + tm = Getattr(tm, tm_methods); if (!tm) break; /* Got a match. Look for next typemap */ - newop = NewStringf("%s-%s+%s:", tmops, ptype, pname); - Delete(tmops); - tmops = newop; + multi_tmap_method = NewStringf("%s-%s+%s:", tm_methods, ptype, pname); + Delete(tm_methods); + tm_methods = multi_tmap_method; p = nextSibling(p); } - Delete(tmops); + Delete(tm_methods); if (!p && tm) { - /* Got some kind of match */ - Swig_typemap_register(op, parms, Getattr(tm, "code"), Getattr(tm, "locals"), Getattr(tm, "kwargs")); + String *parms_str = ParmList_str_multibrackets(parms); + String *srcparms_str = ParmList_str_multibrackets(srcparms); + String *source_directive = NewStringf("typemap(%s) %s = %s", tmap_method, parms_str, srcparms_str); + + typemap_register(tmap_method, parms, Getattr(tm, "code"), Getattr(tm, "locals"), Getattr(tm, "kwargs"), source_directive); + + Delete(source_directive); + Delete(srcparms_str); + Delete(parms_str); return 0; } ts--; @@ -348,38 +389,38 @@ int Swig_typemap_copy(const String_or_char *op, ParmList *srcparms, ParmList *pa /* ----------------------------------------------------------------------------- * Swig_typemap_clear() * - * Delete a multi-valued typemap + * Delete a multi-argument typemap * ----------------------------------------------------------------------------- */ -void Swig_typemap_clear(const String_or_char *op, ParmList *parms) { +void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *parms) { SwigType *type; String *name; Parm *p; - String *newop; + String *multi_tmap_method; Hash *tm = 0; /* This might not work */ - newop = NewString(op); + multi_tmap_method = NewString(tmap_method); p = parms; while (p) { type = Getattr(p, "type"); name = Getattr(p, "name"); - tm = Swig_typemap_get(type, name, tm_scope); + tm = typemap_get(type, name, tm_scope); if (!tm) return; p = nextSibling(p); if (p) - Printf(newop, "-%s+%s:", type, name); + Printf(multi_tmap_method, "-%s+%s:", type, name); } if (tm) { - tm = Getattr(tm, tmop_name(newop)); + tm = Getattr(tm, typemap_method_name(multi_tmap_method)); if (tm) { Delattr(tm, "code"); Delattr(tm, "locals"); Delattr(tm, "kwargs"); } } - Delete(newop); + Delete(multi_tmap_method); } /* ----------------------------------------------------------------------------- @@ -389,8 +430,7 @@ void Swig_typemap_clear(const String_or_char *op, ParmList *parms) { * it works. * ----------------------------------------------------------------------------- */ -static -int count_args(String *s) { +static int count_args(String *s) { /* Count up number of arguments */ int na = 0; char *c = Char(s); @@ -460,7 +500,7 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) { while (ts >= 0) { /* See if there is a matching typemap in this scope */ - sm = Swig_typemap_get(type, name, ts); + sm = typemap_get(type, name, ts); /* if there is not matching, look for a typemap in the original typedef, if any, like in: @@ -472,7 +512,7 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) { if (!sm) { SwigType *ntype = SwigType_typedef_resolve(type); if (ntype && (Cmp(ntype, type) != 0)) { - sm = Swig_typemap_get(ntype, name, ts); + sm = typemap_get(ntype, name, ts); } Delete(ntype); } @@ -502,9 +542,17 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) { locals = Getattr(sm1, "locals"); kwargs = Getattr(sm1, "kwargs"); if (code) { + String *src_str = ParmList_str_multibrackets(src); + String *dest_str = ParmList_str_multibrackets(dest); + String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str); + Replace(nkey, dsig, "", DOH_REPLACE_ANY); Replace(nkey, "tmap:", "", DOH_REPLACE_ANY); - Swig_typemap_register(nkey, dest, code, locals, kwargs); + typemap_register(nkey, dest, code, locals, kwargs, source_directive); + + Delete(source_directive); + Delete(dest_str); + Delete(src_str); } } Delete(nkey); @@ -587,126 +635,164 @@ static SwigType *strip_arrays(SwigType *type) { return t; } +static void debug_search_result_display(Node *tm) { + if (tm) + Printf(stdout, " Using: %%%s\n", Getattr(tm, "source")); + else + Printf(stdout, " None found\n"); +} + +/* ----------------------------------------------------------------------------- + * typemap_search_helper() + * + * Helper function for typemap_search to see if there is a type match in the typemap + * tm. A match is sought in this order: + * %typemap(tm_method) ctype cqualifiedname + * %typemap(tm_method) ctype cname + * %typemap(tm_method) ctype + * ----------------------------------------------------------------------------- */ + +static Hash *typemap_search_helper(int debug_display, Hash *tm, const String *tm_method, SwigType *ctype, const String *cqualifiedname, const String *cname, Hash **backup) { + Hash *result = 0; + Hash *tm1; + if (debug_display && cqualifiedname) + Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, cqualifiedname)); + if (tm && cqualifiedname) { + tm1 = Getattr(tm, cqualifiedname); + if (tm1) { + result = Getattr(tm1, tm_method); /* See if there is a type - qualified name match */ + if (result && Getattr(result, "code")) + goto ret_result; + if (result) + *backup = result; + } + } + if (debug_display && cname) + Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, cname)); + if (tm && cname) { + tm1 = Getattr(tm, cname); + if (tm1) { + result = Getattr(tm1, tm_method); /* See if there is a type - name match */ + if (result && Getattr(result, "code")) + goto ret_result; + if (result) + *backup = result; + } + } + if (debug_display) + Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, 0)); + if (tm) { + result = Getattr(tm, tm_method); /* See if there is simply a type without name match */ + if (result && Getattr(result, "code")) + goto ret_result; + if (result) + *backup = result; + } +ret_result: + return result; +} + /* ----------------------------------------------------------------------------- - * Swig_typemap_search() + * typemap_search() * - * Search for a typemap match. Tries to find the most specific typemap - * that includes a 'code' attribute. + * Search for a typemap match. This is where the typemap pattern matching rules + * are implemented... tries to find the most specific typemap that includes a + * 'code' attribute. * ----------------------------------------------------------------------------- */ -Hash *Swig_typemap_search(const String_or_char *op, SwigType *type, const String_or_char *name, SwigType **matchtype) { - Hash *result = 0, *tm, *tm1, *tma; +static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type, const_String_or_char_ptr name, const_String_or_char_ptr qualifiedname, SwigType **matchtype, Node *node) { + Hash *result = 0; + Hash *tm; Hash *backup = 0; - SwigType *noarrays = 0; SwigType *primitive = 0; SwigType *ctype = 0; + SwigType *ctype_unstripped = 0; int ts; int isarray; const String *cname = 0; - SwigType *unstripped = 0; - String *tmop = tmop_name(op); + const String *cqualifiedname = 0; + String *tm_method = typemap_method_name(tmap_method); + int debug_display = (in_typemap_search_multi == 0) && typemap_search_debug; if ((name) && Len(name)) cname = name; + if ((qualifiedname) && Len(qualifiedname)) + cqualifiedname = qualifiedname; ts = tm_scope; + if (debug_display) { + String *typestr = SwigType_str(type, cqualifiedname ? cqualifiedname : cname); + Swig_diagnostic(Getfile(node), Getline(node), "Searching for a suitable '%s' typemap for: %s\n", tmap_method, typestr); + Delete(typestr); + } while (ts >= 0) { - ctype = type; + ctype = Copy(type); + ctype_unstripped = Copy(ctype); while (ctype) { /* Try to get an exact type-match */ tm = get_typemap(ts, ctype); - if (tm && cname) { - tm1 = Getattr(tm, cname); - if (tm1) { - result = Getattr(tm1, tmop); /* See if there is a type-name match */ + result = typemap_search_helper(debug_display, tm, tm_method, ctype, cqualifiedname, cname, &backup); + if (result && Getattr(result, "code")) + goto ret_result; + + { + /* Look for the type reduced to just the template prefix - for templated types without the template parameter list being specified */ + SwigType *template_prefix = SwigType_istemplate_only_templateprefix(ctype); + if (template_prefix) { + tm = get_typemap(ts, template_prefix); + result = typemap_search_helper(debug_display, tm, tm_method, template_prefix, cqualifiedname, cname, &backup); + Delete(template_prefix); if (result && Getattr(result, "code")) goto ret_result; - if (result) - backup = result; } } - if (tm) { - result = Getattr(tm, tmop); /* See if there is simply a type match */ - if (result && Getattr(result, "code")) - goto ret_result; - if (result) - backup = result; - } + + /* look for [ANY] arrays */ isarray = SwigType_isarray(ctype); if (isarray) { /* If working with arrays, strip away all of the dimensions and replace with "ANY". See if that generates a match */ - if (!noarrays) { - noarrays = strip_arrays(ctype); - } - tma = get_typemap(ts, noarrays); - if (tma && cname) { - tm1 = Getattr(tma, cname); - if (tm1) { - result = Getattr(tm1, tmop); /* type-name match */ - if (result && Getattr(result, "code")) - goto ret_result; - if (result) - backup = result; - } - } - if (tma) { - result = Getattr(tma, tmop); /* type match */ - if (result && Getattr(result, "code")) - goto ret_result; - if (result) - backup = result; - } + SwigType *noarrays = strip_arrays(ctype); + tm = get_typemap(ts, noarrays); + result = typemap_search_helper(debug_display, tm, tm_method, noarrays, cqualifiedname, cname, &backup); Delete(noarrays); - noarrays = 0; + if (result && Getattr(result, "code")) + goto ret_result; } - /* No match so far. If the type is unstripped, we'll strip its - qualifiers and check. Otherwise, we'll try to resolve a typedef */ - - if (!unstripped) { - unstripped = ctype; - ctype = SwigType_strip_qualifiers(ctype); - if (!Equal(ctype, unstripped)) - continue; /* Types are different */ - Delete(ctype); - ctype = unstripped; - unstripped = 0; - } + /* No match so far - try with a qualifier stripped (strip one qualifier at a time until none remain) + * The order of stripping in SwigType_strip_single_qualifier is used to provide some sort of consistency + * with the default (SWIGTYPE) typemap matching rules for the first qualifier to be stripped. */ { - String *octype; - if (unstripped) { - Delete(ctype); - ctype = unstripped; - unstripped = 0; + SwigType *oldctype = ctype; + ctype = SwigType_strip_single_qualifier(oldctype); + if (!Equal(ctype, oldctype)) { + Delete(oldctype); + continue; } - octype = ctype; - ctype = SwigType_typedef_resolve(ctype); - if (octype != type) - Delete(octype); + Delete(oldctype); + } + + /* Once all qualifiers are stripped try resolve a typedef */ + { + SwigType *oldctype = ctype; + ctype = SwigType_typedef_resolve(ctype_unstripped); + Delete(oldctype); + ctype_unstripped = Copy(ctype); } } - /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default mapping */ + /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default (SWIGTYPE) mapping */ - primitive = SwigType_default(type); + primitive = SwigType_default_create(type); while (primitive) { tm = get_typemap(ts, primitive); - if (tm && cname) { - tm1 = Getattr(tm, cname); - if (tm1) { - result = Getattr(tm1, tmop); /* See if there is a type-name match */ - if (result) - goto ret_result; - } - } - if (tm) { /* See if there is simply a type match */ - result = Getattr(tm, tmop); - if (result) - goto ret_result; - } + result = typemap_search_helper(debug_display, tm, tm_method, primitive, cqualifiedname, cname, &backup); + if (result && Getattr(result, "code")) + goto ret_result; + { - SwigType *nprim = SwigType_default(primitive); + SwigType *nprim = SwigType_default_deduce(primitive); Delete(primitive); primitive = nprim; } @@ -720,33 +806,28 @@ Hash *Swig_typemap_search(const String_or_char *op, SwigType *type, const String result = backup; ret_result: - if (noarrays) - Delete(noarrays); - if (primitive) - Delete(primitive); - if ((unstripped) && (unstripped != type)) - Delete(unstripped); - if (matchtype) { + Delete(primitive); + if (matchtype) *matchtype = Copy(ctype); - } - if (type != ctype) - Delete(ctype); + Delete(ctype); + Delete(ctype_unstripped); return result; } /* ----------------------------------------------------------------------------- - * Swig_typemap_search_multi() + * typemap_search_multi() * - * Search for a multi-valued typemap. + * Search for a multi-argument typemap. * ----------------------------------------------------------------------------- */ -Hash *Swig_typemap_search_multi(const String_or_char *op, ParmList *parms, int *nmatch) { +static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList *parms, int *nmatch) { SwigType *type; SwigType *mtype = 0; String *name; - String *newop; - Hash *tm, *tm1; + String *multi_tmap_method; + Hash *tm; + Hash *tm1 = 0; if (!parms) { *nmatch = 0; @@ -756,23 +837,38 @@ Hash *Swig_typemap_search_multi(const String_or_char *op, ParmList *parms, int * name = Getattr(parms, "name"); /* Try to find a match on the first type */ - tm = Swig_typemap_search(op, type, name, &mtype); + tm = typemap_search(tmap_method, type, name, 0, &mtype, parms); if (tm) { if (mtype && SwigType_isarray(mtype)) { Setattr(parms, "tmap:match", mtype); } Delete(mtype); - newop = NewStringf("%s-%s+%s:", op, type, name); - tm1 = Swig_typemap_search_multi(newop, nextSibling(parms), nmatch); + multi_tmap_method = NewStringf("%s-%s+%s:", tmap_method, type, name); + in_typemap_search_multi++; + tm1 = typemap_search_multi(multi_tmap_method, nextSibling(parms), nmatch); + in_typemap_search_multi--; if (tm1) tm = tm1; if (Getattr(tm, "code")) { *(nmatch) = *nmatch + 1; + if (typemap_search_debug && tm1 && (in_typemap_search_multi == 0)) { + Printf(stdout, " Multi-argument typemap found...\n"); + } } else { tm = 0; } - Delete(newop); + Delete(multi_tmap_method); + } + + if (typemap_search_debug && (in_typemap_search_multi == 0)) + debug_search_result_display(tm); + if (typemaps_used_debug && (in_typemap_search_multi == 0) && tm) { + String *typestr = SwigType_str(type, name); + Swig_diagnostic(Getfile(parms), Getline(parms), "Typemap for %s (%s) : %%%s\n", typestr, tmap_method, Getattr(tm, "source")); + assert(Getfile(parms) && Len(Getfile(parms)) > 0); /* Missing file and line numbering information */ + Delete(typestr); } + return tm; } @@ -784,8 +880,7 @@ Hash *Swig_typemap_search_multi(const String_or_char *op, ParmList *parms, int * * type and pname are the type and parameter name. * ----------------------------------------------------------------------------- */ -static -void replace_local_types(ParmList *p, const String *name, const String *rep) { +static void replace_local_types(ParmList *p, const String *name, const String *rep) { SwigType *t; while (p) { t = Getattr(p, "type"); @@ -794,8 +889,7 @@ void replace_local_types(ParmList *p, const String *name, const String *rep) { } } -static -int check_locals(ParmList *p, const char *s) { +static int check_locals(ParmList *p, const char *s) { while (p) { char *c = GetChar(p, "type"); if (strstr(c, s)) @@ -805,14 +899,13 @@ int check_locals(ParmList *p, const char *s) { return 0; } -static -int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType *rtype, String *pname, String *lname, int index) { +static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType *rtype, String *pname, String *lname, int index) { char var[512]; char *varname; SwigType *ftype; int bare_substitution_count = 0; - Replaceall(s, "$typemap", "$TYPEMAP"); + Replaceall(s, "$typemap", "$TYPEMAP"); /* workaround for $type substitution below */ ftype = SwigType_typedef_resolve_all(type); @@ -878,7 +971,7 @@ int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType * { SwigType *star_type, *amp_type, *base_type, *lex_type; SwigType *ltype, *star_ltype, *amp_ltype; - String *mangle, *star_mangle, *amp_mangle, *base_mangle, *base_name; + String *mangle, *star_mangle, *amp_mangle, *base_mangle, *base_name, *base_type_str; String *descriptor, *star_descriptor, *amp_descriptor; String *ts; char *sc; @@ -1047,21 +1140,20 @@ int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType * /* Base type */ if (SwigType_isarray(type)) { - SwigType *bt = Copy(type); - Delete(SwigType_pop_arrays(bt)); - base_type = SwigType_str(bt, 0); - Delete(bt); + base_type = Copy(type); + Delete(SwigType_pop_arrays(base_type)); } else { base_type = SwigType_base(type); } - base_name = SwigType_namestr(base_type); + base_type_str = SwigType_str(base_type, 0); + base_name = SwigType_namestr(base_type_str); if (index == 1) { Replace(s, "$basetype", base_name, DOH_REPLACE_ANY); replace_local_types(locals, "$basetype", base_name); } strcpy(varname, "basetype"); - Replace(s, var, base_type, DOH_REPLACE_ANY); + Replace(s, var, base_type_str, DOH_REPLACE_ANY); replace_local_types(locals, var, base_name); base_mangle = SwigType_manglestr(base_type); @@ -1070,8 +1162,9 @@ int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType * strcpy(varname, "basemangle"); Replace(s, var, base_mangle, DOH_REPLACE_ANY); Delete(base_mangle); - Delete(base_type); Delete(base_name); + Delete(base_type_str); + Delete(base_type); lex_type = SwigType_base(rtype); if (index == 1) @@ -1091,7 +1184,7 @@ int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType * /* Replace the bare $n variable */ sprintf(var, "$%d", index); - bare_substitution_count = Replace(s, var, lname, DOH_REPLACE_ANY); + bare_substitution_count = Replace(s, var, lname, DOH_REPLACE_NUMBER_END); Delete(ftype); return bare_substitution_count; } @@ -1164,73 +1257,109 @@ static void typemap_locals(DOHString * s, ParmList *l, Wrapper *f, int argnum) { } /* ----------------------------------------------------------------------------- + * typemap_warn() + * + * If any warning message is attached to this parameter's "tmap:<method>:warning" + * attribute, return the warning message (special variables will need expanding + * before displaying the warning). + * ----------------------------------------------------------------------------- */ + +static String *typemap_warn(const_String_or_char_ptr tmap_method, Parm *p) { + String *temp = NewStringf("%s:warning", tmap_method); + String *w = Getattr(p, typemap_method_name(temp)); + Delete(temp); + return w ? Copy(w) : 0; +} + +/* ----------------------------------------------------------------------------- * Swig_typemap_lookup() * * Attach one or more typemaps to a node and optionally generate the typemap contents * into the wrapper. - * op - typemap name, eg "out", "newfree" - * node - the node to attach the typemaps to - * lname - name of variable to substitute $1, $2 etc for - * f - wrapper code to generate into if non null - * actioncode - code to generate into f before the out typemap code, unless + * + * Looks for a typemap matching the given type and name and attaches the typemap code + * and any typemap attributes to the provided node. + * + * The node should contain the "type" and "name" attributes for the typemap match on. + * input. The typemap code and typemap attribute values are attached onto the node + * prefixed with "tmap:". For example with tmap_method="in", the typemap code can be retrieved + * with a call to Getattr(node, "tmap:in") (this is also the string returned) and the + * "noblock" attribute can be retrieved with a call to Getattr(node, "tmap:in:noblock"). + * + * tmap_method - typemap method, eg "in", "out", "newfree" + * node - the node to attach the typemap and typemap attributes to + * lname - name of variable to substitute $1, $2 etc for + * f - wrapper code to generate into if non null + * actioncode - code to generate into f before the out typemap code, unless * the optimal attribute is set in the out typemap in which case * $1 in the out typemap will be replaced by the code in actioncode. * ----------------------------------------------------------------------------- */ -static String *Swig_typemap_lookup_impl(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f, String *actioncode) { +static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f, String *actioncode) { SwigType *type; SwigType *mtype = 0; String *pname; + String *qpname = 0; Hash *tm = 0; String *s = 0; String *sdef = 0; + String *warning = 0; ParmList *locals; ParmList *kw; char temp[256]; String *symname; String *cname = 0; String *clname = 0; - char *cop = Char(op); + char *cmethod = Char(tmap_method); int optimal_attribute = 0; int optimal_substitution = 0; int num_substitutions = 0; - - /* special case, we need to check for 'ref' call - and set the default code 'sdef' */ - if (node && Cmp(op, "newfree") == 0) { - sdef = Swig_ref_call(node, lname); - } + SwigType *matchtype = 0; type = Getattr(node, "type"); if (!type) return sdef; + /* Special hook (hack!). Check for the 'ref' feature and add code it contains to any 'newfree' typemap code. + * We could choose to put this hook into a number of different typemaps, not necessarily 'newfree'... + * Rather confusingly 'newfree' is used to release memory and the 'ref' feature is used to add in memory references - yuck! */ + if (node && Cmp(tmap_method, "newfree") == 0) { + String *base = SwigType_base(type); + Node *typenode = Swig_symbol_clookup(base, 0); + if (typenode) + sdef = Swig_ref_call(typenode, lname); + Delete(base); + } + pname = Getattr(node, "name"); -#if 1 if (pname && node && checkAttribute(node, "kind", "function")) { /* - For functions, look qualified names first, such as - + For functions, add on a qualified name search, for example struct Foo { - int *foo(int bar) -> Foo::foo + int *foo(int bar) -> Foo::foo }; */ Symtab *st = Getattr(node, "sym:symtab"); String *qsn = st ? Swig_symbol_string_qualify(pname, st) : 0; - if (qsn) { - if (Len(qsn) && !Equal(qsn, pname)) { - tm = Swig_typemap_search(op, type, qsn, &mtype); - if (tm && (!Getattr(tm, "pname") || strstr(Char(Getattr(tm, "type")), "SWIGTYPE"))) { - tm = 0; - } - } - Delete(qsn); - } + if (qsn && Len(qsn) && !Equal(qsn, pname)) + qpname = qsn; } - if (!tm) -#endif - tm = Swig_typemap_search(op, type, pname, &mtype); + + tm = typemap_search(tmap_method, type, pname, qpname, &mtype, node); + if (typemap_search_debug) + debug_search_result_display(tm); + if (typemaps_used_debug && tm) { + String *typestr = SwigType_str(type, qpname ? qpname : pname); + Swig_diagnostic(Getfile(node), Getline(node), "Typemap for %s (%s) : %%%s\n", typestr, tmap_method, Getattr(tm, "source")); + assert(Getfile(node) && Len(Getfile(node)) > 0); /* Missing file and line numbering information */ + Delete(typestr); + } + + + Delete(qpname); + qpname = 0; + if (!tm) return sdef; @@ -1248,15 +1377,15 @@ static String *Swig_typemap_lookup_impl(const String_or_char *op, Node *node, co kw = Getattr(tm, "kwargs"); while (kw) { String *value = Copy(Getattr(kw, "value")); - String *type = Getattr(kw, "type"); + String *kwtype = Getattr(kw, "type"); char *ckwname = Char(Getattr(kw, "name")); - if (type) { - String *mangle = Swig_string_mangle(type); + if (kwtype) { + String *mangle = Swig_string_mangle(kwtype); Append(value, mangle); Delete(mangle); } - sprintf(temp, "%s:%s", cop, ckwname); - Setattr(node, tmop_name(temp), value); + sprintf(temp, "%s:%s", cmethod, ckwname); + Setattr(node, typemap_method_name(temp), value); if (Cmp(temp, "out:optimal") == 0) optimal_attribute = (Cmp(value, "0") != 0) ? 1 : 0; Delete(value); @@ -1268,6 +1397,7 @@ static String *Swig_typemap_lookup_impl(const String_or_char *op, Node *node, co * If f and actioncode are NULL, then the caller is just looking to attach the "out" attributes * ie, not use the typemap code, otherwise both f and actioncode must be non null. */ if (actioncode) { + const String *result_equals = NewStringf("%s = ", Swig_cresult_name()); clname = Copy(actioncode); /* check that the code in the typemap can be used in this optimal way. * The code should be in the form "result = ...;\n". We need to extract @@ -1276,8 +1406,8 @@ static String *Swig_typemap_lookup_impl(const String_or_char *op, Node *node, co * hack and circumvents the normal requirement for a temporary variable * to hold the result returned from a wrapped function call. */ - if (Strncmp(clname, "result = ", 9) == 0) { - int numreplacements = Replace(clname, "result = ", "", DOH_REPLACE_ID_BEGIN); + if (Strncmp(clname, result_equals, 9) == 0) { + int numreplacements = Replace(clname, result_equals, "", DOH_REPLACE_ID_BEGIN); if (numreplacements == 1) { numreplacements = Replace(clname, ";\n", "", DOH_REPLACE_ID_END); if (numreplacements == 1) { @@ -1290,7 +1420,8 @@ static String *Swig_typemap_lookup_impl(const String_or_char *op, Node *node, co } } if (!optimal_substitution) { - Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute in the out typemap at %s:%d ignored as the following cannot be used to generate optimal code: %s\n", Swig_name_decl(node), Getfile(s), Getline(s), clname); + Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute ignored\n", Swig_name_decl(node)); + Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(s), Getline(s), "in the out typemap as the following cannot be used to generate optimal code: %s\n", clname); Delattr(node, "tmap:out:optimal"); } } else { @@ -1319,55 +1450,60 @@ static String *Swig_typemap_lookup_impl(const String_or_char *op, Node *node, co lname = clname; } - if (mtype && SwigType_isarray(mtype)) { - num_substitutions = typemap_replace_vars(s, locals, mtype, type, pname, (char *) lname, 1); - } else { - num_substitutions = typemap_replace_vars(s, locals, type, type, pname, (char *) lname, 1); + matchtype = mtype && SwigType_isarray(mtype) ? mtype : type; + num_substitutions = typemap_replace_vars(s, locals, matchtype, type, pname, (char *) lname, 1); + if (optimal_substitution && num_substitutions > 1) { + Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(node), Getline(node), "Multiple calls to %s might be generated due to\n", Swig_name_decl(node)); + Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(s), Getline(s), "optimal attribute usage in the out typemap.\n"); } - if (optimal_substitution && num_substitutions > 1) - Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(node), Getline(node), "Multiple calls to %s might be generated due to optimal attribute usage in the out typemap at %s:%d.\n", Swig_name_decl(node), Getfile(s), Getline(s)); if (locals && f) { typemap_locals(s, locals, f, -1); } - replace_embedded_typemap(s); + + { + ParmList *parm_sublist = NewParmWithoutFileLineInfo(type, pname); + Setattr(parm_sublist, "lname", lname); + replace_embedded_typemap(s, parm_sublist, f, tm); + Delete(parm_sublist); + } Replace(s, "$name", pname, DOH_REPLACE_ANY); symname = Getattr(node, "sym:name"); - if (symname) { + if (symname) Replace(s, "$symname", symname, DOH_REPLACE_ANY); - } - Setattr(node, tmop_name(op), s); + Setattr(node, typemap_method_name(tmap_method), s); if (locals) { - sprintf(temp, "%s:locals", cop); - Setattr(node, tmop_name(temp), locals); + sprintf(temp, "%s:locals", cmethod); + Setattr(node, typemap_method_name(temp), locals); Delete(locals); } if (Checkattr(tm, "type", "SWIGTYPE")) { - sprintf(temp, "%s:SWIGTYPE", cop); - Setattr(node, tmop_name(temp), "1"); + sprintf(temp, "%s:SWIGTYPE", cmethod); + Setattr(node, typemap_method_name(temp), "1"); } - /* Look for warnings */ - { - String *w; - sprintf(temp, "%s:warning", cop); - w = Getattr(node, tmop_name(temp)); - if (w) { - Swig_warning(0, Getfile(node), Getline(node), "%s\n", w); - } + /* Print warnings, if any */ + warning = typemap_warn(cmethod, node); + if (warning) { + typemap_replace_vars(warning, 0, matchtype, type, pname, (char *) lname, 1); + Replace(warning, "$name", pname, DOH_REPLACE_ANY); + if (symname) + Replace(warning, "$symname", symname, DOH_REPLACE_ANY); + Swig_warning(0, Getfile(node), Getline(node), "%s\n", warning); + Delete(warning); } /* Look for code fragments */ { - String *f; - sprintf(temp, "%s:fragment", cop); - f = Getattr(node, tmop_name(temp)); - if (f) { - String *fname = Copy(f); + String *fragment; + sprintf(temp, "%s:fragment", cmethod); + fragment = Getattr(node, typemap_method_name(temp)); + if (fragment) { + String *fname = Copy(fragment); Setfile(fname, Getfile(node)); Setline(fname, Getline(node)); Swig_fragment_emit(fname); @@ -1388,19 +1524,18 @@ static String *Swig_typemap_lookup_impl(const String_or_char *op, Node *node, co return s; } -String *Swig_typemap_lookup_out(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f, String *actioncode) { +String *Swig_typemap_lookup_out(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f, String *actioncode) { assert(actioncode); - assert(Cmp(op, "out") == 0); - return Swig_typemap_lookup_impl(op, node, lname, f, actioncode); + assert(Cmp(tmap_method, "out") == 0); + return Swig_typemap_lookup_impl(tmap_method, node, lname, f, actioncode); } -String *Swig_typemap_lookup(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f) { - return Swig_typemap_lookup_impl(op, node, lname, f, 0); +String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f) { + return Swig_typemap_lookup_impl(tmap_method, node, lname, f, 0); } - /* ----------------------------------------------------------------------------- - * Swig_typemap_attach_kwargs() + * typemap_attach_kwargs() * * If this hash (tm) contains a linked list of parameters under its "kwargs" * attribute, add keys for each of those named keyword arguments to this @@ -1410,7 +1545,7 @@ String *Swig_typemap_lookup(const String_or_char *op, Node *node, const String_o * A new attribute called "tmap:in:foo" with value "xyz" is attached to p. * ----------------------------------------------------------------------------- */ -void Swig_typemap_attach_kwargs(Hash *tm, const String_or_char *op, Parm *p) { +static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method, Parm *p) { String *temp = NewStringEmpty(); Parm *kw = Getattr(tm, "kwargs"); while (kw) { @@ -1424,36 +1559,20 @@ void Swig_typemap_attach_kwargs(Hash *tm, const String_or_char *op, Parm *p) { value = v; } Clear(temp); - Printf(temp, "%s:%s", op, Getattr(kw, "name")); - Setattr(p, tmop_name(temp), value); + Printf(temp, "%s:%s", tmap_method, Getattr(kw, "name")); + Setattr(p, typemap_method_name(temp), value); Delete(value); kw = nextSibling(kw); } Clear(temp); - Printf(temp, "%s:match_type", op); - Setattr(p, tmop_name(temp), Getattr(tm, "type")); + Printf(temp, "%s:match_type", tmap_method); + Setattr(p, typemap_method_name(temp), Getattr(tm, "type")); Delete(temp); } -/* ----------------------------------------------------------------------------- - * Swig_typemap_warn() - * - * If any warning message is attached to this parameter's "tmap:op:warning" - * attribute, print that warning message. - * ----------------------------------------------------------------------------- */ - -static void Swig_typemap_warn(const String_or_char *op, Parm *p) { - String *temp = NewStringf("%s:warning", op); - String *w = Getattr(p, tmop_name(temp)); - Delete(temp); - if (w) { - Swig_warning(0, Getfile(p), Getline(p), "%s\n", w); - } -} - -static void Swig_typemap_emit_code_fragments(const String_or_char *op, Parm *p) { - String *temp = NewStringf("%s:fragment", op); - String *f = Getattr(p, tmop_name(temp)); +static void typemap_emit_code_fragments(const_String_or_char_ptr tmap_method, Parm *p) { + String *temp = NewStringf("%s:fragment", tmap_method); + String *f = Getattr(p, typemap_method_name(temp)); if (f) { String *fname = Copy(f); Setfile(fname, Getfile(p)); @@ -1464,14 +1583,7 @@ static void Swig_typemap_emit_code_fragments(const String_or_char *op, Parm *p) Delete(temp); } -/* ----------------------------------------------------------------------------- - * Swig_typemap_attach_parms() - * - * Given a parameter list, this function attaches all of the typemaps for a - * given typemap type - * ----------------------------------------------------------------------------- */ - -String *Swig_typemap_get_option(Hash *tm, String *name) { +static String *typemap_get_option(Hash *tm, const_String_or_char_ptr name) { Parm *kw = Getattr(tm, "kwargs"); while (kw) { String *kname = Getattr(kw, "name"); @@ -1483,30 +1595,47 @@ String *Swig_typemap_get_option(Hash *tm, String *name) { return 0; } -void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrapper *f) { +/* ----------------------------------------------------------------------------- + * Swig_typemap_attach_parms() + * + * Given a parameter list, this function attaches all of the typemaps and typemap + * attributes to the parameter for each type in the parameter list. + * + * This function basically provides the typemap code and typemap attribute values as + * attributes on each parameter prefixed with "tmap:". For example with tmap_method="in", the typemap + * code can be retrieved for the first parameter with a call to Getattr(parm, "tmap:in") + * and the "numinputs" attribute can be retrieved with a call to Getattr(parm, "tmap:in:numinputs"). + * + * tmap_method - typemap method, eg "in", "out", "newfree" + * parms - parameter list to attach each typemap and all typemap attributes + * f - wrapper code to generate into if non null + * ----------------------------------------------------------------------------- */ + +void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f) { Parm *p, *firstp; Hash *tm; int nmatch = 0; int i; String *s; + String *warning = 0; ParmList *locals; int argnum = 0; char temp[256]; - char *cop = Char(op); + char *cmethod = Char(tmap_method); String *kwmatch = 0; p = parms; #ifdef SWIG_DEBUG - Printf(stdout, "Swig_typemap_attach_parms: %s\n", op); + Printf(stdout, "Swig_typemap_attach_parms: %s\n", tmap_method); #endif while (p) { argnum++; nmatch = 0; #ifdef SWIG_DEBUG - Printf(stdout, "parms: %s %s %s\n", op, Getattr(p, "name"), Getattr(p, "type")); + Printf(stdout, "parms: %s %s %s\n", tmap_method, Getattr(p, "name"), Getattr(p, "type")); #endif - tm = Swig_typemap_search_multi(op, p, &nmatch); + tm = typemap_search_multi(tmap_method, p, &nmatch); #ifdef SWIG_DEBUG if (tm) Printf(stdout, "found: %s\n", tm); @@ -1525,7 +1654,7 @@ void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrappe here, the freearg typemap requires the "in" typemap to match, or the 'var$argnum' variable will not exist. */ - kwmatch = Swig_typemap_get_option(tm, "match"); + kwmatch = typemap_get_option(tm, "match"); if (kwmatch) { String *tmname = NewStringf("tmap:%s", kwmatch); String *tmin = Getattr(p, tmname); @@ -1551,7 +1680,7 @@ void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrappe continue; } else { int nnmatch; - Hash *tmapin = Swig_typemap_search_multi(kwmatch, p, &nnmatch); + Hash *tmapin = typemap_search_multi(kwmatch, p, &nnmatch); String *tmname = Getattr(tm, "pname"); String *tnname = Getattr(tmapin, "pname"); if (!(tmname && tnname && Equal(tmname, tnname)) && !(!tmname && !tnname)) { @@ -1592,27 +1721,19 @@ void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrappe Printf(stdout, "nmatch: %d\n", nmatch); #endif for (i = 0; i < nmatch; i++) { - SwigType *type; - String *pname; - String *lname; - SwigType *mtype; - - - type = Getattr(p, "type"); - pname = Getattr(p, "name"); - lname = Getattr(p, "lname"); - mtype = Getattr(p, "tmap:match"); - - if (mtype) { - typemap_replace_vars(s, locals, mtype, type, pname, lname, i + 1); + SwigType *type = Getattr(p, "type"); + String *pname = Getattr(p, "name"); + String *lname = Getattr(p, "lname"); + SwigType *mtype = Getattr(p, "tmap:match"); + SwigType *matchtype = mtype ? mtype : type; + + typemap_replace_vars(s, locals, matchtype, type, pname, lname, i + 1); + if (mtype) Delattr(p, "tmap:match"); - } else { - typemap_replace_vars(s, locals, type, type, pname, lname, i + 1); - } if (Checkattr(tm, "type", "SWIGTYPE")) { - sprintf(temp, "%s:SWIGTYPE", cop); - Setattr(p, tmop_name(temp), "1"); + sprintf(temp, "%s:SWIGTYPE", cmethod); + Setattr(p, typemap_method_name(temp), "1"); } p = nextSibling(p); } @@ -1621,42 +1742,53 @@ void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrappe typemap_locals(s, locals, f, argnum); } - replace_embedded_typemap(s); - - /* Replace the argument number */ - sprintf(temp, "%d", argnum); - Replace(s, "$argnum", temp, DOH_REPLACE_ANY); + replace_embedded_typemap(s, firstp, f, tm); /* Attach attributes to object */ #ifdef SWIG_DEBUG - Printf(stdout, "attach: %s %s %s\n", Getattr(firstp, "name"), tmop_name(op), s); + Printf(stdout, "attach: %s %s %s\n", Getattr(firstp, "name"), typemap_method_name(tmap_method), s); #endif - Setattr(firstp, tmop_name(op), s); /* Code object */ + Setattr(firstp, typemap_method_name(tmap_method), s); /* Code object */ if (locals) { - sprintf(temp, "%s:locals", cop); - Setattr(firstp, tmop_name(temp), locals); + sprintf(temp, "%s:locals", cmethod); + Setattr(firstp, typemap_method_name(temp), locals); Delete(locals); } /* Attach a link to the next parameter. Needed for multimaps */ - sprintf(temp, "%s:next", cop); - Setattr(firstp, tmop_name(temp), p); + sprintf(temp, "%s:next", cmethod); + Setattr(firstp, typemap_method_name(temp), p); /* Attach kwargs */ - Swig_typemap_attach_kwargs(tm, op, firstp); + typemap_attach_kwargs(tm, tmap_method, firstp); + + /* Replace the argument number */ + sprintf(temp, "%d", argnum); + Replace(s, "$argnum", temp, DOH_REPLACE_ANY); /* Print warnings, if any */ - Swig_typemap_warn(op, firstp); + warning = typemap_warn(tmap_method, firstp); + if (warning) { + SwigType *type = Getattr(firstp, "type"); + String *pname = Getattr(firstp, "name"); + String *lname = Getattr(firstp, "lname"); + SwigType *mtype = Getattr(firstp, "tmap:match"); + SwigType *matchtype = mtype ? mtype : type; + typemap_replace_vars(warning, 0, matchtype, type, pname, lname, 1); + Replace(warning, "$argnum", temp, DOH_REPLACE_ANY); + Swig_warning(0, Getfile(firstp), Getline(firstp), "%s\n", warning); + Delete(warning); + } /* Look for code fragments */ - Swig_typemap_emit_code_fragments(op, firstp); + typemap_emit_code_fragments(tmap_method, firstp); /* increase argnum to consider numinputs */ argnum += nmatch - 1; Delete(s); #ifdef SWIG_DEBUG - Printf(stdout, "res: %s %s %s\n", Getattr(firstp, "name"), tmop_name(op), Getattr(firstp, tmop_name(op))); + Printf(stdout, "res: %s %s %s\n", Getattr(firstp, "name"), typemap_method_name(tmap_method), Getattr(firstp, typemap_method_name(tmap_method))); #endif } @@ -1666,30 +1798,17 @@ void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrappe } -/* ----------------------------------------------------------------------------- - * split_embedded() - * - * This function replaces the special variable $typemap(....) with typemap - * code. The general form of $typemap is as follows: - * - * $TYPEMAP(method, $var1=value, $var2=value, $var3=value,...) - * - * For example: - * - * $TYPEMAP(in, $1=int x, $input=y, ...) - * - * Note: this was added as an experiment and could be removed - * ----------------------------------------------------------------------------- */ - /* Splits the arguments of an embedded typemap */ -static List *split_embedded(String *s) { +static List *split_embedded_typemap(String *s) { List *args = 0; char *c, *start; int level = 0; + int angle_level = 0; int leading = 1; - args = NewList(); + args = NewList(); c = strchr(Char(s), '('); + assert(c); c++; start = c; @@ -1706,7 +1825,7 @@ static List *split_embedded(String *s) { c++; } } - if ((level == 0) && ((*c == ',') || (*c == ')'))) { + if ((level == 0) && angle_level == 0 && ((*c == ',') || (*c == ')'))) { String *tmp = NewStringWithSize(start, c - start); Append(args, tmp); Delete(tmp); @@ -1721,6 +1840,10 @@ static List *split_embedded(String *s) { level++; if (*c == ')') level--; + if (*c == '<') + angle_level++; + if (*c == '>') + angle_level--; if (isspace((int) *c) && leading) start++; if (!isspace((int) *c)) @@ -1730,41 +1853,36 @@ static List *split_embedded(String *s) { return args; } -static void split_var(String *s, String **name, String **value) { - char *eq; - char *c; - - eq = strchr(Char(s), '='); - if (!eq) { - *name = 0; - *value = 0; - return; - } - c = Char(s); - *name = NewStringWithSize(c, eq - c); - - /* Look for $n variables */ - if (isdigit((int) *(c))) { - /* Parse the value as a type */ - String *v; - Parm *p; - v = NewString(eq + 1); - p = Swig_cparse_parm(v); - Delete(v); - *value = p; - } else { - *value = NewString(eq + 1); - } -} +/* ----------------------------------------------------------------------------- + * replace_embedded_typemap() + * + * This function replaces the special variable macro $typemap(...) with typemap + * code. The general form of $typemap is as follows: + * + * $typemap(method, typelist, var1=value, var2=value, ...) + * + * where varx parameters are optional and undocumented; they were used in an earlier version of $typemap. + * A search is made using the typemap matching rules of form: + * + * %typemap(method) typelist {...} + * + * and if found will substitute in the typemap contents, making appropriate variable replacements. + * + * For example: + * $typemap(in, int) # simple usage matching %typemap(in) int { ... } + * $typemap(in, int b) # simple usage matching %typemap(in) int b { ... } or above %typemap + * $typemap(in, (Foo<int, bool> a, int b)) # multi-argument typemap matching %typemap(in) (Foo<int, bool> a, int b) {...} + * ----------------------------------------------------------------------------- */ -static void replace_embedded_typemap(String *s) { +static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f, Node *file_line_node) { char *start = 0; - while ((start = strstr(Char(s), "$TYPEMAP("))) { + while ((start = strstr(Char(s), "$TYPEMAP("))) { /* note $typemap capitalisation to $TYPEMAP hack */ - /* Gather the argument */ + /* Gather the parameters */ char *end = 0, *c; int level = 0; - String *tmp; + String *dollar_typemap; + int syntax_error = 1; c = start; while (*c) { if (*c == '(') @@ -1779,119 +1897,186 @@ static void replace_embedded_typemap(String *s) { c++; } if (end) { - tmp = NewStringWithSize(start, (end - start)); + dollar_typemap = NewStringWithSize(start, (end - start)); + syntax_error = 0; } else { - tmp = 0; + dollar_typemap = NewStringWithSize(start, (c - start)); } - /* Got a substitution. Split it apart into pieces */ - if (tmp) { + if (!syntax_error) { List *l; + String *tmap_method; Hash *vars; - String *method; - int i, ilen; - - l = split_embedded(tmp); - vars = NewHash(); - ilen = Len(l); - for (i = 1; i < ilen; i++) { - String *n, *v; - split_var(Getitem(l, i), &n, &v); - if (n && v) { - Insert(n, 0, "$"); - Setattr(vars, n, v); + syntax_error = 1; + + /* Split apart each parameter in $typemap(...) */ + l = split_embedded_typemap(dollar_typemap); + + if (Len(l) >= 2) { + ParmList *to_match_parms; + tmap_method = Getitem(l, 0); + + /* the second parameter might contain multiple sub-parameters for multi-argument + * typemap matching, so split these parameters apart */ + to_match_parms = Swig_cparse_parms(Getitem(l, 1), file_line_node); + if (to_match_parms) { + Parm *p = to_match_parms; + Parm *sub_p = parm_sublist; + String *empty_string = NewStringEmpty(); + String *lname = empty_string; + while (p) { + if (sub_p) { + lname = Getattr(sub_p, "lname"); + sub_p = nextSibling(sub_p); + } + Setattr(p, "lname", lname); + p = nextSibling(p); + } + Delete(empty_string); } - Delete(n); - Delete(v); - } - method = Getitem(l, 0); - /* Generate the parameter list for matching typemaps */ - - { - Parm *p = 0; - Parm *first = 0; - char temp[32]; - int n = 1; - while (1) { - Hash *v; - sprintf(temp, "$%d", n); - v = Getattr(vars, temp); - if (v) { - if (p) { - set_nextSibling(p, v); - set_previousSibling(v, p); + /* process optional extra parameters - the variable replacements (undocumented) */ + vars = NewHash(); + { + int i, ilen; + ilen = Len(l); + for (i = 2; i < ilen; i++) { + String *parm = Getitem(l, i); + char *eq = strchr(Char(parm), '='); + char *c = Char(parm); + if (eq && (eq - c > 0)) { + String *name = NewStringWithSize(c, eq - c); + String *value = NewString(eq + 1); + Insert(name, 0, "$"); + Setattr(vars, name, value); + } else { + to_match_parms = 0; /* error - variable replacement parameters must be of form varname=value */ } - p = v; - Setattr(p, "lname", Getattr(p, "name")); - if (Getattr(p, "value")) { - Setattr(p, "name", Getattr(p, "value")); - } - if (!first) - first = p; - DohIncref(p); - Delattr(vars, temp); - } else { - break; } - n++; } + /* Perform a typemap search */ - if (first) { + if (to_match_parms) { + static int already_substituting = 0; + String *tm; + String *attr; + int match = 0; #ifdef SWIG_DEBUG Printf(stdout, "Swig_typemap_attach_parms: embedded\n"); #endif - Swig_typemap_attach_parms(method, first, 0); - { - String *tm; - int match = 0; - char attr[64]; - sprintf(attr, "tmap:%s", Char(method)); + if (already_substituting < 10) { + already_substituting++; + if ((in_typemap_search_multi == 0) && typemap_search_debug) { + String *dtypemap = NewString(dollar_typemap); + Replaceall(dtypemap, "$TYPEMAP", "$typemap"); + Printf(stdout, " Containing: %s\n", dtypemap); + Delete(dtypemap); + } + Swig_typemap_attach_parms(tmap_method, to_match_parms, f); + already_substituting--; /* Look for the typemap code */ - tm = Getattr(first, attr); + attr = NewStringf("tmap:%s", tmap_method); + tm = Getattr(to_match_parms, attr); if (tm) { - sprintf(attr, "tmap:%s:next", Char(method)); - if (!Getattr(first, attr)) { - /* Should be no more matches. Hack??? */ - /* Replace all of the remaining variables */ + Printf(attr, "%s", ":next"); + /* fail if multi-argument lookup requested in $typemap(...) and the lookup failed */ + if (!Getattr(to_match_parms, attr)) { + /* Replace parameter variables */ Iterator ki; for (ki = First(vars); ki.key; ki = Next(ki)) { Replace(tm, ki.key, ki.item, DOH_REPLACE_ANY); } - /* Do the replacement */ - Replace(s, tmp, tm, DOH_REPLACE_ANY); + /* offer the target language module the chance to make special variable substitutions */ + Language_replace_special_variables(tmap_method, tm, to_match_parms); + /* finish up - do the substitution */ + Replace(s, dollar_typemap, tm, DOH_REPLACE_ANY); Delete(tm); match = 1; } } + if (!match) { - Swig_error(Getfile(s), Getline(s), "No typemap found for %s\n", tmp); + String *dtypemap = NewString(dollar_typemap); + Replaceall(dtypemap, "$TYPEMAP", "$typemap"); + Swig_error(Getfile(s), Getline(s), "No typemap found for %s\n", dtypemap); + Delete(dtypemap); } + Delete(attr); + } else { + /* Simple recursive call check to prevent infinite recursion - this strategy only allows a limited + * number of calls by a embedded typemaps to other embedded typemaps though */ + String *dtypemap = NewString(dollar_typemap); + Replaceall(dtypemap, "$TYPEMAP", "$typemap"); + Swig_error(Getfile(s), Getline(s), "Likely recursive $typemap calls containing %s. Use -debug-tmsearch to debug.\n", dtypemap); + Delete(dtypemap); } + syntax_error = 0; } + Delete(vars); } - Replace(s, tmp, "<embedded typemap>", DOH_REPLACE_ANY); - Delete(vars); - Delete(tmp); Delete(l); } + + if (syntax_error) { + String *dtypemap = NewString(dollar_typemap); + Replaceall(dtypemap, "$TYPEMAP", "$typemap"); + Swig_error(Getfile(s), Getline(s), "Syntax error in: %s\n", dtypemap); + Delete(dtypemap); + } + Replace(s, dollar_typemap, "<error in embedded typemap>", DOH_REPLACE_ANY); + Delete(dollar_typemap); } } /* ----------------------------------------------------------------------------- * Swig_typemap_debug() + * + * Display all typemaps * ----------------------------------------------------------------------------- */ void Swig_typemap_debug() { int ts; + int nesting_level = 2; Printf(stdout, "---[ typemaps ]--------------------------------------------------------------\n"); ts = tm_scope; while (ts >= 0) { Printf(stdout, "::: scope %d\n\n", ts); - Printf(stdout, "%s\n", typemaps[ts]); + Swig_print(typemaps[ts], nesting_level); ts--; } Printf(stdout, "-----------------------------------------------------------------------------\n"); } + + +/* ----------------------------------------------------------------------------- + * Swig_typemap_search_debug_set() + * + * Turn on typemap searching debug display + * ----------------------------------------------------------------------------- */ + +void Swig_typemap_search_debug_set(void) { + typemap_search_debug = 1; +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_used_debug_set() + * + * Turn on typemaps used debug display + * ----------------------------------------------------------------------------- */ + +void Swig_typemap_used_debug_set(void) { + typemaps_used_debug = 1; +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_register_debug_set() + * + * Turn on typemaps used debug display + * ----------------------------------------------------------------------------- */ + +void Swig_typemap_register_debug_set(void) { + typemap_register_debug = 1; +} + diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c index 2732e2fd5..b8ecf6e6a 100644 --- a/Source/Swig/typeobj.c +++ b/Source/Swig/typeobj.c @@ -50,6 +50,9 @@ char cvsroot_typeobj_c[] = "$Id$"; * 'q(str).' = Qualifier (such as const or volatile) (const, volatile) * 'm(qual).' = Pointer to member (qual::*) * + * The complete type representation for varargs is: + * 'v(...)' + * * The encoding follows the order that you might describe a type in words. * For example "p.a(200).int" is "A pointer to array of int's" and * "p.q(const).char" is "a pointer to a const char". @@ -114,7 +117,7 @@ char cvsroot_typeobj_c[] = "$Id$"; * ----------------------------------------------------------------------------- */ #ifdef NEW -SwigType *NewSwigType(const String_or_char *initial) { +SwigType *NewSwigType(const_String_or_char_ptr initial) { return NewString(initial); } @@ -177,6 +180,9 @@ SwigType *SwigType_del_element(SwigType *t) { * SwigType_pop() * * Pop one type element off the type. + * Example: t in: q(const).p.Integer + * t out: p.Integer + * result: q(const). * ----------------------------------------------------------------------------- */ SwigType *SwigType_pop(SwigType *t) { @@ -204,7 +210,7 @@ SwigType *SwigType_pop(SwigType *t) { * Returns the parameter of an operator as a string * ----------------------------------------------------------------------------- */ -String *SwigType_parm(SwigType *t) { +String *SwigType_parm(const SwigType *t) { char *start, *c; int nparens = 0; @@ -356,7 +362,7 @@ SwigType *SwigType_del_pointer(SwigType *t) { return t; } -int SwigType_ispointer(SwigType *t) { +int SwigType_ispointer(const SwigType *t) { char *c; if (!t) return 0; @@ -398,7 +404,7 @@ SwigType *SwigType_del_reference(SwigType *t) { return t; } -int SwigType_isreference(SwigType *t) { +int SwigType_isreference(const SwigType *t) { char *c; if (!t) return 0; @@ -423,7 +429,7 @@ int SwigType_isreference(SwigType *t) { * stored in exactly the same way as "q(const volatile)". * ----------------------------------------------------------------------------- */ -SwigType *SwigType_add_qualifier(SwigType *t, const String_or_char *qual) { +SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual) { char temp[256], newq[256]; int sz, added = 0; char *q, *cqual; @@ -488,7 +494,7 @@ SwigType *SwigType_del_qualifier(SwigType *t) { return t; } -int SwigType_isqualifier(SwigType *t) { +int SwigType_isqualifier(const SwigType *t) { char *c; if (!t) return 0; @@ -503,7 +509,7 @@ int SwigType_isqualifier(SwigType *t) { * Function Pointers * ----------------------------------------------------------------------------- */ -int SwigType_isfunctionpointer(SwigType *t) { +int SwigType_isfunctionpointer(const SwigType *t) { char *c; if (!t) return 0; @@ -541,7 +547,7 @@ SwigType *SwigType_functionpointer_decompose(SwigType *t) { * Add, remove, and test for C++ pointer to members. * ----------------------------------------------------------------------------- */ -SwigType *SwigType_add_memberpointer(SwigType *t, const String_or_char *name) { +SwigType *SwigType_add_memberpointer(SwigType *t, const_String_or_char_ptr name) { String *temp = NewStringf("m(%s).", name); Insert(t, 0, temp); Delete(temp); @@ -556,7 +562,7 @@ SwigType *SwigType_del_memberpointer(SwigType *t) { return t; } -int SwigType_ismemberpointer(SwigType *t) { +int SwigType_ismemberpointer(const SwigType *t) { char *c; if (!t) return 0; @@ -583,7 +589,7 @@ int SwigType_ismemberpointer(SwigType *t) { * SwigType_pop_arrays() - Remove all arrays * ----------------------------------------------------------------------------- */ -SwigType *SwigType_add_array(SwigType *t, const String_or_char *size) { +SwigType *SwigType_add_array(SwigType *t, const_String_or_char_ptr size) { char temp[512]; strcpy(temp, "a("); strcat(temp, Char(size)); @@ -600,7 +606,7 @@ SwigType *SwigType_del_array(SwigType *t) { return t; } -int SwigType_isarray(SwigType *t) { +int SwigType_isarray(const SwigType *t) { char *c; if (!t) return 0; @@ -616,7 +622,7 @@ int SwigType_isarray(SwigType *t) { * Determine if the type is a 1D array type that is treated as a pointer within SWIG * eg Foo[], Foo[3] return true, but Foo[3][3], Foo*[], Foo*[3], Foo**[] return false */ -int SwigType_prefix_is_simple_1D_array(SwigType *t) { +int SwigType_prefix_is_simple_1D_array(const SwigType *t) { char *c = Char(t); if (c && (strncmp(c, "a(", 2) == 0)) { @@ -642,7 +648,7 @@ SwigType *SwigType_pop_arrays(SwigType *t) { } /* Return number of array dimensions */ -int SwigType_array_ndim(SwigType *t) { +int SwigType_array_ndim(const SwigType *t) { int ndim = 0; char *c = Char(t); @@ -655,7 +661,7 @@ int SwigType_array_ndim(SwigType *t) { } /* Get nth array dimension */ -String *SwigType_array_getdim(SwigType *t, int n) { +String *SwigType_array_getdim(const SwigType *t, int n) { char *c = Char(t); while (c && (strncmp(c, "a(", 2) == 0) && (n > 0)) { c = strchr(c, '.'); @@ -677,7 +683,7 @@ String *SwigType_array_getdim(SwigType *t, int n) { } /* Replace nth array dimension */ -void SwigType_array_setdim(SwigType *t, int n, const String_or_char *rep) { +void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep) { String *result = 0; char temp; char *start; @@ -707,7 +713,7 @@ void SwigType_array_setdim(SwigType *t, int n, const String_or_char *rep) { } /* Return base type of an array */ -SwigType *SwigType_array_type(SwigType *ty) { +SwigType *SwigType_array_type(const SwigType *ty) { SwigType *t; t = Copy(ty); while (SwigType_isarray(t)) { @@ -765,7 +771,7 @@ SwigType *SwigType_pop_function(SwigType *t) { return g; } -int SwigType_isfunction(SwigType *t) { +int SwigType_isfunction(const SwigType *t) { char *c; if (!t) { return 0; @@ -785,13 +791,15 @@ int SwigType_isfunction(SwigType *t) { return 0; } -ParmList *SwigType_function_parms(SwigType *t) { +/* Create a list of parameters from the type t, using the file_line_node Node for + * file and line numbering for the parameters */ +ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node) { List *l = SwigType_parmlist(t); Hash *p, *pp = 0, *firstp = 0; Iterator o; for (o = First(l); o.item; o = Next(o)) { - p = NewParm(o.item, 0); + p = file_line_node ? NewParm(o.item, 0, file_line_node) : NewParmWithoutFileLineInfo(o.item, 0); if (!firstp) firstp = p; if (pp) { @@ -854,11 +862,12 @@ SwigType *SwigType_add_template(SwigType *t, ParmList *parms) { * SwigType_templateprefix() * * Returns the prefix before the first template definition. + * Returns the type unmodified if not a template. * For example: * - * Foo<(p.int)>::bar - * - * returns "Foo" + * Foo<(p.int)>::bar => Foo + * r.q(const).Foo<(p.int)>::bar => r.q(const).Foo + * Foo => Foo * ----------------------------------------------------------------------------- */ String *SwigType_templateprefix(const SwigType *t) { @@ -900,6 +909,51 @@ String *SwigType_templatesuffix(const SwigType *t) { } /* ----------------------------------------------------------------------------- + * SwigType_istemplate_templateprefix() + * + * Combines SwigType_istemplate and SwigType_templateprefix efficiently into one function. + * Returns the prefix before the first template definition. + * Returns NULL if not a template. + * For example: + * + * Foo<(p.int)>::bar => Foo + * r.q(const).Foo<(p.int)>::bar => r.q(const).Foo + * Foo => NULL + * ----------------------------------------------------------------------------- */ + +String *SwigType_istemplate_templateprefix(const SwigType *t) { + const char *s = Char(t); + const char *c = strstr(s, "<("); + return c ? NewStringWithSize(s, c - s) : 0; +} + +/* ----------------------------------------------------------------------------- + * SwigType_istemplate_only_templateprefix() + * + * Similar to SwigType_istemplate_templateprefix() but only returns the template + * prefix if the type is just the template and not a subtype/symbol within the template. + * Returns NULL if not a template or is a template with a symbol within the template. + * For example: + * + * Foo<(p.int)> => Foo + * Foo<(p.int)>::bar => NULL + * r.q(const).Foo<(p.int)> => r.q(const).Foo + * r.q(const).Foo<(p.int)>::bar => NULL + * Foo => NULL + * ----------------------------------------------------------------------------- */ + +String *SwigType_istemplate_only_templateprefix(const SwigType *t) { + int len = Len(t); + const char *s = Char(t); + if (len >= 4 && strcmp(s + len - 2, ")>") == 0) { + const char *c = strstr(s, "<("); + return c ? NewStringWithSize(s, c - s) : 0; + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- * SwigType_templateargs() * * Returns the template arguments @@ -1066,7 +1120,7 @@ String *SwigType_prefix(const SwigType *t) { * Strip all qualifiers from a type and return a new type * ----------------------------------------------------------------------------- */ -SwigType *SwigType_strip_qualifiers(SwigType *t) { +SwigType *SwigType_strip_qualifiers(const SwigType *t) { static Hash *memoize_stripped = 0; SwigType *r; List *l; @@ -1097,3 +1151,62 @@ SwigType *SwigType_strip_qualifiers(SwigType *t) { } return r; } + +/* ----------------------------------------------------------------------------- + * SwigType_strip_single_qualifier() + * + * If the type contains a qualifier, strip one qualifier and return a new type. + * The left most qualifier is stripped first (when viewed as C source code) but + * this is the equivalent to the right most qualifier using SwigType notation. + * Example: + * r.q(const).p.q(const).int => r.q(const).p.int + * r.q(const).p.int => r.p.int + * r.p.int => r.p.int + * ----------------------------------------------------------------------------- */ + +SwigType *SwigType_strip_single_qualifier(const SwigType *t) { + static Hash *memoize_stripped = 0; + SwigType *r = 0; + List *l; + int numitems; + + if (!memoize_stripped) + memoize_stripped = NewHash(); + r = Getattr(memoize_stripped, t); + if (r) + return Copy(r); + + l = SwigType_split(t); + + numitems = Len(l); + if (numitems >= 2) { + int item; + /* iterate backwards from last but one item */ + for (item = numitems - 2; item >= 0; --item) { + String *subtype = Getitem(l, item); + if (SwigType_isqualifier(subtype)) { + Iterator it; + Delitem(l, item); + r = NewStringEmpty(); + for (it = First(l); it.item; it = Next(it)) { + Append(r, it.item); + } + break; + } + } + } + if (!r) + r = Copy(t); + + Delete(l); + { + String *key, *value; + key = Copy(t); + value = Copy(r); + Setattr(memoize_stripped, key, value); + Delete(key); + Delete(value); + } + return r; +} + diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c index 90df2ebd1..a6b23a225 100644 --- a/Source/Swig/typesys.c +++ b/Source/Swig/typesys.c @@ -79,7 +79,7 @@ char cvsroot_typesys_c[] = "$Id$"; * * class Bar : public Foo { * void blah(Integer x); - * } + * }; * * The argument type of Bar::blah will be set to Foo::Integer. * @@ -107,12 +107,12 @@ static Typetab *global_scope = 0; /* The global scope static Hash *scopes = 0; /* Hash table containing fully qualified scopes */ /* Performance optimization */ -#define SWIG_TYPEDEF_RESOLVE_CACHE +#define SWIG_TYPEDEF_RESOLVE_CACHE static Hash *typedef_resolve_cache = 0; static Hash *typedef_all_cache = 0; static Hash *typedef_qualified_cache = 0; -static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix); +static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix); /* common attribute keys, to avoid calling find_key all the times */ @@ -167,7 +167,7 @@ void SwigType_typesystem_init() { * already defined. * ----------------------------------------------------------------------------- */ -int SwigType_typedef(SwigType *type, String_or_char *name) { +int SwigType_typedef(const SwigType *type, const_String_or_char_ptr name) { if (Getattr(current_typetab, name)) return -1; /* Already defined */ if (Strcmp(type, name) == 0) { /* Can't typedef a name to itself */ @@ -197,7 +197,7 @@ int SwigType_typedef(SwigType *type, String_or_char *name) { * Defines a class in the current scope. * ----------------------------------------------------------------------------- */ -int SwigType_typedef_class(String_or_char *name) { +int SwigType_typedef_class(const_String_or_char_ptr name) { String *cname; /* Printf(stdout,"class : '%s'\n", name); */ if (Getattr(current_typetab, name)) @@ -236,7 +236,7 @@ String *SwigType_scope_name(Typetab *ttab) { * Creates a new scope * ----------------------------------------------------------------------------- */ -void SwigType_new_scope(const String_or_char *name) { +void SwigType_new_scope(const_String_or_char_ptr name) { Typetab *s; Hash *ttab; String *qname; @@ -389,12 +389,13 @@ void SwigType_attach_symtab(Symtab *sym) { * Debugging function for printing out current scope * ----------------------------------------------------------------------------- */ -void SwigType_print_scope(Typetab *t) { +void SwigType_print_scope(void) { Hash *ttab; Iterator i, j; + Printf(stdout, "SCOPES start =======================================\n"); for (i = First(scopes); i.key; i = Next(i)) { - t = i.item; + Printf(stdout, "-------------------------------------------------------------\n"); ttab = Getattr(i.item, "typetab"); Printf(stdout, "Type scope '%s' (%x)\n", i.key, i.item); @@ -407,19 +408,22 @@ void SwigType_print_scope(Typetab *t) { } } } - Printf(stdout, "-------------------------------------------------------------\n"); for (j = First(ttab); j.key; j = Next(j)) { Printf(stdout, "%40s -> %s\n", j.key, j.item); } } + Printf(stdout, "SCOPES finish =======================================\n"); } -static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix) { +static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix) { Typetab *ss; + Typetab *s_orig = s; String *nnameprefix = 0; static int check_parent = 1; - /* Printf(stdout,"find_scope: %x(%s) '%s'\n", s, Getattr(s,"name"), nameprefix); */ + if (Getmark(s)) + return 0; + Setmark(s, 1); if (SwigType_istemplate(nameprefix)) { nnameprefix = SwigType_typedef_resolve_all(nameprefix); @@ -444,6 +448,7 @@ static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix) { if (s) { if (nnameprefix) Delete(nnameprefix); + Setmark(s_orig, 0); return s; } if (!s) { @@ -463,6 +468,7 @@ static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix) { if (s) { if (nnameprefix) Delete(nnameprefix); + Setmark(s_orig, 0); return s; } } @@ -474,6 +480,7 @@ static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix) { } if (nnameprefix) Delete(nnameprefix); + Setmark(s_orig, 0); return 0; } @@ -533,6 +540,53 @@ static SwigType *_typedef_resolve(Typetab *s, String *base, int look_parent) { return type; } +/* ----------------------------------------------------------------------------- + * template_parameters_resolve() + * + * For use with templates only. The template parameters are resolved. If none + * of the parameters can be resolved, zero is returned. + * ----------------------------------------------------------------------------- */ + +static String *template_parameters_resolve(const String *base) { + List *tparms; + String *suffix; + String *type; + int i, sz; + int rep = 0; + type = SwigType_templateprefix(base); + suffix = SwigType_templatesuffix(base); + Append(type, "<("); + tparms = SwigType_parmlist(base); + sz = Len(tparms); + for (i = 0; i < sz; i++) { + SwigType *tpr; + SwigType *tp = Getitem(tparms, i); + if (!rep) { + tpr = SwigType_typedef_resolve(tp); + } else { + tpr = 0; + } + if (tpr) { + Append(type, tpr); + Delete(tpr); + rep = 1; + } else { + Append(type, tp); + } + if ((i + 1) < sz) + Append(type, ","); + } + Append(type, ")>"); + Append(type, suffix); + Delete(suffix); + Delete(tparms); + if (!rep) { + Delete(type); + type = 0; + } + return type; +} + static SwigType *typedef_resolve(Typetab *s, String *base) { return _typedef_resolve(s, base, 1); } @@ -543,7 +597,7 @@ static SwigType *typedef_resolve(Typetab *s, String *base) { * ----------------------------------------------------------------------------- */ /* #define SWIG_DEBUG */ -SwigType *SwigType_typedef_resolve(SwigType *t) { +SwigType *SwigType_typedef_resolve(const SwigType *t) { String *base; String *type = 0; String *r = 0; @@ -553,12 +607,6 @@ SwigType *SwigType_typedef_resolve(SwigType *t) { String *nameprefix = 0; int newtype = 0; - /* - if (!noscope) { - noscope = NewStringEmpty(); - } - */ - resolved_scope = 0; #ifdef SWIG_TYPEDEF_RESOLVE_CACHE @@ -602,6 +650,9 @@ SwigType *SwigType_typedef_resolve(SwigType *t) { #endif if (nameprefix) { /* Name had a prefix on it. See if we can locate the proper scope for it */ + String *rnameprefix = template_parameters_resolve(nameprefix); + nameprefix = rnameprefix ? Copy(rnameprefix) : nameprefix; + Delete(rnameprefix); s = SwigType_find_scope(s, nameprefix); /* Couldn't locate a scope for the type. */ @@ -668,42 +719,8 @@ SwigType *SwigType_typedef_resolve(SwigType *t) { template arguments one by one to see if they can be resolved. */ if (!type && SwigType_istemplate(base)) { - List *tparms; - String *suffix; - int i, sz; - int rep = 0; - type = SwigType_templateprefix(base); newtype = 1; - suffix = SwigType_templatesuffix(base); - Append(type, "<("); - tparms = SwigType_parmlist(base); - sz = Len(tparms); - for (i = 0; i < sz; i++) { - SwigType *tpr; - SwigType *tp = Getitem(tparms, i); - if (!rep) { - tpr = SwigType_typedef_resolve(tp); - } else { - tpr = 0; - } - if (tpr) { - Append(type, tpr); - Delete(tpr); - rep = 1; - } else { - Append(type, tp); - } - if ((i + 1) < sz) - Append(type, ","); - } - Append(type, ")>"); - Append(type, suffix); - Delete(suffix); - Delete(tparms); - if (!rep) { - Delete(type); - type = 0; - } + type = template_parameters_resolve(base); } if (namebase) Delete(namebase); @@ -806,9 +823,10 @@ return_result: * Fully resolve a type down to its most basic datatype * ----------------------------------------------------------------------------- */ -SwigType *SwigType_typedef_resolve_all(SwigType *t) { +SwigType *SwigType_typedef_resolve_all(const SwigType *t) { SwigType *n; SwigType *r; + int count = 0; /* Check to see if the typedef resolve has been done before by checking the cache */ if (!typedef_all_cache) { @@ -824,6 +842,10 @@ SwigType *SwigType_typedef_resolve_all(SwigType *t) { while ((n = SwigType_typedef_resolve(r))) { Delete(r); r = n; + if (++count >= 512) { + Swig_error(Getfile(t), Getline(t), "Recursive typedef detected resolving '%s' to '%s' to '%s' and so on...\n", SwigType_str(t, 0), SwigType_str(SwigType_typedef_resolve(t), 0), SwigType_str(SwigType_typedef_resolve(SwigType_typedef_resolve(t)), 0)); + break; + } } /* Add the typedef to the cache for next time it is looked up */ @@ -844,17 +866,15 @@ SwigType *SwigType_typedef_resolve_all(SwigType *t) { * * Given a type declaration, this function tries to fully qualify it according to * typedef scope rules. + * If the unary scope operator (::) is used as a prefix to the type to denote global + * scope, it is left in place. * ----------------------------------------------------------------------------- */ -SwigType *SwigType_typedef_qualified(SwigType *t) { +SwigType *SwigType_typedef_qualified(const SwigType *t) { List *elements; String *result; int i, len; - if (strncmp(Char(t), "::", 2) == 0) { - return Copy(t); - } - if (!typedef_qualified_cache) typedef_qualified_cache = NewHash(); result = Getattr(typedef_qualified_cache, t); @@ -1002,10 +1022,6 @@ SwigType *SwigType_typedef_qualified(SwigType *t) { Delete(qprefix); Delete(parms); } - if (strncmp(Char(e), "::", 2) == 0) { - Delitem(e, 0); - Delitem(e, 0); - } Append(result, e); Delete(ty); } else if (SwigType_isfunction(e)) { @@ -1055,7 +1071,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t) { * Checks a typename to see if it is a typedef. * ----------------------------------------------------------------------------- */ -int SwigType_istypedef(SwigType *t) { +int SwigType_istypedef(const SwigType *t) { String *type; type = SwigType_typedef_resolve(t); @@ -1075,7 +1091,7 @@ int SwigType_istypedef(SwigType *t) { * Name is a qualified name like A::B. * ----------------------------------------------------------------------------- */ -int SwigType_typedef_using(String_or_char *name) { +int SwigType_typedef_using(const_String_or_char_ptr name) { String *base; String *td; String *prefix; @@ -1123,11 +1139,13 @@ int SwigType_typedef_using(String_or_char *name) { /* Figure out the scope the using directive refers to */ { prefix = Swig_scopename_prefix(name); - s = SwigType_find_scope(current_scope, prefix); - if (s) { - Hash *ttab = Getattr(s, "typetab"); - if (!Getattr(ttab, base) && defined_name) { - Setattr(ttab, base, defined_name); + if (prefix) { + s = SwigType_find_scope(current_scope, prefix); + if (s) { + Hash *ttab = Getattr(s, "typetab"); + if (!Getattr(ttab, base) && defined_name) { + Setattr(ttab, base, defined_name); + } } } } @@ -1154,7 +1172,7 @@ int SwigType_typedef_using(String_or_char *name) { * a class. * ----------------------------------------------------------------------------- */ -int SwigType_isclass(SwigType *t) { +int SwigType_isclass(const SwigType *t) { SwigType *qty, *qtys; int isclass = 0; @@ -1169,9 +1187,9 @@ int SwigType_isclass(SwigType *t) { isclass = 1; } /* Hmmm. Not a class. If a template, it might be uninstantiated */ - if (!isclass && SwigType_istemplate(qtys)) { - String *tp = SwigType_templateprefix(qtys); - if (Strcmp(tp, t) != 0) { + if (!isclass) { + String *tp = SwigType_istemplate_templateprefix(qtys); + if (tp && Strcmp(tp, t) != 0) { isclass = SwigType_isclass(tp); } Delete(tp); @@ -1190,7 +1208,7 @@ int SwigType_isclass(SwigType *t) { * everything is based on typemaps. * ----------------------------------------------------------------------------- */ -int SwigType_type(SwigType *t) { +int SwigType_type(const SwigType *t) { char *c; /* Check for the obvious stuff */ c = Char(t); @@ -1299,7 +1317,7 @@ int SwigType_type(SwigType *t) { * %feature("valuewrapper"). * ----------------------------------------------------------------------------- */ -SwigType *SwigType_alttype(SwigType *t, int local_tmap) { +SwigType *SwigType_alttype(const SwigType *t, int local_tmap) { Node *n; SwigType *w = 0; int use_wrapper = 0; @@ -1417,9 +1435,9 @@ static Hash *r_clientdata = 0; /* Hash mapping resolved types to client data static Hash *r_mangleddata = 0; /* Hash mapping mangled types to client data */ static Hash *r_remembered = 0; /* Hash of types we remembered already */ -static void (*r_tracefunc) (SwigType *t, String *mangled, String *clientdata) = 0; +static void (*r_tracefunc) (const SwigType *t, String *mangled, String *clientdata) = 0; -void SwigType_remember_mangleddata(String *mangled, const String_or_char *clientdata) { +void SwigType_remember_mangleddata(String *mangled, const_String_or_char_ptr clientdata) { if (!r_mangleddata) { r_mangleddata = NewHash(); } @@ -1427,7 +1445,7 @@ void SwigType_remember_mangleddata(String *mangled, const String_or_char *client } -void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata) { +void SwigType_remember_clientdata(const SwigType *t, const_String_or_char_ptr clientdata) { String *mt; SwigType *lt; Hash *h; @@ -1540,12 +1558,12 @@ void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata) } } -void SwigType_remember(SwigType *ty) { +void SwigType_remember(const SwigType *ty) { SwigType_remember_clientdata(ty, 0); } -void (*SwigType_remember_trace(void (*tf) (SwigType *, String *, String *))) (SwigType *, String *, String *) { - void (*o) (SwigType *, String *, String *) = r_tracefunc; +void (*SwigType_remember_trace(void (*tf) (const SwigType *, String *, String *))) (const SwigType *, String *, String *) { + void (*o) (const SwigType *, String *, String *) = r_tracefunc; r_tracefunc = tf; return o; } @@ -1717,7 +1735,7 @@ void SwigType_inherit(String *derived, String *base, String *cast, String *conve * Determines if a t1 is a subtype of t2, ie, is t1 derived from t2 * ----------------------------------------------------------------------------- */ -int SwigType_issubtype(SwigType *t1, SwigType *t2) { +int SwigType_issubtype(const SwigType *t1, const SwigType *t2) { SwigType *ft1, *ft2; String *b1, *b2; Hash *h; @@ -1777,7 +1795,7 @@ void SwigType_inherit_equiv(File *out) { continue; } - /* This type has subclasses. We now need to walk through these subtypes and generate pointer converion functions */ + /* This type has subclasses. We now need to walk through these subtypes and generate pointer conversion functions */ rh = Getattr(r_resolved, rk.key); rlist = NewList(); diff --git a/Source/Swig/warn.c b/Source/Swig/warn.c deleted file mode 100644 index b01815354..000000000 --- a/Source/Swig/warn.c +++ /dev/null @@ -1,38 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. - * - * warn.c - * - * SWIG warning framework. This was added to warn developers about - * deprecated APIs and other features. - * ----------------------------------------------------------------------------- */ - -char cvsroot_warn_c[] = "$Id$"; - -#include "swig.h" - -static Hash *warnings = 0; - -/* ----------------------------------------------------------------------------- - * Swig_warn() - * - * Issue a warning - * ----------------------------------------------------------------------------- */ - -void Swig_warn(const char *filename, int line, const char *msg) { - String *key; - if (!warnings) { - warnings = NewHash(); - } - key = NewStringf("%s:%d", filename, line); - if (!Getattr(warnings, key)) { - Printf(stderr, "swig-dev warning:%s:%d:%s\n", filename, line, msg); - Setattr(warnings, key, key); - } - Delete(key); -} diff --git a/Source/Swig/wrapfunc.c b/Source/Swig/wrapfunc.c index 2e18474aa..2c9f7c86a 100644 --- a/Source/Swig/wrapfunc.c +++ b/Source/Swig/wrapfunc.c @@ -27,7 +27,7 @@ static int Max_line_size = 128; * Create a new wrapper function object. * ----------------------------------------------------------------------------- */ -Wrapper *NewWrapper() { +Wrapper *NewWrapper(void) { Wrapper *w; w = (Wrapper *) malloc(sizeof(Wrapper)); w->localh = NewHash(); @@ -410,7 +410,7 @@ void Wrapper_print(Wrapper *w, File *f) { * present (which may or may not be okay to the caller). * ----------------------------------------------------------------------------- */ -int Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) { +int Wrapper_add_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl) { /* See if the local has already been declared */ if (Getattr(w->localh, name)) { return -1; @@ -428,7 +428,7 @@ int Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_ch * to manually construct the 'decl' string before calling. * ----------------------------------------------------------------------------- */ -int Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...) { +int Wrapper_add_localv(Wrapper *w, const_String_or_char_ptr name, ...) { va_list ap; int ret; String *decl; @@ -455,7 +455,7 @@ int Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...) { * Check to see if a local name has already been declared * ----------------------------------------------------------------------------- */ -int Wrapper_check_local(Wrapper *w, const String_or_char *name) { +int Wrapper_check_local(Wrapper *w, const_String_or_char_ptr name) { if (Getattr(w->localh, name)) { return 1; } @@ -469,7 +469,7 @@ int Wrapper_check_local(Wrapper *w, const String_or_char *name) { * used. Returns the name that was actually selected. * ----------------------------------------------------------------------------- */ -char *Wrapper_new_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) { +char *Wrapper_new_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl) { int i; String *nname = NewString(name); String *ndecl = NewString(decl); @@ -500,7 +500,7 @@ char *Wrapper_new_local(Wrapper *w, const String_or_char *name, const String_or_ * to manually construct the 'decl' string before calling. * ----------------------------------------------------------------------------- */ -char *Wrapper_new_localv(Wrapper *w, const String_or_char *name, ...) { +char *Wrapper_new_localv(Wrapper *w, const_String_or_char_ptr name, ...) { va_list ap; char *ret; String *decl; |