diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2013-01-28 07:01:37 +0000 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2013-01-28 07:01:37 +0000 |
commit | e805d5f9256cdafab06f9958cc48c51083d860da (patch) | |
tree | d5ab9ab1f58d3c291a49529a2696798f46de70fa /Source/Swig | |
parent | 34d46510cfbcecdeb4fd1a98a2957ecfe5a2db6a (diff) | |
parent | 38d454a1022f65d76e292fd13d699da896c0c2cf (diff) | |
download | swig-e805d5f9256cdafab06f9958cc48c51083d860da.tar.gz |
Merge branch 'master' into gsoc2009-matevz
parser.y still to be fixed up
Conflicts:
Doc/Devel/engineering.html
Examples/Makefile.in
Lib/allegrocl/allegrocl.swg
Lib/csharp/csharp.swg
Lib/csharp/enums.swg
Lib/csharp/enumsimple.swg
Lib/csharp/enumtypesafe.swg
Lib/java/java.swg
Lib/python/pydocs.swg
Lib/r/rtype.swg
Source/Include/swigwarn.h
Source/Modules/octave.cxx
Source/Modules/python.cxx
Source/Modules/ruby.cxx
Source/Swig/scanner.c
Source/Swig/stype.c
Source/Swig/swig.h
configure.ac
Diffstat (limited to 'Source/Swig')
-rw-r--r-- | Source/Swig/cwrap.c | 200 | ||||
-rw-r--r-- | Source/Swig/deprecate.c | 4 | ||||
-rw-r--r-- | Source/Swig/error.c | 37 | ||||
-rw-r--r-- | Source/Swig/fragment.c | 6 | ||||
-rw-r--r-- | Source/Swig/getopt.c | 2 | ||||
-rw-r--r-- | Source/Swig/include.c | 83 | ||||
-rw-r--r-- | Source/Swig/misc.c | 263 | ||||
-rw-r--r-- | Source/Swig/naming.c | 214 | ||||
-rw-r--r-- | Source/Swig/parms.c | 24 | ||||
-rw-r--r-- | Source/Swig/scanner.c | 178 | ||||
-rw-r--r-- | Source/Swig/stype.c | 261 | ||||
-rw-r--r-- | Source/Swig/swig.h | 107 | ||||
-rw-r--r-- | Source/Swig/swigfile.h | 9 | ||||
-rw-r--r-- | Source/Swig/swigparm.h | 3 | ||||
-rw-r--r-- | Source/Swig/swigscan.h | 2 | ||||
-rw-r--r-- | Source/Swig/symbol.c | 108 | ||||
-rw-r--r-- | Source/Swig/tree.c | 18 | ||||
-rw-r--r-- | Source/Swig/typemap.c | 211 | ||||
-rw-r--r-- | Source/Swig/typeobj.c | 119 | ||||
-rw-r--r-- | Source/Swig/typesys.c | 173 | ||||
-rw-r--r-- | Source/Swig/wrapfunc.c | 2 |
21 files changed, 1356 insertions, 668 deletions
diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index 1ec790167..de93d84c0 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -12,11 +12,10 @@ * the naming of local variables, calling conventions, and so forth. * ----------------------------------------------------------------------------- */ -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 +27,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 * ----------------------------------------------------------------------------- */ @@ -229,7 +249,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); @@ -316,12 +336,13 @@ String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or break; case T_RVALUE_REFERENCE: { + String *const_lvalue_str; String *lstr = SwigType_lstr(t, 0); SwigType *tt = Copy(t); SwigType_del_rvalue_reference(tt); SwigType_add_qualifier(tt, "const"); SwigType_add_reference(tt); - String *const_lvalue_str = SwigType_rcaststr(tt, 0); + const_lvalue_str = SwigType_rcaststr(tt, 0); Printf(fcall, "%s = (%s) &%s", name, lstr, const_lvalue_str); @@ -603,7 +624,7 @@ String *Swig_cppconstructor_director_call(const_String_or_char_ptr name, ParmLis } /* ----------------------------------------------------------------------------- - * Swig_rflag_search() + * recursive_flag_search() * * This function searches for the class attribute 'attr' in the class * 'n' or recursively in its bases. @@ -624,7 +645,7 @@ String *Swig_cppconstructor_director_call(const_String_or_char_ptr name, ParmLis * ----------------------------------------------------------------------------- */ /* #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)) { @@ -638,7 +659,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); @@ -657,12 +678,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); @@ -676,12 +696,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); @@ -699,7 +718,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; @@ -721,7 +741,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 { @@ -795,6 +816,46 @@ String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String } /* ----------------------------------------------------------------------------- + * Swig_replace_special_variables() + * + * Replaces special variables with a value from the supplied node + * ----------------------------------------------------------------------------- */ +void Swig_replace_special_variables(Node *n, Node *parentnode, String *code) { + Node *parentclass = parentnode; + String *overloaded = Getattr(n, "sym:overloaded"); + Replaceall(code, "$name", Getattr(n, "name")); + Replaceall(code, "$symname", Getattr(n, "sym:name")); + Replaceall(code, "$wrapname", Getattr(n, "wrap:name")); + Replaceall(code, "$overname", overloaded ? Char(Getattr(n, "sym:overname")) : ""); + + if (Strstr(code, "$decl")) { + String *decl = Swig_name_decl(n); + Replaceall(code, "$decl", decl); + Delete(decl); + } + if (Strstr(code, "$fulldecl")) { + String *fulldecl = Swig_name_fulldecl(n); + Replaceall(code, "$fulldecl", fulldecl); + Delete(fulldecl); + } + + if (parentclass && !Equal(nodeType(parentclass), "class")) + parentclass = 0; + if (Strstr(code, "$parentclasssymname")) { + String *parentclasssymname = 0; + if (parentclass) + parentclasssymname = Getattr(parentclass, "sym:name"); + Replaceall(code, "$parentclasssymname", parentclasssymname ? parentclasssymname : ""); + } + if (Strstr(code, "$parentclassname")) { + String *parentclassname = 0; + if (parentclass) + parentclassname = Getattr(parentclass, "name"); + Replaceall(code, "$parentclassname", parentclassname ? parentclassname : ""); + } +} + +/* ----------------------------------------------------------------------------- * extension_code() * * Generates an extension function (a function defined in %extend) @@ -802,14 +863,17 @@ String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String * return_type function_name(parms) code * * ----------------------------------------------------------------------------- */ -static String *extension_code(const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) { +static String *extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) { String *parms_str = cplusplus ? ParmList_str_defaultargs(parms) : ParmList_str(parms); String *sig = NewStringf("%s(%s)", function_name, parms_str); String *rt_sig = SwigType_str(return_type, sig); String *body = NewStringf("SWIGINTERN %s", rt_sig); Printv(body, code, "\n", NIL); - if (self) - Replaceall(body, "$self", self); + if (Strstr(body, "$")) { + Swig_replace_special_variables(n, parentNode(parentNode(n)), body); + if (self) + Replaceall(body, "$self", self); + } Delete(parms_str); Delete(sig); Delete(rt_sig); @@ -826,7 +890,7 @@ static String *extension_code(const String *function_name, ParmList *parms, Swig * * ----------------------------------------------------------------------------- */ int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) { - String *body = extension_code(function_name, parms, return_type, code, cplusplus, self); + String *body = extension_code(n, function_name, parms, return_type, code, cplusplus, self); Setattr(n, "wrap:code", body); Delete(body); return SWIG_OK; @@ -840,15 +904,37 @@ int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parm * ----------------------------------------------------------------------------- */ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int flags, SwigType *director_type, int is_director) { - String *name, *qualifier; + String *name; ParmList *parms; SwigType *type; Parm *p; String *self = 0; + int is_smart_pointer_overload = 0; + String *qualifier = Getattr(n, "qualifier"); + String *directorScope = NewString(nspace); - /* If smart pointer, change self dereferencing */ + Replace(directorScope, NSPACE_SEPARATOR, "_", DOH_REPLACE_ANY); + + /* 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 */ @@ -856,7 +942,6 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas flags &= ~(CWRAP_EXTEND); name = Getattr(n, "name"); - qualifier = Getattr(n, "qualifier"); parms = CopyParmList(nonvoid_parms(Getattr(n, "parms"))); type = NewString(classname); @@ -911,7 +996,10 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas /* If protected access (can only be if a director method) then call the extra public accessor method (language module must provide this) */ String *explicit_qualifier_tmp = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname")); explicitcall_name = NewStringf("%sSwigPublic", name); - explicit_qualifier = NewStringf("SwigDirector_%s", explicit_qualifier_tmp); + if (Len(directorScope) > 0) + explicit_qualifier = NewStringf("SwigDirector_%s_%s", directorScope, explicit_qualifier_tmp); + else + explicit_qualifier = NewStringf("SwigDirector_%s", explicit_qualifier_tmp); Delete(explicit_qualifier_tmp); } else { explicit_qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname")); @@ -919,7 +1007,7 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas } 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")); @@ -932,7 +1020,7 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas /* 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); @@ -978,10 +1066,18 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas 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); @@ -1005,12 +1101,12 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas } } 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); @@ -1023,6 +1119,7 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas Delete(p); Delete(self); Delete(parms); + Delete(directorScope); return SWIG_OK; } @@ -1072,10 +1169,11 @@ int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String Parm *p; ParmList *directorparms; SwigType *type; - Node *classNode; int use_director; + String *directorScope = NewString(nspace); + + Replace(directorScope, NSPACE_SEPARATOR, "_", DOH_REPLACE_ANY); - classNode = Swig_methodclass(n); use_director = Swig_directorclass(n); parms = CopyParmList(nonvoid_parms(Getattr(n, "parms"))); @@ -1122,7 +1220,7 @@ int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String } 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); @@ -1133,14 +1231,19 @@ int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String /* if a C++ director class exists, create it rather than the original class */ if (use_director) { Node *parent = Swig_methodclass(n); - int abstract = Getattr(parent, "abstract") != 0; + int abstract = Getattr(parent, "abstracts") != 0; String *name = Getattr(parent, "sym:name"); - String *directorname = NewStringf("SwigDirector_%s", name); + String *directorname; String *action = NewStringEmpty(); String *tmp_none_comparison = Copy(none_comparison); String *director_call; String *nodirector_call; + if (Len(directorScope) > 0) + directorname = NewStringf("SwigDirector_%s_%s", directorScope, name); + else + directorname = NewStringf("SwigDirector_%s", name); + Replaceall(tmp_none_comparison, "$arg", "arg1"); director_call = Swig_cppconstructor_director_call(directorname, directorparms); @@ -1153,7 +1256,7 @@ int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String * 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 { @@ -1168,11 +1271,11 @@ int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String 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); } @@ -1182,14 +1285,14 @@ int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String 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); @@ -1201,6 +1304,7 @@ int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String if (directorparms != parms) Delete(directorparms); Delete(parms); + Delete(directorScope); return SWIG_OK; } @@ -1367,6 +1471,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)->"); } @@ -1400,7 +1508,7 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { 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); @@ -1410,7 +1518,7 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { 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); @@ -1501,14 +1609,14 @@ int Swig_VargetToFunction(Node *n, int flags) { 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..08dc06a66 100644 --- a/Source/Swig/deprecate.c +++ b/Source/Swig/deprecate.c @@ -13,8 +13,6 @@ * that the function and/or API needs to be changed in some future release. * ----------------------------------------------------------------------------- */ -char cvsroot_deprecate_c[] = "$Id: parms.c 9630 2007-01-02 21:17:19Z beazley $"; - #include "swig.h" /* --------------------------------------------------------------------- @@ -77,7 +75,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 fa82ad8d9..2c93cfb21 100644 --- a/Source/Swig/error.c +++ b/Source/Swig/error.c @@ -12,8 +12,6 @@ * error messages. * ----------------------------------------------------------------------------- */ -char cvsroot_error_c[] = "$Id$"; - #include "swig.h" #include <stdarg.h> #include <ctype.h> @@ -285,6 +283,41 @@ static String *format_filename(const_String_or_char_ptr 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. diff --git a/Source/Swig/fragment.c b/Source/Swig/fragment.c index 896461b30..15f701ae4 100644 --- a/Source/Swig/fragment.c +++ b/Source/Swig/fragment.c @@ -16,8 +16,6 @@ * wrapper code and to generate cleaner wrapper files. * ----------------------------------------------------------------------------- */ -char cvsroot_fragment_c[] = "$Id$"; - #include "swig.h" #include "swigwarn.h" @@ -60,6 +58,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 +142,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 f6f196bfd..74076a5f0 100644 --- a/Source/Swig/getopt.c +++ b/Source/Swig/getopt.c @@ -20,8 +20,6 @@ * Should have cleaner error handling in general. * ----------------------------------------------------------------------------- */ -char cvsroot_getopt_c[] = "$Id$"; - #include "swig.h" static char **args; diff --git a/Source/Swig/include.c b/Source/Swig/include.c index baae44bb8..13afb21ae 100644 --- a/Source/Swig/include.c +++ b/Source/Swig/include.c @@ -13,14 +13,13 @@ * are provided. * ----------------------------------------------------------------------------- */ -char cvsroot_include_c[] = "$Id$"; - #include "swig.h" 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) { @@ -173,6 +172,9 @@ static FILE *Swig_open_file(const_String_or_char_ptr name, int sysfile, int use_ cname = Char(name); filename = NewString(cname); assert(filename); + if (file_debug) { + Printf(stdout, " Open: %s\n", filename); + } f = fopen(Char(filename), "r"); if (!f && use_include_path) { spath = Swig_search_path_any(sysfile); @@ -221,6 +223,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') { @@ -311,58 +315,41 @@ File *Swig_filebyname(const_String_or_char_ptr filename) { } /* ----------------------------------------------------------------------------- - * Swig_file_suffix() + * Swig_file_extension() * - * Returns the suffix of a file + * Returns the extension of a file * ----------------------------------------------------------------------------- */ -char *Swig_file_suffix(const_String_or_char_ptr filename) { - char *d; - char *c = Char(filename); - int len = Len(filename); - if (strlen(c)) { - d = c + len - 1; - while (d != c) { - if (*d == '.') - return d; - d--; - } - return c + len; - } - return c; +String *Swig_file_extension(const_String_or_char_ptr filename) { + String *name = Swig_file_filename(filename); + const char *c = strrchr(Char(name), '.'); + String *extension = c ? NewString(c) : NewString(""); + Delete(name); + return extension; } /* ----------------------------------------------------------------------------- * Swig_file_basename() * - * Returns the filename with no suffix attached. + * Returns the filename with the extension removed. * ----------------------------------------------------------------------------- */ -char *Swig_file_basename(const_String_or_char_ptr filename) { - static char tmp[1024]; - char *c; - strcpy(tmp, Char(filename)); - c = Swig_file_suffix(tmp); - *c = 0; - return tmp; +String *Swig_file_basename(const_String_or_char_ptr filename) { + String *extension = Swig_file_extension(filename); + String *basename = NewStringWithSize(filename, Len(filename) - Len(extension)); + Delete(extension); + return basename; } /* ----------------------------------------------------------------------------- * Swig_file_filename() * - * Return the file with any leading path stripped off + * Return the file name with any leading path stripped off * ----------------------------------------------------------------------------- */ -char *Swig_file_filename(const_String_or_char_ptr filename) { - static char tmp[1024]; +String *Swig_file_filename(const_String_or_char_ptr filename) { const char *delim = SWIG_FILE_DELIMITER; - char *c; - - strcpy(tmp, Char(filename)); - c = strrchr(tmp, *delim); - if (c) - return c + 1; - else - return tmp; + const char *c = strrchr(Char(filename), *delim); + return c ? NewString(c + 1) : NewString(filename); } /* ----------------------------------------------------------------------------- @@ -370,17 +357,15 @@ char *Swig_file_filename(const_String_or_char_ptr filename) { * * Return the name of the directory associated with a file * ----------------------------------------------------------------------------- */ -char *Swig_file_dirname(const_String_or_char_ptr filename) { - static char tmp[1024]; +String *Swig_file_dirname(const_String_or_char_ptr filename) { const char *delim = SWIG_FILE_DELIMITER; - char *c; - strcpy(tmp, Char(filename)); - if (!strstr(tmp, delim)) { - return ""; - } - c = tmp + strlen(tmp) - 1; - while (*c != *delim) - c--; - *(++c) = 0; - return tmp; + const char *c = strrchr(Char(filename), *delim); + return c ? NewStringWithSize(filename, c - Char(filename) + 1) : NewString(""); +} + +/* + * Swig_file_debug() + */ +void Swig_file_debug_set() { + file_debug = 1; } diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index f0a9155eb..05dd0c480 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -11,8 +11,6 @@ * Miscellaneous functions that don't really fit anywhere else. * ----------------------------------------------------------------------------- */ -char cvsroot_misc_c[] = "$Id$"; - #include "swig.h" #include <errno.h> #include <ctype.h> @@ -167,44 +165,36 @@ static int is_directory(String *directory) { * 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. + * basedirectory can be empty to indicate current directory but not NULL. * ----------------------------------------------------------------------------- */ String *Swig_new_subdirectory(String *basedirectory, String *subdirectory) { String *error = 0; - struct stat st; - int current_directory = basedirectory ? (Len(basedirectory) == 0 ? 1 : 0) : 0; + int current_directory = Len(basedirectory) == 0; if (current_directory || is_directory(basedirectory)) { Iterator it; - String *dir = basedirectory ? NewString(basedirectory) : NewString(""); + String *dir = NewString(basedirectory); List *subdirs = Split(subdirectory, SWIG_FILE_DELIMITER[0], INT_MAX); for (it = First(subdirs); it.item; it = Next(it)) { - int statdir; + int result; 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)); + result = _mkdir(Char(dir)); #else - int result = mkdir(Char(dir), 0777); + result = mkdir(Char(dir), 0777); #endif - Printf(dir, SWIG_FILE_DELIMITER); - if (result != 0 && errno != EEXIST) { - error = NewStringf("Cannot create directory %s", dir); - break; - } + if (result != 0 && errno != EEXIST) { + error = NewStringf("Cannot create directory %s: %s", dir, strerror(errno)); + break; } + if (!is_directory(dir)) { + error = NewStringf("Cannot create directory %s: it may already exist but not be a directory", dir); + break; + } + Printf(dir, SWIG_FILE_DELIMITER); } } 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); @@ -220,7 +210,14 @@ String *Swig_new_subdirectory(String *basedirectory, String *subdirectory) { * ----------------------------------------------------------------------------- */ void Swig_filename_correct(String *filename) { - (void)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); @@ -232,6 +229,9 @@ void Swig_filename_correct(String *filename) { /* 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); } /* ----------------------------------------------------------------------------- @@ -242,13 +242,11 @@ void Swig_filename_correct(String *filename) { 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 '/' */ - /* remove all double '\' in case any already present */ - while (Replaceall(adjusted_filename, "\\\\", "\\")) { - } Replaceall(adjusted_filename, "\\", "\\\\"); #endif - return adjusted_filename; + return adjusted_filename; } /* ----------------------------------------------------------------------------- @@ -527,7 +525,6 @@ String *Swig_string_schemify(String *s) { return ns; } - /* ----------------------------------------------------------------------------- * Swig_string_typecode() * @@ -873,8 +870,8 @@ String *Swig_scopename_last(const String *s) { while (*c) { if ((*c == ':') && (*(c + 1) == ':')) { - cc = c; c += 2; + cc = c; } else { if (*c == '<') { int level = 1; @@ -891,7 +888,7 @@ String *Swig_scopename_last(const String *s) { } } } - return NewString(cc + 2); + return NewString(cc); } /* ----------------------------------------------------------------------------- @@ -1108,112 +1105,132 @@ String *Swig_string_strip(String *s) { } -/* ----------------------------------------------------------------------------- - * Swig_string_rxspencer() - * - * Executes a regexp substitution via the RxSpencer library. For example: - * - * Printf(stderr,"gsl%(rxspencer:[GSL_.*_][@1])s","GSL_Hello_") -> gslHello - * ----------------------------------------------------------------------------- */ -#if defined(HAVE_RXSPENCER) -#include <sys/types.h> -#include <rxspencer/regex.h> -#define USE_RXSPENCER -#endif +#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); -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; + while (*p) { + /* Copy part without substitutions */ + const char *q = strchr(p, '\\'); + if (!q) { + Write(result, p, strlen(p)); + break; } - if (*ce == pe) { - if (!lb) { - end = 1; - --ce; + 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); + } } else { - --lb; + 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); } } - ++ce; } - return end ? ce : 0; + + 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; -#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); - } - } - } - regfree(&compiled); - } + 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); } } - if (!res) - res = NewStringEmpty(); - return res; + + 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); } -#endif +String *Swig_pcre_version(void) { + return NewStringf("PCRE not used"); +} + +#endif /* ----------------------------------------------------------------------------- * Swig_init() @@ -1233,9 +1250,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 07e42f2d4..a4bff35af 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -20,8 +20,6 @@ * %v - variable name is substituted * ----------------------------------------------------------------------------- */ -char cvsroot_naming_c[] = "$Id$"; - #include "swig.h" #include "cparse.h" #include <ctype.h> @@ -565,6 +563,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; @@ -573,6 +572,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); @@ -580,13 +582,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)) { @@ -599,8 +608,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); } /* ----------------------------------------------------------------------------- @@ -863,13 +881,16 @@ List *Swig_name_rename_list() { int Swig_need_name_warning(Node *n) { int need = 1; /* - we don't use name warnings for: + We don't use name warnings for: - class forwards, no symbol is generated at the target language. - template declarations, only for real instances using %template(name). - - typedefs, they have no effect at the target language. + - typedefs, have no effect at the target language. + - using declarations and using directives, have no effect at the target language. */ if (checkAttribute(n, "nodeType", "classforward")) { need = 0; + } else if (checkAttribute(n, "nodeType", "using")) { + need = 0; } else if (checkAttribute(n, "storage", "typedef")) { need = 0; } else if (Getattr(n, "hidden")) { @@ -893,11 +914,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"); @@ -956,8 +980,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) @@ -1000,7 +1033,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) { @@ -1017,6 +1050,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; @@ -1061,25 +1096,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); @@ -1114,7 +1145,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)) @@ -1155,36 +1186,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) @@ -1227,17 +1272,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); @@ -1277,7 +1316,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); @@ -1294,10 +1333,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) { @@ -1393,7 +1439,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 */ @@ -1604,19 +1650,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) @@ -1642,10 +1689,36 @@ String *Swig_name_decl(Node *n) { Printf(qname, "%s::", qualifier); Printf(qname, "%s", SwigType_str(name, 0)); - decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : ""); - 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; @@ -1655,7 +1728,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 283a2f5c2..bec1e63fa 100644 --- a/Source/Swig/parms.c +++ b/Source/Swig/parms.c @@ -11,21 +11,19 @@ * Parameter list class. * ----------------------------------------------------------------------------- */ -char cvsroot_parms_c[] = "$Id$"; - #include "swig.h" /* ------------------------------------------------------------------------ * NewParm() * * Create a new parameter from datatype 'type' and name 'name' copying - * the file and line number from the Node file_line_node. + * the file and line number from the Node from_node. * ------------------------------------------------------------------------ */ -Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *file_line_node) { +Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *from_node) { Parm *p = NewParmWithoutFileLineInfo(type, name); - Setfile(p, Getfile(file_line_node)); - Setline(p, Getline(file_line_node)); + Setfile(p, Getfile(from_node)); + Setline(p, Getline(from_node)); return p; } @@ -49,6 +47,20 @@ Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name) } /* ------------------------------------------------------------------------ + * NewParmNode() + * + * Create a new parameter from datatype 'type' and name and symbol table as + * well as file and line number from the 'from_node'. + * The resulting Parm will be similar to a Node used for typemap lookups. + * ------------------------------------------------------------------------ */ + +Parm *NewParmNode(SwigType *type, Node *from_node) { + Parm *p = NewParm(type, Getattr(from_node, "name"), from_node); + Setattr(p, "sym:symtab", Getattr(from_node, "sym:symtab")); + return p; +} + +/* ------------------------------------------------------------------------ * CopyParm() * ------------------------------------------------------------------------ */ diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c index 6389cc988..7e9f45c9e 100644 --- a/Source/Swig/scanner.c +++ b/Source/Swig/scanner.c @@ -14,12 +14,11 @@ * to easily construct yacc-compatible scanners. * ----------------------------------------------------------------------------- */ -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; @@ -39,6 +38,13 @@ struct Scanner { List *brackets; /* Current level of < > brackets on each level */ }; +typedef struct Locator { + String *filename; + int line_number; + struct Locator *next; +} Locator; +static int follow_locators = 0; + void Scanner_push_brackets(Scanner*); void Scanner_clear_brackets(Scanner*); @@ -61,6 +67,7 @@ Scanner *NewScanner(void) { s->text = NewStringEmpty(); s->str = 0; s->error = 0; + s->error_line = 0; s->freeze_line = 0; s->brackets = NewList(); Scanner_push_brackets(s); @@ -104,6 +111,12 @@ void Scanner_clear(Scanner * s) { s->nexttoken = -1; s->start_line = 0; s->yylen = 0; + /* Should these be cleared too? + s->idstart; + s->file; + s->error_line; + s->freeze_line; + */ } /* ----------------------------------------------------------------------------- @@ -209,10 +222,8 @@ static char nextchar(Scanner * s) { if (Len(s->scanobjs) == 0) return 0; s->str = Getitem(s->scanobjs, 0); - if (s->str) { - s->line = Getline(s->str); - DohIncref(s->str); - } + s->line = Getline(s->str); + DohIncref(s->str); } if ((nc == '\n') && (!s->freeze_line)) s->line++; @@ -238,8 +249,7 @@ static void set_error(Scanner *s, int line, const_String_or_char_ptr msg) { * Returns error information (if any) * ----------------------------------------------------------------------------- */ -String * -Scanner_errmsg(Scanner *s) { +String *Scanner_errmsg(Scanner *s) { return s->error; } @@ -249,13 +259,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; } @@ -343,7 +352,7 @@ static void retract(Scanner * s, int n) { if (str[l - 1] == '\n') { if (!s->freeze_line) s->line--; } - Seek(s->str, -1, SEEK_CUR); + (void)Seek(s->str, -1, SEEK_CUR); Delitem(s->text, DOH_END); } } @@ -1414,10 +1423,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)); @@ -1426,6 +1434,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) { @@ -1459,17 +1468,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 == '\"') @@ -1489,10 +1506,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; } @@ -1503,8 +1553,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; + (void)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 b63530b53..e4af7437f 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -12,8 +12,6 @@ * the form of simple strings. * ----------------------------------------------------------------------------- */ -char cvsroot_stype_c[] = "$Id$"; - #include "swig.h" #include "cparse.h" #include <ctype.h> @@ -190,7 +188,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) @@ -203,7 +201,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) @@ -216,7 +214,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; @@ -242,7 +240,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_isrvalue_reference(qt) || SwigType_isarray(qt)) { @@ -253,7 +251,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; @@ -263,7 +261,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; @@ -321,7 +319,7 @@ int SwigType_issimple(SwigType *t) { * r.q(const).enum SWIGTYPE * ----------------------------------------------------------------------------- */ -SwigType *SwigType_default_create(SwigType *ty) { +SwigType *SwigType_default_create(const SwigType *ty) { SwigType *r = 0; List *l; Iterator it; @@ -379,7 +377,7 @@ SwigType *SwigType_default_create(SwigType *ty) { * SwigType_default_create() before calling this function. * * Example deductions (matching the examples described in SwigType_default_create), - * where the the most specialized matches are highest in the list: + * where the most specialized matches are highest in the list: * * a(ANY).a(ANY).SWIGTYPE * a(ANY).a().SWIGTYPE @@ -400,7 +398,7 @@ SwigType *SwigType_default_create(SwigType *ty) { * SWIGTYPE * ----------------------------------------------------------------------------- */ -SwigType *SwigType_default_deduce(SwigType *t) { +SwigType *SwigType_default_deduce(const SwigType *t) { SwigType *r = NewStringEmpty(); List *l; Iterator it; @@ -524,9 +522,11 @@ String *SwigType_namestr(const SwigType *t) { * Create a C string representation of a datatype. * ----------------------------------------------------------------------------- */ -String *SwigType_str(SwigType *s, const_String_or_char_ptr 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; @@ -549,8 +549,14 @@ String *SwigType_str(SwigType *s, const_String_or_char_ptr 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; @@ -560,7 +566,7 @@ String *SwigType_str(SwigType *s, const_String_or_char_ptr 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, ")"); } @@ -569,14 +575,14 @@ String *SwigType_str(SwigType *s, const_String_or_char_ptr 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, ")"); } @@ -625,12 +631,12 @@ String *SwigType_str(SwigType *s, const_String_or_char_ptr 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; @@ -735,7 +741,7 @@ SwigType *SwigType_ltype(SwigType *s) { * with an equivalent assignable version. * -------------------------------------------------------------------- */ -String *SwigType_lstr(SwigType *s, const_String_or_char_ptr id) { +String *SwigType_lstr(const SwigType *s, const_String_or_char_ptr id) { String *result; SwigType *tc; @@ -752,17 +758,19 @@ String *SwigType_lstr(SwigType *s, const_String_or_char_ptr id) { * datatype printed by str(). * ----------------------------------------------------------------------------- */ -String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr 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 isfunction = 0; - int isarray = 0; result = NewStringEmpty(); @@ -798,8 +806,14 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr 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 +824,7 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr 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,25 +835,27 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr 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_isrvalue_reference(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; clear = 0; } else if (SwigType_isarray(element)) { DOH *size; @@ -854,7 +870,6 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) { Delete(size); clear = 0; } - isarray = 1; } else if (SwigType_isfunction(element)) { DOH *parms, *p; int j, plen; @@ -886,12 +901,8 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) { cast = NewStringf("(%s)", result); } if (name) { - if (!isfunction) { - if (isreference) { - if (isarray) - Clear(cast); - Append(cast, "*"); - } + if (isreference) { + Append(cast, "*"); } Append(cast, name); } @@ -907,7 +918,7 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) { * Casts a variable from the real type to the local datatype. * ----------------------------------------------------------------------------- */ -String *SwigType_lcaststr(SwigType *s, const_String_or_char_ptr name) { +String *SwigType_lcaststr(const SwigType *s, const_String_or_char_ptr name) { String *result; result = NewStringEmpty(); @@ -939,27 +950,163 @@ String *SwigType_lcaststr(SwigType *s, const_String_or_char_ptr 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); -/* keep old mangling since Java codes need it */ -String *SwigType_manglestr_default(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 + +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); @@ -1006,13 +1153,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; } - -String *SwigType_manglestr(SwigType *s) { - return SwigType_manglestr_default(s); +#endif + +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); } /* ----------------------------------------------------------------------------- @@ -1131,7 +1288,7 @@ SwigType *SwigType_remove_global_scope_prefix(const SwigType *t) { * 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 0b3edf17e..2dd027155 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -136,86 +136,83 @@ extern "C" { 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, Node *file_line_node); + 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_ptr id); - extern String *SwigType_lstr(SwigType *s, const_String_or_char_ptr id); - extern String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr id); - extern String *SwigType_lcaststr(SwigType *s, const_String_or_char_ptr 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_isrvalue_reference(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_isrvalue_reference(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_ptr decl); - extern SwigType *SwigType_strip_qualifiers(SwigType *t); - extern SwigType *SwigType_strip_single_qualifier(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 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(SwigType *t); - extern String *SwigType_default(SwigType *t); - extern SwigType *SwigType_default_create(SwigType *ty); - extern SwigType *SwigType_default_deduce(SwigType *t); + 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_remove_global_scope_prefix(const SwigType *t); - 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_alttype(const SwigType *t, int ltmap); /* --- Type-system managment --- */ extern void SwigType_typesystem_init(void); - extern int SwigType_typedef(SwigType *type, const_String_or_char_ptr name); + 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_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 void SwigType_print_scope(void); extern SwigType *SwigType_typedef_resolve(const 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 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_ptr clientdata); + 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) (SwigType *, String *, String *))) (SwigType *, String *, String *); + 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 --- */ @@ -238,6 +235,7 @@ extern "C" { 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 Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n); 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 *)); @@ -248,7 +246,7 @@ extern "C" { 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); @@ -294,6 +292,7 @@ extern int ParmList_is_compactdefargs(ParmList *p); 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); @@ -327,7 +326,7 @@ extern int ParmList_is_compactdefargs(ParmList *p); 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 int Swig_value_wrapper_mode(int mode); @@ -342,8 +341,11 @@ extern int ParmList_is_compactdefargs(ParmList *p); 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); @@ -360,6 +362,7 @@ extern int ParmList_is_compactdefargs(ParmList *p); 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); + extern void Swig_replace_special_variables(Node *n, Node *parentnode, String *code); /* --- Transformations --- */ @@ -377,6 +380,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); @@ -394,6 +398,7 @@ extern int ParmList_is_compactdefargs(ParmList *p); 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 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); @@ -416,6 +421,8 @@ extern int ParmList_is_compactdefargs(ParmList *p); 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 cdf23cddc..f12b33081 100644 --- a/Source/Swig/swigfile.h +++ b/Source/Swig/swigfile.h @@ -26,10 +26,11 @@ extern void Swig_set_push_dir(int dopush); extern int Swig_get_push_dir(void); 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 String *Swig_file_extension(const_String_or_char_ptr filename); +extern String *Swig_file_basename(const_String_or_char_ptr filename); +extern String *Swig_file_filename(const_String_or_char_ptr filename); +extern String *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/swigparm.h b/Source/Swig/swigparm.h index 70a39390e..368b4d26b 100644 --- a/Source/Swig/swigparm.h +++ b/Source/Swig/swigparm.h @@ -13,8 +13,9 @@ * ----------------------------------------------------------------------------- */ /* Individual parameters */ -extern Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *file_line_node); +extern Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *from_node); extern Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name); +extern Parm *NewParmNode(SwigType *type, Node *from_node); extern Parm *CopyParm(Parm *p); /* Parameter lists */ diff --git a/Source/Swig/swigscan.h b/Source/Swig/swigscan.h index ae2e9ea4d..017ef58d5 100644 --- a/Source/Swig/swigscan.h +++ b/Source/Swig/swigscan.h @@ -30,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 */ diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index b5e114683..e77f818de 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -11,8 +11,6 @@ * This file implements the SWIG symbol table. See details below. * ----------------------------------------------------------------------------- */ -char cvsroot_symbol_c[] = "$Id$"; - #include "swig.h" #include "swigwarn.h" #include <ctype.h> @@ -176,6 +174,8 @@ static Hash *current_symtab = 0; /* Current symbol table node */ static Hash *symtabs = 0; /* Hash of all symbol tables by fully-qualified name */ static Hash *global_scope = 0; /* Global scope */ +static int use_inherit = 1; + /* common attribute keys, to avoid calling find_key all the times */ @@ -222,7 +222,10 @@ static void symbol_print_symbols(const char *symboltabletype) { Iterator it = First(symtab); while (it.key) { String *symname = it.key; - Printf(stdout, " %s\n", symname); + Printf(stdout, " %s (%s)\n", symname, nodeType(it.item)); + /* + Printf(stdout, " %s - %p (%s)\n", symname, it.item, Getattr(it.item, "name")); + */ it = Next(it); } } @@ -460,6 +463,7 @@ Symtab *Swig_symbol_current(void) { * Swig_symbol_alias() * * Makes an alias for a symbol in the global symbol table. + * Primarily for namespace aliases such as 'namespace X = Y;'. * ----------------------------------------------------------------------------- */ void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *s) { @@ -478,7 +482,9 @@ void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *s) { /* ----------------------------------------------------------------------------- * Swig_symbol_inherit() * - * Inherit symbols from another scope. + * Inherit symbols from another scope. Primarily for C++ inheritance and + * for using directives, such as 'using namespace X;' + * but not for using declarations, such as 'using A;'. * ----------------------------------------------------------------------------- */ void Swig_symbol_inherit(Symtab *s) { @@ -532,6 +538,7 @@ void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) { if (!name) return; + if (SwigType_istemplate(name)) { String *cname = NewString(name); String *dname = Swig_symbol_template_deftype(cname, 0); @@ -542,7 +549,7 @@ void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) { Delete(cname); } #ifdef SWIG_DEBUG - Printf(stderr, "symbol_cadd %s %x\n", name, n); + Printf(stderr, "symbol_cadd %s %p\n", name, n); #endif cn = Getattr(ccurrent, name); @@ -877,7 +884,7 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) { /* Well, we made it this far. Guess we can drop the symbol in place */ Setattr(n, "sym:symtab", current_symtab); Setattr(n, "sym:name", symname); - /* Printf(stdout,"%s %x\n", Getattr(n,"sym:overname"), current_symtab); */ + /* Printf(stdout,"%s %p\n", Getattr(n,"sym:overname"), current_symtab); */ assert(!Getattr(n, "sym:overname")); overname = NewStringf("__SWIG_%d", pn); Setattr(n, "sym:overname", overname); @@ -924,11 +931,10 @@ static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (No return 0; Setmark(symtab, 1); - n = Getattr(sym, name); #ifdef SWIG_DEBUG - Printf(stderr, "symbol_look %s %x %x %s\n", name, n, symtab, Getattr(symtab, "name")); + Printf(stderr, "symbol_look %s %p %p %s\n", name, n, symtab, Getattr(symtab, "name")); #endif if (n) { @@ -960,10 +966,11 @@ static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (No Delete(dname); if (n) return n; + Setmark(symtab, 1); } inherit = Getattr(symtab, "inherit"); - if (inherit) { + if (inherit && use_inherit) { int i, len; len = Len(inherit); for (i = 0; i < len; i++) { @@ -1049,6 +1056,25 @@ static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symt Node *pn = Getattr(symtab, "parentNode"); if (pn) n = symbol_lookup_qualified(name, pn, prefix, local, checkfunc); + + /* Check inherited scopes */ + if (!n) { + List *inherit = Getattr(symtab, "inherit"); + if (inherit && use_inherit) { + int i, len; + len = Len(inherit); + for (i = 0; i < len; i++) { + Node *prefix_node = symbol_lookup(prefix, Getitem(inherit, i), checkfunc); + if (prefix_node) { + Node *prefix_symtab = Getattr(prefix_node, "symtab"); + if (prefix_symtab) { + n = symbol_lookup(name, prefix_symtab, checkfunc); + break; + } + } + } + } + } } else { n = 0; } @@ -1061,8 +1087,9 @@ static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symt * Swig_symbol_clookup() * * Look up a symbol in the symbol table. This uses the C name, not scripting - * names. Note: If we come across a using a directive, we follow it to - * to get the real node. + * names. Note: If we come across a using declaration, we follow it to + * to get the real node. Any using directives are also followed (but this is + * implemented in symbol_lookup()). * ----------------------------------------------------------------------------- */ Node *Swig_symbol_clookup(const_String_or_char_ptr name, Symtab *n) { @@ -1203,22 +1230,23 @@ Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (* /* ----------------------------------------------------------------------------- * Swig_symbol_clookup_local() + * + * Same as Swig_symbol_clookup but parent nodes are not searched, that is, just + * this symbol table is searched. * ----------------------------------------------------------------------------- */ Node *Swig_symbol_clookup_local(const_String_or_char_ptr name, Symtab *n) { - Hash *h, *hsym; + 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)) { @@ -1256,19 +1284,17 @@ Node *Swig_symbol_clookup_local(const_String_or_char_ptr name, Symtab *n) { * ----------------------------------------------------------------------------- */ Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *)) { - Hash *h, *hsym; + 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)) { @@ -1301,6 +1327,20 @@ Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, return s; } +/* ----------------------------------------------------------------------------- + * Swig_symbol_clookup_no_inherit() + * + * Symbol lookup like Swig_symbol_clookup but does not follow using declarations. + * ----------------------------------------------------------------------------- */ + +Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n) { + Node *s = 0; + assert(use_inherit==1); + use_inherit = 0; + s = Swig_symbol_clookup(name, n); + use_inherit = 1; + return s; +} /* ----------------------------------------------------------------------------- * Swig_symbol_cscope() @@ -1411,7 +1451,7 @@ String *Swig_symbol_qualified(Node *n) { if (!symtab) return NewStringEmpty(); #ifdef SWIG_DEBUG - Printf(stderr, "symbol_qscope %s %x %s\n", Getattr(n, "name"), symtab, Getattr(symtab, "name")); + Printf(stderr, "symbol_qscope %s %p %s\n", Getattr(n, "name"), symtab, Getattr(symtab, "name")); #endif return Swig_symbol_qualifiedscopename(symtab); } @@ -1427,14 +1467,14 @@ Node *Swig_symbol_isoverloaded(Node *n) { } /* ----------------------------------------------------------------------------- - * Swig_symbol_type_qualify() + * symbol_template_qualify() * - * Create a fully qualified type name + * Internal function to create a fully qualified type name for templates * ----------------------------------------------------------------------------- */ /* This cache produces problems with OSS, don't active it */ /* #define SWIG_TEMPLATE_QUALIFY_CACHE */ -static SwigType *Swig_symbol_template_qualify(const SwigType *e, Symtab *st) { +static SwigType *symbol_template_qualify(const SwigType *e, Symtab *st) { String *tprefix, *tsuffix; SwigType *qprefix; List *targs; @@ -1499,10 +1539,17 @@ static SwigType *Swig_symbol_template_qualify(const SwigType *e, Symtab *st) { } -static int no_constructor(Node *n) { +static int symbol_no_constructor(Node *n) { return !Checkattr(n, "nodeType", "constructor"); } +/* ----------------------------------------------------------------------------- + * Swig_symbol_type_qualify() + * + * Create a fully qualified type name + * Note: Does not resolve a constructor if passed in as the 'type'. + * ----------------------------------------------------------------------------- */ + SwigType *Swig_symbol_type_qualify(const SwigType *t, Symtab *st) { List *elements; String *result = NewStringEmpty(); @@ -1519,13 +1566,14 @@ SwigType *Swig_symbol_type_qualify(const SwigType *t, Symtab *st) { for (i = 0; i < len; i++) { String *e = Getitem(elements, i); if (SwigType_issimple(e)) { - Node *n = Swig_symbol_clookup_check(e, st, no_constructor); + /* Note: the unary scope operator (::) is being removed from the template parameters here. */ + Node *n = Swig_symbol_clookup_check(e, st, symbol_no_constructor); if (n) { String *name = Getattr(n, "name"); Clear(e); Append(e, name); #ifdef SWIG_DEBUG - Printf(stderr, "symbol_qual_ei %d %s %s %x\n", i, name, e, st); + Printf(stderr, "symbol_qual_ei %d %s %s %p\n", i, name, e, st); #endif if (!Swig_scopename_check(name)) { String *qname = Swig_symbol_qualified(n); @@ -1534,12 +1582,12 @@ SwigType *Swig_symbol_type_qualify(const SwigType *t, Symtab *st) { Insert(e, 0, qname); } #ifdef SWIG_DEBUG - Printf(stderr, "symbol_qual_sc %d %s %s %x\n", i, qname, e, st); + Printf(stderr, "symbol_qual_sc %d %s %s %p\n", i, qname, e, st); #endif Delete(qname); } } else if (SwigType_istemplate(e)) { - SwigType *ty = Swig_symbol_template_qualify(e, st); + SwigType *ty = symbol_template_qualify(e, st); Clear(e); Append(e, ty); Delete(ty); @@ -1572,7 +1620,7 @@ SwigType *Swig_symbol_type_qualify(const SwigType *t, Symtab *st) { } Delete(elements); #ifdef SWIG_DEBUG - Printf(stderr, "symbol_qualify %s %s %x %s\n", t, result, st, st ? Getattr(st, "name") : 0); + Printf(stderr, "symbol_qualify %s %s %p %s\n", t, result, st, st ? Getattr(st, "name") : 0); #endif return result; @@ -1642,7 +1690,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; @@ -1749,8 +1797,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 == ':') || (*c == '~' && first_char) || (isdigit((int) *c) && !first_char)) { Putc(*c, id); have_id = 1; } else { @@ -1763,6 +1812,7 @@ String *Swig_symbol_string_qualify(String *s, Symtab *st) { } Putc(*c, r); } + first_char = (*c == ':'); c++; } if (have_id) { diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c index c76ac958e..784d3ab84 100644 --- a/Source/Swig/tree.c +++ b/Source/Swig/tree.c @@ -12,8 +12,6 @@ * parse trees. * ----------------------------------------------------------------------------- */ -char cvsroot_tree_c[] = "$Id$"; - #include "swig.h" #include <stdarg.h> #include <assert.h> @@ -77,12 +75,12 @@ void Swig_print_node(Node *obj) { if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) || (Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) { /* Do nothing */ - } else if (Cmp(k, "parms") == 0) { + } else if (Cmp(k, "parms") == 0 || Cmp(k, "wrap:parms") == 0) { print_indent(2); - Printf(stdout, "%-12s - %s\n", k, ParmList_protostr(Getattr(obj, k))); + Printf(stdout, "%-12s - %s\n", k, ParmList_str_defaultargs(Getattr(obj, k))); } else { DOH *o; - char *trunc = ""; + const char *trunc = ""; print_indent(2); if (DohIsString(Getattr(obj, k))) { o = Str(Getattr(obj, k)); @@ -92,7 +90,7 @@ void Swig_print_node(Node *obj) { Printf(stdout, "%-12s - \"%(escape)-0.80s%s\"\n", k, o, trunc); Delete(o); } else { - Printf(stdout, "%-12s - 0x%x\n", k, Getattr(obj, k)); + Printf(stdout, "%-12s - %p\n", k, Getattr(obj, k)); } } ki = Next(ki); @@ -291,10 +289,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 +335,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 5c8735e46..981b0b436 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -11,8 +11,6 @@ * A somewhat generalized implementation of SWIG1.1 typemaps. * ----------------------------------------------------------------------------- */ -char cvsroot_typemap_c[] = "$Id$"; - #include "swig.h" #include "cparse.h" #include <ctype.h> @@ -23,6 +21,7 @@ char cvsroot_typemap_c[] = "$Id$"; 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); @@ -88,22 +87,34 @@ static Hash *get_typemap(int tm_scope, const SwigType *type) { return tm; } -static void set_typemap(int tm_scope, const SwigType *type, Hash *tm) { +static void set_typemap(int tm_scope, const SwigType *type, Hash **tmhash) { SwigType *hashtype = 0; + Hash *new_tm = 0; + assert(*tmhash == 0); if (SwigType_istemplate(type)) { - String *ty = Swig_symbol_template_deftype(type, 0); + 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); + *tmhash = Getattr(typemaps[tm_scope], hashtype); + Delete(rty); Delete(tyq); Delete(ty); } else { hashtype = SwigType_remove_global_scope_prefix(type); } + if (!*tmhash) { + /* this type has not been seen before even after resolving template parameter types */ + new_tm = NewHash(); + *tmhash = new_tm; + } + /* note that the unary scope operator (::) prefix indicating global scope has been removed from the type */ - Setattr(typemaps[tm_scope], hashtype, tm); + Setattr(typemaps[tm_scope], hashtype, *tmhash); Delete(hashtype); + Delete(new_tm); } @@ -189,9 +200,14 @@ static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *par String *tm_method; SwigType *type; String *pname; - if (!parms) return; + + 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 */ @@ -202,9 +218,7 @@ static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *par /* See if this type has been seen before */ tm = get_typemap(tm_scope, type); if (!tm) { - tm = NewHash(); - set_typemap(tm_scope, type, tm); - Delete(tm); + set_typemap(tm_scope, type, &tm); } if (pname) { /* See if parameter has been seen before */ @@ -468,9 +482,7 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) { type = Getattr(lastdp, "type"); tm = get_typemap(tm_scope, type); if (!tm) { - tm = NewHash(); - set_typemap(tm_scope, type, tm); - Delete(tm); + set_typemap(tm_scope, type, &tm); } name = Getattr(lastdp, "name"); if (name) { @@ -728,8 +740,8 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type goto ret_result; { - /* Look for the type reduced to just the template prefix */ - SwigType *template_prefix = SwigType_istemplate_templateprefix(ctype); + /* 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); @@ -963,7 +975,7 @@ static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, Swi { 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; @@ -1132,21 +1144,20 @@ static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, Swi /* 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); @@ -1155,8 +1166,9 @@ static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, Swi 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) @@ -1176,7 +1188,7 @@ static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, Swi /* 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; } @@ -1252,16 +1264,15 @@ 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, print that warning message. + * attribute, return the warning message (special variables will need expanding + * before displaying the warning). * ----------------------------------------------------------------------------- */ -static void typemap_warn(const_String_or_char_ptr tmap_method, Parm *p) { +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); - if (w) { - Swig_warning(0, Getfile(p), Getline(p), "%s\n", w); - } + return w ? Copy(w) : 0; } /* ----------------------------------------------------------------------------- @@ -1293,9 +1304,11 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No SwigType *mtype = 0; String *pname; String *qpname = 0; + String *noscope_pname = 0; Hash *tm = 0; String *s = 0; String *sdef = 0; + String *warning = 0; ParmList *locals; ParmList *kw; char temp[256]; @@ -1306,32 +1319,50 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No 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(tmap_method, "newfree") == 0) { - sdef = Swig_ref_call(node, lname); - } + SwigType *matchtype = 0; type = Getattr(node, "type"); if (!type) return sdef; - pname = Getattr(node, "name"); + /* 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 (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); + } - if (pname && node && checkAttribute(node, "kind", "function")) { - /* - For functions, add on a qualified name search, for example - struct Foo { - int *foo(int bar) -> Foo::foo - }; + pname = Getattr(node, "name"); + noscope_pname = Copy(pname); + + if (pname && Getattr(node, "sym:symtab")) { + /* Add on a qualified name search for any symbol in the symbol table, for example: + * struct Foo { + * int *foo(int bar) -> Foo::foo + * }; + * Note that if node is a parameter (Parm *) then there will be no symbol table attached to the Parm *. */ - Symtab *st = Getattr(node, "sym:symtab"); - String *qsn = st ? Swig_symbol_string_qualify(pname, st) : 0; - if (qsn && Len(qsn) && !Equal(qsn, pname)) - qpname = qsn; + String *qsn; + if (Swig_scopename_check(pname)) { + /* sometimes pname is qualified, so we remove all the scope for the lookup */ + Delete(noscope_pname); + noscope_pname = Swig_scopename_last(pname); + /* + Printf(stdout, "Removed scope: %s => %s\n", pname, noscope_pname); + */ + } + qsn = Swig_symbol_qualified(node); + if (qsn && Len(qsn)) { + qpname = NewStringf("%s::%s", qsn, noscope_pname); + Delete(qsn); + } } - tm = typemap_search(tmap_method, type, pname, qpname, &mtype, node); + tm = typemap_search(tmap_method, type, noscope_pname, qpname, &mtype, node); if (typemap_search_debug) debug_search_result_display(tm); if (typemaps_used_debug && tm) { @@ -1344,6 +1375,8 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No Delete(qpname); qpname = 0; + Delete(noscope_pname); + noscope_pname = 0; if (!tm) return sdef; @@ -1382,6 +1415,7 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No * 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 @@ -1390,8 +1424,8 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No * 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) { @@ -1434,14 +1468,11 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No 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 optimal attribute usage in\n", Swig_name_decl(node)); - Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(s), Getline(s), "the out typemap.\n"); + 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 (locals && f) { @@ -1458,9 +1489,8 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No 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, typemap_method_name(tmap_method), s); if (locals) { @@ -1475,7 +1505,15 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No } /* Print warnings, if any */ - typemap_warn(cmethod, node); + 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 */ { @@ -1597,6 +1635,7 @@ void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *p int nmatch = 0; int i; String *s; + String *warning = 0; ParmList *locals; int argnum = 0; char temp[256]; @@ -1700,23 +1739,15 @@ void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *p 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", cmethod); @@ -1731,10 +1762,6 @@ void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *p replace_embedded_typemap(s, firstp, f, tm); - /* Replace the argument number */ - sprintf(temp, "%d", argnum); - Replace(s, "$argnum", temp, DOH_REPLACE_ANY); - /* Attach attributes to object */ #ifdef SWIG_DEBUG Printf(stdout, "attach: %s %s %s\n", Getattr(firstp, "name"), typemap_method_name(tmap_method), s); @@ -1754,8 +1781,23 @@ void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *p /* Attach kwargs */ 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 */ - typemap_warn(tmap_method, 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 */ typemap_emit_code_fragments(tmap_method, firstp); @@ -2013,12 +2055,13 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper 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"); @@ -2045,3 +2088,13 @@ 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 ffb802089..89283abfa 100644 --- a/Source/Swig/typeobj.c +++ b/Source/Swig/typeobj.c @@ -14,8 +14,6 @@ * like typedef, namespaces, etc. * ----------------------------------------------------------------------------- */ -char cvsroot_typeobj_c[] = "$Id$"; - #include "swig.h" #include <ctype.h> @@ -214,7 +212,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; @@ -366,7 +364,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; @@ -408,7 +406,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; @@ -443,7 +441,7 @@ SwigType *SwigType_del_rvalue_reference(SwigType *t) { return t; } -int SwigType_isrvalue_reference(SwigType *t) { +int SwigType_isrvalue_reference(const SwigType *t) { char *c; if (!t) return 0; @@ -469,7 +467,7 @@ int SwigType_isrvalue_reference(SwigType *t) { * ----------------------------------------------------------------------------- */ SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual) { - char temp[256], newq[256]; + String *newq; int sz, added = 0; char *q, *cqual; @@ -477,8 +475,9 @@ SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual) { cqual = Char(qual); if (!(strncmp(c, "q(", 2) == 0)) { - sprintf(temp, "q(%s).", cqual); + String *temp = NewStringf("q(%s).", cqual); Insert(t, 0, temp); + Delete(temp); return t; } @@ -488,40 +487,40 @@ SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual) { order */ sz = element_size(c); - strncpy(temp, c, (sz < 256) ? sz : 256); - if (strstr(temp, cqual)) { + if (strstr(c, cqual)) { /* Qualifier already added */ return t; } /* Add the qualifier to the existing list. */ - strcpy(newq, "q("); - q = temp + 2; + newq = NewString("q("); + q = c + 2; q = strtok(q, " )."); while (q) { if (strcmp(cqual, q) < 0) { /* New qualifier is less that current qualifier. We need to insert it */ - strcat(newq, cqual); - strcat(newq, " "); - strcat(newq, q); + Append(newq, cqual); + Append(newq, " "); + Append(newq, q); added = 1; } else { - strcat(newq, q); + Append(newq, q); } q = strtok(NULL, " )."); if (q) { - strcat(newq, " "); + Append(newq, " "); } } if (!added) { - strcat(newq, " "); - strcat(newq, cqual); + Append(newq, " "); + Append(newq, cqual); } - strcat(newq, ")."); + Append(newq, ")."); Delslice(t, 0, sz); Insert(t, 0, newq); + Delete(newq); return t; } @@ -533,7 +532,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; @@ -548,7 +547,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; @@ -601,7 +600,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; @@ -629,11 +628,11 @@ int SwigType_ismemberpointer(SwigType *t) { * ----------------------------------------------------------------------------- */ SwigType *SwigType_add_array(SwigType *t, const_String_or_char_ptr size) { - char temp[512]; - strcpy(temp, "a("); - strcat(temp, Char(size)); - strcat(temp, ")."); + String *temp = NewString("a("); + Append(temp, size); + Append(temp, ")."); Insert(t, 0, temp); + Delete(temp); return t; } @@ -645,7 +644,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; @@ -661,13 +660,13 @@ 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)) { c = strchr(c, '.'); - c++; - return (*c == 0); + if (c) + return (*(++c) == 0); } return 0; } @@ -687,25 +686,29 @@ 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); while (c && (strncmp(c, "a(", 2) == 0)) { c = strchr(c, '.'); - c++; - ndim++; + if (c) { + c++; + ndim++; + } } return ndim; } /* 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, '.'); - c++; - n--; + if (c) { + c++; + n--; + } } if (n == 0) { String *dim = SwigType_parm(c); @@ -734,8 +737,10 @@ void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep) { while (c && (strncmp(c, "a(", 2) == 0) && (n > 0)) { c = strchr(c, '.'); - c++; - n--; + if (c) { + c++; + n--; + } } if (n == 0) { temp = *c; @@ -752,7 +757,7 @@ void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr 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)) { @@ -810,7 +815,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; @@ -832,7 +837,7 @@ int SwigType_isfunction(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(SwigType *t, Node *file_line_node) { +ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node) { List *l = SwigType_parmlist(t); Hash *p, *pp = 0, *firstp = 0; Iterator o; @@ -967,6 +972,32 @@ String *SwigType_istemplate_templateprefix(const SwigType *t) { } /* ----------------------------------------------------------------------------- + * 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 @@ -1133,7 +1164,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; @@ -1177,7 +1208,7 @@ SwigType *SwigType_strip_qualifiers(SwigType *t) { * r.p.int => r.p.int * ----------------------------------------------------------------------------- */ -SwigType *SwigType_strip_single_qualifier(SwigType *t) { +SwigType *SwigType_strip_single_qualifier(const SwigType *t) { static Hash *memoize_stripped = 0; SwigType *r = 0; List *l; diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c index 2de9bcb1d..781554fa2 100644 --- a/Source/Swig/typesys.c +++ b/Source/Swig/typesys.c @@ -14,8 +14,6 @@ * run-time type checker is also handled here. * ----------------------------------------------------------------------------- */ -char cvsroot_typesys_c[] = "$Id$"; - #include "swig.h" #include "cparse.h" @@ -107,12 +105,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 +165,7 @@ void SwigType_typesystem_init() { * already defined. * ----------------------------------------------------------------------------- */ -int SwigType_typedef(SwigType *type, const_String_or_char_ptr 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 */ @@ -297,7 +295,7 @@ void SwigType_inherit_scope(Typetab *scope) { void SwigType_scope_alias(String *aliasname, Typetab *ttab) { String *q; - /* Printf(stdout,"alias: '%s' '%x'\n", aliasname, ttab); */ + /* Printf(stdout,"alias: '%s' '%p'\n", aliasname, ttab); */ q = SwigType_scope_name(current_scope); if (Len(q)) { Append(q, "::"); @@ -389,37 +387,41 @@ 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); + Printf(stdout, "Type scope '%s' (%p)\n", i.key, i.item); { List *inherit = Getattr(i.item, "inherit"); if (inherit) { Iterator j; for (j = First(inherit); j.item; j = Next(j)) { - Printf(stdout, " Inherits from '%s' (%x)\n", Getattr(j.item, "qname"), j.item); + Printf(stdout, " Inherits from '%s' (%p)\n", Getattr(j.item, "qname"), j.item); } } } - 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 +446,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 +466,7 @@ static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix) { if (s) { if (nnameprefix) Delete(nnameprefix); + Setmark(s_orig, 0); return s; } } @@ -474,6 +478,7 @@ static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix) { } if (nnameprefix) Delete(nnameprefix); + Setmark(s_orig, 0); return 0; } @@ -533,6 +538,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); } @@ -553,12 +605,6 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) { String *nameprefix = 0; int newtype = 0; - /* - if (!noscope) { - noscope = NewStringEmpty(); - } - */ - resolved_scope = 0; #ifdef SWIG_TYPEDEF_RESOLVE_CACHE @@ -602,6 +648,9 @@ SwigType *SwigType_typedef_resolve(const 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. */ @@ -617,7 +666,7 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) { Printf(stdout, "namebase = '%s'\n", namebase); #endif type = typedef_resolve(s, namebase); - if (type) { + if (type && resolved_scope) { /* we need to look for the resolved type, this will also fix the resolved_scope if 'type' and 'namebase' are declared in different scopes */ @@ -629,7 +678,7 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) { #ifdef SWIG_DEBUG Printf(stdout, "%s type = '%s'\n", Getattr(s, "name"), type); #endif - if ((type) && (!Swig_scopename_check(type)) && resolved_scope) { + if (type && (!Swig_scopename_check(type)) && resolved_scope) { Typetab *rtab = resolved_scope; String *qname = Getattr(resolved_scope, "qname"); /* If qualified *and* the typename is defined from the resolved scope, we qualify */ @@ -668,42 +717,8 @@ SwigType *SwigType_typedef_resolve(const 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 +821,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 +840,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 */ @@ -848,7 +868,7 @@ SwigType *SwigType_typedef_resolve_all(SwigType *t) { * 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; @@ -876,7 +896,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t) { e = ty; } resolved_scope = 0; - if (typedef_resolve(current_scope, e)) { + if (typedef_resolve(current_scope, e) && resolved_scope) { /* resolved_scope contains the scope that actually resolved the symbol */ String *qname = Getattr(resolved_scope, "qname"); if (qname) { @@ -933,6 +953,10 @@ SwigType *SwigType_typedef_qualified(SwigType *t) { Parm *p; List *parms; ty = Swig_symbol_template_deftype(e, current_symtab); + /* + String *dt = Swig_symbol_template_deftype(e, current_symtab); + ty = Swig_symbol_type_qualify(dt, 0); + */ e = ty; parms = SwigType_parmlist(e); tprefix = SwigType_templateprefix(e); @@ -999,6 +1023,9 @@ SwigType *SwigType_typedef_qualified(SwigType *t) { Delete(tprefix); Delete(qprefix); Delete(parms); + /* + Delete(dt); + */ } Append(result, e); Delete(ty); @@ -1049,7 +1076,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); @@ -1092,14 +1119,14 @@ int SwigType_typedef_using(const_String_or_char_ptr name) { /* See if the using name is a scope */ /* tt = SwigType_find_scope(current_scope,name); - Printf(stdout,"tt = %x, name = '%s'\n", tt, name); */ + Printf(stdout,"tt = %p, name = '%s'\n", tt, name); */ /* We set up a typedef B --> A::B */ Setattr(current_typetab, base, name); /* Find the scope name where the symbol is defined */ td = SwigType_typedef_resolve(name); - /* Printf(stdout,"td = '%s' %x\n", td, resolved_scope); */ + /* Printf(stdout,"td = '%s' %p\n", td, resolved_scope); */ if (resolved_scope) { defined_name = Getattr(resolved_scope, "qname"); if (defined_name) { @@ -1150,7 +1177,7 @@ int SwigType_typedef_using(const_String_or_char_ptr name) { * a class. * ----------------------------------------------------------------------------- */ -int SwigType_isclass(SwigType *t) { +int SwigType_isclass(const SwigType *t) { SwigType *qty, *qtys; int isclass = 0; @@ -1186,7 +1213,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); @@ -1303,7 +1330,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; @@ -1421,7 +1448,7 @@ 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_ptr clientdata) { if (!r_mangleddata) { @@ -1431,7 +1458,7 @@ void SwigType_remember_mangleddata(String *mangled, const_String_or_char_ptr cli } -void SwigType_remember_clientdata(SwigType *t, const_String_or_char_ptr clientdata) { +void SwigType_remember_clientdata(const SwigType *t, const_String_or_char_ptr clientdata) { String *mt; SwigType *lt; Hash *h; @@ -1549,12 +1576,12 @@ void SwigType_remember_clientdata(SwigType *t, const_String_or_char_ptr clientda } } -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; } @@ -1726,7 +1753,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; @@ -1794,13 +1821,13 @@ void SwigType_inherit_equiv(File *out) { Append(rlist, ck.key); } /* Printf(stdout,"rk.key = '%s'\n", rk.key); - Printf(stdout,"rh = %x '%s'\n", rh,rh); */ + Printf(stdout,"rh = %p '%s'\n", rh,rh); */ bk = First(sub); while (bk.key) { prefix = SwigType_prefix(rk.key); Append(prefix, bk.key); - /* Printf(stdout,"set %x = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */ + /* Printf(stdout,"set %p = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */ mprefix = SwigType_manglestr(prefix); Setattr(rh, mprefix, prefix); mkey = SwigType_manglestr(rk.key); diff --git a/Source/Swig/wrapfunc.c b/Source/Swig/wrapfunc.c index 2c9f7c86a..29a59cc49 100644 --- a/Source/Swig/wrapfunc.c +++ b/Source/Swig/wrapfunc.c @@ -13,8 +13,6 @@ * to be created in a piecemeal manner. * ----------------------------------------------------------------------------- */ -char cvsroot_wrapfunc_c[] = "$Id$"; - #include "swig.h" #include <ctype.h> |