summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Jezabek <jezabek@poczta.onet.pl>2009-09-02 23:37:38 +0000
committerJan Jezabek <jezabek@poczta.onet.pl>2009-09-02 23:37:38 +0000
commit492d1fac78800b83e819b4f41c30d4ac625b66af (patch)
tree6f55be6bf0c82e258a33af1bf395a9d37828f3d8
parente979cbf2d5b8ea1feed745e191313b21e1579c67 (diff)
downloadswig-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.y22
-rw-r--r--Source/Modules/com.cxx1
-rw-r--r--Source/Swig/swig.h3
-rw-r--r--Source/Swig/symbol.c30
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;
+}