summaryrefslogtreecommitdiffstats
path: root/contrib/tools/swig/Source/Swig/extend.c
diff options
context:
space:
mode:
authorrobot-piglet <[email protected]>2025-08-28 14:27:58 +0300
committerrobot-piglet <[email protected]>2025-08-28 14:57:06 +0300
commit81d828c32c8d5477cb2f0ce5da06a1a8d9392ca3 (patch)
tree3081d566f0d5158d76e9093261344f6406fd09f7 /contrib/tools/swig/Source/Swig/extend.c
parent77ea11423f959e51795cc3ef36a48d808b4ffb98 (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.c140
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);
+ }
+ }
+}
+