From 94a82526ec5d358515bc42ba801e6031b4b18446 Mon Sep 17 00:00:00 2001 From: Marcelo Matus Date: Mon, 19 Dec 2005 10:46:41 +0000 Subject: [PATCH] fix %extend(%typemaps + %fragments) before class declaration git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@8011 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/parser.y | 33 ++++++++++++++++++++++++++++++--- Source/Swig/swig.h | 1 + Source/Swig/tree.c | 24 ++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index a7ef93f3c..f9c9bf581 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -724,6 +724,32 @@ static void merge_extensions(Node *cls, Node *am) { } } +static 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 preppended */ + 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) preppendChild(cls,pe); + if (ae) appendChild(cls,ae); +} + + /* Check for unused %extend. Special case, don't report unused extensions for templates */ @@ -2682,7 +2708,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va /* Printf(stdout,"%s: %s %x %x\n", Getattr(templnode,"name"), clsname, Swig_symbol_current(), Getattr(templnode,"symtab")); */ merge_extensions(templnode,am); Swig_symbol_setscope(st); - appendChild(templnode,am); + append_previous_extension(templnode,am); Delattr(extendhash,clsname); } if (stmp) Delete(stmp); @@ -3203,7 +3229,8 @@ cpp_class_decl : Delete(scpname); appendChild($$,$7); - if (am) appendChild($$,am); + + if (am) append_previous_extension($$,am); p = $9; if (p) { @@ -3367,7 +3394,7 @@ cpp_class_decl : if (am) { /* Merge the extension into the symbol table */ merge_extensions($$,am); - appendChild($$,am); + append_previous_extension($$,am); Delattr(extendhash,clsname); } Delete(clsname); diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 4f1089b72..3526061f2 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -369,6 +369,7 @@ extern int checkAttribute(Node *obj, const String_or_char *name, const String_or #define set_lastChild(x,v) Setattr(x,"lastChild",v) extern void appendChild(Node *node, Node *child); +extern void preppendChild(Node *node, Node *child); extern void deleteNode(Node *node); extern Node *copyNode(Node *node); diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c index fd678f7aa..e88ae5e60 100644 --- a/Source/Swig/tree.c +++ b/Source/Swig/tree.c @@ -149,6 +149,30 @@ appendChild(Node *node, Node *chd) { set_lastChild(node,lc); } +/* ----------------------------------------------------------------------------- + * preppendChild() + * + * Preppends a new child to a node + * ----------------------------------------------------------------------------- */ + +void +preppendChild(Node *node, Node *chd) { + Node *fc; + + if (!chd) return; + + fc = firstChild(node); + if (fc) { + set_nextSibling(chd,fc); + set_previousSibling(fc,chd); + } + set_firstChild(node,chd); + while (chd) { + set_parentNode(chd,node); + chd = nextSibling(chd); + } +} + /* ----------------------------------------------------------------------------- * deleteNode() *