* 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.
*
* lang.cxx
*
* Language base class functions. Default C++ handling is also implemented here.
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
#include "cparse.h"
#include <ctype.h>
static int directors_allowed = 0;
static int director_language = 0;
static int director_mode = 0;
static int director_protected_mode = 1;
static int all_protected_mode = 0;
static int naturalvar_mode = 0;
Language *Language::this_ = 0;
int Swig_directors_enabled() {
return director_language && CPlusPlus && (directors_allowed || director_mode);
}
void Wrapper_director_mode_set(int flag) {
director_mode = flag;
}
void Wrapper_director_protected_mode_set(int flag) {
director_protected_mode = flag;
}
void Wrapper_all_protected_mode_set(int flag) {
all_protected_mode = flag;
}
void Wrapper_naturalvar_mode_set(int flag) {
naturalvar_mode = flag;
}
extern "C" {
int Swig_director_mode() {
return director_mode;
}
int Swig_director_protected_mode() {
return director_protected_mode;
}
int Swig_all_protected_mode() {
return all_protected_mode;
}
void Language_replace_special_variables(String *method, String *tm, Parm *parm) {
Language::instance()->replaceSpecialVariables(method, tm, parm);
}
}
static int InClass = 0;
static String *ClassName = 0;
static String *EnumClassName = 0;
static String *ClassPrefix = 0;
static String *EnumClassPrefix = 0;
static String *NSpace = 0;
static String *ClassType = 0;
static String *DirectorClassName = 0;
int Abstract = 0;
int ImportMode = 0;
int IsVirtual = 0;
static String *AttributeFunctionGet = 0;
static String *AttributeFunctionSet = 0;
static Node *CurrentClass = 0;
int line_number = 0;
String *input_file = 0;
int SmartPointer = 0;
static Hash *classhash;
extern int ForceExtern;
extern int AddExtern;
extern "C" {
extern int UseWrapperSuffix;
}
#define IMPORT_MODE 1
* Dispatcher::emit_one()
*
* Dispatch a single node
* ---------------------------------------------------------------------- */
int Dispatcher::emit_one(Node *n) {
int ret = SWIG_OK;
char *tag = Char(nodeType(n));
if (!tag) {
node!\n"); */
return SWIG_OK;
}
if (Getattr(n, "error"))
return SWIG_OK;
String *wrn = Getattr(n, "feature:warnfilter");
if (wrn)
Swig_warnfilter(wrn, 1);
* C/C++ parsing
* ============================================================ */
if (strcmp(tag, "extern") == 0) {
ret = externDeclaration(n);
} else if (strcmp(tag, "cdecl") == 0) {
ret = cDeclaration(n);
} else if (strcmp(tag, "enum") == 0) {
ret = enumDeclaration(n);
} else if (strcmp(tag, "enumitem") == 0) {
ret = enumvalueDeclaration(n);
} else if (strcmp(tag, "enumforward") == 0) {
ret = enumforwardDeclaration(n);
} else if (strcmp(tag, "class") == 0) {
ret = classDeclaration(n);
} else if (strcmp(tag, "classforward") == 0) {
ret = classforwardDeclaration(n);
} else if (strcmp(tag, "constructor") == 0) {
ret = constructorDeclaration(n);
} else if (strcmp(tag, "destructor") == 0) {
ret = destructorDeclaration(n);
} else if (strcmp(tag, "access") == 0) {
ret = accessDeclaration(n);
} else if (strcmp(tag, "using") == 0) {
ret = usingDeclaration(n);
} else if (strcmp(tag, "namespace") == 0) {
ret = namespaceDeclaration(n);
} else if (strcmp(tag, "template") == 0) {
ret = templateDeclaration(n);
} else if (strcmp(tag, "lambda") == 0) {
ret = lambdaDeclaration(n);
}
* SWIG directives
* =============================================================== */
else if (strcmp(tag, "top") == 0) {
ret = top(n);
} else if (strcmp(tag, "extend") == 0) {
ret = extendDirective(n);
} else if (strcmp(tag, "apply") == 0) {
ret = applyDirective(n);
} else if (strcmp(tag, "clear") == 0) {
ret = clearDirective(n);
} else if (strcmp(tag, "constant") == 0) {
ret = constantDirective(n);
} else if (strcmp(tag, "fragment") == 0) {
ret = fragmentDirective(n);
} else if (strcmp(tag, "import") == 0) {
ret = importDirective(n);
} else if (strcmp(tag, "include") == 0) {
ret = includeDirective(n);
} else if (strcmp(tag, "insert") == 0) {
ret = insertDirective(n);
} else if (strcmp(tag, "module") == 0) {
ret = moduleDirective(n);
} else if (strcmp(tag, "native") == 0) {
ret = nativeDirective(n);
} else if (strcmp(tag, "pragma") == 0) {
ret = pragmaDirective(n);
} else if (strcmp(tag, "typemap") == 0) {
ret = typemapDirective(n);
} else if (strcmp(tag, "typemapcopy") == 0) {
ret = typemapcopyDirective(n);
} else if (strcmp(tag, "typemapitem") == 0) {
ret = typemapitemDirective(n);
} else if (strcmp(tag, "types") == 0) {
ret = typesDirective(n);
} else {
Swig_error(input_file, line_number, "Unrecognized parse tree node type '%s'\n", tag);
ret = SWIG_ERROR;
}
if (wrn)
Swig_warnfilter(wrn, 0);
return ret;
}
* Dispatcher::emit_children()
*
* Emit all children that match the given type. type = 0 means all types.
* ---------------------------------------------------------------------- */
int Dispatcher::emit_children(Node *n) {
Node *c;
char *eo = Char(Getattr(n, "feature:emitonlychildren"));
for (c = firstChild(n); c; c = nextSibling(c)) {
if (eo) {
const char *tag = Char(nodeType(c));
if (strcmp(tag, "cdecl") == 0) {
if (checkAttribute(c, "storage", "typedef"))
tag = "typedef";
}
if (strstr(eo, tag) == 0) {
continue;
}
}
emit_one(c);
}
return SWIG_OK;
}
to fill in traversal code */
int Dispatcher::defaultHandler(Node *) {
return SWIG_OK;
}
int Dispatcher::extendDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::applyDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::clearDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::constantDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::fragmentDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::importDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::includeDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::insertDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::moduleDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::nativeDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::pragmaDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::typemapDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::typemapitemDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::typemapcopyDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::typesDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::cDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::externDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::enumDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::enumvalueDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::enumforwardDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::classDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::templateDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::lambdaDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::classforwardDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::constructorDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::destructorDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::accessDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::usingDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::namespaceDeclaration(Node *n) {
return defaultHandler(n);
}
Dispatcher::AccessMode Dispatcher::accessModeFromString(String *access) {
Dispatcher::AccessMode mode = PUBLIC;
if (Cmp(access, "public") == 0) {
mode = PUBLIC;
} else if (Cmp(access, "private") == 0) {
mode = PRIVATE;
} else if (Cmp(access, "protected") == 0) {
mode = PROTECTED;
} else {
assert(0);
}
return mode;
}
Language::Language():
none_comparison(NewString("$arg != 0")),
director_ctor_code(NewString("")),
director_prot_ctor_code(0),
director_multiple_inheritance(1),
doxygenTranslator(NULL),
symtabs(NewHash()),
overloading(0),
multiinput(0),
cplus_runtime(0) {
symbolAddScope("");
argc_template_string = NewString("argc");
argv_template_string = NewString("argv[%d]");
Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", " $director_new \n", "} else {\n", " $nondirector_new \n", "}\n", NIL);
assert(!this_);
this_ = this;
}
Language::~Language() {
Delete(symtabs);
Delete(director_ctor_code);
Delete(none_comparison);
this_ = 0;
}
* directorClassName()
* ----------------------------------------------------------------------------- */
String *Language::directorClassName(Node *n) {
String *dirclassname;
String *nspace = NewString(Getattr(n, "sym:nspace"));
const char *attrib = "director:classname";
String *classname = getClassPrefix();
Replace(nspace, NSPACE_SEPARATOR, "_", DOH_REPLACE_ANY);
if (Len(nspace) > 0)
dirclassname = NewStringf("SwigDirector_%s_%s", nspace, classname);
else
dirclassname = NewStringf("SwigDirector_%s", classname);
Setattr(n, attrib, dirclassname);
Delete(nspace);
return dirclassname;
}
emit_one()
---------------------------------------------------------------------- */
int Language::emit_one(Node *n) {
int ret;
int oldext;
if (!n)
return SWIG_OK;
if (GetFlag(n, "feature:ignore")
&& !Getattr(n, "feature:onlychildren"))
return SWIG_OK;
oldext = Extend;
if (Getattr(n, "feature:extend"))
Extend = 1;
line_number = Getline(n);
input_file = Getfile(n);
symtab = Getattr(n,"symtab");
if (symtab) {
symtab = Swig_symbol_setscope(symtab);
}
*/
ret = Dispatcher::emit_one(n);
if (symtab) {
Swig_symbol_setscope(symtab);
}
*/
Extend = oldext;
return ret;
}
static Parm *nonvoid_parms(Parm *p) {
if (p) {
SwigType *t = Getattr(p, "type");
if (SwigType_type(t) == T_VOID)
return 0;
}
return p;
}
* cplus_value_type()
*
* Returns the alternative value type needed in C++ for class value
* types. When swig is not sure about using a plain $ltype value,
* since the class doesn't have a default constructor, or it can't be
* assigned, you will get back 'SwigValueWrapper<(type)>'.
*
* ----------------------------------------------------------------------------- */
SwigType *cplus_value_type(SwigType *t) {
return SwigType_alttype(t, 0);
}
static Node *first_nontemplate(Node *n) {
while (n) {
if (Strcmp(nodeType(n), "template") != 0)
return n;
n = Getattr(n, "sym:nextSibling");
}
return n;
}
* swig_pragma()
*
* Handle swig pragma directives.
* -------------------------------------------------------------------------- */
static void swig_pragma(char *lang, char *name, char *value) {
if (strcmp(lang, "swig") == 0) {
if (strcmp(name, "attributefunction") == 0) {
String *nvalue = NewString(value);
char *s = strchr(Char(nvalue), ':');
if (!s) {
Swig_error(input_file, line_number, "Bad value for attributefunction. Expected \"fmtget:fmtset\".\n");
} else {
*s = 0;
AttributeFunctionGet = NewString(Char(nvalue));
AttributeFunctionSet = NewString(s + 1);
}
Delete(nvalue);
} else if (strcmp(name, "noattributefunction") == 0) {
AttributeFunctionGet = 0;
AttributeFunctionSet = 0;
}
}
}
* Language::use_naturalvar_mode()
*
* Determine whether to use const ref typemaps instead of pointer typemaps
* for variable access.
* -------------------------------------------------------------------------- */
int Language::use_naturalvar_mode(Node *n) const {
if (Getattr(n, "unnamed"))
return 0;
String *naturalvar = Getattr(n, "feature:naturalvar");
bool explicitly_off = naturalvar && Strcmp(naturalvar, "0") == 0;
int nvar = GetFlag(n, "feature:naturalvar");
if (!explicitly_off && !nvar) {
SwigType *ty = Getattr(n, "type");
SwigType *fullty = SwigType_typedef_resolve_all(ty);
if (SwigType_isclass(fullty)) {
SwigType *tys = SwigType_strip_qualifiers(fullty);
if (!CPlusPlus) {
Replaceall(tys, "struct ", "");
Replaceall(tys, "union ", "");
Replaceall(tys, "class ", "");
}
Node *typenode = Swig_symbol_clookup(tys, 0);
if (typenode) {
naturalvar = Getattr(typenode, "feature:naturalvar");
explicitly_off = naturalvar && Strcmp(naturalvar, "0") == 0;
nvar = nvar || GetFlag(typenode, "feature:naturalvar");
}
Delete(tys);
}
Delete(fullty);
}
nvar = nvar || naturalvar_mode;
return explicitly_off ? 0 : nvar ? CWRAP_NATURAL_VAR : 0;
}
* Language::top() - Top of parsing tree
* ---------------------------------------------------------------------- */
int Language::top(Node *n) {
Node *mod = Getattr(n, "module");
if (mod) {
Node *options = Getattr(mod, "options");
if (options) {
if (Getattr(options, "naturalvar")) {
naturalvar_mode = 1;
}
}
}
classhash = Getattr(n, "classes");
return emit_children(n);
}
* Language::extendDirective()
* ---------------------------------------------------------------------- */
int Language::extendDirective(Node *n) {
save_value<int> oldam(Extend, CWRAP_EXTEND);
save_value<AccessMode> oldmode(cplus_mode, PUBLIC);
emit_children(n);
return SWIG_OK;
}
* Language::applyDirective()
* ---------------------------------------------------------------------- */
int Language::applyDirective(Node *n) {
Parm *pattern = Getattr(n, "pattern");
Node *c = firstChild(n);
while (c) {
Parm *apattern = Getattr(c, "pattern");
if (ParmList_len(pattern) != ParmList_len(apattern)) {
Swig_error(input_file, line_number, "Can't apply (%s) to (%s). Number of arguments don't match.\n", ParmList_str(pattern), ParmList_str(apattern));
} else {
if (!Swig_typemap_apply(pattern, apattern)) {
Swig_warning(WARN_TYPEMAP_APPLY_UNDEF, input_file, line_number, "Can't apply (%s). No typemaps are defined.\n", ParmList_str(pattern));
}
}
c = nextSibling(c);
}
return SWIG_OK;
}
* Language::clearDirective()
* ---------------------------------------------------------------------- */
int Language::clearDirective(Node *n) {
Node *p;
for (p = firstChild(n); p; p = nextSibling(p)) {
ParmList *pattern = Getattr(p, "pattern");
Swig_typemap_clear_apply(pattern);
}
return SWIG_OK;
}
* Language::constantDirective()
* ---------------------------------------------------------------------- */
int Language::constantDirective(Node *n) {
if (CurrentClass && (cplus_mode != PUBLIC))
return SWIG_NOWRAP;
if (!GetFlag(n, "feature:allowexcept")) {
UnsetFlag(n, "feature:except");
}
if (Getattr(n, "feature:exceptvar")) {
Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
}
if (!ImportMode) {
Swig_require("constantDirective", n, "name", "?value", NIL);
if (!Getattr(n, "value")) {
Setattr(n, "value", Getattr(n, "name"));
}
this->constantWrapper(n);
Swig_restore(n);
return SWIG_OK;
}
return SWIG_NOWRAP;
}
* Language::fragmentDirective()
* ---------------------------------------------------------------------- */
int Language::fragmentDirective(Node *n) {
if (!(Getattr(n, "emitonly") && ImportMode))
Swig_fragment_register(n);
return SWIG_OK;
}
* Language::importDirective()
* ---------------------------------------------------------------------- */
int Language::importDirective(Node *n) {
int oldim = ImportMode;
ImportMode = IMPORT_MODE;
emit_children(n);
ImportMode = oldim;
return SWIG_OK;
}
* Language::includeDirective()
* ---------------------------------------------------------------------- */
int Language::includeDirective(Node *n) {
emit_children(n);
return SWIG_OK;
}
* Language::insertDirective()
* ---------------------------------------------------------------------- */
int Language::insertDirective(Node *n) {
if ((!ImportMode) || Getattr(n, "generated")) {
String *code = Getattr(n, "code");
String *section = Getattr(n, "section");
File *f = 0;
if (!section) {
f = Swig_filebyname("header");
} else {
f = Swig_filebyname(section);
}
if (f) {
Printf(f, "%s\n", code);
} else {
Swig_error(input_file, line_number, "Unknown target '%s' for %%insert directive.\n", section);
}
return SWIG_OK;
} else {
return SWIG_NOWRAP;
}
}
* Language::moduleDirective()
* ---------------------------------------------------------------------- */
int Language::moduleDirective(Node *n) {
(void) n;
return SWIG_OK;
}
* Language::nativeDirective()
* ---------------------------------------------------------------------- */
int Language::nativeDirective(Node *n) {
if (!ImportMode) {
return nativeWrapper(n);
} else {
return SWIG_NOWRAP;
}
}
* Language::pragmaDirective()
* ---------------------------------------------------------------------- */
int Language::pragmaDirective(Node *n) {
if (!ImportMode) {
String *lan = Getattr(n, "lang");
String *name = Getattr(n, "name");
String *value = Getattr(n, "value");
swig_pragma(Char(lan), Char(name), Char(value));
return SWIG_OK;
}
return SWIG_OK;
}
* Language::typemapDirective()
* ---------------------------------------------------------------------- */
int Language::typemapDirective(Node *n) {
String *method = Getattr(n, "method");
String *code = Getattr(n, "code");
Parm *kwargs = Getattr(n, "kwargs");
Node *items = firstChild(n);
static int nameerror = 0;
if (code && (Strstr(code, "$source") || (Strstr(code, "$target")))) {
Swig_error(Getfile(n), Getline(n), "Obsolete typemap feature ($source/$target).\n");
if (!nameerror) {
Swig_error(Getfile(n), Getline(n), "The use of $source and $target in a typemap declaration is no longer supported.\n\
For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\
$source by $input and $target by $1. For typemaps related to return values (out,\n\
argout,ret,except), replace $source by $1 and $target by $result. See the file\n\
Doc/Manual/Typemaps.html for complete details.\n");
nameerror = 1;
}
}
if (Strcmp(method, "except") == 0) {
Swig_error(Getfile(n), Getline(n), "%%typemap(except) is no longer supported. Use the %%exception directive.\n");
}
if (Strcmp(method, "in") == 0) {
Hash *k;
k = kwargs;
while (k) {
if (checkAttribute(k, "name", "numinputs")) {
if (!multiinput && (GetInt(k, "value") > 1)) {
Swig_error(Getfile(n), Getline(n), "Multiple-input typemaps (numinputs > 1) not supported by this target language module.\n");
return SWIG_ERROR;
}
break;
}
k = nextSibling(k);
}
if (!k) {
k = NewHash();
Setattr(k, "name", "numinputs");
Setattr(k, "value", "1");
set_nextSibling(k, kwargs);
Setattr(n, "kwargs", k);
kwargs = k;
}
}
if (Strcmp(method, "ignore") == 0) {
Swig_error(Getfile(n), Getline(n), "%%typemap(ignore) is no longer supported. Use %%typemap(in,numinputs=0).\n");
}
if (code) {
Setfile(code, Getfile(n));
Setline(code, Getline(n));
Swig_cparse_replace_descriptor(code);
}
while (items) {
Parm *pattern = Getattr(items, "pattern");
Parm *parms = Getattr(items, "parms");
if (code) {
Swig_typemap_register(method, pattern, code, parms, kwargs);
} else {
Swig_typemap_clear(method, pattern);
}
items = nextSibling(items);
}
return SWIG_OK;
}
* Language::typemapcopyDirective()
* ---------------------------------------------------------------------- */
int Language::typemapcopyDirective(Node *n) {
String *method = Getattr(n, "method");
Parm *pattern = Getattr(n, "pattern");
Node *items = firstChild(n);
int nsrc = 0;
nsrc = ParmList_len(pattern);
while (items) {
ParmList *npattern = Getattr(items, "pattern");
if (nsrc != ParmList_len(npattern)) {
Swig_error(input_file, line_number, "Can't copy typemap. Number of types differ.\n");
} else {
if (Swig_typemap_copy(method, pattern, npattern) < 0) {
Swig_error(input_file, line_number, "Can't copy typemap (%s) %s = %s\n", method, ParmList_str(pattern), ParmList_str(npattern));
}
}
items = nextSibling(items);
}
return SWIG_OK;
}
* Language::typesDirective()
* ---------------------------------------------------------------------- */
int Language::typesDirective(Node *n) {
Parm *parms = Getattr(n, "parms");
String *convcode = Getattr(n, "convcode");
while (parms) {
SwigType *t = Getattr(parms, "type");
String *v = Getattr(parms, "value");
if (!v) {
SwigType_remember(t);
} else {
if (SwigType_issimple(t)) {
SwigType_inherit(t, v, 0, convcode);
}
}
parms = nextSibling(parms);
}
return SWIG_OK;
}
* Language::cDeclaration()
* ---------------------------------------------------------------------- */
int Language::cDeclaration(Node *n) {
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
SwigType *decl = Getattr(n, "decl");
String *storage = Getattr(n, "storage");
Node *over;
File *f_header = 0;
SwigType *ty, *fullty;
if (Getattr(n, "feature:onlychildren")) {
if (GetFlag(n, "feature:ignore")) {
return SWIG_NOWRAP;
} else {
if (Strncmp(symname, "__dummy_", 8) == 0 && Cmp(storage, "typedef") != 0) {
SetFlag(n, "feature:ignore");
Swig_warning(WARN_LANG_TEMPLATE_METHOD_IGNORE, input_file, line_number,
"%%template() contains no name. Template method ignored: %s\n", Swig_name_decl(n));
return SWIG_NOWRAP;
}
}
}
if (cplus_mode != PUBLIC || !is_public(n)) {
int isfriend = (Strstr(storage, "friend") != NULL);
if (!isfriend) {
* Also wrap non-virtual protected members if asked for (allprotected mode). */
if (!(Swig_directors_enabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || isNonVirtualProtectedAccess(n)))) {
return SWIG_NOWRAP;
}
String *wrapname = NewStringf("nonpublic_%s%s", symname, Getattr(n, "sym:overname"));
if (Getattr(CurrentClass, wrapname)) {
Delete(wrapname);
return SWIG_NOWRAP;
}
SetFlag(CurrentClass, wrapname);
Delete(wrapname);
}
}
if (Cmp(storage, "typedef") == 0) {
Swig_save("cDeclaration", n, "type", NIL);
SwigType *t = Copy(type);
if (t) {
SwigType_push(t, decl);
Setattr(n, "type", t);
typedefHandler(n);
}
Swig_restore(n);
return SWIG_OK;
}
if (ImportMode)
return SWIG_NOWRAP;
if (Extend) {
String *code = Getattr(n, "code");
if (code) {
Setfile(code, Getfile(n));
Setline(code, Getline(n));
Swig_cparse_replace_descriptor(code);
}
}
over = Swig_symbol_isoverloaded(n);
if (!overloading) {
if (over)
over = first_nontemplate(over);
if (over && (over != n)) {
Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored. %s\n", Swig_name_decl(n));
Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over), "Previous declaration is %s\n", Swig_name_decl(over));
return SWIG_NOWRAP;
}
}
if (!validIdentifier(symname)) {
Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap '%s' unless renamed to a valid identifier.\n", SwigType_namestr(symname));
return SWIG_NOWRAP;
}
ty = NewString(type);
SwigType_push(ty, decl);
fullty = SwigType_typedef_resolve_all(ty);
if (SwigType_isfunction(fullty)) {
if (!SwigType_isfunction(ty)) {
Delete(ty);
ty = fullty;
fullty = 0;
ParmList *parms = SwigType_function_parms(ty, n);
Setattr(n, "parms", parms);
}
if (!CurrentClass) {
f_header = Swig_filebyname("header");
if (AddExtern) {
if (f_header) {
if (Swig_storage_isextern(n) || (ForceExtern && !storage)) {
and it produces some problems when namespace and SUN
Studio is used.
Printf(f_header,"extern %s", SwigType_str(ty,name));
In fact generating extern declarations is quite error prone and is
no longer the default. Getting it right seems impossible with namespaces
and default arguments and when a method is declared with the various Windows
calling conventions - SWIG doesn't understand Windows (non standard) calling
conventions in the first place, so can't regenerate them.
*/
String *str = SwigType_str(ty, name);
Printf(f_header, "%s", str);
Delete(str);
{
DOH *t = Getattr(n, "throws");
if (t) {
Printf(f_header, " throw(");
while (t) {
Printf(f_header, "%s", Getattr(t, "type"));
t = nextSibling(t);
if (t)
Printf(f_header, ",");
}
Printf(f_header, ")");
}
}
Printf(f_header, ";\n");
} else if (Swig_storage_isexternc(n)) {
String *str = SwigType_str(ty, name);
Printf(f_header, "extern \"C\" %s;\n", str);
Delete(str);
}
}
}
}
if (SwigType_isqualifier(ty)) {
SwigType *qual = SwigType_pop(ty);
Setattr(n, "qualifier", qual);
Delete(qual);
}
Delete(SwigType_pop_function(ty));
DohIncref(type);
Setattr(n, "type", ty);
functionHandler(n);
Setattr(n, "type", type);
Delete(ty);
Delete(type);
return SWIG_OK;
} else {
String *declaration = Copy(decl);
Delattr(n, "decl");
if (!CurrentClass) {
if (Swig_storage_isextern(n) || ForceExtern) {
if (AddExtern) {
f_header = Swig_filebyname("header");
if (f_header) {
String *str = SwigType_str(ty, name);
Printf(f_header, "%s %s;\n", Getattr(n, "storage"), str);
Delete(str);
}
}
}
}
DohIncref(type);
Setattr(n, "type", ty);
variableHandler(n);
Setattr(n, "type", type);
Setattr(n, "decl", declaration);
Delete(ty);
Delete(type);
Delete(fullty);
return SWIG_OK;
}
}
* Language::functionHandler()
* ---------------------------------------------------------------------- */
int Language::functionHandler(Node *n) {
String *storage = Getattr(n, "storage");
int isfriend = CurrentClass && Strstr(storage, "friend");
int isstatic = CurrentClass && Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"));
Parm *p = Getattr(n, "parms");
if (GetFlag(n, "feature:del")) {
if (CurrentClass && !isstatic && !isfriend) {
SetFlag(n, "feature:self:disown");
} else {
if (p)
SetFlag(p, "wrap:disown");
}
}
if (!CurrentClass) {
globalfunctionHandler(n);
} else {
if (isstatic) {
staticmemberfunctionHandler(n);
} else if (isfriend) {
int oldInClass = InClass;
InClass = 0;
globalfunctionHandler(n);
InClass = oldInClass;
} else {
SetFlag(n, "memberfunction");
Node *explicit_n = 0;
if (Swig_directors_enabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
if (virtual_but_not_pure_virtual) {
explicit_n = Copy(n);
String *new_symname = Copy(Getattr(n, "sym:name"));
String *suffix = Getattr(parentNode(n), "sym:name");
Printv(new_symname, "SwigExplicit", suffix, NIL);
Setattr(explicit_n, "sym:name", new_symname);
Delattr(explicit_n, "storage");
Delattr(explicit_n, "override");
Delattr(explicit_n, "hides");
SetFlag(explicit_n, "explicitcall");
Setattr(n, "explicitcallnode", explicit_n);
}
}
memberfunctionHandler(n);
if (explicit_n) {
memberfunctionHandler(explicit_n);
Delattr(explicit_n, "explicitcall");
Delete(explicit_n);
}
}
}
return SWIG_OK;
}
* Language::globalfunctionHandler()
* ---------------------------------------------------------------------- */
int Language::globalfunctionHandler(Node *n) {
Swig_require("globalfunctionHandler", n, "name", "sym:name", "type", "?parms", NIL);
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
ParmList *parms = Getattr(n, "parms");
String *cb = GetFlagAttr(n, "feature:callback");
if (cb) {
String *cbname = Getattr(n, "feature:callback:name");
if (!cbname) {
cbname = NewStringf(cb, symname);
Setattr(n, "feature:callback:name", cbname);
}
callbackfunctionHandler(n);
if (Cmp(cbname, symname) == 0) {
Delete(cbname);
Swig_restore(n);
return SWIG_NOWRAP;
}
Delete(cbname);
}
Setattr(n, "parms", nonvoid_parms(parms));
String *extendname = Getattr(n, "extendname");
String *call = Swig_cfunction_call(extendname ? extendname : name, parms);
String *cres = Swig_cresult(type, Swig_cresult_name(), call);
String *friendusing = Getattr(n, "friendusing");
if (friendusing) {
String *action = NewStringf("%s\n%s", friendusing, cres);
Setattr(n, "wrap:action", action);
Delete(action);
} else {
Setattr(n, "wrap:action", cres);
}
Delete(cres);
Delete(call);
functionWrapper(n);
Swig_restore(n);
return SWIG_OK;
}
* Language::callbackfunctionHandler()
* ---------------------------------------------------------------------- */
int Language::callbackfunctionHandler(Node *n) {
Swig_require("callbackfunctionHandler", n, "name", "*sym:name", "*type", "?value", NIL);
String *type = Getattr(n, "type");
String *name = Getattr(n, "name");
String *parms = Getattr(n, "parms");
String *cbname = Getattr(n, "feature:callback:name");
String *calltype = NewStringf("(%s (*)(%s))(%s)", SwigType_str(type, 0), ParmList_str(parms), SwigType_namestr(name));
SwigType *cbty = Copy(type);
SwigType_add_function(cbty, parms);
SwigType_add_pointer(cbty);
Setattr(n, "sym:name", cbname);
Setattr(n, "type", cbty);
Setattr(n, "value", calltype);
Node *ns = symbolLookup(cbname);
if (!ns)
constantWrapper(n);
Delete(cbty);
Swig_restore(n);
return SWIG_OK;
}
* Language::memberfunctionHandler()
* ---------------------------------------------------------------------- */
int Language::memberfunctionHandler(Node *n) {
Swig_require("memberfunctionHandler", n, "*name", "*sym:name", "*type", "?parms", "?value", NIL);
String *storage = Getattr(n, "storage");
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *value = Getattr(n, "value");
ParmList *parms = Getattr(n, "parms");
String *cb = GetFlagAttr(n, "feature:callback");
if (Cmp(storage, "virtual") == 0) {
if (Cmp(value, "0") == 0) {
IsVirtual = PURE_VIRTUAL;
} else {
IsVirtual = PLAIN_VIRTUAL;
}
} else {
IsVirtual = 0;
}
if (cb) {
Node *cbn = NewHash();
String *cbname = Getattr(n, "feature:callback:name");
if (!cbname) {
cbname = NewStringf(cb, symname);
}
SwigType *cbty = Copy(type);
SwigType_add_function(cbty, parms);
SwigType_add_memberpointer(cbty, ClassName);
String *cbvalue = NewStringf("&%s::%s", ClassName, name);
Setattr(cbn, "sym:name", cbname);
Setattr(cbn, "type", cbty);
Setattr(cbn, "value", cbvalue);
Setattr(cbn, "name", name);
Setfile(cbn, Getfile(n));
Setline(cbn, Getline(n));
memberconstantHandler(cbn);
Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname));
Delete(cb);
Delete(cbn);
Delete(cbvalue);
Delete(cbty);
Delete(cbname);
if (Cmp(cbname, symname) == 0) {
Swig_restore(n);
return SWIG_NOWRAP;
}
}
String *fname = Swig_name_member(NSpace, ClassPrefix, symname);
if (Extend && SmartPointer) {
if (!Getattr(n, "extendsmartclassname")) {
Setattr(n, "extendsmartclassname", Getattr(CurrentClass, "allocate:smartpointerpointeeclassname"));
}
}
String *director_type = 0;
if (!is_public(n) && (is_member_director(CurrentClass, n) || GetFlag(n, "explicitcall") || isNonVirtualProtectedAccess(n))) {
director_type = Copy(DirectorClassName);
String *qualifier = Getattr(n, "qualifier");
if (qualifier)
SwigType_push(director_type, qualifier);
SwigType_add_pointer(director_type);
}
int DirectorExtraCall = 0;
if (Swig_directors_enabled() && is_member_director(CurrentClass, n) && !SmartPointer)
if (extraDirectorProtectedCPPMethodsRequired())
DirectorExtraCall = CWRAP_DIRECTOR_TWO_CALLS;
if (GetFlag(n, "explicitcall"))
DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL;
int extendmember = GetFlag(n, "isextendmember") ? Extend : 0;
int flags = Getattr(n, "template") ? extendmember | SmartPointer : Extend | SmartPointer | DirectorExtraCall;
Swig_MethodToFunction(n, NSpace, ClassType, flags, director_type, is_member_director(CurrentClass, n));
Setattr(n, "sym:name", fname);
Setattr(n, "doc:low:name", fname);
Setattr(n, "doc:high:name", symname);
functionWrapper(n);
Delete(director_type);
Delete(fname);
Swig_restore(n);
return SWIG_OK;
}
* Language::staticmemberfunctionHandler()
* ---------------------------------------------------------------------- */
int Language::staticmemberfunctionHandler(Node *n) {
Swig_require("staticmemberfunctionHandler", n, "*name", "*sym:name", "*type", NIL);
Swig_save("staticmemberfunctionHandler", n, "storage", NIL);
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
ParmList *parms = Getattr(n, "parms");
String *cb = GetFlagAttr(n, "feature:callback");
String *cname;
String *mrename = Swig_name_member(NSpace, ClassPrefix, symname);
if (!(Extend && GetFlag(n, "isextendmember"))) {
Node *sb = Getattr(n, "cplus:staticbase");
String *sname = Getattr(sb, "name");
if (isNonVirtualProtectedAccess(n))
cname = NewStringf("%s::%s", DirectorClassName, name);
else
cname = NewStringf("%s::%s", sname, name);
} else {
String *classname_str = SwigType_namestr(ClassName);
String *mname = Swig_name_mangle_string(classname_str);
cname = Swig_name_member(NSpace, mname, name);
Delete(mname);
Delete(classname_str);
String *code = Getattr(n, "code");
String *defaultargs = Getattr(n, "defaultargs");
String *mangled = Swig_name_mangle_string(mrename);
Delete(mrename);
mrename = mangled;
if (code) {
if (Getattr(n, "sym:overloaded")) {
Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
} else if (UseWrapperSuffix) {
Append(cname, "__SWIG");
}
if (!defaultargs) {
String *mangled_cname = Swig_name_mangle_string(cname);
Swig_add_extension_code(n, mangled_cname, parms, type, code, CPlusPlus, 0);
Setattr(n, "extendname", mangled_cname);
Delete(mangled_cname);
}
}
}
Setattr(n, "name", cname);
Setattr(n, "sym:name", mrename);
Setattr(n, "doc:low:name", mrename);
Setattr(n, "doc:high:name", symname);
if (cb) {
String *cbname = NewStringf(cb, symname);
Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname));
Setattr(n, "feature:callback:staticname", name);
}
Delattr(n, "storage");
globalfunctionHandler(n);
Delete(cname);
Delete(mrename);
Swig_restore(n);
return SWIG_OK;
}
* Language::variableHandler()
* ---------------------------------------------------------------------- */
int Language::variableHandler(Node *n) {
feature:except. There is no way C++ or C would throw
an exception merely for accessing a member data.
Caveat: Some compilers seem to route attribute access through
methods which can generate exceptions. The feature:allowexcept
allows this. Also, the feature:exceptvar can be used to match
only variables.
*/
if (!(Extend | SmartPointer)) {
if (!GetFlag(n, "feature:allowexcept")) {
UnsetFlag(n, "feature:except");
}
if (Getattr(n, "feature:exceptvar")) {
Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
}
}
if (!CurrentClass) {
globalvariableHandler(n);
} else {
Swig_save("variableHandler", n, "feature:immutable", NIL);
if (SmartPointer) {
if (!Getattr(CurrentClass, "allocate:smartpointermutable")) {
SetFlag(n, "feature:immutable");
}
}
if (Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"))) {
staticmembervariableHandler(n);
} else {
membervariableHandler(n);
}
Swig_restore(n);
}
return SWIG_OK;
}
* Language::globalvariableHandler()
* ---------------------------------------------------------------------- */
int Language::globalvariableHandler(Node *n) {
variableWrapper(n);
return SWIG_OK;
}
* Language::membervariableHandler()
* ---------------------------------------------------------------------- */
int Language::membervariableHandler(Node *n) {
Swig_require("membervariableHandler", n, "*name", "*sym:name", "*type", NIL);
Swig_save("membervariableHandler", n, "parms", NIL);
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
if (!AttributeFunctionGet) {
String *mname = Swig_name_member(0, ClassPrefix, symname);
String *mrename_get = Swig_name_get(NSpace, mname);
String *mrename_set = Swig_name_set(NSpace, mname);
Delete(mname);
int assignable = !is_immutable(n);
if (SmartPointer) {
if (!Getattr(CurrentClass, "allocate:smartpointermutable")) {
assignable = 0;
}
}
if (assignable) {
int make_set_wrapper = 1;
String *tm = 0;
String *target = 0;
if (!Extend) {
if (SmartPointer) {
if (Swig_storage_isstatic(n)) {
Node *sn = Getattr(n, "cplus:staticbase");
String *base = Getattr(sn, "name");
target = NewStringf("%s::%s", base, name);
} else {
String *pname = Swig_cparm_name(0, 0);
target = NewStringf("(*%s)->%s", pname, name);
Delete(pname);
}
} else {
String *pname = isNonVirtualProtectedAccess(n) ? NewString("darg") : Swig_cparm_name(0, 0);
target = NewStringf("%s->%s", pname, name);
Delete(pname);
}
Parm *nin = NewParm(type, name, n);
tm = Swig_typemap_lookup("memberin", nin, target, 0);
Delete(nin);
}
int flags = Extend | SmartPointer | use_naturalvar_mode(n);
if (isNonVirtualProtectedAccess(n))
flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
Swig_MembersetToFunction(n, ClassType, flags);
Setattr(n, "memberset", "1");
if (!Extend) {
if (!tm) {
if (SwigType_isarray(type)) {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
make_set_wrapper = 0;
}
} else {
String *pname0 = Swig_cparm_name(0, 0);
String *pname1 = Swig_cparm_name(0, 1);
Replace(tm, "$input", pname1, DOH_REPLACE_ANY);
Replace(tm, "$self", pname0, DOH_REPLACE_ANY);
Setattr(n, "wrap:action", tm);
Delete(tm);
Delete(pname0);
Delete(pname1);
}
Delete(target);
}
if (make_set_wrapper) {
Setattr(n, "sym:name", mrename_set);
functionWrapper(n);
} else {
SetFlag(n, "feature:immutable");
}
Setattr(n, "type", type);
Setattr(n, "name", name);
Setattr(n, "sym:name", symname);
Delattr(n, "memberset");
Iterator ki;
for (ki = First(n); ki.key; ki = Next(ki)) {
if (Strncmp(ki.key, "tmap:", 5) == 0)
Delattr(n, ki.key);
}
}
{
int flags = Extend | SmartPointer | use_naturalvar_mode(n);
if (isNonVirtualProtectedAccess(n))
flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
Swig_MembergetToFunction(n, ClassType, flags);
Setattr(n, "sym:name", mrename_get);
Setattr(n, "memberget", "1");
functionWrapper(n);
Delattr(n, "memberget");
}
Delete(mrename_get);
Delete(mrename_set);
} else {
where member variables are converted automagically to
accessor functions */
#if 0
Parm *p;
String *gname;
SwigType *vty;
p = NewParm(type, 0, n);
gname = NewStringf(AttributeFunctionGet, symname);
if (!Extend) {
ActionFunc = Copy(Swig_cmemberget_call(name, type));
cpp_member_func(Char(gname), Char(gname), type, 0);
Delete(ActionFunc);
} else {
String *cname = Swig_name_get(NSpace, name);
cpp_member_func(Char(cname), Char(gname), type, 0);
Delete(cname);
}
Delete(gname);
if (!GetFlag(n, "feature:immutable")) {
gname = NewStringf(AttributeFunctionSet, symname);
vty = NewString("void");
if (!Extend) {
ActionFunc = Copy(Swig_cmemberset_call(name, type));
cpp_member_func(Char(gname), Char(gname), vty, p);
Delete(ActionFunc);
} else {
String *cname = Swig_name_set(NSpace, name);
cpp_member_func(Char(cname), Char(gname), vty, p);
Delete(cname);
}
Delete(gname);
}
ActionFunc = 0;
#endif
}
Swig_restore(n);
return SWIG_OK;
}
* Language::staticmembervariableHandler()
* ---------------------------------------------------------------------- */
int Language::staticmembervariableHandler(Node *n) {
Swig_require("staticmembervariableHandler", n, "*name", "*sym:name", "*type", "?value", NIL);
String *value = Getattr(n, "value");
String *classname = !SmartPointer ? (isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerpointeeclassname");
if (!value || !Getattr(n, "hasconsttype")) {
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
String *cname, *mrename;
mrename = Swig_name_member(0, ClassPrefix, symname);
cname = NewStringf("%s::%s", classname, name);
Setattr(n, "sym:name", mrename);
Setattr(n, "name", cname);
variableWrapper(n);
Delete(mrename);
Delete(cname);
} else {
Certain C++ compilers optimize this out so that there is no linkage to a
memory address. Example:
class Foo {
public:
static const int x = 3;
};
Some discussion of this in section 9.4 of the C++ draft standard.
Also, we have to manage the case:
class Foo {
public:
%extend {
static const int x = 3;
}
};
in which there's no actual Foo::x variable to refer to. In this case,
the best we can do is to wrap the given value verbatim.
*/
String *name = Getattr(n, "name");
String *cname = NewStringf("%s::%s", classname, name);
if (Extend) {
There's nothing we can do; we just keep the given value */
} else {
String *value = SwigType_namestr(cname);
Setattr(n, "value", value);
}
SwigType *t1 = SwigType_typedef_resolve_all(Getattr(n, "type"));
SwigType *t2 = SwigType_strip_qualifiers(t1);
Setattr(n, "type", t2);
Delete(t1);
Delete(t2);
SetFlag(n, "wrappedasconstant");
memberconstantHandler(n);
Delete(cname);
}
Swig_restore(n);
return SWIG_OK;
}
* Language::externDeclaration()
* ---------------------------------------------------------------------- */
int Language::externDeclaration(Node *n) {
return emit_children(n);
}
* Language::enumDeclaration()
* ---------------------------------------------------------------------- */
int Language::enumDeclaration(Node *n) {
if (CurrentClass && (cplus_mode != PUBLIC))
return SWIG_NOWRAP;
String *oldNSpace = NSpace;
NSpace = Getattr(n, "sym:nspace");
String *oldEnumClassPrefix = EnumClassPrefix;
if (GetFlag(n, "scopedenum")) {
assert(Getattr(n, "sym:name"));
assert(Getattr(n, "name"));
EnumClassPrefix = ClassPrefix ? NewStringf("%s_", ClassPrefix) : NewString("");
Printv(EnumClassPrefix, Getattr(n, "sym:name"), NIL);
EnumClassName = Copy(Getattr(n, "name"));
}
if (!ImportMode) {
emit_children(n);
}
if (GetFlag(n, "scopedenum")) {
Delete(EnumClassName);
EnumClassName = 0;
Delete(EnumClassPrefix);
EnumClassPrefix = oldEnumClassPrefix;
}
NSpace = oldNSpace;
return SWIG_OK;
}
* Language::enumvalueDeclaration()
* ---------------------------------------------------------------------- */
int Language::enumvalueDeclaration(Node *n) {
if (CurrentClass && (cplus_mode != PUBLIC))
return SWIG_NOWRAP;
Swig_require("enumvalueDeclaration", n, "*name", "*sym:name", "?value", NIL);
String *value = Getattr(n, "value");
String *name = Getattr(n, "name");
String *tmpValue;
if (value)
tmpValue = NewString(value);
else
tmpValue = NewString(name);
Setattr(n, "value", tmpValue);
Node *parent = parentNode(n);
if (GetFlag(parent, "scopedenum")) {
String *symname = Swig_name_member(0, Getattr(parent, "sym:name"), Getattr(n, "sym:name"));
Setattr(n, "sym:name", symname);
Delete(symname);
}
if (!CurrentClass || !cparse_cplusplus) {
Setattr(n, "name", tmpValue);
constantWrapper(n);
} else {
memberconstantHandler(n);
}
Delete(tmpValue);
Swig_restore(n);
return SWIG_OK;
}
* Language::enumforwardDeclaration()
* ---------------------------------------------------------------------- */
int Language::enumforwardDeclaration(Node *n) {
(void) n;
if (GetFlag(n, "enumMissing"))
enumDeclaration(n);
return SWIG_OK;
}
* Language::memberconstantHandler()
* ----------------------------------------------------------------------------- */
int Language::memberconstantHandler(Node *n) {
Swig_require("memberconstantHandler", n, "*name", "*sym:name", "value", NIL);
if (!GetFlag(n, "feature:allowexcept")) {
UnsetFlag(n, "feature:except");
}
if (Getattr(n, "feature:exceptvar")) {
Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
}
String *enumvalue_symname = Getattr(n, "enumvalueDeclaration:sym:name");
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
String *value = Getattr(n, "value");
String *mrename = Swig_name_member(0, EnumClassPrefix, enumvalue_symname ? enumvalue_symname : symname);
Setattr(n, "sym:name", mrename);
String *new_name = 0;
if (Extend)
new_name = Copy(value);
else if (EnumClassName)
new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : EnumClassName, name);
else
new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName, name);
Setattr(n, "name", new_name);
constantWrapper(n);
Delete(mrename);
Delete(new_name);
Swig_restore(n);
return SWIG_OK;
}
* Language::typedefHandler()
* ---------------------------------------------------------------------- */
int Language::typedefHandler(Node *n) {
typedef pointer, if already it is not a pointer or reference, as
in
typedef void NT;
int func(NT *p);
see director_basic.i for example.
*/
SwigType *name = Getattr(n, "name");
SwigType *decl = Getattr(n, "decl");
Setfile(name, Getfile(n));
Setline(name, Getline(n));
if (!SwigType_ispointer(decl) && !SwigType_isreference(decl)) {
SwigType *pname = Copy(name);
SwigType_add_pointer(pname);
SwigType_remember(pname);
Delete(pname);
}
return SWIG_OK;
}
* Language::classDirectorMethod()
* ---------------------------------------------------------------------- */
int Language::classDirectorMethod(Node *n, Node *parent, String *super) {
(void) n;
(void) parent;
(void) super;
return SWIG_OK;
}
* Language::classDirectorConstructor()
* ---------------------------------------------------------------------- */
int Language::classDirectorConstructor(Node *n) {
(void) n;
return SWIG_OK;
}
* Language::classDirectorDefaultConstructor()
* ---------------------------------------------------------------------- */
int Language::classDirectorDefaultConstructor(Node *n) {
(void) n;
return SWIG_OK;
}
static String *vtable_method_id(Node *n) {
String *nodeType = Getattr(n, "nodeType");
int is_destructor = (Cmp(nodeType, "destructor") == 0);
if (is_destructor)
return 0;
String *name = Getattr(n, "name");
String *decl = Getattr(n, "decl");
String *local_decl = SwigType_typedef_resolve_all(decl);
String *tmp = SwigType_pop_function(local_decl);
Delete(local_decl);
local_decl = tmp;
String *method_id = NewStringf("%s|%s", name, local_decl);
Delete(local_decl);
return method_id;
}
* Language::unrollOneVirtualMethod()
* ---------------------------------------------------------------------- */
void Language::unrollOneVirtualMethod(String *classname, Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) {
if (!checkAttribute(n, "storage", "virtual"))
return;
if (GetFlag(n, "final"))
return;
String *nodeType = Getattr(n, "nodeType");
int is_destructor = (Cmp(nodeType, "destructor") == 0);
if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
String *decl = Getattr(n, "decl");
if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(n)) || need_nonpublic_member(n))) {
String *name = Getattr(n, "name");
String *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(n);
int len = Len(vm);
const int DO_NOT_REPLACE = -1;
int replace = DO_NOT_REPLACE;
for (int i = 0; i < len; i++) {
Node *item = Getitem(vm, i);
String *check_vmid = Getattr(item, "vmid");
if (Strcmp(method_id, check_vmid) == 0) {
replace = i;
break;
}
}
String *fqdname = NewStringf("%s::%s", classname, name);
Hash *item = NewHash();
Setattr(item, "fqdname", fqdname);
Node *m = Copy(n);
SwigType *ty = NewString(Getattr(m, "type"));
SwigType_push(ty, decl);
if (SwigType_isqualifier(ty)) {
Delete(SwigType_pop(ty));
}
Delete(SwigType_pop_function(ty));
Setattr(m, "returntype", ty);
String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name);
Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m);
Setattr(item, "methodNode", m);
Setattr(item, "vmid", method_id);
if (replace == DO_NOT_REPLACE)
Append(vm, item);
else
Setitem(vm, replace, item);
Setattr(n, "directorNode", m);
Delete(mname);
}
if (is_destructor) {
virtual_destructor = 1;
}
}
}
* Language::unrollVirtualMethods()
* ---------------------------------------------------------------------- */
int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) {
bool first_base = false;
List *bl = Getattr(n, "bases");
if (bl) {
Iterator bi;
for (bi = First(bl); bi.item; bi = Next(bi)) {
if (first_base && !director_multiple_inheritance)
break;
unrollVirtualMethods(bi.item, parent, vm, virtual_destructor);
first_base = true;
}
}
bl = Getattr(n, "protectedbases");
if (bl) {
Iterator bi;
for (bi = First(bl); bi.item; bi = Next(bi)) {
if (first_base && !director_multiple_inheritance)
break;
unrollVirtualMethods(bi.item, parent, vm, virtual_destructor, 1);
first_base = true;
}
}
String *classname = Getattr(n, "name");
for (Node *ni = firstChild(n); ni; ni = nextSibling(ni)) {
if (Equal(nodeType(ni), "using")) {
for (Node *nn = firstChild(ni); nn; nn = Getattr(nn, "sym:nextSibling")) {
unrollOneVirtualMethod(classname, nn, parent, vm, virtual_destructor, protectedbase);
}
}
unrollOneVirtualMethod(classname, ni, parent, vm, virtual_destructor, protectedbase);
}
We delete all the nodirector methods. This prevents the
generation of 'empty' director classes.
Done once we've collated all the virtual methods into vm.
*/
if (n == parent) {
int len = Len(vm);
for (int i = 0; i < len; i++) {
Node *item = Getitem(vm, i);
Node *m = Getattr(item, "methodNode");
int mdir = GetFlag(m, "feature:director");
int mndir = GetFlag(m, "feature:nodirector");
int dir = (mdir || mndir) ? (mdir && !mndir) : 1;
Node *p = Getattr(m, "parentNode");
if (p != n) {
Node *c = Copy(m);
Setattr(c, "parentNode", n);
int cdir = GetFlag(c, "feature:director");
int cndir = GetFlag(c, "feature:nodirector");
dir = (cdir || cndir) ? (cdir && !cndir) : dir;
Delete(c);
}
if (dir) {
if (mndir)
Delattr(m, "feature:nodirector");
} else {
Delitem(vm, i);
len--;
i--;
}
}
}
return SWIG_OK;
}
* Language::classDirectorDisown()
* ---------------------------------------------------------------------- */
int Language::classDirectorDisown(Node *n) {
Node *disown = NewHash();
String *mrename;
String *symname = Getattr(n, "sym:name");
mrename = Swig_name_disown(NSpace, symname);
String *type = NewString(ClassType);
String *name = NewString("self");
SwigType_add_pointer(type);
Parm *p = NewParm(type, name, n);
Delete(name);
Delete(type);
type = NewString("void");
String *action = NewString("");
Printv(action, "{\n", "Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);\n", "if (director) director->swig_disown();\n", "}\n", NULL);
Setfile(disown, Getfile(n));
Setline(disown, Getline(n));
Setattr(disown, "wrap:action", action);
Setattr(disown, "name", mrename);
Setattr(disown, "sym:name", mrename);
Setattr(disown, "type", type);
Setattr(disown, "parms", p);
Delete(action);
Delete(mrename);
Delete(type);
Delete(p);
functionWrapper(disown);
Delete(disown);
return SWIG_OK;
}
* Language::classDirectorConstructors()
* ---------------------------------------------------------------------- */
int Language::classDirectorConstructors(Node *n) {
String *nodeType;
Node *parent = Swig_methodclass(n);
int default_ctor = Getattr(parent, "allocate:default_constructor") ? 1 : 0;
int protected_ctor = 0;
int constructor = 0;
List *constructors = NewList();
for (Node *ni = firstChild(n); ni; ni = nextSibling(ni)) {
nodeType = Getattr(ni, "nodeType");
if (Equal(nodeType, "constructor")) {
Append(constructors, ni);
} else if (Equal(nodeType, "using") && GetFlag(ni, "usingctor")) {
for (Node *ui = firstChild(ni); ui; ui = nextSibling(ui)) {
Append(constructors, ui);
}
}
}
for (Iterator it = First(constructors); it.item; it = Next(it)) {
Node *ni = it.item;
if (GetFlag(ni, "feature:ignore"))
continue;
Parm *parms = Getattr(ni, "parms");
if (is_public(ni)) {
classDirectorConstructor(ni);
constructor = 1;
if (default_ctor)
default_ctor = !ParmList_numrequired(parms);
} else {
if (need_nonpublic_ctor(ni)) {
classDirectorConstructor(ni);
constructor = 1;
protected_ctor = 1;
if (default_ctor)
default_ctor = !ParmList_numrequired(parms);
}
}
}
Delete(constructors);
if (!constructor) {
if (!default_ctor) {
default constructor, therefore, the director class can't be
created, ie, is kind of abstract. */
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n), "Director class '%s' can't be constructed\n", SwigType_namestr(Getattr(n, "name")));
return SWIG_OK;
}
classDirectorDefaultConstructor(n);
default_ctor = 1;
}
constructor is always emitted, even when protected, and not
needed, since there is a public constructor already defined.
(scottm) This code is needed here to make the director_abstract +
test generate compilable code (Example2 in director_abstract.i).
(mmatus) This is very strange, since swig compiled with gcc3.2.3
doesn't need it here....
*/
if (!default_ctor && !protected_ctor) {
if (Getattr(parent, "allocate:default_base_constructor")) {
classDirectorDefaultConstructor(n);
}
}
return SWIG_OK;
}
* Language::classDirectorMethods()
* ---------------------------------------------------------------------- */
int Language::classDirectorMethods(Node *n) {
Node *vtable = Getattr(n, "vtable");
int len = Len(vtable);
for (int i = 0; i < len; i++) {
Node *item = Getitem(vtable, i);
String *method = Getattr(item, "methodNode");
String *fqdname = Getattr(item, "fqdname");
if (GetFlag(method, "feature:nodirector") || GetFlag(method, "final"))
continue;
String *wrn = Getattr(method, "feature:warnfilter");
if (wrn)
Swig_warnfilter(wrn, 1);
String *type = Getattr(method, "nodeType");
if (!Cmp(type, "destructor")) {
classDirectorDestructor(method);
} else {
Swig_require("classDirectorMethods", method, "*type", NIL);
assert(Getattr(method, "returntype"));
Setattr(method, "type", Getattr(method, "returntype"));
if (classDirectorMethod(method, n, fqdname) == SWIG_OK)
SetFlag(item, "director");
Swig_restore(method);
}
if (wrn)
Swig_warnfilter(wrn, 0);
}
return SWIG_OK;
}
* Language::classDirectorInit()
* ---------------------------------------------------------------------- */
int Language::classDirectorInit(Node *n) {
(void) n;
return SWIG_OK;
}
* Language::classDirectorDestructor()
* ---------------------------------------------------------------------- */
int Language::classDirectorDestructor(Node *n) {
Always emit the virtual destructor in the declaration and in the
compilation unit. Being explicit here can't make any damage, and
can solve some nasty C++ compiler problems.
*/
File *f_directors = Swig_filebyname("director");
File *f_directors_h = Swig_filebyname("director_h");
if (Getattr(n, "throw")) {
Printf(f_directors_h, " virtual ~%s() throw();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() throw() {\n}\n\n", DirectorClassName, DirectorClassName);
} else {
Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() {\n}\n\n", DirectorClassName, DirectorClassName);
}
return SWIG_OK;
}
* Language::classDirectorEnd()
* ---------------------------------------------------------------------- */
int Language::classDirectorEnd(Node *n) {
(void) n;
return SWIG_OK;
}
* Language::classDirector()
* ---------------------------------------------------------------------- */
int Language::classDirector(Node *n) {
Node *module = Getattr(n, "module");
String *classtype = Getattr(n, "classtype");
Hash *directormap = 0;
if (module) {
directormap = Getattr(module, "wrap:directormap");
if (directormap == 0) {
directormap = NewHash();
Setattr(module, "wrap:directormap", directormap);
}
}
List *vtable = NewList();
int virtual_destructor = 0;
unrollVirtualMethods(n, n, vtable, virtual_destructor);
Node *ni;
String *using_protected_members_code = NewString("");
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
String *nodeType = nodeType(ni);
if (Cmp(nodeType, "destructor") == 0 && GetFlag(ni, "final")) {
String *classtype = Getattr(n, "classtype");
SWIG_WARN_NODE_BEGIN(ni);
Swig_warning(WARN_LANG_DIRECTOR_FINAL, input_file, line_number, "Destructor %s is final, %s cannot be a director class.\n", Swig_name_decl(ni), classtype);
SWIG_WARN_NODE_END(ni);
SetFlag(n, "feature:nodirector");
Delete(vtable);
Delete(using_protected_members_code);
return SWIG_OK;
}
Node *nn = ni;
bool cdeclaration = Equal(nodeType, "cdecl");
if (!cdeclaration && Equal(nodeType, "using")) {
nn = Getattr(ni, "firstChild");
cdeclaration = nn && Equal(nodeType(nn), "cdecl") ? true : false;
}
if (cdeclaration && !GetFlag(nn, "feature:ignore")) {
if (isNonVirtualProtectedAccess(nn)) {
Node *overloaded = Getattr(nn, "sym:overloaded");
if (!overloaded || (overloaded && (overloaded == nn)))
Printf(using_protected_members_code, " using %s::%s;\n", SwigType_namestr(ClassName), Getattr(nn, "name"));
}
}
}
if (virtual_destructor || Len(vtable) > 0) {
if (!virtual_destructor) {
String *classtype = Getattr(n, "classtype");
Swig_warning(WARN_LANG_DIRECTOR_VDESTRUCT, input_file, line_number, "Director base class %s has no virtual destructor.\n", classtype);
}
Setattr(n, "vtable", vtable);
if (directormap != 0) {
Setattr(directormap, classtype, n);
}
classDirectorInit(n);
classDirectorConstructors(n);
classDirectorMethods(n);
File *f_directors_h = Swig_filebyname("director_h");
Printv(f_directors_h, using_protected_members_code, NIL);
classDirectorEnd(n);
}
Delete(vtable);
Delete(using_protected_members_code);
return SWIG_OK;
}
* Language::classDeclaration()
* ---------------------------------------------------------------------- */
int Language::classDeclaration(Node *n) {
String *ochildren = Getattr(n, "feature:onlychildren");
if (ochildren) {
Setattr(n, "feature:emitonlychildren", ochildren);
emit_children(n);
Delattr(n, "feature:emitonlychildren");
SetFlag(n, "feature:ignore");
return SWIG_NOWRAP;
}
int oldInClass = InClass;
String *oldClassType = ClassType;
String *oldClassPrefix = ClassPrefix;
String *oldEnumClassPrefix = EnumClassPrefix;
String *oldClassName = ClassName;
String *oldDirectorClassName = DirectorClassName;
String *oldNSpace = NSpace;
Node *oldCurrentClass = CurrentClass;
int dir = 0;
String *kind = Getattr(n, "kind");
String *name = Getattr(n, "name");
String *tdname = Getattr(n, "tdname");
String *unnamed = Getattr(n, "unnamed");
String *symname = Getattr(n, "sym:name");
int strip = CPlusPlus ? 1 : unnamed && tdname;
if (cplus_mode != PUBLIC)
return SWIG_NOWRAP;
if (!name) {
Swig_warning(WARN_LANG_CLASS_UNNAMED, input_file, line_number, "Can't generate wrappers for unnamed struct/class.\n");
return SWIG_NOWRAP;
}
if (!validIdentifier(symname)) {
Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap class %s unless renamed to a valid identifier.\n", SwigType_namestr(symname));
return SWIG_NOWRAP;
}
AccessMode oldAccessMode = cplus_mode;
Node *outerClass = Getattr(n, "nested:outer");
if (outerClass && oldAccessMode != PUBLIC)
return SWIG_NOWRAP;
ClassName = Copy(name);
ClassPrefix = Copy(symname);
if (Cmp(kind, "class") == 0) {
cplus_mode = PRIVATE;
} else {
cplus_mode = PUBLIC;
}
for (; outerClass; outerClass = Getattr(outerClass, "nested:outer")) {
Push(ClassPrefix, "_");
Push(ClassPrefix, Getattr(outerClass, "sym:name"));
}
EnumClassPrefix = Copy(ClassPrefix);
if (strip) {
ClassType = Copy(name);
} else {
ClassType = NewStringf("%s %s", kind, name);
}
Setattr(n, "classtypeobj", Copy(ClassType));
Setattr(n, "classtype", SwigType_namestr(ClassType));
InClass = 1;
CurrentClass = n;
NSpace = Getattr(n, "sym:nspace");
int oldAbstract = Abstract;
if (!ImportMode) {
if (Swig_directors_enabled()) {
int ndir = GetFlag(n, "feature:director");
int nndir = GetFlag(n, "feature:nodirector");
dir = (ndir || nndir) ? (ndir && !nndir) : 0;
}
if (dir) {
DirectorClassName = directorClassName(n);
classDirector(n);
}
Abstract = abstractClassTest(n);
classHandler(n);
} else {
Abstract = abstractClassTest(n);
Language::classHandler(n);
}
Abstract = oldAbstract;
cplus_mode = oldAccessMode;
NSpace = oldNSpace;
InClass = oldInClass;
CurrentClass = oldCurrentClass;
Delete(ClassType);
ClassType = oldClassType;
Delete(EnumClassPrefix);
EnumClassPrefix = oldEnumClassPrefix;
Delete(ClassPrefix);
ClassPrefix = oldClassPrefix;
Delete(ClassName);
ClassName = oldClassName;
if (dir) {
Delete(DirectorClassName);
}
DirectorClassName = oldDirectorClassName;
return SWIG_OK;
}
* Language::classHandler()
* ---------------------------------------------------------------------- */
int Language::classHandler(Node *n) {
save_value<int> oldExtend(Extend);
if (Getattr(n, "template"))
Extend = 0;
bool hasDirector = Swig_directorclass(n) ? true : false;
emit_children(n);
if (Getattr(n, "allocate:smartpointer")) {
List *methods = Getattr(n, "allocate:smartpointer");
cplus_mode = PUBLIC;
SmartPointer = CWRAP_SMART_POINTER;
if (Getattr(n, "allocate:smartpointerconst") && Getattr(n, "allocate:smartpointermutable")) {
SmartPointer |= CWRAP_SMART_POINTER_OVERLOAD;
}
Iterator c;
for (c = First(methods); c.item; c = Next(c)) {
emit_one(c.item);
}
SmartPointer = 0;
}
cplus_mode = PUBLIC;
if (hasDirector) {
classDirectorDisown(n);
* codes logic in the C++ layer instead of the director proxy class method - primarily
* to catch public use of protected methods by the scripting languages. */
if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) {
Node *vtable = Getattr(n, "vtable");
String *symname = Getattr(n, "sym:name");
save_value<AccessMode> old_mode(cplus_mode);
cplus_mode = PROTECTED;
int len = Len(vtable);
for (int i = 0; i < len; i++) {
Node *item = Getitem(vtable, i);
Node *method = Getattr(item, "methodNode");
SwigType *type = Getattr(method, "nodeType");
if (Strcmp(type, "cdecl") != 0)
continue;
if (GetFlag(method, "feature:ignore"))
continue;
String *methodname = Getattr(method, "sym:name");
String *wrapname = NewStringf("%s_%s", symname, methodname);
if (!symbolLookup(wrapname, "") && (!is_public(method))) {
Node *m = Copy(method);
Setattr(m, "director", "1");
Setattr(m, "parentNode", n);
* There is a bug that needs fixing still...
* This area of code is creating methods which have not been overridden in a derived class (director methods that are protected in the base)
* If the method is overloaded, then Swig_overload_dispatch() incorrectly generates a call to the base wrapper, _wrap_xxx method
* See director_protected_overloaded.i - Possibly sym:overname needs correcting here.
Printf(stdout, "new method: %s::%s(%s)\n", Getattr(parentNode(m), "name"), Getattr(m, "name"), ParmList_str_defaultargs(Getattr(m, "parms")));
*/
cDeclaration(m);
Delete(m);
}
Delete(wrapname);
}
}
}
return SWIG_OK;
}
* Language::classforwardDeclaration()
* ---------------------------------------------------------------------- */
int Language::classforwardDeclaration(Node *n) {
(void) n;
return SWIG_OK;
}
* Language::constructorDeclaration()
* ---------------------------------------------------------------------- */
int Language::constructorDeclaration(Node *n) {
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
if (!symname)
return SWIG_NOWRAP;
if (!CurrentClass)
return SWIG_NOWRAP;
if (ImportMode)
return SWIG_NOWRAP;
if (Extend) {
int num_required = ParmList_numrequired(Getattr(n, "parms"));
if ((num_required == 0) && Getattr(CurrentClass, "has_default_constructor")) {
return SWIG_NOWRAP;
}
if ((num_required == 1) && Getattr(CurrentClass, "has_copy_constructor")) {
String *ccdecl = Getattr(CurrentClass, "copy_constructor_decl");
if (ccdecl && (Strcmp(ccdecl, Getattr(n, "decl")) == 0)) {
return SWIG_NOWRAP;
}
}
}
Node *over = Swig_symbol_isoverloaded(n);
if (over && !Getattr(CurrentClass, "sym:cleanconstructor")) {
int dirclass = Swig_directorclass(CurrentClass);
Node *nn = over;
while (nn) {
if (!is_public(nn)) {
if (!dirclass || !need_nonpublic_ctor(nn)) {
SetFlag(nn, "feature:ignore");
}
}
nn = Getattr(nn, "sym:nextSibling");
}
clean_overloaded(over);
Setattr(CurrentClass, "sym:cleanconstructor", "1");
}
if (!is_public(n)) {
if (!Swig_directorclass(CurrentClass) || !need_nonpublic_ctor(n))
return SWIG_NOWRAP;
}
Swig_save("constructorDeclaration", n, "sym:name", NIL);
{
String *base = Swig_scopename_last(name);
if (Equal(base, symname) && !Equal(symname, ClassPrefix)) {
if (!Getattr(n, "template"))
Setattr(n, "sym:name", ClassPrefix);
}
Delete(base);
}
if (!Abstract) {
Node *over;
over = Swig_symbol_isoverloaded(n);
if (over)
over = first_nontemplate(over);
if ((over) && (!overloading)) {
we invoke copyconstructorHandler() as a special case. */
if (Getattr(n, "copy_constructor") && (!Getattr(CurrentClass, "has_copy_constructor"))) {
copyconstructorHandler(n);
Setattr(CurrentClass, "has_copy_constructor", "1");
} else {
if (Getattr(over, "copy_constructor"))
over = Getattr(over, "sym:nextSibling");
if (over != n) {
Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, input_file, line_number,
"Overloaded constructor ignored. %s\n", Swig_name_decl(n));
Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, Getfile(over), Getline(over),
"Previous declaration is %s\n", Swig_name_decl(over));
} else {
constructorHandler(n);
}
}
} else {
String *expected_name = ClassName;
String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0;
String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name);
Delete(scope);
if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name) && !SwigType_istemplate(actual_name)) {
bool illegal_name = true;
if (Extend) {
SwigType *name_resolved = SwigType_typedef_resolve_all(actual_name);
SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name);
if (!CPlusPlus) {
if (Strncmp(name_resolved, "struct ", 7) == 0)
Replace(name_resolved, "struct ", "", DOH_REPLACE_FIRST);
else if (Strncmp(name_resolved, "union ", 6) == 0)
Replace(name_resolved, "union ", "", DOH_REPLACE_FIRST);
}
illegal_name = !Equal(name_resolved, expected_name_resolved);
if (!illegal_name)
Swig_warning(WARN_LANG_EXTEND_CONSTRUCTOR, input_file, line_number, "Use of an illegal constructor name '%s' in %%extend is deprecated, the constructor name should be '%s'.\n",
SwigType_str(Swig_scopename_last(actual_name), 0), SwigType_str(Swig_scopename_last(expected_name), 0));
Delete(name_resolved);
Delete(expected_name_resolved);
}
if (illegal_name) {
Swig_warning(WARN_LANG_RETURN_TYPE, input_file, line_number, "Function %s must have a return type. Ignored.\n", Swig_name_decl(n));
Swig_restore(n);
return SWIG_NOWRAP;
}
}
constructorHandler(n);
}
}
Swig_restore(n);
return SWIG_OK;
}
* get_director_ctor_code()
* ---------------------------------------------------------------------- */
static String *get_director_ctor_code(Node *n, String *director_ctor_code, String *director_prot_ctor_code, List *&abstracts) {
String *director_ctor = director_ctor_code;
int use_director = Swig_directorclass(n);
if (use_director) {
Node *pn = Swig_methodclass(n);
abstracts = Getattr(pn, "abstracts");
if (director_prot_ctor_code) {
int is_notabstract = GetFlag(pn, "feature:notabstract");
int is_abstract = abstracts && !is_notabstract;
if (is_protected(n) || is_abstract) {
director_ctor = director_prot_ctor_code;
abstracts = Copy(abstracts);
Delattr(pn, "abstracts");
} else {
if (is_notabstract) {
abstracts = Copy(abstracts);
Delattr(pn, "abstracts");
} else {
abstracts = 0;
}
}
}
}
return director_ctor;
}
* Language::constructorHandler()
* ---------------------------------------------------------------------- */
int Language::constructorHandler(Node *n) {
Swig_require("constructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
String *symname = Getattr(n, "sym:name");
String *mrename = Swig_name_construct(NSpace, symname);
String *nodeType = Getattr(n, "nodeType");
int constructor = (!Cmp(nodeType, "constructor"));
List *abstracts = 0;
String *director_ctor = get_director_ctor_code(n, director_ctor_code,
director_prot_ctor_code,
abstracts);
if (!constructor) {
Setattr(n, "handled_as_constructor", "1");
}
int extendmember = GetFlag(n, "isextendmember") ? Extend : 0;
int flags = Getattr(n, "template") ? extendmember : Extend;
Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, flags, DirectorClassName);
Setattr(n, "sym:name", mrename);
functionWrapper(n);
Delete(mrename);
Swig_restore(n);
if (abstracts)
Setattr(Swig_methodclass(n), "abstracts", abstracts);
return SWIG_OK;
}
* Language::copyconstructorHandler()
* ---------------------------------------------------------------------- */
int Language::copyconstructorHandler(Node *n) {
Swig_require("copyconstructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
String *symname = Getattr(n, "sym:name");
String *mrename = Swig_name_copyconstructor(NSpace, symname);
List *abstracts = 0;
String *director_ctor = get_director_ctor_code(n, director_ctor_code,
director_prot_ctor_code,
abstracts);
Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend, DirectorClassName);
Setattr(n, "sym:name", mrename);
functionWrapper(n);
Delete(mrename);
Swig_restore(n);
if (abstracts)
Setattr(Swig_methodclass(n), "abstracts", abstracts);
return SWIG_OK;
}
* Language::destructorDeclaration()
* ---------------------------------------------------------------------- */
int Language::destructorDeclaration(Node *n) {
if (!CurrentClass)
return SWIG_NOWRAP;
if (cplus_mode != PUBLIC && !Getattr(CurrentClass, "feature:unref"))
return SWIG_NOWRAP;
if (ImportMode)
return SWIG_NOWRAP;
Swig_save("destructorDeclaration", n, "name", "sym:name", NIL);
char *c = GetChar(n, "sym:name");
if (c && (*c == '~')) {
Setattr(n, "sym:name", c + 1);
}
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
if ((Strcmp(name, symname) == 0) || (Strcmp(symname, ClassPrefix) != 0)) {
Setattr(n, "sym:name", ClassPrefix);
}
String *nprefix = 0;
String *nlast = 0;
String *tprefix;
Swig_scopename_split(ClassName, &nprefix, &nlast);
tprefix = SwigType_templateprefix(nlast);
String *expected_name = NewStringf("~%s", tprefix);
String *actual_name = Copy(name);
if (!Equal(actual_name, expected_name) && !(Getattr(n, "template"))) {
bool illegal_name = true;
if (Extend) {
Replace(actual_name, "~", "", DOH_REPLACE_FIRST);
Replace(expected_name, "~", "", DOH_REPLACE_FIRST);
if (Len(nprefix) > 0) {
String *old_actual_name = actual_name;
String *old_expected_name = expected_name;
actual_name = NewStringf("%s::%s", nprefix, actual_name);
expected_name = NewStringf("%s::%s", nprefix, expected_name);
Delete(old_expected_name);
Delete(old_actual_name);
}
SwigType *name_resolved = SwigType_typedef_resolve_all(actual_name);
SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name);
if (!CPlusPlus) {
if (Strncmp(name_resolved, "struct ", 7) == 0)
Replace(name_resolved, "struct ", "", DOH_REPLACE_FIRST);
else if (Strncmp(name_resolved, "union ", 6) == 0)
Replace(name_resolved, "union ", "", DOH_REPLACE_FIRST);
}
illegal_name = !Equal(name_resolved, expected_name_resolved);
if (!illegal_name)
Swig_warning(WARN_LANG_EXTEND_DESTRUCTOR, input_file, line_number, "Use of an illegal destructor name '%s' in %%extend is deprecated, the destructor name should be '%s'.\n",
SwigType_str(Swig_scopename_last(actual_name), 0), SwigType_str(Swig_scopename_last(expected_name), 0));
Delete(name_resolved);
Delete(expected_name_resolved);
}
if (illegal_name) {
Swig_warning(WARN_LANG_ILLEGAL_DESTRUCTOR, input_file, line_number, "Illegal destructor name %s. Ignored.\n", Swig_name_decl(n));
Swig_restore(n);
Delete(tprefix);
Delete(nlast);
Delete(nprefix);
Delete(expected_name);
Delete(actual_name);
return SWIG_NOWRAP;
}
}
destructorHandler(n);
Setattr(CurrentClass, "has_destructor", "1");
Swig_restore(n);
Delete(tprefix);
Delete(nlast);
Delete(nprefix);
Delete(expected_name);
Delete(actual_name);
return SWIG_OK;
}
* Language::destructorHandler()
* ---------------------------------------------------------------------- */
int Language::destructorHandler(Node *n) {
Swig_require("destructorHandler", n, "?name", "*sym:name", NIL);
Swig_save("destructorHandler", n, "type", "parms", NIL);
String *symname = Getattr(n, "sym:name");
String *mrename;
char *csymname = Char(symname);
if (*csymname == '~')
csymname += 1;
mrename = Swig_name_destroy(NSpace, csymname);
Swig_DestructorToFunction(n, NSpace, ClassType, CPlusPlus, Extend);
Setattr(n, "sym:name", mrename);
functionWrapper(n);
Delete(mrename);
Swig_restore(n);
return SWIG_OK;
}
* Language::accessDeclaration()
* ---------------------------------------------------------------------- */
int Language::accessDeclaration(Node *n) {
cplus_mode = accessModeFromString(Getattr(n, "kind"));
return SWIG_OK;
}
* Language::namespaceDeclaration()
* ----------------------------------------------------------------------------- */
int Language::namespaceDeclaration(Node *n) {
if (Getattr(n, "alias"))
return SWIG_OK;
if (Getattr(n, "unnamed"))
return SWIG_OK;
emit_children(n);
return SWIG_OK;
}
int Language::validIdentifier(String *s) {
char *c = Char(s);
while (*c) {
if (!(isalnum(*c) || (*c == '_')))
return 0;
c++;
}
return 1;
}
* Language::usingDeclaration()
* ----------------------------------------------------------------------------- */
int Language::usingDeclaration(Node *n) {
if ((cplus_mode == PUBLIC) || (!is_public(n) && dirprot_mode())) {
Node *np = Copy(n);
Node *c;
for (c = firstChild(np); c; c = nextSibling(c)) {
if (CurrentClass)
Setattr(c, "parentNode", CurrentClass);
emit_one(c);
}
Delete(np);
}
return SWIG_OK;
}
* Language::constantWrapper()
* ---------------------------------------------------------------------- */
int Language::constantWrapper(Node *n) {
String *name = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *value = Getattr(n, "value");
String *str = SwigType_str(type, name);
Printf(stdout, "constantWrapper : %s = %s\n", str, value);
Delete(str);
return SWIG_OK;
}
* Language::variableWrapper()
* ---------------------------------------------------------------------- */
int Language::variableWrapper(Node *n) {
Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", "?varset", "?varget", NIL);
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *name = Getattr(n, "name");
Delattr(n,"varset");
Delattr(n,"varget");
String *newsymname = 0;
if (!CurrentClass && EnumClassPrefix) {
newsymname = Swig_name_member(0, EnumClassPrefix, symname);
symname = newsymname;
}
int assignable = !is_immutable(n);
int flags = use_naturalvar_mode(n);
if (!GetFlag(n, "wrappedasconstant"))
flags = flags | Extend;
if (assignable) {
int make_set_wrapper = 1;
String *tm = Swig_typemap_lookup("globalin", n, name, 0);
Swig_VarsetToFunction(n, flags);
String *sname = Swig_name_set(NSpace, symname);
Setattr(n, "sym:name", sname);
Delete(sname);
if (!tm) {
if (SwigType_isarray(type)) {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
make_set_wrapper = 0;
}
} else {
String *pname0 = Swig_cparm_name(0, 0);
Replace(tm, "$input", pname0, DOH_REPLACE_ANY);
Setattr(n, "wrap:action", tm);
Delete(tm);
Delete(pname0);
}
if (make_set_wrapper) {
Setattr(n, "varset", "1");
functionWrapper(n);
} else {
SetFlag(n, "feature:immutable");
}
Setattr(n, "sym:name", symname);
Setattr(n, "type", type);
Setattr(n, "name", name);
Delattr(n, "varset");
Iterator ki;
for (ki = First(n); ki.key; ki = Next(ki)) {
if (Strncmp(ki.key, "tmap:", 5) == 0)
Delattr(n, ki.key);
}
}
Swig_VargetToFunction(n, flags);
String *gname = Swig_name_get(NSpace, symname);
Setattr(n, "sym:name", gname);
Delete(gname);
Setattr(n, "varget", "1");
functionWrapper(n);
Delattr(n, "varget");
Swig_restore(n);
Delete(newsymname);
return SWIG_OK;
}
* Language::functionWrapper()
* ---------------------------------------------------------------------- */
int Language::functionWrapper(Node *n) {
String *name = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
ParmList *parms = Getattr(n, "parms");
Printf(stdout, "functionWrapper : %s\n", SwigType_str(type, NewStringf("%s(%s)", name, ParmList_str_defaultargs(parms))));
Printf(stdout, " action : %s\n", Getattr(n, "wrap:action"));
return SWIG_OK;
}
* Language::nativeWrapper()
* ----------------------------------------------------------------------------- */
int Language::nativeWrapper(Node *n) {
(void) n;
return SWIG_OK;
}
void Language::main(int argc, char *argv[]) {
(void) argc;
(void) argv;
}
* Language::addSymbol()
*
* Adds a symbol entry into the target language symbol tables.
* Returns 1 if the symbol is added successfully.
* Prints an error message and returns 0 if a conflict occurs.
* The scope is optional for target languages and if supplied must be a fully
* qualified scope and the symbol s must not contain any scope qualifiers.
* ----------------------------------------------------------------------------- */
int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) {
Hash *symbols = symbolScopeLookup(scope);
if (!symbols) {
symbols = symbolAddScope(scope);
} else {
Node *c = Getattr(symbols, s);
if (c && (c != n)) {
if (scope && Len(scope) > 0)
Swig_error(input_file, line_number, "'%s' is multiply defined in the generated target language module in scope '%s'.\n", s, scope);
else
Swig_error(input_file, line_number, "'%s' is multiply defined in the generated target language module.\n", s);
Swig_error(Getfile(c), Getline(c), "Previous declaration of '%s'\n", s);
return 0;
}
}
Setattr(symbols, s, n);
return 1;
}
* Language::addInterfaceSymbol()
*
* Adds a symbol entry into the target language symbol tables - for the interface
* feature only.
* Returns 1 if the symbol is added successfully.
* The scope is as per addSymbol.
* ----------------------------------------------------------------------------- */
int Language::addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope) {
if (interface_name) {
Node *existing_symbol = symbolLookup(interface_name, scope);
if (existing_symbol) {
String *proxy_class_name = Getattr(n, "sym:name");
Swig_error(input_file, line_number, "The interface feature name '%s' for proxy class '%s' is already defined in the generated target language module in scope '%s'.\n",
interface_name, proxy_class_name, scope);
Swig_error(Getfile(existing_symbol), Getline(existing_symbol), "Previous declaration of '%s'\n", interface_name);
return 0;
}
if (!addSymbol(interface_name, n, scope))
return 0;
}
return 1;
}
* Language::symbolAddScope()
*
* Creates a scope (symbols Hash) for given name. This method is auxiliary,
* you don't have to call it - addSymbol will lazily create scopes automatically.
* If scope with given name already exists, then do nothing.
* Returns newly created (or already existing) scope.
* ----------------------------------------------------------------------------- */
Hash *Language::symbolAddScope(const_String_or_char_ptr scope) {
Hash *symbols = symbolScopeLookup(scope);
if (!symbols) {
symbols = NewHash();
Setattr(symtabs, scope, symbols);
const_String_or_char_ptr top_scope = "";
Hash *topscope_symbols = Getattr(symtabs, top_scope);
Node *symbol = Getattr(topscope_symbols, scope);
Hash *pseudo_symbol = 0;
if (symbol) {
pseudo_symbol = symbol;
} else {
pseudo_symbol = NewHash();
Setattr(pseudo_symbol, "sym:scope", "1");
}
Setattr(topscope_symbols, scope, pseudo_symbol);
}
return symbols;
}
* Language::symbolScopeLookup()
*
* Lookup and returns a symtable (hash) representing given scope. Hash contains
* all symbols in this scope.
* ----------------------------------------------------------------------------- */
Hash *Language::symbolScopeLookup(const_String_or_char_ptr scope) {
Hash *symbols = Getattr(symtabs, scope ? scope : "");
return symbols;
}
* Language::symbolScopePseudoSymbolLookup()
*
* For every scope there is a special pseudo-symbol in the top scope (""). It
* exists solely to detect name clashes. This pseudo symbol may contain a few properties,
* but more could be added. This is also true for the top level scope ("").
* It contains a pseudo symbol with name "" (empty). Pseudo symbol contains the
* following properties:
* sym:scope = "1" - a flag that this is a scope pseudo symbol
*
* Pseudo symbols are a Hash*, not a Node*.
* There is no difference from symbolLookup() method except for signature
* and return type.
* ----------------------------------------------------------------------------- */
Hash *Language::symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope)
{
const_String_or_char_ptr top_scope = "";
Hash *symbols = Getattr(symtabs, top_scope);
return Getattr(symbols, scope);
}
* Language::dumpSymbols()
* ----------------------------------------------------------------------------- */
void Language::dumpSymbols() {
Printf(stdout, "LANGUAGE SYMBOLS start =======================================\n");
Node *table = symtabs;
Iterator ki = First(table);
while (ki.key) {
String *k = ki.key;
Printf(stdout, "===================================================\n");
Printf(stdout, "%s -\n", k);
{
Symtab *symtab = Getattr(table, k);
Iterator it = First(symtab);
while (it.key) {
String *symname = it.key;
Printf(stdout, " %s\n", symname);
it = Next(it);
}
}
ki = Next(ki);
}
Printf(stdout, "LANGUAGE SYMBOLS finish =======================================\n");
}
* Language::symbolLookup()
* ----------------------------------------------------------------------------- */
Node *Language::symbolLookup(const String *s, const_String_or_char_ptr scope) {
Hash *symbols = Getattr(symtabs, scope ? scope : "");
if (!symbols) {
return NULL;
}
return Getattr(symbols, s);
}
* Language::classLookup()
*
* Tries to locate a class from a type definition
* ----------------------------------------------------------------------------- */
Node *Language::classLookup(const SwigType *s) {
static Hash *classtypes = 0;
Node *n = 0;
n = classtypes ? Getattr(classtypes, s) : 0;
if (!n) {
Symtab *stab = 0;
SwigType *ty1 = SwigType_typedef_resolve_all(s);
SwigType *ty2 = SwigType_strip_qualifiers(ty1);
String *base = SwigType_base(ty2);
Replaceall(base, "class ", "");
Replaceall(base, "struct ", "");
Replaceall(base, "union ", "");
if (strncmp(Char(base), "::", 2) == 0) {
String *oldbase = base;
base = NewString(Char(base) + 2);
Delete(oldbase);
}
String *prefix = SwigType_prefix(ty2);
while (!n) {
Hash *nstab;
n = Swig_symbol_clookup(base, stab);
if (!n)
break;
if (Strcmp(nodeType(n), "class") == 0)
break;
Node *sibling = n;
while (sibling) {
sibling = Getattr(sibling, "csym:nextSibling");
if (sibling && Strcmp(nodeType(sibling), "class") == 0)
break;
}
if (sibling)
break;
n = parentNode(n);
if (!n)
break;
nstab = Getattr(n, "sym:symtab");
n = 0;
if ((!nstab) || (nstab == stab)) {
break;
}
stab = nstab;
}
if (n) {
the cases where we want a proxy class for the particular type */
bool acceptable_prefix =
(Len(prefix) == 0) ||
(Strcmp(prefix, "p.") == 0) ||
(Strcmp(prefix, "r.") == 0) ||
(Strcmp(prefix, "z.") == 0) ||
SwigType_prefix_is_simple_1D_array(prefix);
if (!acceptable_prefix && (Strcmp(prefix, "r.p.") == 0)) {
Delete(prefix);
prefix = SwigType_prefix(ty1);
acceptable_prefix = (Strncmp(prefix, "r.q(const", 9) == 0);
}
if (acceptable_prefix) {
SwigType *cs = Copy(s);
if (!classtypes)
classtypes = NewHash();
Setattr(classtypes, cs, n);
Delete(cs);
} else {
n = 0;
}
}
Delete(prefix);
Delete(base);
Delete(ty2);
Delete(ty1);
}
if (n && (GetFlag(n, "feature:ignore") || Getattr(n, "feature:onlychildren"))) {
n = 0;
}
return n;
}
* Language::enumLookup()
*
* Finds and returns the Node containing the enum declaration for the (enum)
* type passed in.
* ----------------------------------------------------------------------------- */
Node *Language::enumLookup(SwigType *s) {
static Hash *enumtypes = 0;
Node *n = 0;
n = enumtypes ? Getattr(enumtypes, s) : 0;
if (!n) {
Symtab *stab = 0;
SwigType *lt = SwigType_ltype(s);
SwigType *ty1 = SwigType_typedef_resolve_all(lt);
SwigType *ty2 = SwigType_strip_qualifiers(ty1);
String *base = SwigType_base(ty2);
Replaceall(base, "enum ", "");
String *prefix = SwigType_prefix(ty2);
if (strncmp(Char(base), "::", 2) == 0) {
String *oldbase = base;
base = NewString(Char(base) + 2);
Delete(oldbase);
}
while (!n) {
Hash *nstab;
n = Swig_symbol_clookup(base, stab);
if (!n)
break;
if (Equal(nodeType(n), "enum"))
break;
if (Equal(nodeType(n), "enumforward") && GetFlag(n, "enumMissing"))
break;
n = parentNode(n);
if (!n)
break;
nstab = Getattr(n, "sym:symtab");
n = 0;
if ((!nstab) || (nstab == stab)) {
break;
}
stab = nstab;
}
if (n) {
if (Len(prefix) == 0) {
if (!enumtypes)
enumtypes = NewHash();
Setattr(enumtypes, Copy(s), n);
} else {
n = 0;
}
}
Delete(prefix);
Delete(base);
Delete(ty2);
Delete(ty1);
Delete(lt);
}
if (n && (GetFlag(n, "feature:ignore"))) {
n = 0;
}
return n;
}
* Language::allow_overloading()
* ----------------------------------------------------------------------------- */
void Language::allow_overloading(int val) {
overloading = val;
}
* Language::allow_multiple_input()
* ----------------------------------------------------------------------------- */
void Language::allow_multiple_input(int val) {
multiinput = val;
}
* Language::enable_cplus_runtime_mode()
* ----------------------------------------------------------------------------- */
void Language::enable_cplus_runtime_mode() {
cplus_runtime = 1;
}
* Language::cplus_runtime_mode()
* ----------------------------------------------------------------------------- */
int Language::cplus_runtime_mode() {
return cplus_runtime;
}
* Language::directorLanguage()
* ----------------------------------------------------------------------------- */
void Language::directorLanguage(int val) {
director_language = val;
}
* Language::allow_directors()
* ----------------------------------------------------------------------------- */
void Language::allow_directors(int val) {
directors_allowed = val;
}
* Language::allow_dirprot()
* ----------------------------------------------------------------------------- */
void Language::allow_dirprot(int val) {
director_protected_mode = val;
}
* Language::allow_allprotected()
* ----------------------------------------------------------------------------- */
void Language::allow_allprotected(int val) {
all_protected_mode = val;
}
* Language::dirprot_mode()
* ----------------------------------------------------------------------------- */
int Language::dirprot_mode() const {
return Swig_directors_enabled() ? director_protected_mode : 0;
}
* Language::need_nonpublic_ctor()
* ----------------------------------------------------------------------------- */
int Language::need_nonpublic_ctor(Node *n) {
detects when a protected constructor is needed, which is always
the case if 'dirprot' mode is used. However, if that is not the
case, we will try to strictly emit what is minimal to don't break
the generated, while preserving compatibility with java, which
always try to emit the default constructor.
rules:
- when dirprot mode is used, the protected constructors are
always needed.
- the protected default constructor is always needed.
- if dirprot mode is not used, the protected constructors will be
needed only if:
- there is no any public constructor in the class, and
- there is no protected default constructor
In that case, all the declared protected constructors are
needed since we don't know which one to pick up.
Note: given all the complications here, I am always in favor to
always enable 'dirprot', since is the C++ idea of protected
members, and use %ignore for the method you don't want to add in
the director class.
*/
if (Swig_directors_enabled()) {
if (is_protected(n)) {
if (dirprot_mode()) {
always needed */
return 1;
} else {
int is_default_ctor = !ParmList_numrequired(Getattr(n, "parms"));
if (is_default_ctor) {
return 1;
} else {
Node *parent = Swig_methodclass(n);
int public_ctor = Getattr(parent, "allocate:default_constructor")
|| Getattr(parent, "allocate:public_constructor");
if (!public_ctor) {
if there is no protected default constructor declared */
int no_prot_default_ctor = !Getattr(parent, "allocate:default_base_constructor");
return no_prot_default_ctor;
}
}
}
}
}
return 0;
}
* Language::need_nonpublic_member()
* ----------------------------------------------------------------------------- */
int Language::need_nonpublic_member(Node *n) {
if (Swig_directors_enabled() && DirectorClassName) {
if (is_protected(n)) {
if (dirprot_mode()) {
return 1;
} else {
int pure_virtual = (Cmp(Getattr(n, "value"), "0") == 0);
return pure_virtual;
}
}
}
return 0;
}
* Language::is_smart_pointer()
* ----------------------------------------------------------------------------- */
int Language::is_smart_pointer() const {
return SmartPointer;
}
* Language::makeParameterName()
*
* Inputs:
* n - Node
* p - parameter node
* arg_num - parameter argument number
* setter - set this flag when wrapping variables
* Return:
* arg - a unique parameter name
* ----------------------------------------------------------------------------- */
String *Language::makeParameterName(Node *n, Parm *p, int arg_num, bool setter) const {
String *arg = 0;
String *pn = Getattr(p, "name");
int count = 0;
Parm *first_duplicate_parm = 0;
ParmList *plist = Getattr(n, "parms");
while (plist) {
if ((Cmp(pn, Getattr(plist, "name")) == 0)) {
if (!first_duplicate_parm)
first_duplicate_parm = plist;
count++;
}
plist = nextSibling(plist);
}
if (!pn || (count > 1 && p != first_duplicate_parm)) {
arg = NewStringf("arg%d", arg_num);
} else {
arg = Swig_name_make(p, 0, pn, 0, 0);
}
if (setter && Cmp(arg, "self") != 0) {
Delete(arg);
arg = NewString("value");
}
return arg;
}
* Language::()
* ----------------------------------------------------------------------------- */
bool Language::isNonVirtualProtectedAccess(Node *n) const {
return DirectorClassName && is_non_virtual_protected_access(n);
}
* Language::extraDirectorProtectedCPPMethodsRequired()
* ----------------------------------------------------------------------------- */
bool Language::extraDirectorProtectedCPPMethodsRequired() const {
return true;
}
* Language::nestedClassesSupport()
* ----------------------------------------------------------------------------- */
Language::NestedClassSupport Language::nestedClassesSupport() const {
return NCS_Unknown;
}
* Language::kwargsSupport()
* ----------------------------------------------------------------------------- */
bool Language::kwargsSupport() const {
return false;
}
* Language::is_wrapping_class()
* ----------------------------------------------------------------------------- */
int Language::is_wrapping_class() const {
return InClass;
}
* Language::getCurrentClass()
* ----------------------------------------------------------------------------- */
Node *Language::getCurrentClass() const {
return CurrentClass;
}
* Language::getNSpace()
* ----------------------------------------------------------------------------- */
String *Language::getNSpace() const {
return NSpace;
}
* Language::getClassName()
* ----------------------------------------------------------------------------- */
String *Language::getClassName() const {
return ClassName;
}
* Language::getClassPrefix()
* ----------------------------------------------------------------------------- */
String *Language::getClassPrefix() const {
return ClassPrefix;
}
* Language::getEnumClassPrefix()
* ----------------------------------------------------------------------------- */
String *Language::getEnumClassPrefix() const {
return EnumClassPrefix;
}
* Language::getClassType()
* ----------------------------------------------------------------------------- */
String *Language::getClassType() const {
return ClassType;
}
* Dispatcher::abstractClassTest()
* ----------------------------------------------------------------------------- */
int Dispatcher::abstractClassTest(Node *n) {
if (GetFlag(n, "feature:notabstract"))
return 0;
if (Getattr(n, "allocate:nonew"))
return 1;
List *bases = Getattr(n, "bases");
if (bases) {
for (int i = 0; i < Len(bases); i++) {
Node *b = Getitem(bases, i);
if (GetFlag(b, "allocate:private_destructor"))
return 1;
}
}
List *abstracts = Getattr(n, "abstracts");
if (!abstracts)
return 0;
int labs = Len(abstracts);
#ifdef SWIG_DEBUG
List *allbases = Getattr(n, "allbases");
Printf(stderr, "testing %s %d %d\n", Getattr(n, "name"), labs, Len(allbases));
#endif
if (!labs)
return 0;
if (abstracts && !Swig_directors_enabled())
return 1;
if (!GetFlag(n, "feature:director"))
return 1;
Node *dirabstract = 0;
Node *vtable = Getattr(n, "vtable");
if (vtable) {
#ifdef SWIG_DEBUG
Printf(stderr, "vtable %s %d %d\n", Getattr(n, "name"), Len(vtable), labs);
#endif
for (int i = 0; i < labs; i++) {
Node *ni = Getitem(abstracts, i);
String *method_id = vtable_method_id(ni);
if (!method_id)
continue;
bool exists_item = false;
int len = Len(vtable);
for (int i = 0; i < len; i++) {
Node *item = Getitem(vtable, i);
String *check_item = Getattr(item, "vmid");
if (Strcmp(method_id, check_item) == 0) {
exists_item = true;
break;
}
}
#ifdef SWIG_DEBUG
Printf(stderr, "method %s %d\n", method_id, exists_item ? 1 : 0);
#endif
Delete(method_id);
if (!exists_item) {
dirabstract = ni;
break;
}
}
if (dirabstract) {
if (is_public(dirabstract)) {
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
"Director class '%s' is abstract, abstract method '%s' is not accessible, maybe due to multiple inheritance or 'nodirector' feature\n",
SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
} else {
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
"Director class '%s' is abstract, abstract method '%s' is private\n", SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
}
return 1;
}
} else {
return 1;
}
return 0;
}
void Language::setSubclassInstanceCheck(String *nc) {
none_comparison = nc;
}
void Language::setOverloadResolutionTemplates(String *argc, String *argv) {
Delete(argc_template_string);
argc_template_string = Copy(argc);
Delete(argv_template_string);
argv_template_string = Copy(argv);
}
int Language::is_immutable(Node *n) {
return GetFlag(n, "feature:immutable");
}
String *Language::runtimeCode() {
return NewString("");
}
String *Language::defaultExternalRuntimeFilename() {
return 0;
}
* Language::replaceSpecialVariables()
*
* Language modules should implement this if special variables are to be handled
* correctly in the $typemap(...) special variable macro.
* method - typemap method name
* tm - string containing typemap contents
* parm - a parameter describing the typemap type to be handled
* ----------------------------------------------------------------------------- */
void Language::replaceSpecialVariables(String *method, String *tm, Parm *parm) {
(void)method;
(void)tm;
(void)parm;
}
Language *Language::instance() {
return this_;
}
Hash *Language::getClassHash() const {
return classhash;
}