diff options
author | robot-piglet <[email protected]> | 2025-08-28 14:27:58 +0300 |
---|---|---|
committer | robot-piglet <[email protected]> | 2025-08-28 14:57:06 +0300 |
commit | 81d828c32c8d5477cb2f0ce5da06a1a8d9392ca3 (patch) | |
tree | 3081d566f0d5158d76e9093261344f6406fd09f7 /contrib/tools/swig/Source/Swig/extend.c | |
parent | 77ea11423f959e51795cc3ef36a48d808b4ffb98 (diff) |
Intermediate changes
commit_hash:d5b1af16dbe9030537a04c27eb410c88c2f496cd
Diffstat (limited to 'contrib/tools/swig/Source/Swig/extend.c')
-rw-r--r-- | contrib/tools/swig/Source/Swig/extend.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/contrib/tools/swig/Source/Swig/extend.c b/contrib/tools/swig/Source/Swig/extend.c new file mode 100644 index 00000000000..4e430ed5dee --- /dev/null +++ b/contrib/tools/swig/Source/Swig/extend.c @@ -0,0 +1,140 @@ +/* ----------------------------------------------------------------------------- + * 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 https://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; + + 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"))) { + Node *c; + /* Remove node from its symbol table */ + Swig_symbol_remove(n); + c = Swig_symbol_add(symname,n); + if (c != n) { + /* Conflict with previous definition. Nuke previous definition */ + String *e = NewStringEmpty(); + String *en = NewStringEmpty(); + String *ec = NewStringEmpty(); + Printf(ec, "Redefinition of identifier '%s' by %%extend ignored,", symname); + Printf(en, "%%extend definition of '%s'.", symname); + SWIG_WARN_NODE_BEGIN(n); + Swig_warning(WARN_PARSE_REDEFINED, Getfile(c), Getline(c), "%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(c), Getline(c), ec, Getfile(n),Getline(n),en); + Setattr(c, "error", e); + Delete(e); + Delete(en); + Delete(ec); + Swig_symbol_remove(c); /* 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 = Swig_cparse_new_node("extend"); + appendChild(pe, n); + } else { + if (!ae) ae = Swig_cparse_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); + } + } +} + |