Create separate extetnd.c file for handling extensions / %extend
This is just a simple code refactor, moving and function renaming to remove the %extend code out of the parser into its own file now that it isn't just used in the parser.
This commit is contained in:
parent
9e4bce051d
commit
71e72c45ed
8 changed files with 205 additions and 158 deletions
|
|
@ -59,7 +59,7 @@ extern "C" {
|
||||||
extern void cparse_normalize_void(Node *);
|
extern void cparse_normalize_void(Node *);
|
||||||
extern Parm *Swig_cparse_parm(String *s);
|
extern Parm *Swig_cparse_parm(String *s);
|
||||||
extern ParmList *Swig_cparse_parms(String *s, Node *file_line_node);
|
extern ParmList *Swig_cparse_parms(String *s, Node *file_line_node);
|
||||||
|
extern Node *new_node(const_String_or_char_ptr tag);
|
||||||
|
|
||||||
/* templ.c */
|
/* templ.c */
|
||||||
extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope);
|
extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope);
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ int yyparse();
|
||||||
|
|
||||||
static Node *top = 0; /* Top of the generated parse tree */
|
static Node *top = 0; /* Top of the generated parse tree */
|
||||||
static int unnamed = 0; /* Unnamed datatype counter */
|
static int unnamed = 0; /* Unnamed datatype counter */
|
||||||
Hash *extendhash = 0; /* Hash table of added methods */
|
|
||||||
static Hash *classes = 0; /* Hash table of classes */
|
static Hash *classes = 0; /* Hash table of classes */
|
||||||
static Hash *classes_typedefs = 0; /* Hash table of typedef classes: typedef struct X {...} Y; */
|
static Hash *classes_typedefs = 0; /* Hash table of typedef classes: typedef struct X {...} Y; */
|
||||||
static Symtab *prev_symtab = 0;
|
static Symtab *prev_symtab = 0;
|
||||||
|
|
@ -71,14 +70,6 @@ static void yyerror (const char *e) {
|
||||||
(void)e;
|
(void)e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Node *new_node(const_String_or_char_ptr tag) {
|
|
||||||
Node *n = NewHash();
|
|
||||||
set_nodeType(n,tag);
|
|
||||||
Setfile(n,cparse_file);
|
|
||||||
Setline(n,cparse_line);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copies a node. Does not copy tree links or symbol table data (except for
|
/* Copies a node. Does not copy tree links or symbol table data (except for
|
||||||
sym:name) */
|
sym:name) */
|
||||||
|
|
||||||
|
|
@ -650,106 +641,6 @@ static void add_symbols_copy(Node *n) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extension merge. This function is used to handle the %extend directive
|
|
||||||
when it appears before a class definition. To handle this, the %extend
|
|
||||||
actually needs to take precedence. Therefore, we will selectively nuke symbols
|
|
||||||
from the current symbol table, replacing them with the added methods */
|
|
||||||
|
|
||||||
void merge_extensions(Node *cls, Node *am) {
|
|
||||||
Node *n;
|
|
||||||
Node *csym;
|
|
||||||
|
|
||||||
n = firstChild(am);
|
|
||||||
while (n) {
|
|
||||||
String *symname;
|
|
||||||
if (Strcmp(nodeType(n),"constructor") == 0) {
|
|
||||||
symname = Getattr(n,"sym:name");
|
|
||||||
if (symname) {
|
|
||||||
if (Strcmp(symname,Getattr(n,"name")) == 0) {
|
|
||||||
/* If the name and the sym:name of a constructor are the same,
|
|
||||||
then it hasn't been renamed. However---the name of the class
|
|
||||||
itself might have been renamed so we need to do a consistency
|
|
||||||
check here */
|
|
||||||
if (Getattr(cls,"sym:name")) {
|
|
||||||
Setattr(n,"sym:name", Getattr(cls,"sym:name"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
symname = Getattr(n,"sym:name");
|
|
||||||
DohIncref(symname);
|
|
||||||
if ((symname) && (!Getattr(n,"error"))) {
|
|
||||||
/* Remove node from its symbol table */
|
|
||||||
Swig_symbol_remove(n);
|
|
||||||
csym = Swig_symbol_add(symname,n);
|
|
||||||
if (csym != n) {
|
|
||||||
/* Conflict with previous definition. Nuke previous definition */
|
|
||||||
String *e = NewStringEmpty();
|
|
||||||
String *en = NewStringEmpty();
|
|
||||||
String *ec = NewStringEmpty();
|
|
||||||
Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname);
|
|
||||||
Printf(en,"%%extend definition of '%s'.",symname);
|
|
||||||
SWIG_WARN_NODE_BEGIN(n);
|
|
||||||
Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec);
|
|
||||||
Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
|
|
||||||
SWIG_WARN_NODE_END(n);
|
|
||||||
Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec,
|
|
||||||
Getfile(n),Getline(n),en);
|
|
||||||
Setattr(csym,"error",e);
|
|
||||||
Delete(e);
|
|
||||||
Delete(en);
|
|
||||||
Delete(ec);
|
|
||||||
Swig_symbol_remove(csym); /* Remove class definition */
|
|
||||||
Swig_symbol_add(symname,n); /* Insert extend definition */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n = nextSibling(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void append_previous_extension(Node *cls, Node *am) {
|
|
||||||
Node *n, *ne;
|
|
||||||
Node *pe = 0;
|
|
||||||
Node *ae = 0;
|
|
||||||
|
|
||||||
if (!am) return;
|
|
||||||
|
|
||||||
n = firstChild(am);
|
|
||||||
while (n) {
|
|
||||||
ne = nextSibling(n);
|
|
||||||
set_nextSibling(n,0);
|
|
||||||
/* typemaps and fragments need to be prepended */
|
|
||||||
if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) {
|
|
||||||
if (!pe) pe = new_node("extend");
|
|
||||||
appendChild(pe, n);
|
|
||||||
} else {
|
|
||||||
if (!ae) ae = new_node("extend");
|
|
||||||
appendChild(ae, n);
|
|
||||||
}
|
|
||||||
n = ne;
|
|
||||||
}
|
|
||||||
if (pe) prependChild(cls,pe);
|
|
||||||
if (ae) appendChild(cls,ae);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Check for unused %extend. Special case, don't report unused
|
|
||||||
extensions for templates */
|
|
||||||
|
|
||||||
void check_extensions() {
|
|
||||||
Iterator ki;
|
|
||||||
|
|
||||||
if (!extendhash) return;
|
|
||||||
for (ki = First(extendhash); ki.key; ki = Next(ki)) {
|
|
||||||
if (!Strchr(ki.key,'<')) {
|
|
||||||
SWIG_WARN_NODE_BEGIN(ki.item);
|
|
||||||
Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", SwigType_namestr(ki.key));
|
|
||||||
SWIG_WARN_NODE_END(ki.item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check a set of declarations to see if any are pure-abstract */
|
/* Check a set of declarations to see if any are pure-abstract */
|
||||||
|
|
||||||
static List *pure_abstracts(Node *n) {
|
static List *pure_abstracts(Node *n) {
|
||||||
|
|
@ -1682,14 +1573,13 @@ extend_directive : EXTEND options idcolon LBRACE {
|
||||||
cplus_mode = CPLUS_PUBLIC;
|
cplus_mode = CPLUS_PUBLIC;
|
||||||
if (!classes) classes = NewHash();
|
if (!classes) classes = NewHash();
|
||||||
if (!classes_typedefs) classes_typedefs = NewHash();
|
if (!classes_typedefs) classes_typedefs = NewHash();
|
||||||
if (!extendhash) extendhash = NewHash();
|
|
||||||
clsname = make_class_name($3);
|
clsname = make_class_name($3);
|
||||||
cls = Getattr(classes,clsname);
|
cls = Getattr(classes,clsname);
|
||||||
if (!cls) {
|
if (!cls) {
|
||||||
cls = Getattr(classes_typedefs, clsname);
|
cls = Getattr(classes_typedefs, clsname);
|
||||||
if (!cls) {
|
if (!cls) {
|
||||||
/* No previous definition. Create a new scope */
|
/* No previous definition. Create a new scope */
|
||||||
Node *am = Getattr(extendhash,clsname);
|
Node *am = Getattr(Swig_extend_hash(),clsname);
|
||||||
if (!am) {
|
if (!am) {
|
||||||
Swig_symbol_newscope();
|
Swig_symbol_newscope();
|
||||||
Swig_symbol_setscopename($3);
|
Swig_symbol_setscopename($3);
|
||||||
|
|
@ -1735,13 +1625,13 @@ extend_directive : EXTEND options idcolon LBRACE {
|
||||||
appendChild(current_class,$$);
|
appendChild(current_class,$$);
|
||||||
} else {
|
} else {
|
||||||
/* We store the extensions in the extensions hash */
|
/* We store the extensions in the extensions hash */
|
||||||
Node *am = Getattr(extendhash,clsname);
|
Node *am = Getattr(Swig_extend_hash(),clsname);
|
||||||
if (am) {
|
if (am) {
|
||||||
/* Append the members to the previous extend methods */
|
/* Append the members to the previous extend methods */
|
||||||
appendChild(am,$6);
|
appendChild(am,$6);
|
||||||
} else {
|
} else {
|
||||||
appendChild($$,$6);
|
appendChild($$,$6);
|
||||||
Setattr(extendhash,clsname,$$);
|
Setattr(Swig_extend_hash(),clsname,$$);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_class = 0;
|
current_class = 0;
|
||||||
|
|
@ -2824,8 +2714,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
||||||
|
|
||||||
/* !!! This may be broken. We may have to add the
|
/* !!! This may be broken. We may have to add the
|
||||||
%extend methods at the beginning of the class */
|
%extend methods at the beginning of the class */
|
||||||
|
{
|
||||||
if (extendhash) {
|
|
||||||
String *stmp = 0;
|
String *stmp = 0;
|
||||||
String *clsname;
|
String *clsname;
|
||||||
Node *am;
|
Node *am;
|
||||||
|
|
@ -2834,32 +2723,32 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
||||||
} else {
|
} else {
|
||||||
clsname = Getattr(templnode,"name");
|
clsname = Getattr(templnode,"name");
|
||||||
}
|
}
|
||||||
am = Getattr(extendhash,clsname);
|
am = Getattr(Swig_extend_hash(),clsname);
|
||||||
if (am) {
|
if (am) {
|
||||||
Symtab *st = Swig_symbol_current();
|
Symtab *st = Swig_symbol_current();
|
||||||
Swig_symbol_setscope(Getattr(templnode,"symtab"));
|
Swig_symbol_setscope(Getattr(templnode,"symtab"));
|
||||||
/* Printf(stdout,"%s: %s %p %p\n", Getattr(templnode,"name"), clsname, Swig_symbol_current(), Getattr(templnode,"symtab")); */
|
/* Printf(stdout,"%s: %s %p %p\n", Getattr(templnode,"name"), clsname, Swig_symbol_current(), Getattr(templnode,"symtab")); */
|
||||||
merge_extensions(templnode,am);
|
Swig_extend_merge(templnode,am);
|
||||||
Swig_symbol_setscope(st);
|
Swig_symbol_setscope(st);
|
||||||
append_previous_extension(templnode,am);
|
Swig_extend_append_previous(templnode,am);
|
||||||
Delattr(extendhash,clsname);
|
Delattr(Swig_extend_hash(),clsname);
|
||||||
}
|
}
|
||||||
if (stmp) Delete(stmp);
|
if (stmp) Delete(stmp);
|
||||||
}
|
}
|
||||||
/* Add to classes hash */
|
|
||||||
if (!classes) classes = NewHash();
|
|
||||||
|
|
||||||
{
|
/* Add to classes hash */
|
||||||
if (Namespaceprefix) {
|
if (!classes)
|
||||||
String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
|
classes = NewHash();
|
||||||
Setattr(classes,temp,templnode);
|
|
||||||
Delete(temp);
|
if (Namespaceprefix) {
|
||||||
} else {
|
String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
|
||||||
String *qs = Swig_symbol_qualifiedscopename(templnode);
|
Setattr(classes,temp,templnode);
|
||||||
Setattr(classes, qs,templnode);
|
Delete(temp);
|
||||||
Delete(qs);
|
} else {
|
||||||
}
|
String *qs = Swig_symbol_qualifiedscopename(templnode);
|
||||||
}
|
Setattr(classes, qs,templnode);
|
||||||
|
Delete(qs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3571,13 +3460,12 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
|
||||||
Setattr($$,"abstracts", pure_abstracts($7));
|
Setattr($$,"abstracts", pure_abstracts($7));
|
||||||
|
|
||||||
/* This bit of code merges in a previously defined %extend directive (if any) */
|
/* This bit of code merges in a previously defined %extend directive (if any) */
|
||||||
|
{
|
||||||
if (extendhash) {
|
|
||||||
String *clsname = Swig_symbol_qualifiedscopename(0);
|
String *clsname = Swig_symbol_qualifiedscopename(0);
|
||||||
am = Getattr(extendhash, clsname);
|
am = Getattr(Swig_extend_hash(), clsname);
|
||||||
if (am) {
|
if (am) {
|
||||||
merge_extensions($$, am);
|
Swig_extend_merge($$, am);
|
||||||
Delattr(extendhash, clsname);
|
Delattr(Swig_extend_hash(), clsname);
|
||||||
}
|
}
|
||||||
Delete(clsname);
|
Delete(clsname);
|
||||||
}
|
}
|
||||||
|
|
@ -3588,7 +3476,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
|
||||||
appendChild($$, $7);
|
appendChild($$, $7);
|
||||||
|
|
||||||
if (am)
|
if (am)
|
||||||
append_previous_extension($$, am);
|
Swig_extend_append_previous($$, am);
|
||||||
|
|
||||||
p = $9;
|
p = $9;
|
||||||
if (p && !nscope_inner) {
|
if (p && !nscope_inner) {
|
||||||
|
|
@ -3787,15 +3675,16 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
|
||||||
n = nextSibling(n);
|
n = nextSibling(n);
|
||||||
}
|
}
|
||||||
n = $8;
|
n = $8;
|
||||||
/* Check for previous extensions */
|
|
||||||
if (extendhash) {
|
/* Check for previous extensions */
|
||||||
|
{
|
||||||
String *clsname = Swig_symbol_qualifiedscopename(0);
|
String *clsname = Swig_symbol_qualifiedscopename(0);
|
||||||
Node *am = Getattr(extendhash,clsname);
|
Node *am = Getattr(Swig_extend_hash(),clsname);
|
||||||
if (am) {
|
if (am) {
|
||||||
/* Merge the extension into the symbol table */
|
/* Merge the extension into the symbol table */
|
||||||
merge_extensions($$,am);
|
Swig_extend_merge($$,am);
|
||||||
append_previous_extension($$,am);
|
Swig_extend_append_previous($$,am);
|
||||||
Delattr(extendhash,clsname);
|
Delattr(Swig_extend_hash(),clsname);
|
||||||
}
|
}
|
||||||
Delete(clsname);
|
Delete(clsname);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,3 +88,17 @@ void cparse_normalize_void(Node *n) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* new_node()
|
||||||
|
*
|
||||||
|
* Create an empty parse node, setting file and line number information
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
Node *new_node(const_String_or_char_ptr tag) {
|
||||||
|
Node *n = NewHash();
|
||||||
|
set_nodeType(n,tag);
|
||||||
|
Setfile(n,cparse_file);
|
||||||
|
Setline(n,cparse_line);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ eswig_SOURCES = CParse/cscanner.c \
|
||||||
Swig/cwrap.c \
|
Swig/cwrap.c \
|
||||||
Swig/deprecate.c \
|
Swig/deprecate.c \
|
||||||
Swig/error.c \
|
Swig/error.c \
|
||||||
|
Swig/extend.c \
|
||||||
Swig/fragment.c \
|
Swig/fragment.c \
|
||||||
Swig/getopt.c \
|
Swig/getopt.c \
|
||||||
Swig/include.c \
|
Swig/include.c \
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,6 @@ static String *external_runtime_name = 0;
|
||||||
enum { STAGE1=1, STAGE2=2, STAGE3=4, STAGE4=8, STAGEOVERFLOW=16 };
|
enum { STAGE1=1, STAGE2=2, STAGE3=4, STAGE4=8, STAGEOVERFLOW=16 };
|
||||||
static List *libfiles = 0;
|
static List *libfiles = 0;
|
||||||
static List *all_output_files = 0;
|
static List *all_output_files = 0;
|
||||||
extern "C" void check_extensions();
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* check_extension()
|
* check_extension()
|
||||||
|
|
@ -1173,7 +1172,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
||||||
Printf(stdout, "Processing unnamed structs...\n");
|
Printf(stdout, "Processing unnamed structs...\n");
|
||||||
Swig_nested_name_unnamed_c_structs(top);
|
Swig_nested_name_unnamed_c_structs(top);
|
||||||
}
|
}
|
||||||
check_extensions();
|
Swig_extend_unused_check();
|
||||||
|
|
||||||
if (Verbose) {
|
if (Verbose) {
|
||||||
Printf(stdout, "Processing types...\n");
|
Printf(stdout, "Processing types...\n");
|
||||||
|
|
|
||||||
|
|
@ -338,9 +338,7 @@ static void insertNodeAfter(Node *n, Node *c) {
|
||||||
set_nextSibling(n, c);
|
set_nextSibling(n, c);
|
||||||
set_previousSibling(c, n);
|
set_previousSibling(c, n);
|
||||||
}
|
}
|
||||||
extern "C" Hash *extendhash;
|
|
||||||
extern "C" void merge_extensions(Node *cls, Node *am);
|
|
||||||
extern "C" void append_previous_extension(Node *cls, Node *am);
|
|
||||||
void Swig_nested_name_unnamed_c_structs(Node *n) {
|
void Swig_nested_name_unnamed_c_structs(Node *n) {
|
||||||
if (!classhash)
|
if (!classhash)
|
||||||
classhash = Getattr(n, "classes");
|
classhash = Getattr(n, "classes");
|
||||||
|
|
@ -378,13 +376,11 @@ void Swig_nested_name_unnamed_c_structs(Node *n) {
|
||||||
decl = nextSibling(decl);
|
decl = nextSibling(decl);
|
||||||
}
|
}
|
||||||
Delete(ty);
|
Delete(ty);
|
||||||
if (extendhash) {
|
if (Node *am = Getattr(Swig_extend_hash(), name)) {
|
||||||
if (Node *am = Getattr(extendhash, name)) {
|
// Merge the extension into the symbol table
|
||||||
// Merge the extension into the symbol table
|
Swig_extend_merge(c, am);
|
||||||
merge_extensions(c, am);
|
Swig_extend_append_previous(c, am);
|
||||||
append_previous_extension(c, am);
|
Delattr(Swig_extend_hash(), name);
|
||||||
Delattr(extendhash, name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Swig_symbol_setscope(Swig_symbol_global_scope());
|
Swig_symbol_setscope(Swig_symbol_global_scope());
|
||||||
add_symbols_c(c);
|
add_symbols_c(c);
|
||||||
|
|
|
||||||
141
Source/Swig/extend.c
Normal file
141
Source/Swig/extend.c
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||||
|
* (or any later version) of the GNU General Public License. Some additional
|
||||||
|
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||||
|
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||||
|
* included with the SWIG source code as distributed by the SWIG developers
|
||||||
|
* and at http://www.swig.org/legal.html.
|
||||||
|
*
|
||||||
|
* extend.c
|
||||||
|
*
|
||||||
|
* Extensions support (%extend)
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "swig.h"
|
||||||
|
#include "cparse.h"
|
||||||
|
|
||||||
|
static Hash *extendhash = 0; /* Hash table of added methods */
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Swig_extend_hash()
|
||||||
|
*
|
||||||
|
* Access the extend hash
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
Hash *Swig_extend_hash(void) {
|
||||||
|
if (!extendhash)
|
||||||
|
extendhash = NewHash();
|
||||||
|
return extendhash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Swig_extend_merge()
|
||||||
|
*
|
||||||
|
* Extension merge. This function is used to handle the %extend directive
|
||||||
|
* when it appears before a class definition. To handle this, the %extend
|
||||||
|
* actually needs to take precedence. Therefore, we will selectively nuke symbols
|
||||||
|
* from the current symbol table, replacing them with the added methods.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Swig_extend_merge(Node *cls, Node *am) {
|
||||||
|
Node *n;
|
||||||
|
Node *csym;
|
||||||
|
|
||||||
|
n = firstChild(am);
|
||||||
|
while (n) {
|
||||||
|
String *symname;
|
||||||
|
if (Strcmp(nodeType(n),"constructor") == 0) {
|
||||||
|
symname = Getattr(n,"sym:name");
|
||||||
|
if (symname) {
|
||||||
|
if (Strcmp(symname,Getattr(n,"name")) == 0) {
|
||||||
|
/* If the name and the sym:name of a constructor are the same,
|
||||||
|
then it hasn't been renamed. However---the name of the class
|
||||||
|
itself might have been renamed so we need to do a consistency
|
||||||
|
check here */
|
||||||
|
if (Getattr(cls,"sym:name")) {
|
||||||
|
Setattr(n,"sym:name", Getattr(cls,"sym:name"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
symname = Getattr(n,"sym:name");
|
||||||
|
DohIncref(symname);
|
||||||
|
if ((symname) && (!Getattr(n,"error"))) {
|
||||||
|
/* Remove node from its symbol table */
|
||||||
|
Swig_symbol_remove(n);
|
||||||
|
csym = Swig_symbol_add(symname,n);
|
||||||
|
if (csym != n) {
|
||||||
|
/* Conflict with previous definition. Nuke previous definition */
|
||||||
|
String *e = NewStringEmpty();
|
||||||
|
String *en = NewStringEmpty();
|
||||||
|
String *ec = NewStringEmpty();
|
||||||
|
Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname);
|
||||||
|
Printf(en,"%%extend definition of '%s'.",symname);
|
||||||
|
SWIG_WARN_NODE_BEGIN(n);
|
||||||
|
Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec);
|
||||||
|
Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
|
||||||
|
SWIG_WARN_NODE_END(n);
|
||||||
|
Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec,
|
||||||
|
Getfile(n),Getline(n),en);
|
||||||
|
Setattr(csym,"error",e);
|
||||||
|
Delete(e);
|
||||||
|
Delete(en);
|
||||||
|
Delete(ec);
|
||||||
|
Swig_symbol_remove(csym); /* Remove class definition */
|
||||||
|
Swig_symbol_add(symname,n); /* Insert extend definition */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n = nextSibling(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Swig_extend_append_previous()
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Swig_extend_append_previous(Node *cls, Node *am) {
|
||||||
|
Node *n, *ne;
|
||||||
|
Node *pe = 0;
|
||||||
|
Node *ae = 0;
|
||||||
|
|
||||||
|
if (!am) return;
|
||||||
|
|
||||||
|
n = firstChild(am);
|
||||||
|
while (n) {
|
||||||
|
ne = nextSibling(n);
|
||||||
|
set_nextSibling(n,0);
|
||||||
|
/* typemaps and fragments need to be prepended */
|
||||||
|
if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) {
|
||||||
|
if (!pe) pe = new_node("extend");
|
||||||
|
appendChild(pe, n);
|
||||||
|
} else {
|
||||||
|
if (!ae) ae = new_node("extend");
|
||||||
|
appendChild(ae, n);
|
||||||
|
}
|
||||||
|
n = ne;
|
||||||
|
}
|
||||||
|
if (pe) prependChild(cls,pe);
|
||||||
|
if (ae) appendChild(cls,ae);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Swig_extend_unused_check()
|
||||||
|
*
|
||||||
|
* Check for unused %extend. Special case, don't report unused
|
||||||
|
* extensions for templates
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Swig_extend_unused_check(void) {
|
||||||
|
Iterator ki;
|
||||||
|
|
||||||
|
if (!extendhash) return;
|
||||||
|
for (ki = First(extendhash); ki.key; ki = Next(ki)) {
|
||||||
|
if (!Strchr(ki.key,'<')) {
|
||||||
|
SWIG_WARN_NODE_BEGIN(ki.item);
|
||||||
|
Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", SwigType_namestr(ki.key));
|
||||||
|
SWIG_WARN_NODE_END(ki.item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -420,6 +420,13 @@ extern int ParmList_is_compactdefargs(ParmList *p);
|
||||||
extern void Swig_fragment_emit(String *name);
|
extern void Swig_fragment_emit(String *name);
|
||||||
extern void Swig_fragment_clear(String *section);
|
extern void Swig_fragment_clear(String *section);
|
||||||
|
|
||||||
|
/* --- Extension support --- */
|
||||||
|
|
||||||
|
extern Hash *Swig_extend_hash(void);
|
||||||
|
extern void Swig_extend_merge(Node *cls, Node *am);
|
||||||
|
extern void Swig_extend_append_previous(Node *cls, Node *am);
|
||||||
|
extern void Swig_extend_unused_check(void);
|
||||||
|
|
||||||
/* hacks defined in C++ ! */
|
/* hacks defined in C++ ! */
|
||||||
extern int Swig_director_mode(void);
|
extern int Swig_director_mode(void);
|
||||||
extern int Swig_director_protected_mode(void);
|
extern int Swig_director_protected_mode(void);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue