diff options
author | Jan Jezabek <jezabek@poczta.onet.pl> | 2009-09-02 23:37:38 +0000 |
---|---|---|
committer | Jan Jezabek <jezabek@poczta.onet.pl> | 2009-09-02 23:37:38 +0000 |
commit | 492d1fac78800b83e819b4f41c30d4ac625b66af (patch) | |
tree | 6f55be6bf0c82e258a33af1bf395a9d37828f3d8 | |
parent | e979cbf2d5b8ea1feed745e191313b21e1579c67 (diff) | |
download | swig-492d1fac78800b83e819b4f41c30d4ac625b66af.tar.gz |
Experimental changes to symbol handling to support case-insensitive target languages. If the language is case-insensitive, we should warn if we get a
symbol twice even if it's written in a different case, e.g. 'Hi' vs. 'hi'. Currently only enabled for COM, but other languages (Delphi?) might
benefit from it too. Modules that do not specifically request such handling should see no difference at all to the current behavior.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-jezabek@11679 626c5289-ae23-0410-ae9c-e8d60b6d4f22
-rw-r--r-- | Source/CParse/parser.y | 22 | ||||
-rw-r--r-- | Source/Modules/com.cxx | 1 | ||||
-rw-r--r-- | Source/Swig/swig.h | 3 | ||||
-rw-r--r-- | Source/Swig/symbol.c | 30 |
4 files changed, 52 insertions, 4 deletions
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 0babfbbb8..efff274f4 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -272,6 +272,7 @@ static int add_only_one = 0; static void add_symbols(Node *n) { String *decl; String *wrn = 0; + int case_insensitive_target = Swig_symbol_get_case_insensitive_target(); if (inclass && n) { cparse_normalize_void(n); } @@ -457,24 +458,37 @@ static void add_symbols(Node *n) { if (c != n) { /* symbol conflict attempting to add in the new symbol */ if (Getattr(n,"sym:weak")) { - Setattr(n,"sym:name",symname); + if (case_insensitive_target) { + String *lower_case_name = Swig_string_lower(symname); + Setattr(n,"sym:name",lower_case_name); + Setattr(n,"sym:casePreservingName",symname); + Delete(lower_case_name); + } else { + Setattr(n,"sym:name",symname); + } } else { String *e = NewStringEmpty(); String *en = NewStringEmpty(); String *ec = NewStringEmpty(); + String *csymname; int redefined = Swig_need_redefined_warn(n,c,inclass); + if (case_insensitive_target) { + csymname = Getattr(c, "sym:casePreservingName"); + } else { + csymname = Getattr(c, "sym:name"); + } if (redefined) { Printf(en,"Identifier '%s' redefined (ignored)",symname); - Printf(ec,"previous definition of '%s'",symname); + Printf(ec,"previous definition of '%s'",csymname); } else { Printf(en,"Redundant redeclaration of '%s'",symname); - Printf(ec,"previous declaration of '%s'",symname); + Printf(ec,"previous declaration of '%s'",csymname); } if (Cmp(symname,Getattr(n,"name"))) { Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name"))); } Printf(en,","); - if (Cmp(symname,Getattr(c,"name"))) { + if (Cmp(csymname,Getattr(c,"name"))) { Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name"))); } Printf(ec,"."); diff --git a/Source/Modules/com.cxx b/Source/Modules/com.cxx index dc6667c6e..f9125da29 100644 --- a/Source/Modules/com.cxx +++ b/Source/Modules/com.cxx @@ -250,6 +250,7 @@ public: memset(&module_iid, 0, sizeof(GUID)); memset(&module_clsid, 0, sizeof(GUID)); director_language = 0; + Swig_symbol_set_case_insensitive_target(1); } /* ----------------------------------------------------------------------------- diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 2b2c797c9..d61d5d8f4 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -306,6 +306,9 @@ extern int ParmList_is_compactdefargs(ParmList *p); extern int Swig_value_wrapper_mode(int mode); + extern int Swig_symbol_set_case_insensitive_target(int value); + extern int Swig_symbol_get_case_insensitive_target(void); + #define WARNING(msg) Swig_warn(__FILE__,__LINE__,msg) diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index 055af854f..c864956a7 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -172,6 +172,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 case_insensitive_target = 0; /* Is the target language case insensitive? */ + /* common attribute keys, to avoid calling find_key all the times */ @@ -602,6 +604,7 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) { int pn = 0; int u1 = 0, u2 = 0; String *name, *overname; + String *case_preserving_name; /* See if the node has a name. If so, we place in the C symbol table for this scope. We don't worry about overloading here---the primary purpose of this @@ -641,6 +644,12 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) { if (GetFlag(n, "feature:ignore")) return n; + /* If the target language is case insensitive, use a lower case string */ + if (case_insensitive_target) { + case_preserving_name = NewString(symname); + symname = Swig_string_lower(case_preserving_name); + } + /* See if the symbol already exists in the table */ c = Getattr(current, symname); @@ -679,6 +688,8 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) { Setattr(pcl, "sym:nextSibling", n); Setattr(n, "sym:symtab", current_symtab); Setattr(n, "sym:name", symname); + if (case_insensitive_target) + Setattr(n, "sym:casePreservingName", case_preserving_name); Setattr(n, "sym:previousSibling", pcl); return n; } @@ -714,6 +725,8 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) { Setattr(current, symname, td); Setattr(td, "sym:symtab", current_symtab); Setattr(td, "sym:name", symname); + if (case_insensitive_target) + Setattr(td, "sym:casePreservingName", case_preserving_name); } return n; } @@ -788,6 +801,8 @@ 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); + if (case_insensitive_target) + Setattr(n, "sym:casePreservingName", case_preserving_name); /* Printf(stdout,"%s %x\n", Getattr(n,"sym:overname"), current_symtab); */ assert(!Getattr(n, "sym:overname")); overname = NewStringf("__SWIG_%d", pn); @@ -804,12 +819,18 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) { /* No conflict. Just add it */ Setattr(n, "sym:symtab", current_symtab); Setattr(n, "sym:name", symname); + if (case_insensitive_target) + Setattr(n, "sym:casePreservingName", case_preserving_name); /* Printf(stdout,"%s\n", Getattr(n,"sym:overname")); */ overname = NewStringf("__SWIG_%d", pn); Setattr(n, "sym:overname", overname); Delete(overname); /* Printf(stdout,"%s %s %s\n", symname, Getattr(n,"decl"), Getattr(n,"sym:overname")); */ Setattr(current, symname, n); + if (case_insensitive_target) { + Delete(symname); + Delete(case_preserving_name); + } return n; } @@ -1914,3 +1935,12 @@ SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab) { } return value; } + +int Swig_symbol_set_case_insensitive_target(int value) { + case_insensitive_target = value; + return value; +} + +extern int Swig_symbol_get_case_insensitive_target(void) { + return case_insensitive_target; +} |