Merge branch 'nested' - nested structs/classes support

* nested:
  Deprecation of the 'nestedworkaround' feature
  Ensure -c++out is not used with -c++
  Add missing header to new source file
  Nested C class setters restored in c++out mode for Octave
  Classprefix fixed after private nested classes some comments and spaces added
  Fix template partial specialization detection
  Minor tweaks in Swig_feature_set
  Swig_offset_string moved to misc.c
  nested private classes are discarded while parsing nested relate functions are moved to nested.cxx and renamed accordingly
  out-of-scope template definitions fixed nested_private test disabled again
  fixed out-of-scope nested class definitions, added a test enabled nested C structs assignment (still disabled for Octave), added Java runtime test fixed nested_private test case for Java & C#
  Testcase of private nested class usage causing segfault
  C nested struct passed by value example
  Add in Travis testing for nested branch
  Add C++ nested class example
  Minor code improvements
  Cosmetics/code beautification of nested class support
  Nested classes support
This commit is contained in:
William S Fulton 2013-12-14 15:12:07 +00:00
commit 314fae460b
61 changed files with 2438 additions and 1127 deletions

View file

@ -13,8 +13,8 @@
* ----------------------------------------------------------------------------- */
#include "swig.h"
#include "cparse.h"
extern int cparse_cplusplus;
static const char *cresult_variable_name = "result";
static Parm *nonvoid_parms(Parm *p) {
@ -775,7 +775,25 @@ String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, Stri
if (SwigType_type(type) != T_ARRAY) {
if (!Strstr(type, "enum $unnamed")) {
String *dref = Swig_wrapped_var_deref(type, pname1, varcref);
Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref);
int extra_cast = 0;
if (cparse_cplusplusout) {
/* Required for C nested structs compiled as C++ as a duplicate of the nested struct is put into the global namespace.
* We could improve this by adding the extra casts just for nested structs rather than all structs. */
String *base = SwigType_base(type);
extra_cast = SwigType_isclass(base);
Delete(base);
}
if (extra_cast) {
String *lstr;
SwigType *ptype = Copy(type);
SwigType_add_pointer(ptype);
lstr = SwigType_lstr(ptype, 0);
Printf(func, "if (%s) *(%s)&%s%s = %s", pname0, lstr, self, name, dref);
Delete(lstr);
Delete(ptype);
} else {
Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref);
}
Delete(dref);
} else {
Printf(func, "if (%s && sizeof(int) == sizeof(%s%s)) *(int*)(void*)&(%s%s) = %s", pname0, self, name, self, name, pname1);

View file

@ -1147,6 +1147,55 @@ String *Swig_string_strip(String *s) {
return ns;
}
/* -----------------------------------------------------------------------------
* Swig_offset_string()
*
* Insert number tabs before each new line in s
* ----------------------------------------------------------------------------- */
void Swig_offset_string(String *s, int number) {
char *res;
char *p;
char *end;
/* count a number of lines in s */
int lines = 1;
int len = Len(s);
char *start = strchr(Char(s), '\n');
while (start) {
++lines;
start = strchr(start + 1, '\n');
}
/* do not count pending new line */
if ((Char(s))[len-1] == '\n')
--lines;
/* allocate a temporary storage for a padded string */
res = (char*)malloc(len + lines * number * 2 + 1);
res[len + lines * number * 2] = 0;
/* copy lines to res, prepending tabs to each line */
p = res; /* output pointer */
start = Char(s); /* start of a current line */
end = strchr(start, '\n'); /* end of a current line */
while (end) {
memset(p, ' ', number*2);
p += number*2;
memcpy(p, start, end - start + 1);
p += end - start + 1;
start = end + 1;
end = strchr(start, '\n');
}
/* process the last line */
if (*start) {
memset(p, ' ', number*2);
p += number*2;
strcpy(p, start);
}
/* replace 's' contents with 'res' */
Clear(s);
Append(s, res);
free(res);
}
#ifdef HAVE_PCRE
#include <pcre.h>

View file

@ -774,7 +774,7 @@ void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *d
* concatenating the feature name plus ':' plus the attribute name.
* ----------------------------------------------------------------------------- */
void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs) {
void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, const_String_or_char_ptr value, Hash *featureattribs) {
Hash *n;
Hash *fhash;
@ -1648,6 +1648,80 @@ void Swig_name_inherit(String *base, String *derived) {
Swig_name_object_inherit(Swig_cparse_features(), base, derived);
}
/* -----------------------------------------------------------------------------
* Swig_inherit_base_symbols()
* ----------------------------------------------------------------------------- */
void Swig_inherit_base_symbols(List *bases) {
if (bases) {
Iterator s;
for (s = First(bases); s.item; s = Next(s)) {
Symtab *st = Getattr(s.item, "symtab");
if (st) {
Setfile(st, Getfile(s.item));
Setline(st, Getline(s.item));
Swig_symbol_inherit(st);
}
}
Delete(bases);
}
}
/* -----------------------------------------------------------------------------
* Swig_make_inherit_list()
* ----------------------------------------------------------------------------- */
List *Swig_make_inherit_list(String *clsname, List *names, String *Namespaceprefix) {
int i, ilen;
String *derived;
List *bases = NewList();
if (Namespaceprefix)
derived = NewStringf("%s::%s", Namespaceprefix, clsname);
else
derived = NewString(clsname);
ilen = Len(names);
for (i = 0; i < ilen; i++) {
String *base;
String *n = Getitem(names, i);
/* Try to figure out where this symbol is */
Node *s = Swig_symbol_clookup(n, 0);
if (s) {
while (s && (Strcmp(nodeType(s), "class") != 0)) {
/* Not a class. Could be a typedef though. */
String *storage = Getattr(s, "storage");
if (storage && (Strcmp(storage, "typedef") == 0)) {
String *nn = Getattr(s, "type");
s = Swig_symbol_clookup(nn, Getattr(s, "sym:symtab"));
} else {
break;
}
}
if (s && ((Strcmp(nodeType(s), "class") == 0) || (Strcmp(nodeType(s), "template") == 0))) {
String *q = Swig_symbol_qualified(s);
Append(bases, s);
if (q) {
base = NewStringf("%s::%s", q, Getattr(s, "name"));
Delete(q);
} else {
base = NewString(Getattr(s, "name"));
}
} else {
base = NewString(n);
}
} else {
base = NewString(n);
}
if (base) {
Swig_name_inherit(base, derived);
Delete(base);
}
}
return bases;
}
/* -----------------------------------------------------------------------------
* void Swig_name_str()
*

View file

@ -1546,6 +1546,114 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
return 0;
}
/* -----------------------------------------------------------------------------
* Scanner_get_raw_text_balanced()
*
* Returns raw text between 2 braces, does not change scanner state in any way
* ----------------------------------------------------------------------------- */
String *Scanner_get_raw_text_balanced(Scanner *s, int startchar, int endchar) {
String *result = 0;
char c;
int old_line = s->line;
String *old_text = Copy(s->text);
int position = Tell(s->str);
int num_levels = 1;
int state = 0;
char temp[2] = { 0, 0 };
temp[0] = (char) startchar;
Clear(s->text);
Setfile(s->text, Getfile(s->str));
Setline(s->text, s->line);
Append(s->text, temp);
while (num_levels > 0) {
if ((c = nextchar(s)) == 0) {
Clear(s->text);
Append(s->text, old_text);
Delete(old_text);
s->line = old_line;
return 0;
}
switch (state) {
case 0:
if (c == startchar)
num_levels++;
else if (c == endchar)
num_levels--;
else if (c == '/')
state = 10;
else if (c == '\"')
state = 20;
else if (c == '\'')
state = 30;
break;
case 10:
if (c == '/')
state = 11;
else if (c == '*')
state = 12;
else if (c == startchar) {
state = 0;
num_levels++;
}
else
state = 0;
break;
case 11:
if (c == '\n')
state = 0;
else
state = 11;
break;
case 12: /* first character inside C comment */
if (c == '*')
state = 14;
else
state = 13;
break;
case 13:
if (c == '*')
state = 14;
break;
case 14: /* possible end of C comment */
if (c == '*')
state = 14;
else if (c == '/')
state = 0;
else
state = 13;
break;
case 20:
if (c == '\"')
state = 0;
else if (c == '\\')
state = 21;
break;
case 21:
state = 20;
break;
case 30:
if (c == '\'')
state = 0;
else if (c == '\\')
state = 31;
break;
case 31:
state = 30;
break;
default:
break;
}
}
Seek(s->str, position, SEEK_SET);
result = Copy(s->text);
Clear(s->text);
Append(s->text, old_text);
Delete(old_text);
s->line = old_line;
return result;
}
/* -----------------------------------------------------------------------------
* Scanner_isoperator()
*

View file

@ -286,6 +286,8 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl);
extern void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *namewrn, ParmList *declaratorparms);
extern void Swig_name_inherit(String *base, String *derived);
extern List *Swig_make_inherit_list(String *clsname, List *names, String *Namespaceprefix);
extern void Swig_inherit_base_symbols(List *bases);
extern int Swig_need_protected(Node *n);
extern int Swig_need_name_warning(Node *n);
extern int Swig_need_redefined_warn(Node *a, Node *b, int InClass);
@ -302,7 +304,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl);
extern void Swig_name_object_inherit(Hash *namehash, String *base, String *derived);
extern void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *n);
extern void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs);
extern void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, const_String_or_char_ptr value, Hash *featureattribs);
/* --- Misc --- */
extern char *Swig_copy_string(const char *c);
@ -330,6 +332,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 void Swig_offset_string(String *s, int number);
extern String *Swig_pcre_version(void);
extern void Swig_init(void);
extern int Swig_value_wrapper_mode(int mode);

View file

@ -22,6 +22,7 @@ extern int Scanner_token(Scanner *);
extern String *Scanner_text(Scanner *);
extern void Scanner_skip_line(Scanner *);
extern int Scanner_skip_balanced(Scanner *, int startchar, int endchar);
extern String *Scanner_get_raw_text_balanced(Scanner *, int startchar, int endchar);
extern void Scanner_set_location(Scanner *, String *file, int line);
extern String *Scanner_file(Scanner *);
extern int Scanner_line(Scanner *);

View file

@ -38,6 +38,7 @@ extern void appendChild(Node *node, Node *child);
extern void prependChild(Node *node, Node *child);
extern void removeNode(Node *node);
extern Node *copyNode(Node *node);
extern void appendSibling(Node *node, Node *child);
/* Node restoration/restore functions */

View file

@ -171,6 +171,24 @@ void prependChild(Node *node, Node *chd) {
}
}
void appendSibling(Node *node, Node *chd) {
Node *parent;
Node *lc = node;
while (nextSibling(lc))
lc = nextSibling(lc);
set_nextSibling(lc, chd);
set_previousSibling(chd, lc);
parent = parentNode(node);
if (parent) {
while (chd) {
lc = chd;
set_parentNode(chd, parent);
chd = nextSibling(chd);
}
set_lastChild(parent, lc);
}
}
/* -----------------------------------------------------------------------------
* removeNode()
*