| /* ----------------------------------------------------------------------------- | |
| * 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. | |
| * | |
| * utils.cxx | |
| * | |
| * Various utility functions. | |
| * ----------------------------------------------------------------------------- */ | |
| #include "swigmod.h" | |
| /* ----------------------------------------------------------------------------- | |
| * is_non_negative_integer() | |
| * | |
| * Checks that a typemap attribute value is written as a non-negative integer. | |
| * GetInt() uses atoi(), which quietly turns anything unparseable into zero, so a | |
| * value has to be checked with this before being read with GetInt(). | |
| * ----------------------------------------------------------------------------- */ | |
| bool is_non_negative_integer(String *value) { | |
| const char *c = value ? Char(value) : 0; | |
| if (!c || !*c) | |
| return false; | |
| for (; *c; c++) { | |
| if ((*c < '0') || (*c > '9')) | |
| return false; | |
| } | |
| return true; | |
| } | |
| int is_public(Node *n) { | |
| String *access = Getattr(n, "access"); | |
| return !access || !Cmp(access, "public"); | |
| } | |
| int is_private(Node *n) { | |
| String *access = Getattr(n, "access"); | |
| return access && !Cmp(access, "private"); | |
| } | |
| int is_protected(Node *n) { | |
| String *access = Getattr(n, "access"); | |
| return access && !Cmp(access, "protected"); | |
| } | |
| static int is_member_director_helper(Node *parentnode, Node *member) { | |
| int parent_nodirector = GetFlag(parentnode, "feature:nodirector"); | |
| if (parent_nodirector) | |
| return 0; | |
| int parent_director = Swig_director_mode() && GetFlag(parentnode, "feature:director"); | |
| int cdecl_director = parent_director || GetFlag(member, "feature:director"); | |
| int cdecl_nodirector = GetFlag(member, "feature:nodirector"); | |
| return cdecl_director && !cdecl_nodirector && !GetFlag(member, "feature:extend"); | |
| } | |
| int is_member_director(Node *parentnode, Node *member) { | |
| if (parentnode && checkAttribute(member, "storage", "virtual")) { | |
| return is_member_director_helper(parentnode, member); | |
| } else { | |
| return 0; | |
| } | |
| } | |
| int is_member_director(Node *member) { | |
| return is_member_director(Getattr(member, "parentNode"), member); | |
| } | |
| // Identifies the additional protected members that are generated when the allprotected option is used. | |
| // This does not include protected virtual methods as they are turned on with the dirprot option. | |
| int is_non_virtual_protected_access(Node *n) { | |
| int result = 0; | |
| if (Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode() && is_protected(n) && !checkAttribute(n, "storage", "virtual")) { | |
| Node *parentNode = Getattr(n, "parentNode"); | |
| // When vtable is empty, the director class does not get emitted, so a check for an empty vtable should be done. | |
| // However, vtable is set in Language and so is not yet set when methods in Typepass call clean_overloaded() | |
| // which calls is_non_virtual_protected_access. So commented out below. | |
| // Moving the director vtable creation into Typepass should solve this problem. | |
| if (is_member_director_helper(parentNode, n) /* && Getattr(parentNode, "vtable")*/) | |
| result = 1; | |
| } | |
| return result; | |
| } | |
| /* ----------------------------------------------------------------------------- | |
| * clean_overloaded() | |
| * | |
| * Clean overloaded list. Removes templates, ignored, and errors. | |
| * ----------------------------------------------------------------------------- */ | |
| void clean_overloaded(Node *n) { | |
| Node *nn = Getattr(n, "sym:overloaded"); | |
| Node *first = 0; | |
| while (nn) { | |
| String *ntype = nodeType(nn); | |
| if ((GetFlag(nn, "feature:ignore")) || (Getattr(nn, "error")) || (Strcmp(ntype, "template") == 0) || | |
| ((Strcmp(ntype, "cdecl") == 0) && is_protected(nn) && !is_member_director(nn) && !is_non_virtual_protected_access(n))) { | |
| /* Remove from overloaded list */ | |
| Node *ps = Getattr(nn, "sym:previousSibling"); | |
| Node *ns = Getattr(nn, "sym:nextSibling"); | |
| if (ps) { | |
| Setattr(ps, "sym:nextSibling", ns); | |
| } | |
| if (ns) { | |
| Setattr(ns, "sym:previousSibling", ps); | |
| } | |
| Delattr(nn, "sym:previousSibling"); | |
| Delattr(nn, "sym:nextSibling"); | |
| Delattr(nn, "sym:overloaded"); | |
| Delattr(nn, "sym:overname"); | |
| nn = ns; | |
| continue; | |
| } else { | |
| if (!first) | |
| first = nn; | |
| Setattr(nn, "sym:overloaded", first); | |
| } | |
| nn = Getattr(nn, "sym:nextSibling"); | |
| } | |
| if (!first || (first && !Getattr(first, "sym:nextSibling"))) { | |
| if (Getattr(n, "sym:overloaded")) | |
| Delattr(n, "sym:overloaded"); | |
| } | |
| Swig_symbol_fix_overname(Getattr(n, "sym:overloaded")); | |
| } | |
| /* ----------------------------------------------------------------------------- | |
| * Swig_set_max_hash_expand() | |
| * | |
| * Controls how many Hash objects are displayed when displaying nested Hash objects. | |
| * Makes DohSetMaxHashExpand an externally callable function (for debugger). | |
| * ----------------------------------------------------------------------------- */ | |
| void Swig_set_max_hash_expand(int count) { | |
| SetMaxHashExpand(count); | |
| } | |
| extern "C" { | |
| /* ----------------------------------------------------------------------------- | |
| * Swig_get_max_hash_expand() | |
| * | |
| * Returns how many Hash objects are displayed when displaying nested Hash objects. | |
| * Makes DohGetMaxHashExpand an externally callable function (for debugger). | |
| * ----------------------------------------------------------------------------- */ | |
| int Swig_get_max_hash_expand() { | |
| return GetMaxHashExpand(); | |
| } | |
| /* ----------------------------------------------------------------------------- | |
| * Swig_to_doh_string() | |
| * | |
| * DOH version of Swig_to_string() | |
| * ----------------------------------------------------------------------------- */ | |
| static String *Swig_to_doh_string(DOH *object, int count) { | |
| int old_count = Swig_get_max_hash_expand(); | |
| if (count >= 0) | |
| Swig_set_max_hash_expand(count); | |
| String *debug_string = object ? NewStringf("%s", object) : NewString("NULL"); | |
| Swig_set_max_hash_expand(old_count); | |
| return debug_string; | |
| } | |
| /* ----------------------------------------------------------------------------- | |
| * Swig_to_doh_string_with_location() | |
| * | |
| * DOH version of Swig_to_string_with_location() | |
| * ----------------------------------------------------------------------------- */ | |
| static String *Swig_to_doh_string_with_location(DOH *object, int count) { | |
| int old_count = Swig_get_max_hash_expand(); | |
| if (count >= 0) | |
| Swig_set_max_hash_expand(count); | |
| String *debug_string = Swig_stringify_with_location(object); | |
| Swig_set_max_hash_expand(old_count); | |
| return debug_string; | |
| } | |
| /* ----------------------------------------------------------------------------- | |
| * Swig_to_string() | |
| * | |
| * Swig debug - return C string representation of any DOH type. | |
| * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 | |
| * Note: leaks memory. | |
| * ----------------------------------------------------------------------------- */ | |
| const char *Swig_to_string(DOH *object, int count) { | |
| return Char(Swig_to_doh_string(object, count)); | |
| } | |
| /* ----------------------------------------------------------------------------- | |
| * Swig_to_string_with_location() | |
| * | |
| * Swig debug - return C string representation of any DOH type, within [] brackets | |
| * for Hash and List types, prefixed by line and file information. | |
| * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 | |
| * Note: leaks memory. | |
| * ----------------------------------------------------------------------------- */ | |
| const char *Swig_to_string_with_location(DOH *object, int count) { | |
| return Char(Swig_to_doh_string_with_location(object, count)); | |
| } | |
| /* ----------------------------------------------------------------------------- | |
| * Swig_print() | |
| * | |
| * Swig debug - display string representation of any DOH type. | |
| * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 | |
| * ----------------------------------------------------------------------------- */ | |
| void Swig_print(DOH *object, int count) { | |
| String *output = Swig_to_doh_string(object, count); | |
| Printf(stdout, "%s\n", output); | |
| Delete(output); | |
| } | |
| /* ----------------------------------------------------------------------------- | |
| * Swig_to_string_with_location() | |
| * | |
| * Swig debug - display string representation of any DOH type, within [] brackets | |
| * for Hash and List types, prefixed by line and file information. | |
| * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 | |
| * ----------------------------------------------------------------------------- */ | |
| void Swig_print_with_location(DOH *object, int count) { | |
| String *output = Swig_to_doh_string_with_location(object, count); | |
| Printf(stdout, "%s\n", output); | |
| Delete(output); | |
| } | |
| } // extern "C" |