* 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.
*
* python.cxx
*
* Python language module for SWIG.
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
#include "cparse.h"
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <stdint.h>
#include "pydoc.h"
#define PYSHADOW_MEMBER 0x2
#define WARN_PYTHON_MULTIPLE_INH 405
#define PYTHON_INT_MAX (2147483647)
#define PYTHON_INT_MIN (-2147483647-1)
static String *const_code = 0;
static String *module = 0;
static String *package = 0;
static String *mainmodule = 0;
static String *interface = 0;
static String *global_name = 0;
static int shadow = 1;
static int use_kw = 0;
static int director_method_index = 0;
static int builtin = 0;
static File *f_begin = 0;
static File *f_runtime = 0;
static File *f_runtime_h = 0;
static File *f_header = 0;
static File *f_wrappers = 0;
static File *f_directors = 0;
static File *f_directors_h = 0;
static File *f_init = 0;
static File *f_shadow_py = 0;
static String *f_shadow = 0;
static String *f_shadow_begin = 0;
static Hash *f_shadow_imports = 0;
static String *f_shadow_after_begin = 0;
static String *f_shadow_stubs = 0;
static Hash *builtin_getset = 0;
static Hash *builtin_closures = 0;
static Hash *class_members = 0;
static File *f_builtins = 0;
static String *builtin_tp_init = 0;
static String *builtin_methods = 0;
static String *builtin_default_unref = 0;
static String *builtin_closures_code = 0;
static String *f_varlinks = 0;
static String *methods;
static String *methods_proxydocs;
static String *class_name;
static String *shadow_indent = 0;
static int in_class = 0;
static int no_header_file = 0;
static int max_bases = 0;
static int builtin_bases_needed = 0;
static int have_constructor = 0;
static int have_repr = 0;
static bool have_builtin_static_member_method_callback = false;
static bool have_fast_proxy_static_member_method_callback = false;
static String *real_classname;
static int threads = 0;
static int nothreads = 0;
static int dirvtable = 0;
static int doxygen = 0;
static int fastunpack = 1;
static int fastproxy = 0;
static int olddefs = 0;
static int castmode = 0;
static int extranative = 0;
static int nortti = 0;
static int relativeimport = 0;
static int flat_static_method = 0;
namespace {
enum autodoc_t {
AUTODOC_CLASS,
AUTODOC_CTOR,
AUTODOC_DTOR,
AUTODOC_STATICFUNC,
AUTODOC_FUNC,
AUTODOC_METHOD,
AUTODOC_CONST,
AUTODOC_VAR
};
}
static const char *usage1 = "\
Python Options (available with -python)\n\
-builtin - Create Python built-in types rather than proxy classes, for better performance\n\
-castmode - Enable the casting mode, which allows implicit cast between types in Python\n\
-debug-doxygen-parser - Display doxygen parser module debugging information\n\
-debug-doxygen-translator - Display doxygen translator module debugging information\n\
-dirvtable - Generate a pseudo virtual table for directors for faster dispatch\n\
-doxygen - Convert C++ doxygen comments to pydoc comments in proxy classes\n\
-extranative - Return extra native wrappers for C++ std containers wherever possible\n\
-fastproxy - Use fast proxy mechanism for member methods\n\
-flatstaticmethod - Generate additional flattened Python methods for C++ static methods\n\
-globals <name> - Set <name> used to access C global variable (default: 'cvar')\n\
-interface <mod>- Set low-level C/C++ module name to <mod> (default: module name prefixed by '_')\n\
-keyword - Use keyword arguments\n";
static const char *usage2 = "\
-nofastunpack - Use traditional UnpackTuple method to parse the argument functions\n\
-noh - Don't generate the output header file\n";
static const char *usage3 = "\
-noproxy - Don't generate proxy classes\n\
-nortti - Disable the use of the native C++ RTTI with directors\n\
-nothreads - Disable thread support for the entire interface\n\
-olddefs - Keep the old method definitions when using -fastproxy\n\
-relativeimport - Use relative Python imports\n\
-threads - Add thread support for all the interface\n\
-O - Enable the following optimization options:\n\
-fastdispatch -fastproxy -fvirtual\n\
\n";
static String *getSlot(Node *n = NULL, const char *key = NULL, String *default_slot = NULL) {
static String *zero = NewString("0");
String *val = n && key && *key ? Getattr(n, key) : NULL;
return val ? val : default_slot ? default_slot : zero;
}
static void printSlot(File *f, String *slotval, const char *slotname, const char *functype = NULL) {
String *slotval_override = 0;
if (functype && Strcmp(slotval, "0") == 0)
slotval = slotval_override = NewStringf("(%s) %s", functype, slotval);
int len = Len(slotval);
int fieldwidth = len >= 39 ? 1 : 39 - len;
Printf(f, " %s,%*s/* %s */\n", slotval, fieldwidth, "", slotname);
Delete(slotval_override);
}
static void printSlot2(File *f, String *slotval, const char *slotname, const char *functype = NULL) {
String *slotval_override = 0;
if (functype && Strcmp(slotval, "0") == 0)
slotval = slotval_override = NewStringf("(%s) %s", functype, slotval);
int len = Len(slotname);
int fieldwidth = len >= 30 ? 1 : 30 - len;
Printf(f, " { Py_%s,%*s(void *)%s },\n", slotname, fieldwidth, "", slotval);
Delete(slotval_override);
}
static String *getClosure(String *functype, String *wrapper, int funpack = 0) {
static const char *functypes[] = {
"unaryfunc", "SWIGPY_UNARYFUNC_CLOSURE",
"destructor", "SWIGPY_DESTRUCTOR_CLOSURE",
"inquiry", "SWIGPY_INQUIRY_CLOSURE",
"getiterfunc", "SWIGPY_GETITERFUNC_CLOSURE",
"binaryfunc", "SWIGPY_BINARYFUNC_CLOSURE",
"ternaryfunc", "SWIGPY_TERNARYFUNC_CLOSURE",
"ternarycallfunc", "SWIGPY_TERNARYCALLFUNC_CLOSURE",
"lenfunc", "SWIGPY_LENFUNC_CLOSURE",
"ssizeargfunc", "SWIGPY_SSIZEARGFUNC_CLOSURE",
"ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE",
"ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE",
"ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE",
"objobjproc", "SWIGPY_OBJOBJPROC_CLOSURE",
"objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE",
"reprfunc", "SWIGPY_REPRFUNC_CLOSURE",
"hashfunc", "SWIGPY_HASHFUNC_CLOSURE",
"iternextfunc", "SWIGPY_ITERNEXTFUNC_CLOSURE",
NULL
};
static const char *funpack_functypes[] = {
"unaryfunc", "SWIGPY_UNARYFUNC_CLOSURE",
"destructor", "SWIGPY_DESTRUCTOR_CLOSURE",
"inquiry", "SWIGPY_INQUIRY_CLOSURE",
"getiterfunc", "SWIGPY_GETITERFUNC_CLOSURE",
"ternaryfunc", "SWIGPY_TERNARYFUNC_CLOSURE",
"ternarycallfunc", "SWIGPY_TERNARYCALLFUNC_CLOSURE",
"lenfunc", "SWIGPY_LENFUNC_CLOSURE",
"ssizeargfunc", "SWIGPY_FUNPACK_SSIZEARGFUNC_CLOSURE",
"ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE",
"ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE",
"ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE",
"objobjproc", "SWIGPY_FUNPACK_OBJOBJPROC_CLOSURE",
"objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE",
"reprfunc", "SWIGPY_REPRFUNC_CLOSURE",
"hashfunc", "SWIGPY_HASHFUNC_CLOSURE",
"iternextfunc", "SWIGPY_ITERNEXTFUNC_CLOSURE",
NULL
};
if (!functype)
return NULL;
char *c = Char(functype);
int i;
if (funpack) {
for (i = 0; funpack_functypes[i] != NULL; i += 2) {
if (!strcmp(c, funpack_functypes[i]))
return NewStringf("%s(%s)", funpack_functypes[i + 1], wrapper);
}
} else {
for (i = 0; functypes[i] != NULL; i += 2) {
if (!strcmp(c, functypes[i]))
return NewStringf("%s(%s)", functypes[i + 1], wrapper);
}
}
return NULL;
}
class PYTHON:public Language {
public:
PYTHON() {
director_prot_ctor_code = NewString("");
Printv(director_prot_ctor_code,
"if ( $comparison ) { /* subclassed */\n",
" $director_new \n",
"} else {\n", " SWIG_SetErrorMsg(PyExc_RuntimeError,\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL);
director_multiple_inheritance = 1;
directorLanguage();
}
~PYTHON() {
delete doxygenTranslator;
}
* Thread Implementation
* ------------------------------------------------------------ */
int threads_enable(Node *n) const {
return threads && !GetFlagAttr(n, "feature:nothread");
}
int initialize_threads(String *f_init) {
if (!threads) {
return SWIG_OK;
}
Printf(f_init, "\n");
Printf(f_init, "/* Initialize threading */\n");
Printf(f_init, "SWIG_PYTHON_INITIALIZE_THREADS;\n");
return SWIG_OK;
}
virtual void thread_begin_block(Node *n, String *f) {
if (!GetFlag(n, "feature:nothreadblock")) {
String *bb = Getattr(n, "feature:threadbeginblock");
if (bb) {
Append(f, bb);
} else {
Append(f, "SWIG_PYTHON_THREAD_BEGIN_BLOCK;\n");
}
}
}
virtual void thread_end_block(Node *n, String *f) {
if (!GetFlag(n, "feature:nothreadblock")) {
String *eb = Getattr(n, "feature:threadendblock");
if (eb) {
Append(f, eb);
} else {
Append(f, "SWIG_PYTHON_THREAD_END_BLOCK;\n");
}
}
}
virtual void thread_begin_allow(Node *n, String *f) {
if (!GetFlag(n, "feature:nothreadallow")) {
String *bb = Getattr(n, "feature:threadbeginallow");
Append(f, "{\n");
if (bb) {
Append(f, bb);
} else {
Append(f, "SWIG_PYTHON_THREAD_BEGIN_ALLOW;\n");
}
}
}
virtual void thread_end_allow(Node *n, String *f) {
if (!GetFlag(n, "feature:nothreadallow")) {
String *eb = Getattr(n, "feature:threadendallow");
Append(f, "\n");
if (eb) {
Append(f, eb);
} else {
Append(f, "SWIG_PYTHON_THREAD_END_ALLOW;");
}
Append(f, "\n}");
}
}
* main()
* ------------------------------------------------------------ */
virtual void main(int argc, char *argv[]) {
SWIG_library_directory("python");
int doxygen_translator_flags = 0;
for (int i = 1; i < argc; i++) {
if (argv[i]) {
if (strcmp(argv[i], "-interface") == 0) {
if (argv[i + 1]) {
interface = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-globals") == 0) {
if (argv[i + 1]) {
global_name = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
shadow = 1;
Swig_mark_arg(i);
} else if ((strcmp(argv[i], "-noproxy") == 0)) {
shadow = 0;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-keyword") == 0) {
use_kw = 1;
SWIG_cparse_set_compact_default_args(1);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nortti") == 0) {
nortti = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-threads") == 0) {
threads = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nothreads") == 0) {
nothreads = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-dirvtable") == 0) {
dirvtable = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-doxygen") == 0) {
doxygen = 1;
scan_doxygen_comments = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-debug-doxygen-translator") == 0) {
doxygen_translator_flags |= DoxygenTranslator::debug_translator;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-debug-doxygen-parser") == 0) {
doxygen_translator_flags |= DoxygenTranslator::debug_parser;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nofastunpack") == 0) {
fastunpack = 0;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-fastproxy") == 0) {
fastproxy = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-olddefs") == 0) {
olddefs = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-castmode") == 0) {
castmode = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-extranative") == 0) {
extranative = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-flatstaticmethod") == 0) {
flat_static_method = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-noh") == 0) {
no_header_file = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-newvwm") == 0) {
Swig_value_wrapper_mode(1);
no_header_file = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-O") == 0) {
fastproxy = 1;
Wrapper_fast_dispatch_mode_set(1);
Wrapper_virtual_elimination_mode_set(1);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-help") == 0) {
fputs(usage1, stdout);
fputs(usage2, stdout);
fputs(usage3, stdout);
} else if (strcmp(argv[i], "-builtin") == 0) {
builtin = 1;
Preprocessor_define("SWIGPYTHON_BUILTIN", 0);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-relativeimport") == 0) {
relativeimport = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-cppcast") == 0 ||
strcmp(argv[i], "-fastinit") == 0 ||
strcmp(argv[i], "-fastquery") == 0 ||
strcmp(argv[i], "-fastunpack") == 0 ||
strcmp(argv[i], "-modern") == 0 ||
strcmp(argv[i], "-modernargs") == 0 ||
strcmp(argv[i], "-noproxydel") == 0 ||
strcmp(argv[i], "-safecstrings") == 0) {
Printf(stderr, "Deprecated command line option: %s. Ignored, this option is now always on.\n", argv[i]);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-py3") == 0) {
Printf(stderr, "Deprecated command line option: %s. Ignored, this option is no longer supported.\n", argv[i]);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-aliasobj0") == 0 ||
strcmp(argv[i], "-buildnone") == 0 ||
strcmp(argv[i], "-classic") == 0 ||
strcmp(argv[i], "-classptr") == 0 ||
strcmp(argv[i], "-new_repr") == 0 ||
strcmp(argv[i], "-new_vwm") == 0 ||
strcmp(argv[i], "-newrepr") == 0 ||
strcmp(argv[i], "-noaliasobj0") == 0 ||
strcmp(argv[i], "-nobuildnone") == 0 ||
strcmp(argv[i], "-nocastmode") == 0 ||
strcmp(argv[i], "-nocppcast") == 0 ||
strcmp(argv[i], "-nodirvtable") == 0 ||
strcmp(argv[i], "-noextranative") == 0 ||
strcmp(argv[i], "-nofastinit") == 0 ||
strcmp(argv[i], "-nofastproxy") == 0 ||
strcmp(argv[i], "-nofastquery") == 0 ||
strcmp(argv[i], "-nomodern") == 0 ||
strcmp(argv[i], "-nomodernargs") == 0 ||
strcmp(argv[i], "-noolddefs") == 0 ||
strcmp(argv[i], "-nooutputtuple") == 0 ||
strcmp(argv[i], "-noproxyimport") == 0 ||
strcmp(argv[i], "-nosafecstrings") == 0 ||
strcmp(argv[i], "-old_repr") == 0 ||
strcmp(argv[i], "-oldrepr") == 0 ||
strcmp(argv[i], "-outputtuple") == 0 ||
strcmp(argv[i], "-proxydel") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is no longer available.\n", argv[i]);
Swig_mark_arg(i);
Exit(EXIT_FAILURE);
}
}
}
if (builtin && !shadow) {
Printf(stderr, "Incompatible options -builtin and -noproxy specified.\n");
Exit(EXIT_FAILURE);
}
if (fastproxy) {
Preprocessor_define("SWIGPYTHON_FASTPROXY", 0);
}
if (doxygen)
doxygenTranslator = new PyDocConverter(doxygen_translator_flags);
if (!global_name)
global_name = NewString("cvar");
Preprocessor_define("SWIGPYTHON 1", 0);
SWIG_config_file("python.swg");
allow_overloading();
}
* top()
* ------------------------------------------------------------ */
virtual int top(Node *n) {
* is a "master" switch, without which no director code will be
* emitted. %feature("director") statements are also required
* to enable directors for individual classes or methods.
*
* use %module(directors="1") modulename at the start of the
* interface file to enable director generation.
*/
String *mod_docstring = NULL;
String *moduleimport = NULL;
{
Node *mod = Getattr(n, "module");
if (mod) {
Node *options = Getattr(mod, "options");
if (options) {
int dirprot = 0;
if (Getattr(options, "dirprot")) {
dirprot = 1;
}
if (Getattr(options, "nodirprot")) {
dirprot = 0;
}
if (Getattr(options, "directors")) {
allow_directors();
if (dirprot)
allow_dirprot();
}
if (Getattr(options, "threads")) {
threads = 1;
}
if (Getattr(options, "castmode")) {
castmode = 1;
}
if (Getattr(options, "nocastmode")) {
Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nocastmode");
Exit(EXIT_FAILURE);
}
if (Getattr(options, "extranative")) {
extranative = 1;
}
if (Getattr(options, "noextranative")) {
Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "noextranative");
Exit(EXIT_FAILURE);
}
if (Getattr(options, "outputtuple")) {
Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "outputtuple");
Exit(EXIT_FAILURE);
}
if (Getattr(options, "nooutputtuple")) {
Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nooutputtuple");
Exit(EXIT_FAILURE);
}
mod_docstring = Getattr(options, "docstring");
package = Getattr(options, "package");
moduleimport = Getattr(options, "moduleimport");
}
}
}
setSubclassInstanceCheck(NewString("$arg != Py_None"));
String *outfile = Getattr(n, "outfile");
String *outfile_h = !no_header_file ? Getattr(n, "outfile_h") : 0;
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
f_init = NewString("");
f_header = NewString("");
f_wrappers = NewString("");
f_directors_h = NewString("");
f_directors = NewString("");
builtin_getset = NewHash();
builtin_closures = NewHash();
builtin_closures_code = NewString("");
class_members = NewHash();
builtin_methods = NewString("");
builtin_default_unref = NewString("delete $self;");
f_varlinks = NewString("");
if (builtin) {
f_builtins = NewString("");
}
if (Swig_directors_enabled()) {
if (!no_header_file) {
f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
if (!f_runtime_h) {
FileErrorDisplay(outfile_h);
Exit(EXIT_FAILURE);
}
} else {
f_runtime_h = f_runtime;
}
}
Swig_register_filebyname("header", f_header);
Swig_register_filebyname("wrapper", f_wrappers);
Swig_register_filebyname("begin", f_begin);
Swig_register_filebyname("runtime", f_runtime);
Swig_register_filebyname("init", f_init);
Swig_register_filebyname("director", f_directors);
Swig_register_filebyname("director_h", f_directors_h);
const_code = NewString("");
methods = NewString("");
methods_proxydocs = NewString("");
Swig_banner(f_begin);
Swig_obligatory_macros(f_runtime, "PYTHON");
if (Swig_directors_enabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
}
if (nothreads) {
Printf(f_runtime, "#define SWIG_PYTHON_NO_THREADS\n");
} else if (threads) {
Printf(f_runtime, "#define SWIG_PYTHON_THREADS\n");
}
if (!dirvtable) {
Printf(f_runtime, "#define SWIG_PYTHON_DIRECTOR_NO_VTABLE\n");
}
if (nortti) {
Printf(f_runtime, "#ifndef SWIG_DIRECTOR_NORTTI\n");
Printf(f_runtime, "#define SWIG_DIRECTOR_NORTTI\n");
Printf(f_runtime, "#endif\n");
}
if (castmode) {
Printf(f_runtime, "#define SWIG_CASTRANK_MODE\n");
Printf(f_runtime, "#define SWIG_PYTHON_CAST_MODE\n");
}
if (extranative) {
Printf(f_runtime, "#define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS\n");
}
if (builtin) {
Printf(f_runtime, "#define SWIGPYTHON_BUILTIN\n");
}
if (fastproxy) {
Printf(f_runtime, "#define SWIGPYTHON_FASTPROXY\n");
}
Printf(f_runtime, "\n");
Printf(f_header, "#ifdef SWIG_TypeQuery\n");
Printf(f_header, "# undef SWIG_TypeQuery\n");
Printf(f_header, "#endif\n");
Printf(f_header, "#define SWIG_TypeQuery SWIG_Python_TypeQuery\n");
module = Copy(Getattr(n, "name"));
mainmodule = Getattr(n, "name");
if (Swig_directors_enabled()) {
Swig_banner(f_directors_h);
Printf(f_directors_h, "\n");
Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module);
Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module);
if (dirprot_mode()) {
Printf(f_directors_h, "#include <map>\n");
Printf(f_directors_h, "#include <string>\n\n");
}
Printf(f_directors, "\n\n");
Printf(f_directors, "/* ---------------------------------------------------\n");
Printf(f_directors, " * C++ director class methods\n");
Printf(f_directors, " * --------------------------------------------------- */\n\n");
if (outfile_h) {
String *filename = Swig_file_filename(outfile_h);
Printf(f_directors, "#include \"%s\"\n\n", filename);
Delete(filename);
}
}
String *default_import_code = NewString("");
if (shadow) {
String *filen = NewStringf("%s%s.py", SWIG_output_directory(), Char(module));
if (interface)
module = interface;
else
Insert(module, 0, "_");
if ((f_shadow_py = NewFile(filen, "w", SWIG_output_files())) == 0) {
FileErrorDisplay(filen);
Exit(EXIT_FAILURE);
}
Delete(filen);
filen = NULL;
f_shadow = NewString("");
f_shadow_begin = NewString("");
f_shadow_imports = NewHash();
f_shadow_after_begin = NewString("");
f_shadow_stubs = NewString("");
Swig_register_filebyname("shadow", f_shadow);
Swig_register_filebyname("python", f_shadow);
if (!builtin) {
* since the shadow module may also have been imported by a relative
* import, and there is thus no guarantee that the low-level C/C++ module is on
* sys.path. Relative imports must be explicitly specified from 2.6.0
* onwards (implicit relative imports raised a DeprecationWarning in 2.6,
* and fail in 2.7 onwards).
*
* First check for __package__ which is available from 2.6 onwards, see PEP366.
* Next try determine the shadow wrapper's package based on the __name__ it
* was given by the importer that loaded it.
* If the module is in a package, load the low-level C/C++ module from the
* same package, otherwise load it as a global module.
*/
Printv(default_import_code, "# Import the low-level C/C++ module\n", NULL);
Printv(default_import_code, "if __package__ or \".\" in __name__:\n", NULL);
Printv(default_import_code, tab4, "from . import ", module, "\n", NULL);
Printv(default_import_code, "else:\n", NULL);
Printv(default_import_code, tab4, "import ", module, "\n", NULL);
} else {
Printv(default_import_code, "# Pull in all the attributes from the low-level C/C++ module\n", NULL);
Printv(default_import_code, "if __package__ or \".\" in __name__:\n", NULL);
Printv(default_import_code, tab4, "from .", module, " import *\n", NULL);
Printv(default_import_code, "else:\n", NULL);
Printv(default_import_code, tab4, "from ", module, " import *\n", NULL);
}
if (!builtin) {
defined in this module (try both Python 3 and Python 2 names) */
Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL);
}
if (!builtin && fastproxy) {
Printf(f_shadow, "\n");
Printf(f_shadow, "_swig_new_instance_method = %s.SWIG_PyInstanceMethod_New\n", module);
Printf(f_shadow, "_swig_new_static_method = %s.SWIG_PyStaticMethod_New\n", module);
}
if (!builtin) {
Printv(f_shadow, "\n",
"def _swig_repr(self):\n",
tab4, "try:\n",
tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n",
tab4, "except __builtin__.Exception:\n",
tab4, tab4, "strthis = \"\"\n",
tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
Printv(f_shadow, "\n",
"def _swig_setattr_nondynamic_instance_variable(set):\n",
tab4, "def set_instance_attr(self, name, value):\n",
tab4, tab4, "if name == \"this\":\n",
tab4, tab4, tab4, "set(self, name, value)\n",
tab4, tab4, "elif name == \"thisown\":\n",
tab4, tab4, tab4, "self.this.own(value)\n",
tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n",
tab4, tab4, tab4, "set(self, name, value)\n",
tab4, tab4, "else:\n",
tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n",
tab4, "return set_instance_attr\n\n", NIL);
Printv(f_shadow, "\n",
"def _swig_setattr_nondynamic_class_variable(set):\n",
tab4, "def set_class_attr(cls, name, value):\n",
tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n",
tab4, tab4, tab4, "set(cls, name, value)\n",
tab4, tab4, "else:\n",
tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n",
tab4, "return set_class_attr\n\n", NIL);
Printv(f_shadow, "\n",
"def _swig_add_metaclass(metaclass):\n",
tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n",
tab4, "def wrapper(cls):\n",
tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n",
tab4, "return wrapper\n\n", NIL);
Printv(f_shadow, "\n",
"class _SwigNonDynamicMeta(type):\n",
tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n",
tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n",
"\n", NIL);
Printv(f_shadow, "\n", NIL);
if (Swig_directors_enabled())
Printv(f_shadow, "import weakref\n\n", NIL);
}
}
Printf(f_header, "\n/*-----------------------------------------------\n @(target):= %s.so\n\
------------------------------------------------*/\n", module);
Printf(f_header, "#if PY_VERSION_HEX >= 0x03000000\n");
Printf(f_header, "# define SWIG_init PyInit_%s\n\n", module);
Printf(f_header, "#else\n");
Printf(f_header, "# define SWIG_init init%s\n\n", module);
Printf(f_header, "#endif\n");
Printf(f_runtime, "#define SWIG_name \"%s\"\n", module);
Printf(f_wrappers, "#ifdef __cplusplus\n");
Printf(f_wrappers, "extern \"C\" {\n");
Printf(f_wrappers, "#endif\n");
Append(const_code, "static swig_const_info swig_const_table[] = {\n");
Append(methods, "static PyMethodDef SwigMethods[] = {\n");
Append(methods_proxydocs, "static PyMethodDef SwigMethods_proxydocs[] = {\n");
add_pyinstancemethod_new();
add_pystaticmethod_new();
if (builtin) {
SwigType *s = NewString("SwigPyObject");
SwigType_add_pointer(s);
SwigType_remember(s);
Delete(s);
}
Language::top(n);
if (Swig_directors_enabled()) {
Swig_insert_file("director_common.swg", f_runtime);
Swig_insert_file("director_py_mutex.swg", f_runtime);
Swig_insert_file("director_guard.swg", f_runtime);
Swig_insert_file("director.swg", f_runtime);
}
Append(methods, "\t { NULL, NULL, 0, NULL }\n");
Append(methods, "};\n");
Printf(f_wrappers, "%s\n", methods);
Append(methods_proxydocs, "\t { NULL, NULL, 0, NULL }\n");
Append(methods_proxydocs, "};\n");
if ((fastproxy && !builtin) || have_fast_proxy_static_member_method_callback)
Printf(f_wrappers, "%s\n", methods_proxydocs);
if (builtin) {
Dump(f_builtins, f_wrappers);
}
SwigType_emit_type_table(f_runtime, f_wrappers);
Append(const_code, "{0, 0, 0, 0.0, 0, 0}};\n");
Printf(f_wrappers, "%s\n", const_code);
if (have_fast_proxy_static_member_method_callback)
Printf(f_init, " SWIG_Python_FixMethods(SwigMethods_proxydocs, swig_const_table, swig_types, swig_type_initial);\n\n");
initialize_threads(f_init);
Dump(f_varlinks, f_init);
Printf(f_init, "#if PY_VERSION_HEX >= 0x03000000\n");
Printf(f_init, " return m;\n");
Printf(f_init, "#else\n");
Printf(f_init, " return;\n");
Printf(f_init, "#endif\n");
Printf(f_init, "}\n");
Printf(f_wrappers, "#ifdef __cplusplus\n");
Printf(f_wrappers, "}\n");
Printf(f_wrappers, "#endif\n");
if (shadow) {
Swig_banner_target_lang(f_shadow_py, "#");
if (mod_docstring) {
if (Len(mod_docstring)) {
const char *triple_double = "\"\"\"";
bool multi_line_ds = Strchr(mod_docstring, '\n') != 0;
Printv(f_shadow_py, "\n", triple_double, multi_line_ds ? "\n":"", mod_docstring, multi_line_ds ? "\n":"", triple_double, "\n", NIL);
}
Delete(mod_docstring);
mod_docstring = NULL;
}
if (Len(f_shadow_begin) > 0)
Printv(f_shadow_py, "\n", f_shadow_begin, "\n", NIL);
Printv(f_shadow_py, "\nfrom sys import version_info as _swig_python_version_info\n", NULL);
if (Len(f_shadow_after_begin) > 0)
Printv(f_shadow_py, f_shadow_after_begin, "\n", NIL);
if (moduleimport) {
Replaceall(moduleimport, "$module", module);
Printv(f_shadow_py, moduleimport, "\n", NIL);
} else {
Printv(f_shadow_py, default_import_code, NIL);
}
if (Len(f_shadow) > 0)
Printv(f_shadow_py, "\n", f_shadow, "\n", NIL);
if (Len(f_shadow_stubs) > 0)
Printv(f_shadow_py, f_shadow_stubs, "\n", NIL);
Delete(f_shadow_py);
}
Dump(f_runtime, f_begin);
Dump(f_header, f_begin);
if (Swig_directors_enabled()) {
Dump(f_directors_h, f_runtime_h);
Printf(f_runtime_h, "\n");
Printf(f_runtime_h, "#endif\n");
if (f_runtime_h != f_begin)
Delete(f_runtime_h);
Dump(f_directors, f_begin);
}
Dump(f_wrappers, f_begin);
if (builtin && builtin_bases_needed)
Printf(f_begin, "static PyTypeObject *builtin_bases[%d];\n\n", max_bases + 2);
Wrapper_pretty_print(f_init, f_begin);
Delete(default_import_code);
Delete(f_shadow_after_begin);
Delete(f_shadow_imports);
Delete(f_shadow_begin);
Delete(f_shadow);
Delete(f_header);
Delete(f_wrappers);
Delete(f_builtins);
Delete(f_init);
Delete(f_directors);
Delete(f_directors_h);
Delete(f_runtime);
Delete(f_begin);
Delete(f_varlinks);
return SWIG_OK;
}
* Emit the wrapper for PyInstanceMethod_New to MethodDef array.
* This wrapper is used to implement -fastproxy,
* as a replacement of new.instancemethod in Python 3.
* ------------------------------------------------------------ */
int add_pyinstancemethod_new() {
if (!builtin && fastproxy) {
String *name = NewString("SWIG_PyInstanceMethod_New");
String *line = NewString("");
Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
Append(methods, line);
Append(methods_proxydocs, line);
Delete(line);
Delete(name);
}
return 0;
}
* Emit the wrapper for PyStaticMethod_New to MethodDef array.
* This wrapper is used to ensure the correct documentation is
* generated for static methods when using -fastproxy
* ------------------------------------------------------------ */
int add_pystaticmethod_new() {
if (!builtin && fastproxy) {
String *name = NewString("SWIG_PyStaticMethod_New");
String *line = NewString("");
Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
Append(methods, line);
Append(methods_proxydocs, line);
Delete(line);
Delete(name);
}
return 0;
}
* subpkg_tail()
*
* Return the name of 'other' package relative to 'base'.
*
* 1. If 'other' is a sub-package of 'base', returns the 'other' relative to
* 'base'.
* 2. If 'other' and 'base' are equal, returns empty string "".
* 3. In any other case, NULL pointer is returned.
*
* The 'base' and 'other' are expected to be fully qualified names.
*
* NOTE: none of 'base' nor 'other' can be null.
*
* Examples:
*
* # base other tail
* -- ---- ----- ----
* 1 "Foo" "Foo.Bar" -> "Bar"
* 2 "Foo" "Foo." -> ""
* 3 "Foo" "FooB.ar" -> NULL
* 4 "Foo.Bar" "Foo.Bar" -> ""
* 5 "Foo.Bar" "Foo" -> NULL
* 6 "Foo.Bar" "Foo.Gez" -> NULL
*
* NOTE: the example #2 is actually a syntax error (at input). I believe
* swig parser prevents us from this case happening here.
* ------------------------------------------------------------ */
static String *subpkg_tail(const String *base, const String *other) {
int baselen = Len(base);
int otherlen = Len(other);
if (Strncmp(other, base, baselen) == 0) {
if ((baselen < otherlen) && (Char(other))[baselen] == '.') {
return NewString((Char(other)) + baselen + 1);
} else if (baselen == otherlen) {
return NewString("");
} else {
return 0;
}
} else {
return 0;
}
}
* abs_import_directive_string()
*
* Return a string containing python code to import module.
*
* pkg package name or the module being imported
* mod module name of the module being imported
* pfx optional prefix to module name
*
* NOTE: keep this function consistent with abs_import_name_string().
* ------------------------------------------------------------ */
static String *abs_import_directive_string(const String *pkg, const String *mod, const char *pfx = "") {
String *out = NewString("");
if (pkg && *Char(pkg)) {
Printf(out, "import %s.%s%s\n", pkg, pfx, mod);
} else {
Printf(out, "import %s%s\n", pfx, mod);
}
return out;
}
* rel_import_directive_string()
*
* Return a string containing python code to import module that
* is potentially within a package.
*
* mainpkg package name of the module which imports the other module
* pkg package name or the module being imported
* mod module name of the module being imported
* pfx optional prefix to module name
*
* NOTE: keep this function consistent with rel_import_name_string().
* ------------------------------------------------------------ */
static String *rel_import_directive_string(const String *mainpkg, const String *pkg, const String *mod, const char *pfx = "") {
*
* 0. To import module 'foo', which is not in any package, we do absolute
* import:
*
* import foo
*
* 1. To import 'pkg1.pkg2.foo', when mainpkg != "pkg1" and
* mainpkg != "pkg1.pkg2" or when mainpkg is not given we do absolute
* import:
*
* import pkg1.pkg2.foo
*
* 2. To import module pkg1.foo, when mainpkg == "pkg1", we do:
*
* - for py3 = 0:
*
* import foo
*
* - for py3 = 1:
*
* from . import foo
*
* 3. To import "pkg1.pkg2.pkg3.foo", when mainpkg = "pkg1", we do:
*
* - for py3 == 0:
*
* import pkg2.pkg3.foo
*
* - for py3 == 1:
*
* from . import pkg2 # [1]
* import pkg1.pkg2.pkg3.foo
*
* NOTE: [1] is necessary for pkg2.foo to be present in the importing module
*/
String *apkg = 0;
String *rpkg = 0;
int py3_rlen1 = 0;
String *out = NewString("");
if (pkg && *Char(pkg)) {
if (mainpkg) {
String *tail = subpkg_tail(mainpkg, pkg);
if (tail) {
if (*Char(tail)) {
rpkg = NewString(tail);
const char *py3_end1 = Strchr(rpkg, '.');
if (!py3_end1)
py3_end1 = (Char(rpkg)) + Len(rpkg);
py3_rlen1 = (int)(py3_end1 - Char(rpkg));
} else {
rpkg = NewString("");
}
Delete(tail);
} else {
apkg = NewString(pkg);
}
} else {
apkg = NewString(pkg);
}
} else {
apkg = NewString("");
}
if (apkg) {
Printf(out, "import %s%s%s%s\n", apkg, *Char(apkg) ? "." : "", pfx, mod);
Delete(apkg);
} else {
if (py3_rlen1)
Printf(out, "from . import %.*s\n", py3_rlen1, rpkg);
Printf(out, "from .%s import %s%s\n", rpkg, pfx, mod);
Delete(rpkg);
}
return out;
}
* import_directive_string()
* ------------------------------------------------------------ */
static String *import_directive_string(const String *mainpkg, const String *pkg, const String *mod, const char *pfx = "") {
if (!relativeimport) {
return abs_import_directive_string(pkg, mod, pfx);
} else {
return rel_import_directive_string(mainpkg, pkg, mod, pfx);
}
}
* abs_import_name_string()
*
* Return a string with the name of a symbol (perhaps imported
* from external module by absolute import directive).
*
* mainpkg package name of current module
* mainmod module name of current module
* pkg package name of (perhaps other) module
* mod module name of (perhaps other) module
* sym symbol name
*
* NOTE: mainmod, mod, and sym can't be NULL.
* NOTE: keep this function consistent with abs_import_directive_string()
* ------------------------------------------------------------ */
static String *abs_import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) {
String *out = NewString("");
if (pkg && *Char(pkg)) {
if (mainpkg && *Char(mainpkg)) {
if (Strcmp(mainpkg,pkg) != 0 || Strcmp(mainmod, mod) != 0) {
Printf(out, "%s.%s.", pkg, mod);
}
} else {
Printf(out, "%s.%s.", pkg, mod);
}
} else if ((mainpkg && *Char(mainpkg)) || Strcmp(mainmod, mod) != 0) {
Printf(out, "%s.", mod);
}
Append(out, sym);
return out;
}
* rel_import_name_string()
*
* Return a string with the name of a symbol (perhaps imported
* from external module by relative import directive).
*
* mainpkg package name of current module
* mainmod module name of current module
* pkg package name of (perhaps other) module
* mod module name of (perhaps other) module
* sym symbol name
*
* NOTE: mainmod, mod, and sym can't be NULL.
* NOTE: keep this function consistent with rel_import_directive_string()
* ------------------------------------------------------------ */
static String *rel_import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) {
String *out = NewString("");
if (pkg && *Char(pkg)) {
String *tail = 0;
if (mainpkg)
tail = subpkg_tail(mainpkg, pkg);
if (!tail)
tail = NewString(pkg);
if (*Char(tail)) {
Printf(out, "%s.%s.", tail, mod);
} else if (Strcmp(mainmod, mod) != 0) {
Printf(out, "%s.", mod);
}
Delete(tail);
} else if ((mainpkg && *Char(mainpkg)) || Strcmp(mainmod, mod) != 0) {
Printf(out, "%s.", mod);
}
Append(out, sym);
return out;
}
* import_name_string()
* ------------------------------------------------------------ */
static String *import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) {
if (!relativeimport) {
return abs_import_name_string(mainpkg,mainmod,pkg,mod,sym);
} else {
return rel_import_name_string(mainpkg,mainmod,pkg,mod,sym);
}
}
* importDirective()
* ------------------------------------------------------------ */
virtual int importDirective(Node *n) {
if (shadow) {
String *modname = Getattr(n, "module");
if (modname) {
Node *mod = firstChild(n);
while (mod && Strcmp(nodeType(mod), "module") != 0)
mod = nextSibling(mod);
Node *options = Getattr(mod, "options");
String *pkg = options ? Getattr(options, "package") : 0;
if (!options || (!Getattr(options, "noshadow") && !Getattr(options, "noproxy"))) {
String *_import = import_directive_string(package, pkg, modname, "_");
if (!GetFlagAttr(f_shadow_imports, _import)) {
String *import = import_directive_string(package, pkg, modname);
Printf(builtin ? f_shadow_after_begin : f_shadow, "%s", import);
Delete(import);
SetFlag(f_shadow_imports, _import);
}
Delete(_import);
}
}
}
return Language::importDirective(n);
}
* funcCall()
*
* Emit shadow code to call a function in the extension
* module. Using proper argument and calling style for
* given node n.
* ------------------------------------------------------------ */
String *funcCall(String *name, String *parms) {
String *str = NewString("");
Printv(str, module, ".", name, "(", parms, ")", NIL);
return str;
}
* indent_pythoncode()
*
* Format (indent) Python code.
* Remove leading whitespace from 'code' and re-indent using
* the indentation string in 'indent'.
* ------------------------------------------------------------ */
String *indent_pythoncode(const String *code, const_String_or_char_ptr indent, String *file, int line, const char *directive_name) {
String *out = NewString("");
String *temp;
char *t;
if (!indent)
indent = "";
temp = NewString(code);
t = Char(temp);
if (*t == '{') {
Delitem(temp, 0);
Delitem(temp, DOH_END);
}
List *clist = SplitLines(temp);
Delete(temp);
int py_line = 0;
String *initial = 0;
Iterator si;
* and/or a comment, as the indentation of those doesn't matter:
*
* A logical line that contains only spaces, tabs, formfeeds and
* possibly a comment, is ignored (i.e., no NEWLINE token is
* generated).
*
* see:
* https://docs.python.org/2/reference/lexical_analysis.html#blank-lines
* https://docs.python.org/3/reference/lexical_analysis.html#blank-lines
*/
for (si = First(clist); si.item; si = Next(si), ++py_line) {
const char *c = Char(si.item);
int i;
for (i = 0; isspace((unsigned char)c[i]); i++) {
}
char ch = c[i];
if (ch && ch != '#') {
initial = NewStringWithSize(c, i);
break;
}
if (ch) {
Printv(out, indent, c, NIL);
}
Putc('\n', out);
}
for ( ; si.item; si = Next(si), ++py_line) {
const char *c = Char(si.item);
assert(initial);
int i;
for (i = 0; isspace((unsigned char)c[i]); i++) {
}
char ch = c[i];
if (!ch) {
Putc('\n', out);
continue;
}
if (ch == '#') {
if (i >= Len(initial)) {
Printv(out, indent, NIL);
}
Printv(out, c + i, "\n", NIL);
continue;
}
if (i < Len(initial)) {
Swig_error(file, line, "Line indented less than expected (line %d of %s) as no line should be indented less than the indentation in line 1\n", py_line, directive_name);
Printv(out, indent, c, "\n", NIL);
} else {
if (memcmp(c, Char(initial), Len(initial)) == 0) {
Printv(out, indent, c + Len(initial), "\n", NIL);
continue;
}
Swig_warning(WARN_PYTHON_INDENT_MISMATCH,
file, line, "Whitespace indentation is inconsistent compared to earlier lines (line %d of %s)\n", py_line, directive_name);
Printv(out, indent, c + Len(initial), "\n", NIL);
}
}
Delete(clist);
return out;
}
* indent_docstring()
*
* Format (indent) a Python docstring.
* Remove leading whitespace from 'code' and re-indent using
* the indentation string in 'indent'.
* ------------------------------------------------------------ */
String *indent_docstring(const String *code, const char *indent) {
String *out = NewString("");
String *temp;
char *t;
if (!indent)
indent = "";
temp = NewString(code);
t = Char(temp);
if (*t == '{') {
Delitem(temp, 0);
Delitem(temp, DOH_END);
}
List *clist = SplitLines(temp);
Delete(temp);
Iterator si;
int truncate_characters_count = INT_MAX;
for (si = First(clist); si.item; si = Next(si)) {
const char *c = Char(si.item);
int i;
for (i = 0; isspace((unsigned char)c[i]); i++) {
}
char ch = c[i];
if (ch) {
if (i < truncate_characters_count)
truncate_characters_count = i;
}
}
if (truncate_characters_count == INT_MAX)
truncate_characters_count = 0;
for (si = First(clist); si.item; si = Next(si)) {
const char *c = Char(si.item);
int i;
for (i = 0; isspace((unsigned char)c[i]); i++) {
}
char ch = c[i];
if (!ch) {
Putc('\n', out);
continue;
}
Printv(out, indent, c + truncate_characters_count, "\n", NIL);
}
Delete(clist);
return out;
}
* autodoc level declarations
* ------------------------------------------------------------ */
enum autodoc_l {
NO_AUTODOC = -2,
STRING_AUTODOC = -1,
NAMES_AUTODOC = 0,
TYPES_AUTODOC = 1,
EXTEND_AUTODOC = 2,
EXTEND_TYPES_AUTODOC = 3
};
autodoc_l autodoc_level(String *autodoc) {
autodoc_l dlevel = NO_AUTODOC;
char *c = Char(autodoc);
if (c) {
if (isdigit(c[0])) {
dlevel = (autodoc_l) atoi(c);
} else {
if (strcmp(c, "extended") == 0) {
dlevel = EXTEND_AUTODOC;
} else {
dlevel = STRING_AUTODOC;
}
}
}
return dlevel;
}
* have_docstring()
*
* Check if there is a docstring directive and it has text,
* or there is an autodoc flag set
* ------------------------------------------------------------ */
bool have_docstring(Node *n) {
String *str = Getattr(n, "feature:docstring");
return ((str && Len(str) > 0)
|| (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"))
|| (doxygen && doxygenTranslator->hasDocumentation(n))
);
}
* find_overload_with_docstring()
*
* This function should be called with the node pointing to the
* last element of an overload set and returns an overload with
* a docstring or null if there are none.
*
* The idea is that, because the Python docstring is shared by
* all overloads, it's this function return value and not the
* node itself which needs to be passes to docstring() later.
* ------------------------------------------------------------ */
Node *find_overload_with_docstring(Node *n) {
for (Node *node_with_doc = n; node_with_doc; node_with_doc = Getattr(node_with_doc, "sym:previousSibling")) {
if (have_docstring(node_with_doc))
return node_with_doc;
}
return NULL;
}
* build_combined_docstring()
*
* Build the full docstring:
* Use the docstring if there is one present otherwise
* use the Doxygen comment if there is one present.
* Ignore autodoc if there is a Doxygen comment, otherwise
* create the autodoc string and append to any docstring.
*
* Return new string to be deleted by caller (never NIL but
* may be empty if there is no docstring).
* ------------------------------------------------------------ */
String *build_combined_docstring(Node *n, autodoc_t ad_type, const char *indent = "", bool low_level = false) {
bool add_autodoc = true;
String *docstr = Getattr(n, "feature:docstring");
if (docstr) {
if (!Len(docstr))
docstr = NULL;
else
docstr = Copy(docstr);
}
if (docstr) {
char *t = Char(docstr);
if (*t == '{') {
Delitem(docstr, 0);
Delitem(docstr, DOH_END);
}
}
if (!docstr) {
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
docstr = Getattr(n, "python:docstring");
if (!docstr) {
docstr = doxygenTranslator->getDocumentation(n, 0);
Setattr(n, "python:docstring", Copy(docstr));
} else {
docstr = Copy(docstr);
}
add_autodoc = false;
}
}
if (add_autodoc && Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
String *autodoc = make_autodoc(n, ad_type, low_level);
if (autodoc && Len(autodoc) > 0) {
if (docstr) {
Append(autodoc, "\n");
Append(autodoc, docstr);
}
String *tmp = autodoc;
autodoc = docstr;
docstr = tmp;
}
Delete(autodoc);
}
if (!docstr)
docstr = NewString("");
if (Strchr(docstr, '\n')) {
String *tmp = NewString("");
Append(tmp, "\n");
Append(tmp, indent_docstring(docstr, indent));
Append(tmp, indent);
Delete(docstr);
docstr = tmp;
} else {
Chop(docstr);
const char *c = Char(docstr);
if (isspace((int)*c)) {
while(isspace((int)*(++c))) {
}
String *old_docstr = docstr;
docstr = NewString(c);
Delete(old_docstr);
}
}
return docstr;
}
* docstring()
*
* Get the docstring text, stripping off {} if necessary,
* and enclose in triple double quotes. If autodoc is also
* set then it will build a combined docstring.
* ------------------------------------------------------------ */
String *docstring(Node *n, autodoc_t ad_type, const char *indent, bool low_level = false) {
String *docstr = build_combined_docstring(n, ad_type, indent, low_level);
const int len = Len(docstr);
if (!len)
return docstr;
String *doc = NewString("");
const bool useSingleQuotes = (Char(docstr))[len - 1] == '"';
Append(doc, useSingleQuotes ? "r'''" : "r\"\"\"");
if (useSingleQuotes)
Replaceall(docstr, "'''", "''' \"'''\" '''");
else
Replaceall(docstr, "\"\"\"", "\"\"\" '\"\"\"' \"\"\"");
Append(doc, docstr);
Append(doc, useSingleQuotes ? "'''" : "\"\"\"");
Delete(docstr);
return doc;
}
* cdocstring()
*
* Get the docstring text as it would appear in C-language
* source code (but without quotes around it).
* ------------------------------------------------------------ */
String *cdocstring(Node *n, autodoc_t ad_type, bool low_level = false) {
String *ds = build_combined_docstring(n, ad_type, "", low_level);
Replaceall(ds, "\\", "\\\\");
Replaceall(ds, "\"", "\\\"");
Replaceall(ds, "\n", "\\n\"\n\t\t\"");
return ds;
}
* addMissingParameterNames()
*
* For functions that have not had nameless parameters set in the Language class.
*
* Inputs:
* plist - entire parameter list
* arg_num - the number to start from when naming arguments
* Side effects:
* The "lname" attribute in each parameter in plist will be contain a parameter name
* ----------------------------------------------------------------------------- */
void addMissingParameterNames(Node *n, ParmList *plist, int arg_num) {
Parm *p = plist;
int i = arg_num;
while (p) {
if (!Getattr(p, "lname")) {
String *name = makeParameterName(n, p, i);
Setattr(p, "lname", name);
Delete(name);
}
i++;
p = nextSibling(p);
}
}
* make_autodocParmList()
*
* Generate the documentation for the function parameters
* Parameters:
* arg_num: The number to start assigning unnamed arguments from
* func_annotation: Function annotation support
* ------------------------------------------------------------ */
String *make_autodocParmList(Node *n, bool showTypes, int arg_num = 1, bool calling = false, bool func_annotation = false) {
String *doc = NewString("");
String *pdocs = 0;
ParmList *plist = CopyParmList(Getattr(n, "parms"));
Parm *p;
Parm *pnext;
if (calling)
func_annotation = false;
addMissingParameterNames(n, plist, arg_num);
Swig_typemap_attach_parms("in", plist, 0);
Swig_typemap_attach_parms("doc", plist, 0);
if (Strcmp(ParmList_protostr(plist), "void") == 0) {
return doc;
}
for (p = plist; p; p = pnext) {
String *tm = Getattr(p, "tmap:in");
if (tm) {
pnext = Getattr(p, "tmap:in:next");
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
continue;
}
} else {
pnext = nextSibling(p);
}
String *name = 0;
String *type = 0;
String *value = 0;
String *pdoc = Getattr(p, "tmap:doc");
if (pdoc) {
name = Getattr(p, "tmap:doc:name");
type = Getattr(p, "tmap:doc:type");
value = Getattr(p, "tmap:doc:value");
}
if (Getattr(p, "self")) {
continue;
}
String *made_name = 0;
if (!name) {
name = made_name = makeParameterName(n, p, arg_num);
}
arg_num++;
type = type ? type : Getattr(p, "type");
value = value ? value : Getattr(p, "value");
if (SwigType_isvarargs(type)) {
Delete(made_name);
break;
}
if (Len(doc)) {
Append(doc, ", ");
}
Node *nn = classLookup(Getattr(p, "type"));
String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
if (showTypes)
Printf(doc, "%s ", type_str);
Append(doc, name);
if (pdoc) {
if (!pdocs)
pdocs = NewString("\nParameters\n----------\n");
Printf(pdocs, "%s\n", pdoc);
}
if (func_annotation)
Printf(doc, ": \"%s\"", type_str);
if (value && !calling) {
String *new_value = convertValue(value, Getattr(p, "numval"), Getattr(p, "stringval"), Getattr(p, "type"));
if (new_value) {
value = new_value;
} else {
Node *lookup = Swig_symbol_clookup(value, 0);
if (lookup)
value = Getattr(lookup, "sym:name");
}
Printf(doc, "=%s", value);
if (new_value)
Delete(new_value);
}
Delete(type_str);
Delete(made_name);
}
if (pdocs)
Setattr(n, "feature:pdocs", pdocs);
Delete(plist);
return doc;
}
* make_autodoc()
*
* Build a docstring for the node, using parameter and other
* info in the parse tree. If the value of the autodoc
* attribute is "0" then do not include parameter types, if
* it is "1" (the default) then do. If it has some other
* value then assume it is supplied by the extension writer
* and use it directly.
* ------------------------------------------------------------ */
String *make_autodoc(Node *n, autodoc_t ad_type, bool low_level = false) {
int extended = 0;
bool first_func = true;
while (Getattr(n, "sym:previousSibling"))
n = Getattr(n, "sym:previousSibling");
String *doc = NewString("");
while (n) {
bool showTypes = false;
bool skipAuto = false;
String *autodoc = Getattr(n, "feature:autodoc");
autodoc_l dlevel = autodoc_level(autodoc);
switch (dlevel) {
case NO_AUTODOC:
break;
case NAMES_AUTODOC:
showTypes = false;
break;
case TYPES_AUTODOC:
showTypes = true;
break;
case EXTEND_AUTODOC:
extended = 1;
showTypes = false;
break;
case EXTEND_TYPES_AUTODOC:
extended = 1;
showTypes = true;
break;
case STRING_AUTODOC:
Append(doc, autodoc);
skipAuto = true;
break;
}
if (!skipAuto) {
String *symname = Getattr(n, low_level ? "doc:low:name" : "doc:high:name");
if (!symname) {
symname = Getattr(n, "sym:name");
}
SwigType *type = Getattr(n, "type");
String *type_str = NULL;
if (Getattr(n, "defaultargs") != NULL) {
n = Getattr(n, "sym:nextSibling");
continue;
}
if (!first_func)
Append(doc, "\n");
if (type) {
if (Strcmp(type, "void") == 0) {
type_str = NULL;
} else {
Node *nn = classLookup(type);
type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
}
}
String *kind = Getattr(n, "kind");
if (kind && Strcmp(kind, "variable") == 0) {
if (ad_type == AUTODOC_FUNC) {
ad_type = AUTODOC_METHOD;
}
}
String *nodeType = Getattr(n, "nodeType");
if (nodeType && Strcmp(nodeType, "destructor") == 0) {
if (ad_type == AUTODOC_FUNC) {
ad_type = AUTODOC_METHOD;
}
}
switch (ad_type) {
case AUTODOC_CLASS:
{
String *str = Getattr(n, "feature:docstring");
if (!str || Len(str) == 0) {
if (builtin) {
SwigType *name = Getattr(n, "name");
SwigType *sname = add_explicit_scope(name);
String *rname = SwigType_namestr(sname);
Printf(doc, "%s", rname);
Delete(sname);
Delete(rname);
} else {
String *classname_str = SwigType_namestr(real_classname);
if (CPlusPlus) {
Printf(doc, "Proxy of C++ %s class.", classname_str);
} else {
Printf(doc, "Proxy of C %s struct.", classname_str);
}
Delete(classname_str);
}
}
}
break;
case AUTODOC_CTOR:
if (Strcmp(class_name, symname) == 0) {
String *paramList = make_autodocParmList(n, showTypes, 2);
Printf(doc, "__init__(");
if (showTypes)
Printf(doc, "%s ", class_name);
if (Len(paramList))
Printf(doc, "self, %s) -> %s", paramList, class_name);
else
Printf(doc, "self) -> %s", class_name);
} else
Printf(doc, "%s(%s) -> %s", symname, make_autodocParmList(n, showTypes), class_name);
break;
case AUTODOC_DTOR:
if (showTypes)
Printf(doc, "__del__(%s self)", class_name);
else
Printf(doc, "__del__(self)");
break;
case AUTODOC_STATICFUNC:
Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes));
if (type_str)
Printf(doc, " -> %s", type_str);
break;
case AUTODOC_FUNC:
Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes));
if (type_str)
Printf(doc, " -> %s", type_str);
break;
case AUTODOC_METHOD:
{
String *paramList = make_autodocParmList(n, showTypes, 2);
Printf(doc, "%s(", symname);
if (showTypes)
Printf(doc, "%s ", class_name);
if (Len(paramList))
Printf(doc, "self, %s)", paramList);
else
Printf(doc, "self)");
if (type_str)
Printf(doc, " -> %s", type_str);
}
break;
case AUTODOC_CONST:
return NULL;
case AUTODOC_VAR:
Printf(doc, "%s", symname);
if (showTypes) {
String *type = Getattr(n, "tmap:doc:type");
if (!type)
type = Getattr(n, "membervariableHandler:type");
if (!type)
type = Getattr(n, "type");
Printf(doc, " : %s", type);
}
break;
}
Delete(type_str);
bool variable_getter = kind && Strcmp(kind, "variable") == 0 && Getattr(n, "memberget");
if (extended && ad_type != AUTODOC_VAR && !variable_getter) {
String *pdocs = Getattr(n, "feature:pdocs");
if (pdocs) {
Printv(doc, "\n", pdocs, NULL);
}
}
}
n = Getattr(n, "sym:nextSibling");
if (n)
first_func = false;
}
return doc;
}
* convertIntegerValue()
*
* Check if string v is an integer and can be represented in
* Python. If so, return an appropriate Python representation,
* otherwise (or if we are unsure), return NIL.
* ------------------------------------------------------------ */
String *convertIntegerValue(String *v, SwigType *resolved_type) {
const char *const s = Char(v);
char *end;
errno = 0;
long value = strtol(s, &end, 0);
if (errno == ERANGE || end == s || *end != '\0') {
return NIL;
}
#if LONG_MAX > PYTHON_INT_MAX || LONG_MIN < PYTHON_INT_MIN
if (value > PYTHON_INT_MAX || value < PYTHON_INT_MIN) {
return NIL;
}
#endif
if (Equal(resolved_type, "bool"))
return NewString(value ? "True" : "False");
if (value == 0)
return NewString(SwigType_ispointer(resolved_type) ? "None" : "0");
return Copy(v);
}
* convertDoubleValue()
*
* Check if the given string looks like a decimal floating point constant
* and return it if it does, otherwise return NIL.
* ------------------------------------------------------------ */
String *convertDoubleValue(String *v) {
const char *const s = Char(v);
char *end;
errno = 0;
double value = strtod(s, &end);
(void) value;
if (errno != ERANGE && end != s) {
if (strpbrk(s, "xXnN"))
return NIL;
for (char * p = end; *p != '\0'; ++p) {
switch (*p) {
case 'f':
case 'F':
break;
default:
return NIL;
}
}
return *end == '\0' ? Copy(v) : NewStringWithSize(s, (int)(end - s));
}
return NIL;
}
* convertValue()
*
* Check if string v can be a Python value literal or a
* constant. Return an equivalent Python representation,
* or NIL if it isn't, or we are unsure.
* ------------------------------------------------------------ */
String *convertValue(String *v, String *numval, String *stringval, SwigType *type) {
if (stringval) {
return NIL;
}
SwigType *resolved_type = SwigType_typedef_resolve_all(type);
SwigType *unqualified_type = SwigType_strip_qualifiers(resolved_type);
if (numval) {
if (Equal(unqualified_type, "bool")) {
Delete(resolved_type);
Delete(unqualified_type);
return NewString(*Char(numval) == '0' ? "False" : "True");
}
String *result = convertIntegerValue(numval, unqualified_type);
Delete(resolved_type);
Delete(unqualified_type);
return result;
}
String *result = convertDoubleValue(v);
if (!result) {
if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0)
result = SwigType_ispointer(unqualified_type) ? NewString("None") : NewString("0");
else if (!Strchr(v, ':')) {
Node *lookup = Swig_symbol_clookup(v, 0);
if (lookup) {
if (Cmp(Getattr(lookup, "nodeType"), "enumitem") == 0)
result = Copy(Getattr(lookup, "sym:name"));
}
}
}
Delete(resolved_type);
Delete(unqualified_type);
return result;
}
* is_representable_as_pyargs()
*
* Check if the function parameters default argument values
* can be represented in Python.
*
* If this method returns false, the parameters will be translated
* to a generic "*args" which allows us to deal with default values
* at C++ code level where they can always be handled.
* ------------------------------------------------------------ */
bool is_representable_as_pyargs(Node *n) {
ParmList *plist = CopyParmList(Getattr(n, "parms"));
Swig_typemap_attach_parms("default", plist, NULL);
Parm *p;
Parm *pnext;
for (p = plist; p; p = pnext) {
pnext = nextSibling(p);
String *tm = Getattr(p, "tmap:in");
if (tm) {
Parm *in_next = Getattr(p, "tmap:in:next");
if (in_next)
pnext = in_next;
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
continue;
}
}
if (Getattr(p, "tmap:default"))
return false;
String *value = Getattr(p, "value");
if (value) {
String *convertedValue = convertValue(value, Getattr(p, "numval"), Getattr(p, "stringval"), Getattr(p, "type"));
if (!convertedValue)
return false;
Delete(convertedValue);
}
}
return true;
}
* is_real_overloaded()
*
* Check if the function is overloaded, but not just have some
* siblings generated due to the original function having
* default arguments.
* ------------------------------------------------------------ */
bool is_real_overloaded(Node *n) {
Node *h = Getattr(n, "sym:overloaded");
Node *i;
if (!h)
return false;
i = Getattr(h, "sym:nextSibling");
while (i) {
Node *nn = Getattr(i, "defaultargs");
if (nn != h) {
* pointed to the first overloaded. */
return true;
}
i = Getattr(i, "sym:nextSibling");
}
return false;
}
* make_pyParmList()
*
* Generate parameter list for Python functions or methods,
* reuse make_autodocParmList() to do so.
* ------------------------------------------------------------ */
String *make_pyParmList(Node *n, bool in_class, bool is_calling, int kw, bool has_self_for_count = false) {
* see default_arguments() in parser.y. */
Node *nn = Getattr(n, "defaultargs");
if (nn)
n = nn;
Parm *parms = Getattr(n, "parms");
int varargs = parms ? emit_isvarargs(parms) : 0;
generated Python code as this makes the function more convenient to use,
however in some cases we must replace the real parameters list with just
the catch all "*args". This happens when:
1. The function is overloaded as Python doesn't support this.
2. We were explicitly asked to use the "compact" arguments form.
3. We were explicitly asked to use default args from C via the "python:cdefaultargs" feature.
4. One of the default argument values can't be represented in Python.
5. Varargs that haven't been forced to use a fixed number of arguments with %varargs.
*/
if (is_real_overloaded(n) || GetFlag(n, "feature:compactdefaultargs") || GetFlag(n, "feature:python:cdefaultargs") || !is_representable_as_pyargs(n) || varargs) {
String *parms = NewString("");
if (in_class)
Printf(parms, "self, ");
Printf(parms, "*args");
if (kw)
Printf(parms, ", **kwargs");
return parms;
}
bool funcanno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
String *params = NewString("");
String *_params = make_autodocParmList(n, false, ((in_class || has_self_for_count)? 2 : 1), is_calling, funcanno);
if (in_class) {
Printf(params, "self");
if (Len(_params) > 0)
Printf(params, ", ");
}
Printv(params, _params, NULL);
return params;
}
* have_pythonprepend()
*
* Check if there is a %pythonprepend directive and it has text
* ------------------------------------------------------------ */
bool have_pythonprepend(Node *n) {
String *str = Getattr(n, "feature:pythonprepend");
return (str && Len(str) > 0);
}
* pythonprepend()
*
* Get the %pythonprepend code, stripping off {} if necessary
* ------------------------------------------------------------ */
String *pythonprepend(Node *n) {
String *str = Getattr(n, "feature:pythonprepend");
char *t = Char(str);
if (*t == '{') {
Delitem(str, 0);
Delitem(str, DOH_END);
}
return str;
}
* have_pythonappend()
*
* Check if there is a %pythonappend directive and it has text
* ------------------------------------------------------------ */
bool have_pythonappend(Node *n) {
String *str = Getattr(n, "feature:pythonappend");
if (!str)
str = Getattr(n, "feature:addtofunc");
return (str && Len(str) > 0);
}
* pythonappend()
*
* Get the %pythonappend code, stripping off {} if necessary
* ------------------------------------------------------------ */
String *pythonappend(Node *n) {
String *str = Getattr(n, "feature:pythonappend");
if (!str)
str = Getattr(n, "feature:addtofunc");
char *t = Char(str);
if (*t == '{') {
Delitem(str, 0);
Delitem(str, DOH_END);
}
return str;
}
* have_addtofunc()
*
* Check if there is a %addtofunc directive and it has text
* ------------------------------------------------------------ */
bool have_addtofunc(Node *n) {
return have_pythonappend(n) || have_pythonprepend(n);
}
* returnTypeAnnotation()
*
* Helper function for constructing the function annotation
* of the returning type, return a empty string for Python 2.x
* ------------------------------------------------------------ */
String *returnTypeAnnotation(Node *n) {
String *ret = 0;
Parm *p = Getattr(n, "parms");
String *tm;
* however the result may not accurate. */
while (p) {
if ((tm = Getattr(p, "tmap:argout:match_type"))) {
tm = SwigType_str(tm, 0);
if (ret)
Printv(ret, ", ", tm, NULL);
else
ret = tm;
p = Getattr(p, "tmap:argout:next");
} else {
p = nextSibling(p);
}
}
* the function prototype. */
if (!ret) {
ret = Getattr(n, "type");
if (ret)
ret = SwigType_str(ret, 0);
}
bool funcanno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
return (ret && funcanno) ? NewStringf(" -> \"%s\"", ret) : NewString("");
}
* variableAnnotation()
*
* Helper function for constructing a variable annotation
* ------------------------------------------------------------ */
String *variableAnnotation(Node *n) {
String *type = Getattr(n, "type");
if (type)
type = SwigType_str(type, 0);
bool anno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
anno = GetFlag(n, "feature:python:annotations:novar") ? false : anno;
String *annotation = (type && anno) ? NewStringf(": \"%s\"", type) : NewString("");
Delete(type);
return annotation;
}
* emitFunctionShadowHelper()
*
* Refactoring some common code out of functionWrapper and
* dispatchFunction that writes the proxy code for non-member
* functions.
* ------------------------------------------------------------ */
void emitFunctionShadowHelper(Node *n, File *f_dest, String *name, int kw) {
String *parms = make_pyParmList(n, false, false, kw);
String *callParms = make_pyParmList(n, false, true, kw);
bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback");
if (!fast || olddefs) {
Printv(f_dest, "\n", "def ", name, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
if (Node *node_with_doc = find_overload_with_docstring(n))
Printv(f_dest, tab4, docstring(node_with_doc, AUTODOC_FUNC, tab4, true), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_dest, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
if (have_pythonappend(n)) {
Printv(f_dest, tab4 "val = ", funcCall(name, callParms), "\n", NIL);
Printv(f_dest, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_dest, tab4 "return val\n", NIL);
} else {
Printv(f_dest, tab4 "return ", funcCall(name, callParms), "\n", NIL);
}
}
if (fast) {
Printv(f_dest, name, " = ", module, ".", name, "\n", NIL);
}
}
* check_kwargs()
*
* check if using kwargs is allowed for this Node
* ------------------------------------------------------------ */
int check_kwargs(Node *n) const {
return (use_kw || GetFlag(n, "feature:kwargs"))
&& !GetFlag(n, "memberset") && !GetFlag(n, "memberget");
}
* add_method()
* ------------------------------------------------------------ */
void add_method(String *name, String *function, int kw, Node *n = 0, int funpack = 0, int num_required = -1, int num_arguments = -1) {
String * meth_str = NewString("");
if (!kw) {
if (funpack) {
if (num_required == 0 && num_arguments == 0) {
Printf(meth_str, "\t { \"%s\", %s, METH_NOARGS, ", name, function);
} else if (num_required == 1 && num_arguments == 1) {
Printf(meth_str, "\t { \"%s\", %s, METH_O, ", name, function);
} else {
Printf(meth_str, "\t { \"%s\", %s, METH_VARARGS, ", name, function);
}
} else {
Printf(meth_str, "\t { \"%s\", %s, METH_VARARGS, ", name, function);
}
} else {
Printf(meth_str, "\t { \"%s\", (PyCFunction)(void(*)(void))%s, METH_VARARGS|METH_KEYWORDS, ", name, function);
}
Append(methods, meth_str);
if (fastproxy) {
Append(methods_proxydocs, meth_str);
}
Delete(meth_str);
if (!n) {
Append(methods, "NULL");
if (fastproxy) {
Append(methods_proxydocs, "NULL");
}
} else if (Node *node_with_doc = find_overload_with_docstring(n)) {
String *ds = cdocstring(node_with_doc, Getattr(n, "memberfunction") ? AUTODOC_METHOD : AUTODOC_FUNC, true);
Printf(methods, "\"%s\"", ds);
if (fastproxy) {
Delete(ds);
ds = cdocstring(node_with_doc, Getattr(n, "memberfunction") ? AUTODOC_METHOD : AUTODOC_FUNC);
Printf(methods_proxydocs, "\"%s\"", ds);
}
Delete(ds);
} else if (Getattr(n, "feature:callback")) {
Printf(methods, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
if (fastproxy) {
Printf(methods_proxydocs, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
have_fast_proxy_static_member_method_callback = true;
}
} else {
Append(methods, "NULL");
if (fastproxy) {
Append(methods_proxydocs, "NULL");
}
}
Append(methods, "},\n");
if (fastproxy) {
Append(methods_proxydocs, "},\n");
}
}
* dispatchFunction()
* ------------------------------------------------------------ */
void dispatchFunction(Node *n, String *linkage, int funpack = 0, bool builtin_self = false, bool builtin_ctor = false, bool director_class = false, bool use_static_method = false) {
bool add_self = builtin_self && (!builtin_ctor || director_class);
int maxargs;
String *tmp = NewString("");
String *dispatch;
const char *dispatch_call = funpack ? "%s(self, argc, argv);" : (builtin_ctor ? "%s(self, args, NULL);" : "%s(self, args);");
String *dispatch_code = NewStringf("return %s", dispatch_call);
if (castmode) {
dispatch = Swig_overload_dispatch_cast(n, dispatch_code, &maxargs);
} else {
String *fastdispatch_code;
if (builtin_ctor)
fastdispatch_code = NewStringf("int retval = %s\nif (retval == 0 || !SWIG_Python_TypeErrorOccurred(NULL)) return retval;\nSWIG_fail;", dispatch_call);
else
fastdispatch_code = NewStringf("PyObject *retobj = %s\nif (!SWIG_Python_TypeErrorOccurred(retobj)) return retobj;\nSWIG_fail;", dispatch_call);
if (!CPlusPlus) {
Insert(fastdispatch_code, 0, "{\n");
Append(fastdispatch_code, "\n}");
}
dispatch = Swig_overload_dispatch(n, dispatch_code, &maxargs, fastdispatch_code);
Delete(fastdispatch_code);
}
Wrapper *f = NewWrapper();
String *symname = Getattr(n, "sym:name");
String *wname = Swig_name_wrapper(symname);
const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : "";
Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
if (builtin) {
Append(f->code, "(void)self;\n");
}
Wrapper_add_local(f, "argc", "Py_ssize_t argc");
Printf(tmp, "PyObject *argv[%d] = {0}", maxargs + 1);
Wrapper_add_local(f, "argv", tmp);
if (!fastunpack) {
Wrapper_add_local(f, "ii", "Py_ssize_t ii");
if (builtin_ctor)
Printf(f->code, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", symname);
if (maxargs - (add_self ? 1 : 0) > 0) {
Append(f->code, "if (!PyTuple_Check(args)) SWIG_fail;\n");
Append(f->code, "argc = PyObject_Length(args);\n");
} else {
Append(f->code, "argc = args ? PyObject_Length(args) : 0;\n");
}
if (add_self)
Append(f->code, "argv[0] = self;\n");
Printf(f->code, "for (ii = 0; (ii < %d) && (ii < argc); ii++) {\n", add_self ? maxargs - 1 : maxargs);
Printf(f->code, "argv[ii%s] = PyTuple_GET_ITEM(args,ii);\n", add_self ? " + 1" : "");
Append(f->code, "}\n");
if (add_self)
Append(f->code, "argc++;\n");
} else {
if (builtin_ctor)
Printf(f->code, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", symname);
Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args, \"%s\", 0, %d, argv%s))) SWIG_fail;\n", symname, maxargs, add_self ? "+1" : "");
if (add_self)
Append(f->code, "argv[0] = self;\n");
else
Append(f->code, "--argc;\n");
}
Replaceall(dispatch, "$args", "self, args");
Printv(f->code, dispatch, "\n", NIL);
if (GetFlag(n, "feature:python:maybecall")) {
Append(f->code, "fail:\n");
Append(f->code, " SWIG_Py_INCREF(Py_NotImplemented);\n");
Append(f->code, " return Py_NotImplemented;\n");
} else {
Node *sibl = n;
while (Getattr(sibl, "sym:previousSibling"))
sibl = Getattr(sibl, "sym:previousSibling");
String *protoTypes = NewString("");
do {
String *fulldecl = Swig_name_decl(sibl);
Printf(protoTypes, "\n\" %s\\n\"", fulldecl);
Delete(fulldecl);
} while ((sibl = Getattr(sibl, "sym:nextSibling")));
Append(f->code, "fail:\n");
Printf(f->code, " SWIG_Python_RaiseOrModifyTypeError("
"\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes);
Printf(f->code, "return %s;\n", builtin_ctor ? "-1" : "0");
Delete(protoTypes);
}
Printv(f->code, "}\n", NIL);
Wrapper_print(f, f_wrappers);
if (!builtin_self && (use_static_method || !builtin))
add_method(symname, wname, 0, Getattr(n, "sym:previousSibling") ? n : NULL);
if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) {
emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, symname, 0);
}
DelWrapper(f);
Delete(dispatch);
Delete(dispatch_code);
Delete(tmp);
Delete(wname);
}
* functionWrapper()
* ------------------------------------------------------------ */
A note about argument marshalling with built-in types.
There are three distinct cases for member (non-static) methods:
1) An ordinary member function. In this case, the first param in
the param list is 'this'. For builtin types, 'this' is taken from
the first argument to the wrapper (usually called 'self); it's not
extracted from the second argument (which is usually a tuple).
2) A constructor for a non-director class. In this case, the
param list doesn't contain an entry for 'this', but the first ('self')
argument to the wrapper *does* contain the newly-allocated,
uninitialized object.
3) A constructor for a director class. In this case, the param
list contains a 'self' param, which comes from the first argument
to the wrapper function.
*/
const char *get_implicitconv_flag(Node *klass) {
int conv = 0;
if (klass && GetFlag(klass, "feature:implicitconv")) {
conv = 1;
}
return conv ? "SWIG_POINTER_IMPLICIT_CONV" : "0";
}
virtual int functionWrapper(Node *n) {
String *name = Getattr(n, "name");
String *iname = Getattr(n, "sym:name");
SwigType *returntype = Getattr(n, "type");
ParmList *l = Getattr(n, "parms");
Node *parent = Swig_methodclass(n);
int director_method = 0;
Parm *p;
int i;
char source[64];
Wrapper *f;
String *self_parse;
String *parse_args;
String *arglist;
String *get_pointers;
String *cleanup;
String *outarg;
String *kwargs;
String *tm;
String *overname = 0;
int num_required;
int num_arguments;
int num_fixed_arguments;
int tuple_required;
int tuple_arguments;
int varargs = 0;
int allow_kwargs = check_kwargs(n);
String *nodeType = Getattr(n, "nodeType");
int constructor = (!Cmp(nodeType, "constructor"));
int destructor = (!Cmp(nodeType, "destructor"));
String *storage = Getattr(n, "storage");
int isfriend = Strstr(storage, "friend") != NULL;
constructor can be emitted via %rename */
int handled_as_init = 0;
if (!have_constructor && (constructor || Getattr(n, "handled_as_constructor"))
&& ((shadow & PYSHADOW_MEMBER))) {
String *nname = Getattr(n, "sym:name");
String *sname = Getattr(getCurrentClass(), "sym:name");
String *cname = Swig_name_construct(NSPACE_TODO, sname);
handled_as_init = (Strcmp(nname, sname) == 0) || (Strcmp(nname, cname) == 0);
Delete(cname);
}
bool builtin_self = builtin && in_class && (constructor || (l && Getattr(l, "self")));
bool builtin_ctor = false;
if (builtin_self && constructor) {
String *class_mname = Getattr(getCurrentClass(), "sym:name");
String *mrename = Swig_name_construct(getNSpace(), class_mname);
if (Cmp(iname, mrename))
builtin_self = false;
else
builtin_ctor = true;
Delete(mrename);
}
bool director_class = (getCurrentClass() && Swig_directorclass(getCurrentClass()));
bool add_self = builtin_self && (!builtin_ctor || director_class);
bool builtin_getter = (builtin && GetFlag(n, "memberget"));
bool builtin_setter = (builtin && GetFlag(n, "memberset") && !builtin_getter);
char const *wrap_return = builtin_ctor ? "int " : "PyObject *";
String *linkage = NewString("SWIGINTERN ");
String *wrapper_name = Swig_name_wrapper(iname);
if (Getattr(n, "sym:overloaded")) {
overname = Getattr(n, "sym:overname");
} else {
if (!addSymbol(iname, n))
return SWIG_ERROR;
}
f = NewWrapper();
self_parse = NewString("");
parse_args = NewString("");
arglist = NewString("");
get_pointers = NewString("");
cleanup = NewString("");
outarg = NewString("");
kwargs = NewString("");
int allow_thread = threads_enable(n);
Wrapper_add_local(f, "resultobj", "PyObject *resultobj = 0");
emit_parameter_variables(l, f);
emit_attach_parmmaps(l, f);
Setattr(n, "wrap:parms", l);
tuple_arguments = num_arguments = emit_num_arguments(l);
tuple_required = num_required = emit_num_required(l);
if (add_self) {
--tuple_arguments;
--tuple_required;
}
num_fixed_arguments = tuple_required;
if (((num_arguments == 0) && (num_required == 0)) || ((num_arguments == 1) && (num_required == 1) && Getattr(l, "self")))
if (!builtin_ctor)
allow_kwargs = 0;
varargs = emit_isvarargs(l);
String *wname = Copy(wrapper_name);
if (overname) {
Append(wname, overname);
}
const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : "";
if (!allow_kwargs || overname) {
if (!varargs) {
Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
} else {
Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *self, PyObject *args, PyObject *varargs", builtin_kwargs, ") {", NIL);
}
if (allow_kwargs) {
Swig_warning(WARN_LANG_OVERLOAD_KEYWORD, input_file, line_number, "Can't use keyword arguments with overloaded functions (%s).\n", Swig_name_decl(n));
allow_kwargs = 0;
}
} else {
if (varargs) {
Swig_warning(WARN_LANG_VARARGS_KEYWORD, input_file, line_number, "Can't wrap varargs with keyword arguments enabled\n");
varargs = 0;
}
Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args, PyObject *kwargs) {", NIL);
}
if (!builtin) {
Append(f->code, "(void)self;\n");
}
if (!builtin || !in_class || tuple_arguments > 0 || builtin_ctor) {
if (!allow_kwargs) {
Append(parse_args, " if (!PyArg_ParseTuple(args, \"");
} else {
Append(parse_args, " if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"");
Append(arglist, ", kwnames");
}
}
bool over_varargs = emit_isvarargs_function(n);
int funpack = fastunpack && !varargs && !over_varargs && !allow_kwargs;
int noargs = funpack && (tuple_required == 0 && tuple_arguments == 0);
int onearg = funpack && (tuple_required == 1 && tuple_arguments == 1);
if (builtin && funpack && !overname && !builtin_ctor) {
int compactdefargs = ParmList_is_compactdefargs(l);
if (!(compactdefargs && (tuple_arguments > tuple_required || varargs))) {
String *argattr = NewStringf("%d", tuple_arguments);
Setattr(n, "python:argcount", argattr);
Delete(argattr);
}
}
if (funpack) {
if (num_arguments > (builtin_self && !constructor ? 1 : 0) && !overname) {
sprintf(source, "PyObject *swig_obj[%d]", num_arguments);
Wrapper_add_localv(f, "swig_obj", source, NIL);
}
}
if (constructor && num_arguments == 1 && num_required == 1) {
if (Cmp(storage, "explicit") == 0) {
if (GetFlag(parent, "feature:implicitconv")) {
String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type")));
Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc);
Delete(desc);
}
}
}
if (builtin_ctor && checkAttribute(n, "access", "protected")) {
String *tmp_none_comparison = Copy(none_comparison);
Replaceall(tmp_none_comparison, "$arg", "self");
Printf(self_parse, "if (!(%s)) {\n", tmp_none_comparison);
Printv(self_parse, " SWIG_SetErrorMsg(PyExc_RuntimeError, \"accessing abstract class or protected constructor\");\n SWIG_fail;\n}\n", NIL);
Delete(tmp_none_comparison);
}
int use_parse = 0;
Append(kwargs, "{");
for (i = 0, p = l; i < num_arguments; i++) {
while (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
}
SwigType *pt = Getattr(p, "type");
String *ln = Getattr(p, "lname");
bool parse_from_tuple = (i > 0 || !add_self);
if (SwigType_type(pt) == T_VARARGS) {
parse_from_tuple = false;
num_fixed_arguments -= atoi(Char(Getattr(p, "tmap:in:numinputs")));
}
if (!parse_from_tuple)
sprintf(source, "self");
else if (funpack)
sprintf(source, "swig_obj[%d]", add_self && !overname ? i - 1 : i);
else
sprintf(source, "obj%d", builtin_ctor ? i + 1 : i);
if (parse_from_tuple) {
Printf(arglist, ", ");
if (i == num_required)
Putc('|', parse_args);
}
if (allow_kwargs && parse_from_tuple) {
String *name = makeParameterName(n, p, i + 1);
Printf(kwargs, " (char *)\"%s\", ", name);
Delete(name);
}
if ((tm = Getattr(p, "tmap:in"))) {
String *parse = Getattr(p, "tmap:in:parse");
if (!parse) {
if (builtin_self) {
Replaceall(tm, "$self", "self");
} else if (funpack) {
Replaceall(tm, "$self", "swig_obj[0]");
} else {
Replaceall(tm, "$self", "obj0");
}
Replaceall(tm, "$input", source);
Setattr(p, "emit:input", source);
if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
} else {
Replaceall(tm, "$disown", "0");
}
if (Getattr(p, "tmap:in:implicitconv")) {
const char *convflag = "0";
if (!Getattr(p, "hidden")) {
SwigType *ptype = Getattr(p, "type");
convflag = get_implicitconv_flag(classLookup(ptype));
}
Replaceall(tm, "$implicitconv", convflag);
Setattr(p, "implicitconv", convflag);
}
if (parse_from_tuple)
Putc('O', parse_args);
if (!funpack && parse_from_tuple) {
Wrapper_add_localv(f, source, "PyObject *", source, "= 0", NIL);
Printf(arglist, "&%s", source);
}
if (i >= num_required)
Printv(get_pointers, "if (", source, ") {\n", NIL);
Printv(get_pointers, tm, "\n", NIL);
if (i >= num_required)
Printv(get_pointers, "}\n", NIL);
} else {
use_parse = 1;
Append(parse_args, parse);
if (parse_from_tuple)
Printf(arglist, "&%s", ln);
}
p = Getattr(p, "tmap:in:next");
continue;
} else {
Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
break;
}
}
Append(kwargs, " NULL }");
if (allow_kwargs) {
Printv(f->locals, " char * kwnames[] = ", kwargs, ";\n", NIL);
}
if (use_parse || allow_kwargs) {
Printf(parse_args, ":%s\"", iname);
Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
funpack = 0;
} else {
Clear(parse_args);
if (funpack) {
Clear(f->def);
if (overname) {
if (noargs) {
Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL);
} else {
Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
}
Printf(parse_args, "if ((nobjs < %d) || (nobjs > %d)) SWIG_fail;\n", num_required, num_arguments);
} else {
int is_tp_call = Equal(Getattr(n, "feature:python:slot"), "tp_call");
Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
if (builtin_ctor)
Printf(parse_args, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", iname);
if (onearg && !builtin_ctor && !is_tp_call) {
Printf(parse_args, "if (!args) SWIG_fail;\n");
Append(parse_args, "swig_obj[0] = args;\n");
} else if (!noargs) {
Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args, \"%s\", %d, %d, swig_obj)) SWIG_fail;\n", iname, num_fixed_arguments, tuple_arguments);
} else if (noargs) {
Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args, \"%s\", %d, %d, 0)) SWIG_fail;\n", iname, num_fixed_arguments, tuple_arguments);
}
}
} else {
if (builtin_ctor)
Printf(parse_args, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", iname);
if (builtin && in_class && tuple_arguments == 0) {
Printf(parse_args, " if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, \"%s takes no arguments\");\n", iname);
} else {
Printf(parse_args, "if (!PyArg_UnpackTuple(args, \"%s\", %d, %d", iname, num_fixed_arguments, tuple_arguments);
Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
}
}
}
Printv(f->code, self_parse, parse_args, get_pointers, NIL);
if (varargs) {
if (p && (tm = Getattr(p, "tmap:in"))) {
Replaceall(tm, "$input", "varargs");
Printv(f->code, tm, "\n", NIL);
}
}
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:check"))) {
Printv(f->code, tm, "\n", NIL);
p = Getattr(p, "tmap:check:next");
} else {
p = nextSibling(p);
}
}
for (p = l; p;) {
if (!Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) {
if (Getattr(p, "tmap:freearg:implicitconv")) {
const char *convflag = "0";
if (!Getattr(p, "hidden")) {
SwigType *ptype = Getattr(p, "type");
convflag = get_implicitconv_flag(classLookup(ptype));
}
if (strcmp(convflag, "0") == 0) {
tm = 0;
}
}
if (tm && (Len(tm) != 0)) {
Printv(cleanup, tm, "\n", NIL);
}
p = Getattr(p, "tmap:freearg:next");
} else {
p = nextSibling(p);
}
}
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:argout"))) {
Replaceall(tm, "$arg", Getattr(p, "emit:input"));
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Printv(outarg, tm, "\n", NIL);
p = Getattr(p, "tmap:argout:next");
} else {
p = nextSibling(p);
}
}
* underlying python object, resolve the call by going up the c++
* inheritance chain. otherwise try to resolve the method in python.
* without this check an infinite loop is set up between the director and
* shadow class method calls.
*/
director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
if (director_method) {
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n");
if (dirprot_mode() && !is_public(n)) {
Printf(f->code, "if (!director || !(director->swig_get_inner(\"%s\"))) {\n", name);
Printf(f->code, "SWIG_SetErrorMsg(PyExc_RuntimeError,\"accessing protected member %s\");\n", name);
Append(f->code, "SWIG_fail;\n");
Append(f->code, "}\n");
}
Wrapper_add_local(f, "upcall", "bool upcall = false");
if (funpack) {
const char *self_parm = builtin_self ? "self" : "swig_obj[0]";
Printf(f->code, "upcall = (director && (director->swig_get_self()==%s));\n", self_parm);
} else {
const char *self_parm = builtin_self ? "self" : "obj0";
Printf(f->code, "upcall = (director && (director->swig_get_self()==%s));\n", self_parm);
}
}
if (director_method) {
Append(f->code, "try {\n");
} else {
if (allow_thread) {
String *preaction = NewString("");
thread_begin_allow(n, preaction);
Setattr(n, "wrap:preaction", preaction);
String *postaction = NewString("");
thread_end_allow(n, postaction);
Setattr(n, "wrap:postaction", postaction);
}
}
Setattr(n, "wrap:name", wname);
Swig_director_emit_dynamic_cast(n, f);
String *actioncode = emit_action(n);
if (director_method) {
Append(actioncode, "} catch (Swig::DirectorException&) {\n");
Append(actioncode, " SWIG_fail;\n");
Append(actioncode, "}\n");
}
tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode);
if (tm) {
if (builtin_self) {
Replaceall(tm, "$self", "self");
} else if (funpack) {
Replaceall(tm, "$self", "swig_obj[0]");
} else {
Replaceall(tm, "$self", "obj0");
}
Replaceall(tm, "$result", "resultobj");
if (builtin_ctor) {
Replaceall(tm, "$owner", "SWIG_BUILTIN_INIT");
} else if (handled_as_init) {
Replaceall(tm, "$owner", "SWIG_POINTER_NEW");
} else {
if (GetFlag(n, "feature:new")) {
Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
} else {
Replaceall(tm, "$owner", "0");
}
}
if (!constructor && Swig_director_can_unwrap(n)) {
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
Printf(f->code, "director = SWIG_DIRECTOR_CAST(%s);\n", Swig_cresult_name());
Append(f->code, "if (director) {\n");
Append(f->code, " resultobj = director->swig_get_self();\n");
Append(f->code, " SWIG_Py_INCREF(resultobj);\n");
Append(f->code, "} else {\n");
Printf(f->code, "%s\n", tm);
Append(f->code, "}\n");
} else {
Printf(f->code, "%s\n", tm);
}
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(returntype, 0), name);
}
emit_return_variable(n, returntype, f);
Printv(f->code, outarg, NIL);
int need_cleanup = Len(cleanup) != 0;
if (need_cleanup) {
Printv(f->code, cleanup, NIL);
}
if (GetFlag(n, "feature:new")) {
if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
Printf(f->code, "%s\n", tm);
Delete(tm);
}
}
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
Printf(f->code, "%s\n", tm);
Delete(tm);
}
if (director_method) {
if ((tm = Swig_typemap_lookup("directorfree", n, Swig_cresult_name(), 0))) {
Replaceall(tm, "$input", Swig_cresult_name());
Replaceall(tm, "$result", "resultobj");
Printf(f->code, "%s\n", tm);
Delete(tm);
}
}
if (builtin_ctor)
Append(f->code, " return resultobj == Py_None ? -1 : 0;\n");
else
Append(f->code, " return resultobj;\n");
Append(f->code, "fail:\n");
if (need_cleanup) {
Printv(f->code, cleanup, NIL);
}
if (builtin_ctor) {
Printv(f->code, " return -1;\n", NIL);
} else {
if (GetFlag(n, "feature:python:maybecall")) {
Append(f->code, " if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {\n");
Append(f->code, " return NULL;\n");
Append(f->code, " }\n");
Append(f->code, " PyErr_Clear();\n");
Append(f->code, " SWIG_Py_INCREF(Py_NotImplemented);\n");
Append(f->code, " return Py_NotImplemented;\n");
} else {
Printv(f->code, " return NULL;\n", NIL);
}
}
Append(f->code, "}\n");
Replaceall(f->code, "$cleanup", cleanup);
bool isvoid = !Cmp(returntype, "void");
Replaceall(f->code, "$isvoid", isvoid ? "1" : "0");
Replaceall(f->code, "$symname", iname);
Replaceall(f->code, "$result", "resultobj");
if (builtin_self) {
Replaceall(f->code, "$self", "self");
} else if (funpack) {
Replaceall(f->code, "$self", "swig_obj[0]");
} else {
Replaceall(f->code, "$self", "obj0");
}
Wrapper_print(f, f_wrappers);
if (varargs) {
DelWrapper(f);
f = NewWrapper();
if (funpack) {
Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
} else {
Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
}
Wrapper_add_local(f, "resultobj", builtin_ctor ? "int resultobj" : "PyObject *resultobj");
Wrapper_add_local(f, "varargs", "PyObject *varargs");
Wrapper_add_local(f, "newargs", "PyObject *newargs");
if (funpack) {
Wrapper_add_local(f, "i", "int i");
Printf(f->code, "newargs = PyTuple_New(%d);\n", num_fixed_arguments);
Printf(f->code, "for (i = 0; i < %d; ++i) {\n", num_fixed_arguments);
Printf(f->code, " PyTuple_SET_ITEM(newargs, i, swig_obj[i]);\n");
Printf(f->code, " SWIG_Py_XINCREF(swig_obj[i]);\n");
Printf(f->code, "}\n");
Printf(f->code, "varargs = PyTuple_New(nobjs > %d ? nobjs - %d : 0);\n", num_fixed_arguments, num_fixed_arguments);
Printf(f->code, "for (i = 0; i < nobjs - %d; ++i) {\n", num_fixed_arguments);
Printf(f->code, " PyTuple_SET_ITEM(newargs, i, swig_obj[i + %d]);\n", num_fixed_arguments);
Printf(f->code, " SWIG_Py_XINCREF(swig_obj[i + %d]);\n", num_fixed_arguments);
Printf(f->code, "}\n");
} else {
Printf(f->code, "newargs = PyTuple_GetSlice(args, 0, %d);\n", num_fixed_arguments);
Printf(f->code, "varargs = PyTuple_GetSlice(args, %d, PyTuple_Size(args));\n", num_fixed_arguments);
}
Printf(f->code, "resultobj = %s__varargs__(%s, newargs, varargs%s);\n", wname, builtin ? "self" : "NULL", strlen(builtin_kwargs) == 0 ? "" : ", kwargs");
Append(f->code, "SWIG_Py_XDECREF(newargs);\n");
Append(f->code, "SWIG_Py_XDECREF(varargs);\n");
Append(f->code, "return resultobj;\n");
Append(f->code, "}\n");
Wrapper_print(f, f_wrappers);
}
bool use_static_method = flat_static_method || !Swig_storage_isstatic_custom(n, "staticmemberfunctionHandler:storage");
if (!Getattr(n, "sym:overloaded")) {
if (!builtin_self && (use_static_method || !builtin))
add_method(iname, wname, allow_kwargs, n, funpack, num_required, num_arguments);
if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) {
emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, iname, allow_kwargs);
}
} else {
if (!Getattr(n, "sym:nextSibling")) {
dispatchFunction(n, linkage, funpack, builtin_self, builtin_ctor, director_class, use_static_method);
}
}
if (builtin_ctor) {
if ((director_method || !is_private(n)) && !Getattr(class_members, iname)) {
Setattr(class_members, iname, n);
if (!builtin_tp_init)
builtin_tp_init = Swig_name_wrapper(iname);
}
}
if (builtin) {
const char *memname = "__dict__";
Hash *h = Getattr(builtin_getset, memname);
if (!h) {
h = NewHash();
Setattr(builtin_getset, memname, h);
Delete(h);
}
Setattr(h, "getter", "SwigPyObject_get___dict__");
if (!Getattr(h, "doc")) {
Setattr(n, "doc:high:name", Getattr(n, "name"));
Setattr(h, "doc", cdocstring(n, AUTODOC_VAR));
}
}
if (builtin_getter) {
String *memname = Getattr(n, "membervariableHandler:sym:name");
if (!memname)
memname = iname;
Hash *h = Getattr(builtin_getset, memname);
if (!h) {
h = NewHash();
Setattr(builtin_getset, memname, h);
Delete(h);
}
Setattr(h, "getter", wrapper_name);
Delattr(n, "memberget");
if (!Getattr(h, "doc")) {
Setattr(n, "doc:high:name", Getattr(n, "name"));
String *ds = cdocstring(n, AUTODOC_VAR);
Setattr(h, "doc", ds);
Delete(ds);
}
}
if (builtin_setter) {
String *memname = Getattr(n, "membervariableHandler:sym:name");
if (!memname)
memname = iname;
Hash *h = Getattr(builtin_getset, memname);
if (!h) {
h = NewHash();
Setattr(builtin_getset, memname, h);
Delete(h);
}
Setattr(h, "setter", wrapper_name);
Delattr(n, "memberset");
if (!Getattr(h, "doc")) {
Setattr(n, "doc:high:name", Getattr(n, "name"));
String *ds = cdocstring(n, AUTODOC_VAR);
Setattr(h, "doc", ds);
Delete(ds);
}
}
if (in_class && builtin) {
String *slot = Getattr(n, "feature:python:slot");
if (slot && !isfriend) {
String *func_type = Getattr(n, "feature:python:slot:functype");
String *closure_decl = getClosure(func_type, wrapper_name, overname ? 0 : funpack);
String *feature_name = NewStringf("feature:python:%s", slot);
String *closure_name = 0;
if (closure_decl) {
closure_name = NewStringf("%s_%s_closure", wrapper_name, func_type);
if (!GetFlag(builtin_closures, closure_name))
Printf(builtin_closures_code, "%s /* defines %s */\n\n", closure_decl, closure_name);
SetFlag(builtin_closures, closure_name);
Delete(closure_decl);
} else {
closure_name = Copy(wrapper_name);
}
if (func_type) {
String *s = NewStringf("%s", closure_name);
Delete(closure_name);
closure_name = s;
}
Setattr(parent, feature_name, closure_name);
Delete(feature_name);
Delete(closure_name);
}
String *compare = Getattr(n, "feature:python:compare");
if (compare) {
Hash *richcompare = Getattr(parent, "python:richcompare");
assert(richcompare);
Setattr(richcompare, compare, wrapper_name);
}
}
Delete(self_parse);
Delete(parse_args);
Delete(linkage);
Delete(arglist);
Delete(get_pointers);
Delete(cleanup);
Delete(outarg);
Delete(kwargs);
Delete(wname);
DelWrapper(f);
Delete(wrapper_name);
return SWIG_OK;
}
* variableWrapper()
* ------------------------------------------------------------ */
virtual int variableWrapper(Node *n) {
String *name = Getattr(n, "name");
String *iname = Getattr(n, "sym:name");
SwigType *t = Getattr(n, "type");
static int have_globals = 0;
String *tm;
Wrapper *getf, *setf;
if (!addSymbol(iname, n))
return SWIG_ERROR;
getf = NewWrapper();
setf = NewWrapper();
Python dictionary. */
if (!have_globals) {
Printf(f_init, "\t globals = SWIG_globals();\n");
Printf(f_init, "\t if (!globals) {\n");
Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Failure to create SWIG globals.\");\n");
Printf(f_init, "#if PY_VERSION_HEX >= 0x03000000\n");
Printf(f_init, "\t return NULL;\n");
Printf(f_init, "#else\n");
Printf(f_init, "\t return;\n");
Printf(f_init, "#endif\n");
Printf(f_init, "\t }\n");
Printf(f_init, "\t PyDict_SetItemString(md, \"%s\", globals);\n", global_name);
if (builtin)
Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", global_name);
have_globals = 1;
if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) {
Printf(f_shadow_stubs, "%s = %s.%s\n", global_name, module, global_name);
}
}
int assignable = !is_immutable(n);
if (!builtin && shadow && !assignable && !in_class)
Printf(f_shadow_stubs, "%s = %s.%s\n", iname, global_name, iname);
String *getname = Swig_name_get(NSPACE_TODO, iname);
String *setname = Swig_name_set(NSPACE_TODO, iname);
String *vargetname = NewStringf("Swig_var_%s", getname);
String *varsetname = NewStringf("Swig_var_%s", setname);
if (assignable) {
Setattr(n, "wrap:name", varsetname);
if (builtin && in_class) {
String *set_wrapper = Swig_name_wrapper(setname);
Setattr(n, "pybuiltin:setter", set_wrapper);
Delete(set_wrapper);
}
Printf(setf->def, "SWIGINTERN int %s(PyObject *_val) {", varsetname);
if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
Replaceall(tm, "$input", "_val");
if (Getattr(n, "tmap:varin:implicitconv")) {
Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
}
emit_action_code(n, setf->code, tm);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
}
Printv(setf->code, " return 0;\n", NULL);
Append(setf->code, "fail:\n");
Printv(setf->code, " return 1;\n", NULL);
} else {
if (CPlusPlus) {
Printf(setf->def, "SWIGINTERN int %s(PyObject *) {", varsetname);
} else {
Printf(setf->def, "SWIGINTERN int %s(PyObject *_val SWIGUNUSED) {", varsetname);
}
Printv(setf->code, " SWIG_Error(SWIG_AttributeError,\"Variable ", iname, " is read-only.\");\n", " return 1;\n", NIL);
}
Append(setf->code, "}\n");
Wrapper_print(setf, f_wrappers);
Setattr(n, "wrap:name", vargetname);
if (builtin && in_class) {
String *get_wrapper = Swig_name_wrapper(getname);
Setattr(n, "pybuiltin:getter", get_wrapper);
Delete(get_wrapper);
}
int addfail = 0;
Printf(getf->def, "SWIGINTERN PyObject *%s(void) {", vargetname);
Wrapper_add_local(getf, "pyobj", "PyObject *pyobj = 0");
if (builtin) {
Wrapper_add_local(getf, "self", "PyObject *self = 0");
Append(getf->code, " (void)self;\n");
}
if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
Replaceall(tm, "$result", "pyobj");
addfail = emit_action_code(n, getf->code, tm);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
}
Append(getf->code, " return pyobj;\n");
if (addfail) {
Append(getf->code, "fail:\n");
Append(getf->code, " return NULL;\n");
}
Append(getf->code, "}\n");
Wrapper_print(getf, f_wrappers);
Printf(f_varlinks, "\t SWIG_addvarlink(globals, \"%s\", %s, %s);\n", iname, vargetname, varsetname);
if (builtin && shadow && !assignable && !in_class) {
Printf(f_varlinks, "\t PyDict_SetItemString(md, \"%s\", PyObject_GetAttrString(globals, \"%s\"));\n", iname, iname);
Printf(f_varlinks, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", iname);
}
Delete(vargetname);
Delete(varsetname);
Delete(getname);
Delete(setname);
DelWrapper(setf);
DelWrapper(getf);
return SWIG_OK;
}
* constantWrapper()
* ------------------------------------------------------------ */
bool needs_swigconstant(Node *n) {
SwigType *type = Getattr(n, "type");
SwigType *qtype = SwigType_typedef_resolve_all(type);
SwigType *uqtype = SwigType_strip_qualifiers(qtype);
bool result = false;
* SwigType_base(fptr) does not return the underlying pointer-to-function
* type but the return-type of function. */
if (!SwigType_isfunction(uqtype) && !SwigType_isfunctionpointer(uqtype)) {
SwigType *basetype = SwigType_base(uqtype);
result = SwigType_isclass(basetype) != 0;
Delete(basetype);
}
Delete(qtype);
Delete(uqtype);
return result;
}
virtual int constantWrapper(Node *n) {
String *name = Getattr(n, "name");
String *iname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *value = Getattr(n, "value");
String *tm;
int have_tm = 0;
int have_builtin_symname = 0;
if (!addSymbol(iname, n))
return SWIG_ERROR;
if (SwigType_type(type) == T_MPOINTER) {
String *wname = Swig_name_wrapper(iname);
String *str = SwigType_str(type, wname);
Printf(f_header, "static %s = %s;\n", str, value);
Delete(str);
value = wname;
}
if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
Replaceall(tm, "$value", value);
Printf(const_code, "%s,\n", tm);
Delete(tm);
have_tm = 1;
}
if (builtin && in_class && Getattr(n, "pybuiltin:symname")) {
have_builtin_symname = 1;
Swig_require("builtin_constantWrapper", n, "*sym:name", "pybuiltin:symname", NIL);
Setattr(n, "sym:name", Getattr(n, "pybuiltin:symname"));
}
if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
Replaceall(tm, "$value", value);
if (needs_swigconstant(n) && !builtin && shadow && !(shadow & PYSHADOW_MEMBER) && (!in_class || !Getattr(n, "feature:python:callback"))) {
Printf(f_wrappers, "SWIGINTERN PyObject *%s_swigconstant(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", iname);
Printf(f_wrappers, tab2 "PyObject *module = NULL;\n");
Printf(f_wrappers, tab2 "PyObject *d;\n");
Printf(f_wrappers, tab2 "if (!SWIG_Python_UnpackTuple(args, \"swigconstant\", 1, 1, &module)) return NULL;\n");
Printf(f_wrappers, tab2 "d = PyModule_GetDict(module);\n");
Printf(f_wrappers, tab2 "if (!d) return NULL;\n");
Printf(f_wrappers, tab2 "%s\n", tm);
Printf(f_wrappers, tab2 "return SWIG_Py_Void();\n");
Printf(f_wrappers, "}\n\n\n");
String *cname = NewStringf("%s_swigconstant", iname);
add_method(cname, cname, 0, 0, 1, 1, 1);
Delete(cname);
} else {
Printf(f_init, "%s\n", tm);
}
Delete(tm);
have_tm = 1;
}
if (have_builtin_symname)
Swig_restore(n);
if (!have_tm) {
Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
return SWIG_NOWRAP;
}
if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) {
String *f_s;
if (!in_class) {
f_s = f_shadow;
} else {
f_s = Getattr(n, "feature:python:callback") ? NIL : f_shadow_stubs;
}
if (f_s) {
if (needs_swigconstant(n)) {
Printv(f_s, "\n",NIL);
Printv(f_s, module, ".", iname, "_swigconstant(",module,")\n", NIL);
}
Printv(f_s, iname, " = ", module, ".", iname, "\n", NIL);
if (have_docstring(n))
Printv(f_s, docstring(n, AUTODOC_CONST, tab4), "\n", NIL);
}
}
return SWIG_OK;
}
* nativeWrapper()
* ------------------------------------------------------------ */
virtual int nativeWrapper(Node *n) {
String *name = Getattr(n, "sym:name");
String *wrapname = Getattr(n, "wrap:name");
if (!addSymbol(wrapname, n))
return SWIG_ERROR;
add_method(name, wrapname, 0);
if (!builtin && shadow) {
Printv(f_shadow_stubs, name, " = ", module, ".", name, "\n", NIL);
}
return SWIG_OK;
}
* BEGIN C++ Director Class modifications
* ------------------------------------------------------------------------- */
*
* TODO
*
* Move some boilerplate code generation to Swig_...() functions.
*
*/
* classDirectorMethod()
*
* Emit a virtual director method to pass a method call on to the
* underlying Python object.
* ** Moved down due to gcc-2.96 internal error **
* --------------------------------------------------------------- */
int classDirectorMethods(Node *n);
int classDirectorMethod(Node *n, Node *parent, String *super);
* classDirectorConstructor()
* ------------------------------------------------------------ */
int classDirectorConstructor(Node *n) {
Node *parent = Getattr(n, "parentNode");
String *sub = NewString("");
String *decl = Getattr(n, "decl");
String *supername = Swig_class_name(parent);
String *classname = NewString("");
Printf(classname, "SwigDirector_%s", supername);
Parm *p;
ParmList *superparms = Getattr(n, "parms");
ParmList *parms = CopyParmList(superparms);
String *type = NewString("PyObject");
SwigType_add_pointer(type);
p = NewParm(type, NewString("self"), n);
set_nextSibling(p, parms);
parms = p;
if (!Getattr(n, "defaultargs")) {
{
Wrapper *w = NewWrapper();
String *call;
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, classname, parms, 0);
call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call);
Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
Append(w->def, "}\n");
Delete(target);
Wrapper_print(w, f_directors);
Delete(call);
DelWrapper(w);
}
{
String *target = Swig_method_decl(0, decl, classname, parms, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
}
Delete(sub);
Delete(classname);
Delete(supername);
Delete(parms);
return Language::classDirectorConstructor(n);
}
* classDirectorDefaultConstructor()
* ------------------------------------------------------------ */
int classDirectorDefaultConstructor(Node *n) {
String *classname = Swig_class_name(n);
{
Node *parent = Swig_methodclass(n);
String *basetype = Getattr(parent, "classtype");
Wrapper *w = NewWrapper();
Printf(w->def, "SwigDirector_%s::SwigDirector_%s(PyObject *self) : Swig::Director(self) { \n", classname, classname);
Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
Append(w->def, "}\n");
Wrapper_print(w, f_directors);
DelWrapper(w);
}
Printf(f_directors_h, " SwigDirector_%s(PyObject *self);\n", classname);
Delete(classname);
return Language::classDirectorDefaultConstructor(n);
}
* classDirectorInit()
* ------------------------------------------------------------ */
int classDirectorInit(Node *n) {
String *declaration = Swig_director_declaration(n);
Printf(f_directors_h, "\n");
Printf(f_directors_h, "%s\n", declaration);
Printf(f_directors_h, "public:\n");
Delete(declaration);
return Language::classDirectorInit(n);
}
* classDirectorEnd()
* ------------------------------------------------------------ */
int classDirectorEnd(Node *n) {
String *classname = Swig_class_name(n);
if (dirprot_mode()) {
This implementation uses a std::map<std::string,int>.
It should be possible to rewrite it using a more elegant way,
like copying the Java approach for the 'override' array.
But for now, this seems to be the least intrusive way.
*/
Printf(f_directors_h, "\n");
Printf(f_directors_h, "/* Internal director utilities */\n");
Printf(f_directors_h, "public:\n");
Printf(f_directors_h, " bool swig_get_inner(const char *swig_protected_method_name) const {\n");
Printf(f_directors_h, " std::map<std::string, bool>::const_iterator iv = swig_inner.find(swig_protected_method_name);\n");
Printf(f_directors_h, " return (iv != swig_inner.end() ? iv->second : false);\n");
Printf(f_directors_h, " }\n");
Printf(f_directors_h, " void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const {\n");
Printf(f_directors_h, " swig_inner[swig_protected_method_name] = swig_val;\n");
Printf(f_directors_h, " }\n");
Printf(f_directors_h, "private:\n");
Printf(f_directors_h, " mutable std::map<std::string, bool> swig_inner;\n");
}
if (director_method_index) {
Printf(f_directors_h, "\n");
Printf(f_directors_h, "#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n");
Printf(f_directors_h, "/* VTable implementation */\n");
Printf(f_directors_h, " PyObject *swig_get_method(size_t method_index, const char *method_name) const {\n");
Printf(f_directors_h, " PyObject *method = vtable[method_index];\n");
Printf(f_directors_h, " if (!method) {\n");
Printf(f_directors_h, " swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name);\n");
Printf(f_directors_h, " method = PyObject_GetAttr(swig_get_self(), name);\n");
Printf(f_directors_h, " if (!method) {\n");
Printf(f_directors_h, " std::string msg = \"Method in class %s doesn't exist, undefined \";\n", classname);
Printf(f_directors_h, " msg += method_name;\n");
Printf(f_directors_h, " Swig::DirectorMethodException::raise(msg.c_str());\n");
Printf(f_directors_h, " }\n");
Printf(f_directors_h, " vtable[method_index] = method;\n");
Printf(f_directors_h, " }\n");
Printf(f_directors_h, " return method;\n");
Printf(f_directors_h, " }\n");
Printf(f_directors_h, "private:\n");
Printf(f_directors_h, " mutable swig::SwigVar_PyObject vtable[%d];\n", director_method_index);
Printf(f_directors_h, "#endif\n\n");
}
Printf(f_directors_h, "};\n\n");
return Language::classDirectorEnd(n);
}
* classDirectorDisown()
* ------------------------------------------------------------ */
int classDirectorDisown(Node *n) {
int result;
int oldshadow = shadow;
if (shadow)
shadow = shadow | PYSHADOW_MEMBER;
result = Language::classDirectorDisown(n);
shadow = oldshadow;
if (shadow) {
if (builtin) {
String *rname = SwigType_namestr(real_classname);
Printf(builtin_methods, " { \"__disown__\", Swig::Director::swig_pyobj_disown< %s >, METH_NOARGS, \"\" },\n", rname);
Delete(rname);
} else {
String *symname = Getattr(n, "sym:name");
String *mrename = Swig_name_disown(NSPACE_TODO, symname);
Printv(f_shadow, tab4, "def __disown__(self):\n", NIL);
Printv(f_shadow, tab8, "self.this.disown()\n", NIL);
Printv(f_shadow, tab8, module, ".", mrename, "(self)\n", NIL);
Printv(f_shadow, tab8, "return weakref.proxy(self)\n", NIL);
Delete(mrename);
}
}
return result;
}
* END of C++ Director Class modifications
* ------------------------------------------------------------------------- */
* classDeclaration()
* ------------------------------------------------------------ */
virtual int classDeclaration(Node *n) {
if (shadow && !Getattr(n, "feature:onlychildren")) {
Node *mod = Getattr(n, "module");
if (mod) {
String *modname = Getattr(mod, "name");
Node *options = Getattr(mod, "options");
String *pkg = options ? Getattr(options, "package") : 0;
String *sym = Getattr(n, "sym:name");
String *importname = import_name_string(package, mainmodule, pkg, modname, sym);
Setattr(n, "python:proxy", importname);
Delete(importname);
}
}
int result = Language::classDeclaration(n);
return result;
}
* classHandler()
* ------------------------------------------------------------ */
SwigType *add_explicit_scope(SwigType *s) {
if (!Strstr(s, "::")) {
return NewStringf("::%s", s);
}
return Copy(s);
}
void builtin_pre_decl(Node *n) {
SwigType *name = Getattr(n, "name");
SwigType *sname = add_explicit_scope(name);
String *rname = SwigType_namestr(sname);
String *mname = SwigType_manglestr(sname);
Printf(f_init, "\n/* type '%s' */\n", rname);
Printf(f_init, " d = PyDict_New();\n");
Delete(sname);
Delete(rname);
Delete(mname);
}
void builtin_post_decl(File *f, Node *n) {
SwigType *name = Getattr(n, "name");
SwigType *pname = Copy(name);
SwigType_add_pointer(pname);
String *symname = Getattr(n, "sym:name");
SwigType *sname = add_explicit_scope(name);
String *rname = SwigType_namestr(sname);
String *mname = SwigType_manglestr(sname);
String *pmname = SwigType_manglestr(pname);
String *templ = NewStringf("SwigPyBuiltin_%s", mname);
int funpack = fastunpack;
if (have_builtin_static_member_method_callback) {
Printf(f_init, " SWIG_Python_FixMethods(SwigPyBuiltin_%s_methods, swig_const_table, swig_types, swig_type_initial);\n", mname);
}
Printv(f_init, " builtin_base_count = 0;\n", NIL);
List *baselist = Getattr(n, "bases");
if (baselist) {
int base_count = 0;
for (Iterator b = First(baselist); b.item; b = Next(b)) {
String *bname = Getattr(b.item, "name");
if (!bname || GetFlag(b.item, "feature:ignore"))
continue;
base_count++;
String *base_name = Copy(bname);
SwigType_add_pointer(base_name);
String *base_mname = SwigType_manglestr(base_name);
Printf(f_init, " builtin_basetype = SWIG_MangledTypeQuery(\"%s\");\n", base_mname);
Printv(f_init, " if (builtin_basetype && builtin_basetype->clientdata && ((SwigPyClientData *) builtin_basetype->clientdata)->pytype) {\n", NIL);
Printv(f_init, " builtin_bases[builtin_base_count++] = ((SwigPyClientData *) builtin_basetype->clientdata)->pytype;\n", NIL);
Printv(f_init, " } else {\n", NIL);
Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Could not create type '%s' as base '%s' has not been initialized.\\n\");\n", symname, bname);
Printv(f_init, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
Printv(f_init, " return NULL;\n", NIL);
Printv(f_init, "#else\n", NIL);
Printv(f_init, " return;\n", NIL);
Printv(f_init, "#endif\n", NIL);
Printv(f_init, " }\n", NIL);
Delete(base_name);
Delete(base_mname);
}
if (base_count > max_bases)
max_bases = base_count;
}
Printv(f_init, " builtin_bases[builtin_base_count] = NULL;\n", NIL);
builtin_bases_needed = 1;
static String *tp_dealloc_bad = NewString("SwigPyBuiltin_BadDealloc");
String *getset_name = NewStringf("%s_getset", templ);
String *methods_name = NewStringf("%s_methods", templ);
String *getset_def = NewString("");
Printf(getset_def, "SWIGINTERN PyGetSetDef %s[] = {\n", getset_name);
Printv(f_init, "PyDict_SetItemString(d, \"this\", this_descr);\n", NIL);
Printv(f_init, "PyDict_SetItemString(d, \"thisown\", thisown_descr);\n", NIL);
for (Iterator member_iter = First(builtin_getset); member_iter.item; member_iter = Next(member_iter)) {
String *memname = member_iter.key;
Hash *mgetset = member_iter.item;
String *getter = Getattr(mgetset, "getter");
String *setter = Getattr(mgetset, "setter");
const char *getter_closure = getter ? funpack ? "SwigPyBuiltin_FunpackGetterClosure" : "SwigPyBuiltin_GetterClosure" : "0";
const char *setter_closure = setter ? funpack ? "SwigPyBuiltin_FunpackSetterClosure" : "SwigPyBuiltin_SetterClosure" : "0";
String *gspair = NewStringf("%s_%s_getset", symname, memname);
Printf(f, "static SwigPyGetSet %s = { %s, %s };\n", gspair, getter ? getter : "0", setter ? setter : "0");
String *doc = Getattr(mgetset, "doc");
if (!doc)
doc = NewStringf("%s.%s", name, memname);
String *entry = NewStringf("{ (char *)\"%s\", %s, %s, (char *)\"%s\", &%s }", memname, getter_closure, setter_closure, doc, gspair);
if (GetFlag(mgetset, "static")) {
Printf(f, "static PyGetSetDef %s_def = %s;\n", gspair, entry);
Printf(f_init, "static_getset = SwigPyStaticVar_new_getset(metatype, &%s_def);\n", gspair);
Printf(f_init, "PyDict_SetItemString(d, static_getset->d_getset->name, (PyObject *)static_getset);\n");
Printf(f_init, "SWIG_Py_DECREF((PyObject *)static_getset);\n");
} else {
Printf(getset_def, " %s,\n", entry);
}
Delete(gspair);
Delete(entry);
}
Printv(f, getset_def, " { NULL, NULL, NULL, NULL, NULL } /* Sentinel */\n", "};\n\n", NIL);
Hash *richcompare = Getattr(n, "python:richcompare");
String *richcompare_func = NewStringf("%s_richcompare", templ);
assert(richcompare);
Printf(f, "SWIGINTERN PyObject *\n");
Printf(f, "%s(PyObject *self, PyObject *other, int op) {\n", richcompare_func);
Printf(f, " PyObject *result = NULL;\n");
if (!funpack) {
Printf(f, " PyObject *tuple = PyTuple_New(1);\n");
Printf(f, " assert(tuple);\n");
Printf(f, " PyTuple_SET_ITEM(tuple, 0, other);\n");
Printf(f, " SWIG_Py_XINCREF(other);\n");
}
List *richcompare_list = SortedKeys(richcompare, 0);
Iterator rich_iter = First(richcompare_list);
if (rich_iter.item) {
Printf(f, " switch (op) {\n");
for (; rich_iter.item; rich_iter = Next(rich_iter))
Printf(f, " case %s : result = %s(self, %s); break;\n", rich_iter.item, Getattr(richcompare, rich_iter.item), funpack ? "other" : "tuple");
Printv(f, " default : break;\n", NIL);
Printf(f, " }\n");
}
Delete(richcompare_list);
Printv(f, " if (!result && !PyErr_Occurred()) {\n", NIL);
Printv(f, " if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {\n", NIL);
Printv(f, " result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);\n", NIL);
Printv(f, " } else {\n", NIL);
Printv(f, " result = Py_NotImplemented;\n", NIL);
Printv(f, " SWIG_Py_INCREF(result);\n", NIL);
Printv(f, " }\n", NIL);
Printv(f, " }\n", NIL);
if (!funpack)
Printf(f, " SWIG_Py_DECREF(tuple);\n");
Printf(f, " return result;\n");
Printf(f, "}\n\n");
Printf(f, "SWIGINTERN PyMethodDef %s_methods[] = {\n", templ);
Dump(builtin_methods, f);
Printf(f, " { NULL, NULL, 0, NULL } /* Sentinel */\n};\n\n");
if (GetFlag(n, "feature:python:nondynamic"))
Setattr(n, "feature:python:tp_setattro", "SWIG_Python_NonDynamicSetAttr");
Node *mod = Getattr(n, "module");
String *modname = mod ? Getattr(mod, "name") : 0;
String *quoted_symname;
if (package) {
if (modname)
quoted_symname = NewStringf("\"%s.%s.%s\"", package, modname, symname);
else
quoted_symname = NewStringf("\"%s.%s\"", package, symname);
} else {
if (modname)
quoted_symname = NewStringf("\"%s.%s\"", modname, symname);
else
quoted_symname = NewStringf("\"%s\"", symname);
}
String *quoted_tp_doc_str = NewStringf("\"%s\"", getSlot(n, "feature:python:tp_doc"));
String *tp_init = NewString(builtin_tp_init ? Char(builtin_tp_init) : Swig_directorclass(n) ? "0" : "SwigPyBuiltin_BadInit");
String *tp_flags = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES");
String *tp_flags_py3 = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE");
static String *tp_basicsize = NewStringf("sizeof(SwigPyObject)");
static String *tp_dictoffset_default = NewString("offsetof(SwigPyObject, dict)");
static String *tp_hash = NewString("SwigPyObject_hash");
static String *tp_new = NewString("PyType_GenericNew");
String *tp_as_number = NewStringf("&%s_type.as_number", templ);
String *tp_as_sequence = NewStringf("&%s_type.as_sequence", templ);
String *tp_as_mapping = NewStringf("&%s_type.as_mapping", templ);
String *tp_as_buffer = NewStringf("&%s_type.as_buffer", templ);
Printv(f, "#ifndef SWIG_HEAPTYPES\n", NIL);
Printf(f, "static PyHeapTypeObject %s_type = {\n", templ);
Printf(f, " {\n");
Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
Printv(f, " PyVarObject_HEAD_INIT(NULL, 0)\n", NIL);
Printv(f, "#else\n", NIL);
Printf(f, " PyObject_HEAD_INIT(NULL)\n");
printSlot(f, getSlot(), "ob_size");
Printv(f, "#endif\n", NIL);
printSlot(f, quoted_symname, "tp_name");
printSlot(f, getSlot(n, "feature:python:tp_basicsize", tp_basicsize), "tp_basicsize");
printSlot(f, getSlot(n, "feature:python:tp_itemsize"), "tp_itemsize");
printSlot(f, getSlot(n, "feature:python:tp_dealloc", tp_dealloc_bad), "tp_dealloc", "destructor");
Printv(f, "#if PY_VERSION_HEX < 0x030800b4\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_print"), "tp_print", "printfunc");
Printv(f, "#else\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_vectorcall_offset"), "tp_vectorcall_offset", "Py_ssize_t");
Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_getattr"), "tp_getattr", "getattrfunc");
printSlot(f, getSlot(n, "feature:python:tp_setattr"), "tp_setattr", "setattrfunc");
Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_compare"), "tp_compare");
Printv(f, "#else\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_compare"), "tp_compare", "cmpfunc");
Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_repr"), "tp_repr", "reprfunc");
printSlot(f, getSlot(n, "feature:python:tp_as_number", tp_as_number), "tp_as_number");
printSlot(f, getSlot(n, "feature:python:tp_as_sequence", tp_as_sequence), "tp_as_sequence");
printSlot(f, getSlot(n, "feature:python:tp_as_mapping", tp_as_mapping), "tp_as_mapping");
printSlot(f, getSlot(n, "feature:python:tp_hash", tp_hash), "tp_hash", "hashfunc");
printSlot(f, getSlot(n, "feature:python:tp_call"), "tp_call", "ternaryfunc");
printSlot(f, getSlot(n, "feature:python:tp_str"), "tp_str", "reprfunc");
printSlot(f, getSlot(n, "feature:python:tp_getattro"), "tp_getattro", "getattrofunc");
printSlot(f, getSlot(n, "feature:python:tp_setattro"), "tp_setattro", "setattrofunc");
printSlot(f, getSlot(n, "feature:python:tp_as_buffer", tp_as_buffer), "tp_as_buffer");
Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_flags", tp_flags_py3), "tp_flags");
Printv(f, "#else\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_flags", tp_flags), "tp_flags");
Printv(f, "#endif\n", NIL);
if (have_docstring(n)) {
String *ds = cdocstring(n, AUTODOC_CLASS);
String *tp_doc = NewString("");
Printf(tp_doc, "\"%s\"", ds);
Delete(ds);
printSlot(f, tp_doc, "tp_doc");
Delete(tp_doc);
} else {
printSlot(f, quoted_tp_doc_str, "tp_doc");
}
printSlot(f, getSlot(n, "feature:python:tp_traverse"), "tp_traverse", "traverseproc");
printSlot(f, getSlot(n, "feature:python:tp_clear"), "tp_clear", "inquiry");
printSlot(f, getSlot(n, "feature:python:tp_richcompare", richcompare_func), "tp_richcompare", "richcmpfunc");
printSlot(f, getSlot(n, "feature:python:tp_weaklistoffset"), "tp_weaklistoffset");
printSlot(f, getSlot(n, "feature:python:tp_iter"), "tp_iter", "getiterfunc");
printSlot(f, getSlot(n, "feature:python:tp_iternext"), "tp_iternext", "iternextfunc");
printSlot(f, getSlot(n, "feature:python:tp_methods", methods_name), "tp_methods");
printSlot(f, getSlot(n, "feature:python:tp_members"), "tp_members");
printSlot(f, getSlot(n, "feature:python:tp_getset", getset_name), "tp_getset");
printSlot(f, getSlot(n, "feature:python:tp_base"), "tp_base");
printSlot(f, getSlot(n, "feature:python:tp_dict"), "tp_dict");
printSlot(f, getSlot(n, "feature:python:tp_descr_get"), "tp_descr_get", "descrgetfunc");
printSlot(f, getSlot(n, "feature:python:tp_descr_set"), "tp_descr_set", "descrsetfunc");
printSlot(f, getSlot(n, "feature:python:tp_dictoffset", tp_dictoffset_default), "tp_dictoffset", "Py_ssize_t");
printSlot(f, getSlot(n, "feature:python:tp_init", tp_init), "tp_init", "initproc");
printSlot(f, getSlot(n, "feature:python:tp_alloc"), "tp_alloc", "allocfunc");
printSlot(f, getSlot(), "tp_new", "newfunc");
printSlot(f, getSlot(n, "feature:python:tp_free"), "tp_free", "freefunc");
printSlot(f, getSlot(n, "feature:python:tp_is_gc"), "tp_is_gc", "inquiry");
printSlot(f, getSlot(n, "feature:python:tp_bases"), "tp_bases", "PyObject *");
printSlot(f, getSlot(n, "feature:python:tp_mro"), "tp_mro", "PyObject *");
printSlot(f, getSlot(n, "feature:python:tp_cache"), "tp_cache", "PyObject *");
printSlot(f, getSlot(n, "feature:python:tp_subclasses"), "tp_subclasses", "PyObject *");
printSlot(f, getSlot(n, "feature:python:tp_weaklist"), "tp_weaklist", "PyObject *");
printSlot(f, getSlot(n, "feature:python:tp_del"), "tp_del", "destructor");
printSlot(f, getSlot(n, "feature:python:tp_version_tag"), "tp_version_tag", "int");
Printv(f, "#if PY_VERSION_HEX >= 0x03040000\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_finalize"), "tp_finalize", "destructor");
Printv(f, "#endif\n", NIL);
Printv(f, "#if PY_VERSION_HEX >= 0x03080000\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_vectorcall"), "tp_vectorcall", "vectorcallfunc");
Printv(f, "#endif\n", NIL);
Printv(f, "#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)\n", NIL);
printSlot(f, getSlot(), "tp_print");
Printv(f, "#endif\n", NIL);
Printv(f, "#if PY_VERSION_HEX >= 0x030c0000\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_watched"), "tp_watched", "unsigned char");
Printv(f, "#endif\n", NIL);
Printv(f, "#if PY_VERSION_HEX >= 0x030d00a4\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_versions_used"), "tp_versions_used", "uint16_t");
Printv(f, "#endif\n", NIL);
Printv(f, "#ifdef COUNT_ALLOCS\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_allocs"), "tp_allocs", "Py_ssize_t");
printSlot(f, getSlot(n, "feature:python:tp_frees"), "tp_frees", "Py_ssize_t");
printSlot(f, getSlot(n, "feature:python:tp_maxalloc"), "tp_maxalloc", "Py_ssize_t");
printSlot(f, getSlot(n, "feature:python:tp_prev"), "tp_prev");
printSlot(f, getSlot(n, "feature:python:tp_next"), "tp_next");
Printv(f, "#endif\n", NIL);
Printf(f, " },\n");
Printv(f, "#if PY_VERSION_HEX >= 0x03050000\n", NIL);
Printf(f, " {\n");
printSlot(f, getSlot(n, "feature:python:am_await"), "am_await", "unaryfunc");
printSlot(f, getSlot(n, "feature:python:am_aiter"), "am_aiter", "unaryfunc");
printSlot(f, getSlot(n, "feature:python:am_anext"), "am_anext", "unaryfunc");
Printv(f, "# if PY_VERSION_HEX >= 0x030a0000\n", NIL);
printSlot(f, getSlot(n, "feature:python:am_send"), "am_send", "sendfunc");
Printv(f, "# endif\n", NIL);
Printf(f, " },\n");
Printv(f, "#endif\n", NIL);
Printf(f, " {\n");
printSlot(f, getSlot(n, "feature:python:nb_add"), "nb_add", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_subtract"), "nb_subtract", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_multiply"), "nb_multiply", "binaryfunc");
Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_divide"), "nb_divide", "binaryfunc");
Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_remainder"), "nb_remainder", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_divmod"), "nb_divmod", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_power"), "nb_power", "ternaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_negative"), "nb_negative", "unaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_positive"), "nb_positive", "unaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_absolute"), "nb_absolute", "unaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_nonzero"), "nb_nonzero", "inquiry");
printSlot(f, getSlot(n, "feature:python:nb_invert"), "nb_invert", "unaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_lshift"), "nb_lshift", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_rshift"), "nb_rshift", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_and"), "nb_and", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_xor"), "nb_xor", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_or"), "nb_or", "binaryfunc");
Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_coerce"), "nb_coerce", "coercion");
Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_int"), "nb_int", "unaryfunc");
Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_reserved"), "nb_reserved", "void *");
Printv(f, "#else\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_long"), "nb_long", "unaryfunc");
Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_float"), "nb_float", "unaryfunc");
Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_oct"), "nb_oct", "unaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_hex"), "nb_hex", "unaryfunc");
Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_inplace_add"), "nb_inplace_add", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_subtract"), "nb_inplace_subtract", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_multiply"), "nb_inplace_multiply", "binaryfunc");
Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_inplace_divide"), "nb_inplace_divide", "binaryfunc");
Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_inplace_remainder"), "nb_inplace_remainder", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_power"), "nb_inplace_power", "ternaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_lshift"), "nb_inplace_lshift", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_rshift"), "nb_inplace_rshift", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_and"), "nb_inplace_and", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_xor"), "nb_inplace_xor", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_or"), "nb_inplace_or", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_floor_divide"), "nb_floor_divide", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_divide"), "nb_true_divide", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_floor_divide"), "nb_inplace_floor_divide", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_divide"), "nb_inplace_true_divide", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_index"), "nb_index", "unaryfunc");
Printv(f, "#if PY_VERSION_HEX >= 0x03050000\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_matrix_multiply"), "nb_matrix_multiply", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_matrix_multiply"), "nb_inplace_matrix_multiply", "binaryfunc");
Printv(f, "#endif\n", NIL);
Printf(f, " },\n");
Printf(f, " {\n");
printSlot(f, getSlot(n, "feature:python:mp_length"), "mp_length", "lenfunc");
printSlot(f, getSlot(n, "feature:python:mp_subscript"), "mp_subscript", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:mp_ass_subscript"), "mp_ass_subscript", "objobjargproc");
Printf(f, " },\n");
Printf(f, " {\n");
printSlot(f, getSlot(n, "feature:python:sq_length"), "sq_length", "lenfunc");
printSlot(f, getSlot(n, "feature:python:sq_concat"), "sq_concat", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:sq_repeat"), "sq_repeat", "ssizeargfunc");
printSlot(f, getSlot(n, "feature:python:sq_item"), "sq_item", "ssizeargfunc");
Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
printSlot(f, getSlot(n, "feature:python:was_sq_slice"), "was_sq_slice", "void *");
Printv(f, "#else\n", NIL);
printSlot(f, getSlot(n, "feature:python:sq_slice"), "sq_slice", "ssizessizeargfunc");
Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:sq_ass_item"), "sq_ass_item", "ssizeobjargproc");
Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
printSlot(f, getSlot(n, "feature:python:was_sq_ass_slice"), "was_sq_ass_slice", "void *");
Printv(f, "#else\n", NIL);
printSlot(f, getSlot(n, "feature:python:sq_ass_slice"), "sq_ass_slice", "ssizessizeobjargproc");
Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:sq_contains"), "sq_contains", "objobjproc");
printSlot(f, getSlot(n, "feature:python:sq_inplace_concat"), "sq_inplace_concat", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:sq_inplace_repeat"), "sq_inplace_repeat", "ssizeargfunc");
Printf(f, " },\n");
Printf(f, " {\n");
Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL);
printSlot(f, getSlot(n, "feature:python:bf_getreadbuffer"), "bf_getreadbuffer", "readbufferproc");
printSlot(f, getSlot(n, "feature:python:bf_getwritebuffer"), "bf_getwritebuffer", "writebufferproc");
printSlot(f, getSlot(n, "feature:python:bf_getsegcount"), "bf_getsegcount", "segcountproc");
printSlot(f, getSlot(n, "feature:python:bf_getcharbuffer"), "bf_getcharbuffer", "charbufferproc");
Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:bf_getbuffer"), "bf_getbuffer", "getbufferproc");
printSlot(f, getSlot(n, "feature:python:bf_releasebuffer"), "bf_releasebuffer", "releasebufferproc");
Printf(f, " },\n");
printSlot(f, getSlot(n, "feature:python:ht_name"), "ht_name", "PyObject *");
printSlot(f, getSlot(n, "feature:python:ht_slots"), "ht_slots", "PyObject *");
Printv(f, "#if PY_VERSION_HEX >= 0x03030000\n", NIL);
printSlot(f, getSlot(n, "feature:python:ht_qualname"), "ht_qualname", "PyObject *");
printSlot(f, getSlot(n, "feature:python:ht_cached_keys"), "ht_cached_keys");
Printv(f, "#endif\n", NIL);
Printv(f, "#if PY_VERSION_HEX >= 0x03090000\n", NIL);
printSlot(f, getSlot(n, "feature:python:ht_module"), "ht_module", "PyObject *");
Printv(f, "#endif\n", NIL);
Printv(f, "#if PY_VERSION_HEX >= 0x030b0000\n", NIL);
printSlot(f, getSlot(n, "feature:python:_ht_tpname"), "_ht_tpname", "char *");
Printf(f, " {\n");
printSlot(f, getSlot(n, "feature:python:getitem"), "getitem", "PyObject *");
Printv(f, "#if PY_VERSION_HEX >= 0x030c0000\n", NIL);
printSlot(f, getSlot(n, "feature:python:getitem_version"), "getitem_version", "uint32_t");
Printv(f, "#endif\n", NIL);
Printv(f, "#if PY_VERSION_HEX >= 0x030d0000\n", NIL);
printSlot(f, getSlot(n, "feature:python:init"), "init", "PyObject *");
Printv(f, "#endif\n", NIL);
Printf(f, " }\n");
Printv(f, "#endif\n", NIL);
Printf(f, "};\n\n");
Printf(f, "static PyTypeObject *%s_type_create(PyTypeObject *type, PyTypeObject **bases, PyObject *dict) {\n", templ);
Printv(f, " PyObject *tuple_bases;\n", NIL);
Printf(f, " PyTypeObject *pytype = (PyTypeObject *)&%s_type;\n", templ);
Printf(f, " pytype->tp_dict = dict;\n");
Printv(f, " SwigPyBuiltin_SetMetaType(pytype, type);\n", NIL);
Printf(f, " pytype->tp_new = %s;\n", getSlot(n, "feature:python:tp_new", tp_new));
Printv(f, " tuple_bases = SwigPyBuiltin_InitBases(bases);\n", NIL);
Printv(f, " pytype->tp_base = bases[0];\n", NIL);
Printv(f, " SWIG_Py_INCREF(pytype->tp_base);\n", NIL);
Printv(f, " pytype->tp_bases = tuple_bases;\n", NIL);
Printv(f, " if (PyType_Ready(pytype) < 0) {\n", NIL);
Printf(f, " PyErr_SetString(PyExc_TypeError, \"Could not create type '%s'.\");\n", symname);
Printv(f, " return NULL;\n", NIL);
Printv(f, " }\n", NIL);
Printf(f, " return pytype;\n");
Printf(f, "}\n\n");
Printv(f, "#else\n", NIL);
Printf(f, "static PyTypeObject *%s_type_create(PyTypeObject *type, PyTypeObject **bases, PyObject *dict) {\n", templ);
Printf(f, " PyMemberDef members[] = {\n");
Printf(f, " { (char *)\"__dictoffset__\", Py_T_PYSSIZET, %s, Py_READONLY, NULL },\n", getSlot(n, "feature:python:tp_dictoffset", tp_dictoffset_default));
Printf(f, " { NULL, 0, 0, 0, NULL }\n");
Printf(f, " };\n");
Printf(f, " PyType_Slot slots[] = {\n");
printSlot2(f, getSlot(n, "feature:python:tp_init", tp_init), "tp_init", "initproc");
printSlot2(f, getSlot(n, "feature:python:tp_dealloc", tp_dealloc_bad), "tp_dealloc", "destructor");
printSlot2(f, getSlot(n, "feature:python:tp_alloc"), "tp_alloc", "allocfunc");
printSlot2(f, getSlot(n, "feature:python:tp_free"), "tp_free", "freefunc");
printSlot2(f, getSlot(n, "feature:python:tp_is_gc"), "tp_is_gc", "inquiry");
printSlot2(f, getSlot(n, "feature:python:tp_del"), "tp_del", "destructor");
if (have_docstring(n)) {
String *ds = cdocstring(n, AUTODOC_CLASS);
String *tp_doc = NewString("");
Printf(tp_doc, "\"%s\"", ds);
Delete(ds);
printSlot2(f, tp_doc, "tp_doc");
Delete(tp_doc);
} else {
printSlot2(f, quoted_tp_doc_str, "tp_doc");
}
printSlot2(f, getSlot(n, "feature:python:tp_repr"), "tp_repr", "reprfunc");
printSlot2(f, getSlot(n, "feature:python:tp_str"), "tp_str", "reprfunc");
printSlot2(f, getSlot(n, "feature:python:tp_traverse"), "tp_traverse", "traverseproc");
printSlot2(f, getSlot(n, "feature:python:tp_clear"), "tp_clear", "inquiry");
printSlot2(f, getSlot(n, "feature:python:tp_richcompare", richcompare_func), "tp_richcompare", "richcmpfunc");
printSlot2(f, getSlot(n, "feature:python:tp_methods", methods_name), "tp_methods");
printSlot2(f, getSlot(n, "feature:python:tp_getset", getset_name), "tp_getset");
printSlot2(f, getSlot(n, "feature:python:tp_hash", tp_hash), "tp_hash", "hashfunc");
printSlot2(f, getSlot(n, "feature:python:tp_call"), "tp_call", "ternaryfunc");
printSlot2(f, getSlot(n, "feature:python:tp_getattro"), "tp_getattro", "getattrofunc");
printSlot2(f, getSlot(n, "feature:python:tp_setattro"), "tp_setattro", "setattrofunc");
printSlot2(f, getSlot(n, "feature:python:tp_descr_get"), "tp_descr_get", "descrgetfunc");
printSlot2(f, getSlot(n, "feature:python:tp_descr_set"), "tp_descr_set", "descrsetfunc");
printSlot2(f, getSlot(n, "feature:python:mp_length"), "mp_length", "lenfunc");
printSlot2(f, getSlot(n, "feature:python:mp_subscript"), "mp_subscript", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:mp_ass_subscript"), "mp_ass_subscript", "objobjargproc");
printSlot2(f, getSlot(n, "feature:python:tp_iter"), "tp_iter", "getiterfunc");
printSlot2(f, getSlot(n, "feature:python:tp_iternext"), "tp_iternext", "iternextfunc");
printSlot2(f, getSlot(n, "feature:python:nb_add"), "nb_add", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_subtract"), "nb_subtract", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_multiply"), "nb_multiply", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_remainder"), "nb_remainder", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_divmod"), "nb_divmod", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_power"), "nb_power", "ternaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_negative"), "nb_negative", "unaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_positive"), "nb_positive", "unaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_absolute"), "nb_absolute", "unaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_nonzero"), "nb_bool", "inquiry");
printSlot2(f, getSlot(n, "feature:python:nb_invert"), "nb_invert", "unaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_lshift"), "nb_lshift", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_rshift"), "nb_rshift", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_and"), "nb_and", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_xor"), "nb_xor", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_or"), "nb_or", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_int"), "nb_int", "unaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_float"), "nb_float", "unaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_add"), "nb_inplace_add", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_subtract"), "nb_inplace_subtract", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_multiply"), "nb_inplace_multiply", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_remainder"), "nb_inplace_remainder", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_power"), "nb_inplace_power", "ternaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_lshift"), "nb_inplace_lshift", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_rshift"), "nb_inplace_rshift", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_and"), "nb_inplace_and", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_xor"), "nb_inplace_xor", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_or"), "nb_inplace_or", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_floor_divide"), "nb_floor_divide", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_divide"), "nb_true_divide", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_floor_divide"), "nb_inplace_floor_divide", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_inplace_divide"), "nb_inplace_true_divide", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:nb_index"), "nb_index", "unaryfunc");
printSlot2(f, getSlot(n, "feature:python:sq_length"), "sq_length", "lenfunc");
printSlot2(f, getSlot(n, "feature:python:sq_concat"), "sq_concat", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:sq_repeat"), "sq_repeat", "ssizeargfunc");
printSlot2(f, getSlot(n, "feature:python:sq_item"), "sq_item", "ssizeargfunc");
printSlot2(f, getSlot(n, "feature:python:sq_ass_item"), "sq_ass_item", "ssizeobjargproc");
printSlot2(f, getSlot(n, "feature:python:sq_contains"), "sq_contains", "objobjproc");
printSlot2(f, getSlot(n, "feature:python:sq_inplace_concat"), "sq_inplace_concat", "binaryfunc");
printSlot2(f, getSlot(n, "feature:python:sq_inplace_repeat"), "sq_inplace_repeat", "ssizeargfunc");
Printf(f, " { Py_tp_members, members },\n");
Printf(f, " { 0, NULL }\n");
Printf(f, " };\n");
Printf(f, " PyType_Spec spec = {\n");
Printf(f, " %s,\n", quoted_symname);
Printf(f, " sizeof(SwigPyObject),\n");
Printf(f, " 0,\n");
Printf(f, " %s,\n", getSlot(n, "feature:python:tp_flags", tp_flags_py3), "tp_flags");
Printf(f, " slots\n");
Printf(f, " };\n");
Printv(f, " PyObject *tuple_bases = SwigPyBuiltin_InitBases(bases);\n", NIL);
Printf(f, " PyTypeObject *pytype = (PyTypeObject*)PyType_FromSpecWithBases(&spec, tuple_bases);\n");
Printf(f, " PyDict_Merge(pytype->tp_dict, dict, 1);\n");
Printv(f, " SwigPyBuiltin_SetMetaType(pytype, type);\n", NIL);
Printf(f, " PyType_Modified(pytype);\n");
Printf(f, " Py_DECREF(dict);\n");
Printf(f, " return pytype;\n");
Printv(f, "}\n", NULL);
Printv(f, "#endif\n", NIL);
String *clientdata = NewString("");
Printf(clientdata, "&%s_clientdata", templ);
SwigType_remember_mangleddata(pmname, clientdata);
SwigType *smart = Getattr(n, "smart");
if (smart) {
SwigType *psmart = Copy(smart);
SwigType_add_pointer(psmart);
String *smart_pmname = SwigType_manglestr(psmart);
SwigType_remember_mangleddata(smart_pmname, clientdata);
Delete(smart_pmname);
Delete(psmart);
}
Printf(f, "SWIGINTERN SwigPyClientData %s_clientdata = {0, 0, 0, 0, 0, 0, 0};\n\n", templ);
Printf(f_init, " builtin_pytype = %s_type_create(metatype, builtin_bases, d);\n", templ);
Printf(f_init, " if(!builtin_pytype) {\n", templ);
Printv(f_init, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
Printv(f_init, " return NULL;\n", NIL);
Printv(f_init, "#else\n", NIL);
Printv(f_init, " return;\n", NIL);
Printv(f_init, "#endif\n", NIL);
Printv(f_init, " }\n", NIL);
Printf(f_init, " SwigPyBuiltin_%s_clientdata.pytype = builtin_pytype;\n", mname);
if (GetFlag(n, "feature:implicitconv")) {
Printf(f_init, " SwigPyBuiltin_%s_clientdata.klass = (PyObject *)builtin_pytype;\n", mname);
}
Printv(f_init, " SWIG_Py_INCREF((PyObject *)builtin_pytype);\n", NIL);
Printf(f_init, " PyModule_AddObject(m, \"%s\", (PyObject *)builtin_pytype);\n", symname);
Printf(f_init, " SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", symname);
Printv(f_init, " d = md;\n", NIL);
Delete(clientdata);
Delete(sname);
Delete(rname);
Delete(mname);
Delete(pname);
Delete(pmname);
Delete(templ);
Delete(tp_flags);
Delete(tp_flags_py3);
Delete(tp_as_buffer);
Delete(tp_as_mapping);
Delete(tp_as_sequence);
Delete(tp_as_number);
Delete(quoted_symname);
Delete(quoted_tp_doc_str);
Delete(tp_init);
Delete(richcompare_func);
Delete(getset_name);
Delete(methods_name);
}
virtual int classHandler(Node *n) {
File *f_shadow_file = f_shadow;
Node *base_node = NULL;
if (shadow) {
have_constructor = 0;
have_repr = 0;
have_builtin_static_member_method_callback = false;
class_name = Getattr(n, "sym:name");
real_classname = Getattr(n, "name");
if (!addSymbol(class_name, n))
return SWIG_ERROR;
if (builtin) {
List *baselist = Getattr(n, "bases");
if (baselist && Len(baselist) > 0) {
Iterator b = First(baselist);
base_node = b.item;
}
}
shadow_indent = (String *) tab4;
String *base_class = NewString("");
List *baselist = Getattr(n, "bases");
if (baselist && Len(baselist)) {
Iterator b;
b = First(baselist);
while (b.item) {
String *bname = Getattr(b.item, "python:proxy");
bool ignore = GetFlag(b.item, "feature:ignore") ? true : false;
if (!bname || ignore) {
if (!bname && !ignore) {
Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(n), Getline(n),
"Base class '%s' ignored - unknown module name for base. Either import the appropriate module interface file or specify the name of the module in the %%import directive.\n",
SwigType_namestr(Getattr(b.item, "name")));
}
b = Next(b);
continue;
}
Printv(base_class, bname, NIL);
b = Next(b);
if (b.item) {
Printv(base_class, ", ", NIL);
}
}
}
if (builtin) {
Hash *base_richcompare = NULL;
Hash *richcompare = NULL;
if (base_node)
base_richcompare = Getattr(base_node, "python:richcompare");
if (base_richcompare)
richcompare = Copy(base_richcompare);
else
richcompare = NewHash();
Setattr(n, "python:richcompare", richcompare);
}
String *abcs = Getattr(n, "feature:python:abc");
if (abcs) {
if (Len(base_class) > 0)
Printv(base_class, ", ", NIL);
Printv(base_class, abcs, NIL);
}
if (builtin) {
if (have_docstring(n)) {
String *ds = cdocstring(n, AUTODOC_CLASS);
Setattr(n, "feature:python:tp_doc", ds);
Delete(ds);
} else {
SwigType *name = Getattr(n, "name");
SwigType *sname = add_explicit_scope(name);
String *rname = SwigType_namestr(sname);
Setattr(n, "feature:python:tp_doc", rname);
Delete(sname);
Delete(rname);
}
} else {
if (GetFlag(n, "feature:python:nondynamic"))
Printv(f_shadow, "@_swig_add_metaclass(_SwigNonDynamicMeta)\n", NIL);
Printv(f_shadow, "class ", class_name, NIL);
if (Len(base_class)) {
Printf(f_shadow, "(%s)", base_class);
} else {
if (GetFlag(n, "feature:exceptionclass")) {
Printf(f_shadow, "(Exception)");
} else {
Printf(f_shadow, "(object");
if (GetFlag(n, "feature:python:nondynamic")) {
Printf(f_shadow, ", metaclass=_SwigNonDynamicMeta");
}
*/
Printf(f_shadow, ")");
}
}
Printf(f_shadow, ":\n");
if (have_docstring(n)) {
String *str = docstring(n, AUTODOC_CLASS, tab4);
if (str && Len(str))
Printv(f_shadow, tab4, str, "\n\n", NIL);
}
Printv(f_shadow, tab4, "thisown = property(lambda x: x.this.own(), ", "lambda x, v: x.this.own(v), doc=\"The membership flag\")\n", NIL);
if (GetFlag(n, "feature:python:nondynamic")) {
Printv(f_shadow_file, tab4, "__setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n", NIL);
}
}
}
in_class = 1;
if (builtin)
builtin_pre_decl(n);
f_shadow = NewString("");
Clear(none_comparison);
if (builtin && Swig_directorclass(n)) {
String *p_real_classname = Copy(real_classname);
SwigType_add_pointer(p_real_classname);
String *mangle = SwigType_manglestr(p_real_classname);
String *descriptor = NewStringf("SWIGTYPE%s", mangle);
Printv(none_comparison, "self->ob_type != ((SwigPyClientData *)(", descriptor, ")->clientdata)->pytype", NIL);
Delete(descriptor);
Delete(mangle);
Delete(p_real_classname);
} else {
Printv(none_comparison, "$arg != Py_None", NIL);
}
Language::classHandler(n);
in_class = 0;
if (shadow) {
SwigType *smart = Getattr(n, "smart");
SwigType *ct = Copy(smart ? smart : real_classname);
SwigType_add_pointer(ct);
SwigType *realct = Copy(real_classname);
SwigType_add_pointer(realct);
SwigType_remember(realct);
if (builtin) {
Printv(f_wrappers, builtin_closures_code, NIL);
Delete(builtin_closures_code);
builtin_closures_code = NewString("");
Clear(builtin_closures);
} else {
Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL);
Printv(f_wrappers, " PyObject *obj = NULL;\n", NIL);
Printv(f_wrappers, " if (!SWIG_Python_UnpackTuple(args, \"swigregister\", 1, 1, &obj)) return NULL;\n", NIL);
Printv(f_wrappers,
" SWIG_TypeNewClientData(SWIGTYPE", SwigType_manglestr(ct), ", SWIG_NewClientData(obj));\n", " return SWIG_Py_Void();\n", "}\n\n", NIL);
String *cname = NewStringf("%s_swigregister", class_name);
add_method(cname, cname, 0, 0, 1, 1, 1);
Delete(cname);
}
Delete(ct);
Delete(realct);
if (!have_constructor) {
if (!builtin)
Printv(f_shadow_file, "\n", tab4, "def __init__(self, *args, **kwargs):\n", tab8, "raise AttributeError(\"", "No constructor defined",
(Getattr(n, "abstracts") ? " - class is abstract" : ""), "\")\n", NIL);
} else if (!builtin) {
Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL);
Printv(f_wrappers, " return SWIG_Python_InitShadowInstance(args);\n", "}\n\n", NIL);
String *cname = NewStringf("%s_swiginit", class_name);
add_method(cname, cname, 0);
Delete(cname);
}
if (!have_repr && !builtin) {
String *rname = SwigType_namestr(real_classname);
Printv(f_shadow_file, tab4, "__repr__ = _swig_repr\n", NIL);
Delete(rname);
}
if (builtin)
builtin_post_decl(f_builtins, n);
if (builtin_tp_init) {
Delete(builtin_tp_init);
builtin_tp_init = 0;
}
if (!builtin) {
Printv(f_shadow_file, f_shadow, NIL);
Printf(f_shadow_file, "\n");
Printf(f_shadow_file, "# Register %s in %s:\n", class_name, module);
Printf(f_shadow_file, "%s.%s_swigregister(%s)\n", module, class_name, class_name);
}
shadow_indent = 0;
if (Len(f_shadow_stubs) > 0)
Printf(f_shadow_file, "%s\n", f_shadow_stubs);
Clear(f_shadow_stubs);
}
if (builtin) {
Clear(class_members);
Clear(builtin_getset);
Clear(builtin_methods);
}
Delete(f_shadow);
f_shadow = f_shadow_file;
return SWIG_OK;
}
* functionHandler() - Mainly overloaded for callback handling
* ------------------------------------------------------------ */
virtual int functionHandler(Node *n) {
String *pcb = GetFlagAttr(n, "feature:python:callback");
if (pcb) {
if (Strcmp(pcb, "1") == 0) {
SetFlagAttr(n, "feature:callback", "%s_cb_ptr");
} else {
SetFlagAttr(n, "feature:callback", pcb);
}
autodoc_l dlevel = autodoc_level(Getattr(n, "feature:autodoc"));
if (dlevel != NO_AUTODOC && dlevel > TYPES_AUTODOC) {
Setattr(n, "feature:autodoc", "1");
}
}
return Language::functionHandler(n);
}
* memberfunctionHandler()
* ------------------------------------------------------------ */
virtual int memberfunctionHandler(Node *n) {
String *symname = Getattr(n, "sym:name");
int oldshadow;
if (builtin)
Swig_save("builtin_memberfunc", n, "python:argcount", NIL);
oldshadow = shadow;
if (shadow)
shadow = shadow | PYSHADOW_MEMBER;
Language::memberfunctionHandler(n);
shadow = oldshadow;
if (builtin && in_class) {
if (!checkAttribute(n, "access", "private") && strncmp(Char(symname), "operator ", 9) && !Getattr(class_members, symname)) {
String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname);
String *wname = Swig_name_wrapper(fullname);
Setattr(class_members, symname, n);
int argcount = Getattr(n, "python:argcount") ? atoi(Char(Getattr(n, "python:argcount"))) : 2;
String *ds = have_docstring(n) ? cdocstring(n, AUTODOC_METHOD) : NewString("");
if (check_kwargs(n)) {
Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, METH_VARARGS|METH_KEYWORDS, \"%s\" },\n", symname, wname, ds);
} else if (argcount == 0) {
Printf(builtin_methods, " { \"%s\", %s, METH_NOARGS, \"%s\" },\n", symname, wname, ds);
} else if (argcount == 1) {
Printf(builtin_methods, " { \"%s\", %s, METH_O, \"%s\" },\n", symname, wname, ds);
} else {
Printf(builtin_methods, " { \"%s\", %s, METH_VARARGS, \"%s\" },\n", symname, wname, ds);
}
Delete(fullname);
Delete(wname);
Delete(ds);
}
}
if (builtin)
Swig_restore(n);
if (!Getattr(n, "sym:nextSibling")) {
if (shadow && !builtin) {
int fproxy = fastproxy;
String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname);
if (Strcmp(symname, "__repr__") == 0) {
have_repr = 1;
}
if (Getattr(n, "feature:shadow")) {
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")");
String *pyaction = NewStringf("%s.%s", module, fullname);
Replaceall(pycode, "$action", pyaction);
Delete(pyaction);
Printv(f_shadow, pycode, "\n", NIL);
Delete(pycode);
fproxy = 0;
} else {
int allow_kwargs = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
String *parms = make_pyParmList(n, true, false, allow_kwargs);
String *callParms = make_pyParmList(n, true, true, allow_kwargs);
if (!have_addtofunc(n)) {
if (!fastproxy || olddefs) {
Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
if (Node *node_with_doc = find_overload_with_docstring(n))
Printv(f_shadow, tab8, docstring(node_with_doc, AUTODOC_METHOD, tab8), "\n", NIL);
Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n", NIL);
}
} else {
Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
if (Node *node_with_doc = find_overload_with_docstring(n))
Printv(f_shadow, tab8, docstring(node_with_doc, AUTODOC_METHOD, tab8), "\n", NIL);
if (have_pythonprepend(n)) {
fproxy = 0;
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
}
if (have_pythonappend(n)) {
fproxy = 0;
Printv(f_shadow, tab8, "val = ", funcCall(fullname, callParms), "\n", NIL);
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_shadow, tab8, "return val\n\n", NIL);
} else {
Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n\n", NIL);
}
}
}
if (fproxy) {
Printf(f_shadow, tab4);
Printf(f_shadow, "%s = _swig_new_instance_method(%s.%s)\n", symname, module, Swig_name_member(NSPACE_TODO, class_name, symname));
}
Delete(fullname);
}
}
return SWIG_OK;
}
* staticmemberfunctionHandler()
* ------------------------------------------------------------ */
virtual int staticmemberfunctionHandler(Node *n) {
String *symname = Getattr(n, "sym:name");
if (builtin && in_class) {
Swig_save("builtin_memberconstantHandler", n, "pybuiltin:symname", NIL);
Setattr(n, "pybuiltin:symname", symname);
}
Language::staticmemberfunctionHandler(n);
if (builtin && in_class) {
Swig_restore(n);
}
int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
if (builtin && in_class) {
if ((GetFlagAttr(n, "feature:extend") || checkAttribute(n, "access", "public"))
&& !Getattr(class_members, symname)) {
String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname);
String *wname = Swig_name_wrapper(fullname);
Setattr(class_members, symname, n);
int funpack = fastunpack && !Getattr(n, "sym:overloaded");
String *pyflags = NewString("METH_STATIC|");
int argcount = Getattr(n, "python:argcount") ? atoi(Char(Getattr(n, "python:argcount"))) : 2;
if (funpack && argcount == 0)
Append(pyflags, "METH_NOARGS");
else if (funpack && argcount == 1)
Append(pyflags, "METH_O");
else
Append(pyflags, kw ? "METH_VARARGS|METH_KEYWORDS" : "METH_VARARGS");
if (have_docstring(n)) {
String *ds = cdocstring(n, AUTODOC_STATICFUNC);
Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"%s\" },\n", symname, wname, pyflags, ds);
Delete(ds);
} else if (Getattr(n, "feature:callback")) {
String *ds = NewStringf("swig_ptr: %s", Getattr(n, "feature:callback:name"));
Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"%s\" },\n", symname, wname, pyflags, ds);
Delete(ds);
have_builtin_static_member_method_callback = true;
} else {
Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"\" },\n", symname, wname, pyflags);
}
Delete(fullname);
Delete(wname);
Delete(pyflags);
}
return SWIG_OK;
}
if (Getattr(n, "sym:nextSibling")) {
return SWIG_OK;
}
if (shadow) {
String *staticfunc_name = NewString(fastproxy ? "_swig_new_static_method" : "staticmethod");
bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback");
if (!fast || olddefs) {
String *parms = make_pyParmList(n, false, false, kw);
String *callParms = make_pyParmList(n, false, true, kw);
Printv(f_shadow, "\n", tab4, "@staticmethod", NIL);
Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
if (Node *node_with_doc = find_overload_with_docstring(n))
Printv(f_shadow, tab8, docstring(node_with_doc, AUTODOC_STATICFUNC, tab8), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
if (have_pythonappend(n)) {
Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL);
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_shadow, tab8, "return val\n", NIL);
} else {
Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL);
}
}
if (fast) {
Printv(f_shadow, tab4, symname, " = ", staticfunc_name, "(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname),
")\n", NIL);
}
Delete(staticfunc_name);
}
return SWIG_OK;
}
* constructorDeclaration()
* ------------------------------------------------------------ */
virtual int constructorHandler(Node *n) {
String *symname = Getattr(n, "sym:name");
int oldshadow = shadow;
int use_director = Swig_directorclass(n);
* If we're wrapping the constructor of a C++ director class, prepend a new parameter
* to receive the scripting language object (e.g. 'self')
*
*/
Swig_save("python:constructorHandler", n, "parms", NIL);
if (use_director) {
Parm *parms = Getattr(n, "parms");
Parm *self;
String *name = NewString("self");
String *type = NewString("PyObject");
SwigType_add_pointer(type);
self = NewParm(type, name, n);
Delete(type);
Delete(name);
Setattr(self, "lname", "O");
if (parms)
set_nextSibling(self, parms);
Setattr(n, "parms", self);
Setattr(n, "wrap:self", "1");
Setattr(n, "hidden", "1");
Delete(self);
}
if (shadow)
shadow = shadow | PYSHADOW_MEMBER;
Language::constructorHandler(n);
shadow = oldshadow;
Delattr(n, "wrap:self");
Swig_restore(n);
if (!Getattr(n, "sym:nextSibling")) {
if (shadow) {
int allow_kwargs = (check_kwargs(n) && (!Getattr(n, "sym:overloaded"))) ? 1 : 0;
int handled_as_init = 0;
if (!have_constructor) {
String *nname = Getattr(n, "sym:name");
String *sname = Getattr(getCurrentClass(), "sym:name");
String *cname = Swig_name_construct(NSPACE_TODO, sname);
handled_as_init = (Strcmp(nname, sname) == 0) || (Strcmp(nname, cname) == 0);
Delete(cname);
}
String *subfunc = Swig_name_construct(NSPACE_TODO, symname);
if (!have_constructor && handled_as_init) {
if (!builtin) {
if (Getattr(n, "feature:shadow")) {
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")");
String *pyaction = NewStringf("%s.%s", module, subfunc);
Replaceall(pycode, "$action", pyaction);
Delete(pyaction);
Printv(f_shadow, pycode, "\n", NIL);
Delete(pycode);
} else {
String *pass_self = NewString("");
Node *parent = Swig_methodclass(n);
String *classname = Swig_class_name(parent);
String *rclassname = Swig_class_name(getCurrentClass());
assert(rclassname);
(void)rclassname;
String *parms = make_pyParmList(n, true, false, allow_kwargs);
String *callParms = make_pyParmList(n, false, true, allow_kwargs, true);
if (use_director) {
Insert(callParms, 0, "_self, ");
Printv(pass_self, tab8, NIL);
Printf(pass_self, "if self.__class__ == %s:\n", classname);
Printv(pass_self, tab8, tab4, "_self = None\n", tab8, "else:\n", tab8, tab4, "_self = self\n", NIL);
}
Printv(f_shadow, "\n", tab4, "def __init__(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
if (Node *node_with_doc = find_overload_with_docstring(n))
Printv(f_shadow, tab8, docstring(node_with_doc, AUTODOC_CTOR, tab8), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
Printv(f_shadow, pass_self, NIL);
Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self, ", funcCall(subfunc, callParms), ")\n", NIL);
if (have_pythonappend(n))
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n\n", NIL);
Delete(pass_self);
}
have_constructor = 1;
}
} else {
function for it. */
if (!builtin) {
if (Getattr(n, "feature:shadow")) {
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), "", Getfile(n), Getline(n), "%feature(\"shadow\")");
String *pyaction = NewStringf("%s.%s", module, subfunc);
Replaceall(pycode, "$action", pyaction);
Delete(pyaction);
Printv(f_shadow_stubs, pycode, "\n", NIL);
Delete(pycode);
} else {
String *parms = make_pyParmList(n, false, false, allow_kwargs);
String *callParms = make_pyParmList(n, false, true, allow_kwargs);
Printv(f_shadow_stubs, "\ndef ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
if (Node *node_with_doc = find_overload_with_docstring(n))
Printv(f_shadow_stubs, tab4, docstring(node_with_doc, AUTODOC_CTOR, tab4), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
Printv(f_shadow_stubs, tab4, "val = ", funcCall(subfunc, callParms), "\n", NIL);
if (have_pythonappend(n))
Printv(f_shadow_stubs, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_shadow_stubs, tab4, "return val\n", NIL);
}
} else {
Printf(f_shadow_stubs, "%s = %s\n", symname, subfunc);
}
}
Delete(subfunc);
}
}
return SWIG_OK;
}
* destructorHandler()
* ------------------------------------------------------------ */
virtual int destructorHandler(Node *n) {
String *symname = Getattr(n, "sym:name");
int oldshadow = shadow;
if (builtin && in_class) {
Node *cls = Swig_methodclass(n);
if (!Getattr(cls, "feature:python:tp_dealloc")) {
Setattr(n, "feature:python:slot", "tp_dealloc");
Setattr(n, "feature:python:slot:functype", "destructor");
}
}
if (shadow)
shadow = shadow | PYSHADOW_MEMBER;
Language::destructorHandler(n);
shadow = oldshadow;
if (shadow) {
if (Getattr(n, "feature:shadow")) {
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")");
String *pyaction = NewStringf("%s.%s", module, Swig_name_destroy(NSPACE_TODO, symname));
Replaceall(pycode, "$action", pyaction);
Delete(pyaction);
Printv(f_shadow, pycode, "\n", NIL);
Delete(pycode);
} else {
Printv(f_shadow, tab4, "__swig_destroy__ = ", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "\n", NIL);
if (!have_pythonprepend(n) && !have_pythonappend(n)) {
return SWIG_OK;
}
Printv(f_shadow, tab4, "def __del__(self):\n", NIL);
if (have_docstring(n))
Printv(f_shadow, tab8, docstring(n, AUTODOC_DTOR, tab8), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
if (have_pythonappend(n))
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_shadow, tab8, "pass\n", NIL);
Printv(f_shadow, "\n", NIL);
}
}
return SWIG_OK;
}
* membervariableHandler()
* ------------------------------------------------------------ */
virtual int membervariableHandler(Node *n) {
String *symname = Getattr(n, "sym:name");
int oldshadow = shadow;
if (shadow)
shadow = shadow | PYSHADOW_MEMBER;
Language::membervariableHandler(n);
shadow = oldshadow;
if (shadow && !builtin) {
String *mname = Swig_name_member(NSPACE_TODO, class_name, symname);
String *setname = Swig_name_set(NSPACE_TODO, mname);
String *getname = Swig_name_get(NSPACE_TODO, mname);
int assignable = !is_immutable(n);
String *variable_annotation = variableAnnotation(n);
Printv(f_shadow, tab4, symname, variable_annotation, " = property(", module, ".", getname, NIL);
if (assignable)
Printv(f_shadow, ", ", module, ".", setname, NIL);
if (have_docstring(n)) {
String *s = docstring(n, AUTODOC_VAR, tab4);
if (Len(s))
Printv(f_shadow, ", doc=", s, NIL);
}
Printv(f_shadow, ")\n", NIL);
Delete(variable_annotation);
Delete(mname);
Delete(setname);
Delete(getname);
}
return SWIG_OK;
}
* staticmembervariableHandler()
* ------------------------------------------------------------ */
virtual int staticmembervariableHandler(Node *n) {
Swig_save("builtin_staticmembervariableHandler", n, "builtin_symname", NIL);
Language::staticmembervariableHandler(n);
Swig_restore(n);
if (GetFlag(n, "wrappedasconstant"))
return SWIG_OK;
String *symname = Getattr(n, "sym:name");
if (shadow) {
if (!builtin && GetFlag(n, "hasconsttype")) {
String *mname = Swig_name_member(NSPACE_TODO, class_name, symname);
Printf(f_shadow_stubs, "%s.%s = %s.%s.%s\n", class_name, symname, module, global_name, mname);
Delete(mname);
} else {
String *mname = Swig_name_member(NSPACE_TODO, class_name, symname);
String *getname = Swig_name_get(NSPACE_TODO, mname);
String *wrapgetname = Swig_name_wrapper(getname);
String *vargetname = NewStringf("Swig_var_%s", getname);
String *setname = Swig_name_set(NSPACE_TODO, mname);
String *wrapsetname = Swig_name_wrapper(setname);
String *varsetname = NewStringf("Swig_var_%s", setname);
Wrapper *f = NewWrapper();
Printv(f->def, "SWIGINTERN PyObject *", wrapgetname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(args)) {", NIL);
Printv(f->code, " return ", vargetname, "();\n", NIL);
Append(f->code, "}\n");
add_method(getname, wrapgetname, 0);
Wrapper_print(f, f_wrappers);
DelWrapper(f);
int assignable = !is_immutable(n);
if (assignable) {
int funpack = fastunpack;
Wrapper *f = NewWrapper();
Printv(f->def, "SWIGINTERN PyObject *", wrapsetname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {", NIL);
Wrapper_add_local(f, "res", "int res");
if (!funpack) {
Wrapper_add_local(f, "value", "PyObject *value");
Append(f->code, "if (!PyArg_ParseTuple(args, \"O:set\", &value)) return NULL;\n");
}
Printf(f->code, "res = %s(%s);\n", varsetname, funpack ? "args" : "value");
Append(f->code, "return !res ? SWIG_Py_Void() : NULL;\n");
Append(f->code, "}\n");
Wrapper_print(f, f_wrappers);
add_method(setname, wrapsetname, 0, 0, funpack, 1, 1);
DelWrapper(f);
}
if (!builtin) {
Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
if (assignable)
Printv(f_shadow, ", ", module, ".", setname, NIL);
if (have_docstring(n)) {
String *s = docstring(n, AUTODOC_VAR, tab4);
if (Len(s))
Printv(f_shadow, ", doc=", s, NIL);
}
Printv(f_shadow, ")\n", NIL);
}
String *getter = Getattr(n, "pybuiltin:getter");
String *setter = Getattr(n, "pybuiltin:setter");
Hash *h = NULL;
if (getter || setter) {
h = Getattr(builtin_getset, symname);
if (!h) {
h = NewHash();
Setattr(h, "static", "1");
Setattr(builtin_getset, symname, h);
}
}
if (getter)
Setattr(h, "getter", getter);
if (setter)
Setattr(h, "setter", setter);
if (h)
Delete(h);
Delete(mname);
Delete(getname);
Delete(wrapgetname);
Delete(vargetname);
Delete(setname);
Delete(wrapsetname);
Delete(varsetname);
}
}
return SWIG_OK;
}
* memberconstantHandler()
* ------------------------------------------------------------ */
virtual int memberconstantHandler(Node *n) {
String *symname = Getattr(n, "sym:name");
if (builtin && in_class) {
Swig_save("builtin_memberconstantHandler", n, "pybuiltin:symname", NIL);
Setattr(n, "pybuiltin:symname", symname);
}
int oldshadow = shadow;
if (shadow)
shadow = shadow | PYSHADOW_MEMBER;
Language::memberconstantHandler(n);
shadow = oldshadow;
if (builtin && in_class) {
Swig_restore(n);
} else if (shadow) {
Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), "\n", NIL);
if (have_docstring(n))
Printv(f_shadow, tab4, docstring(n, AUTODOC_CONST, tab4), "\n", NIL);
}
return SWIG_OK;
}
* insertDirective()
*
* Hook for %insert directive. We're going to look for special %shadow inserts
* as a special case so we can do indenting correctly
* ------------------------------------------------------------ */
virtual int insertDirective(Node *n) {
String *code = Getattr(n, "code");
String *section = Getattr(n, "section");
if (!ImportMode && (Cmp(section, "python") == 0 || Cmp(section, "shadow") == 0)) {
if (shadow) {
String *pycode = indent_pythoncode(code, shadow_indent, Getfile(n), Getline(n), "%pythoncode or %insert(\"python\") block");
Printv(f_shadow, pycode, NIL);
Delete(pycode);
}
} else if (!ImportMode && (Cmp(section, "pythonbegin") == 0)) {
if (shadow) {
String *pycode = indent_pythoncode(code, "", Getfile(n), Getline(n), "%pythonbegin or %insert(\"pythonbegin\") block");
Printv(f_shadow_begin, pycode, NIL);
Delete(pycode);
}
} else {
Language::insertDirective(n);
}
return SWIG_OK;
}
virtual String *runtimeCode() {
String *s = NewString("");
String *shead = Swig_include_sys("pyhead.swg");
if (!shead) {
Printf(stderr, "*** Unable to open 'pyhead.swg'\n");
} else {
Append(s, shead);
Delete(shead);
}
String *serrors = Swig_include_sys("pyerrors.swg");
if (!serrors) {
Printf(stderr, "*** Unable to open 'pyerrors.swg'\n");
} else {
Append(s, serrors);
Delete(serrors);
}
String *sthread = Swig_include_sys("pythreads.swg");
if (!sthread) {
Printf(stderr, "*** Unable to open 'pythreads.swg'\n");
} else {
Append(s, sthread);
Delete(sthread);
}
String *sapi = Swig_include_sys("pyapi.swg");
if (!sapi) {
Printf(stderr, "*** Unable to open 'pyapi.swg'\n");
} else {
Append(s, sapi);
Delete(sapi);
}
String *srun = Swig_include_sys("pyrun.swg");
if (!srun) {
Printf(stderr, "*** Unable to open 'pyrun.swg'\n");
} else {
Append(s, srun);
Delete(srun);
}
return s;
}
virtual String *defaultExternalRuntimeFilename() {
return NewString("swigpyrun.h");
}
* kwargsSupport()
*--------------------------------------------------------------------*/
bool kwargsSupport() const {
return true;
}
};
* classDirectorMethod()
*
* Emit a virtual director method to pass a method call on to the
* underlying Python object.
*
* ** Moved it here due to internal error on gcc-2.96 **
* --------------------------------------------------------------- */
int PYTHON::classDirectorMethods(Node *n) {
director_method_index = 0;
return Language::classDirectorMethods(n);
}
int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
int is_void = 0;
int is_pointer = 0;
String *decl = Getattr(n, "decl");
String *name = Getattr(n, "name");
String *classname = Getattr(parent, "sym:name");
String *c_classname = Getattr(parent, "name");
String *symname = Getattr(n, "sym:name");
String *declaration = NewString("");
ParmList *l = Getattr(n, "parms");
Wrapper *w = NewWrapper();
String *tm;
String *wrap_args = NewString("");
SwigType *returntype = Getattr(n, "type");
String *value = Getattr(n, "value");
String *storage = Getattr(n, "storage");
bool pure_virtual = false;
int status = SWIG_OK;
int idx;
bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
if (builtin) {
Parm *p;
for (p = l; p; p = nextSibling(p)) {
String *arg = Getattr(p, "name");
if (arg && Cmp(arg, "self") == 0)
Delattr(p, "name");
}
}
if (Cmp(storage, "virtual") == 0) {
if (Cmp(value, "0") == 0) {
pure_virtual = true;
}
}
is_pointer = SwigType_ispointer_return(decl);
is_void = (!Cmp(returntype, "void") && !is_pointer);
String *target;
String *pclassname = NewStringf("SwigDirector_%s", classname);
String *qualified_name = NewStringf("%s::%s", pclassname, name);
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
Printf(w->def, "%s", target);
Delete(qualified_name);
Delete(target);
target = Swig_method_decl(rtype, decl, name, l, 1);
Printf(declaration, " virtual %s", target);
Delete(target);
if (Getattr(n, "noexcept")) {
Append(w->def, " noexcept");
Append(declaration, " noexcept");
}
ParmList *throw_parm_list = 0;
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
Parm *p;
int gencomma = 0;
Append(w->def, " throw(");
Append(declaration, " throw(");
if (throw_parm_list)
Swig_typemap_attach_parms("throws", throw_parm_list, 0);
for (p = throw_parm_list; p; p = nextSibling(p)) {
if (Getattr(p, "tmap:throws")) {
if (gencomma++) {
Append(w->def, ", ");
Append(declaration, ", ");
}
String *str = SwigType_str(Getattr(p, "type"), 0);
Append(w->def, str);
Append(declaration, str);
Delete(str);
}
}
Append(w->def, ")");
Append(declaration, ")");
}
Append(w->def, " {");
Append(declaration, ";\n");
* if the return value is a reference or const reference, a specialized typemap must
* handle it, including declaration of c_result ($result).
*/
if (!is_void && (!ignored_method || pure_virtual)) {
if (!SwigType_isclass(returntype)) {
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
Delete(construct_result);
} else {
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
}
} else {
String *cres = SwigType_lstr(returntype, "c_result");
Printf(w->code, "%s;\n", cres);
Delete(cres);
}
}
if (builtin) {
Printv(w->code, "PyObject *self = NULL;\n", NIL);
Printv(w->code, "(void)self;\n", NIL);
}
if (ignored_method) {
if (!pure_virtual) {
if (!is_void)
Printf(w->code, "return ");
String *super_call = Swig_method_call(super, l);
Printf(w->code, "%s;\n", super_call);
Delete(super_call);
} else {
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
SwigType_namestr(name));
}
} else {
String *arglist = NewString("");
String *parse_args = NewString("");
Swig_director_parms_fixup(l);
Swig_typemap_attach_parms("in", l, 0);
Swig_typemap_attach_parms("directorin", l, w);
Swig_typemap_attach_parms("directorargout", l, w);
Parm *p;
char source[256];
int outputs = 0;
if (!is_void)
outputs++;
idx = 0;
p = l;
int use_parse = 0;
while (p) {
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
continue;
}
if (Getattr(p, "tmap:directorargout") != 0)
outputs++;
String *pname = Getattr(p, "name");
String *ptype = Getattr(p, "type");
Putc(',', arglist);
if ((tm = Getattr(p, "tmap:directorin")) != 0) {
String *parse = Getattr(p, "tmap:directorin:parse");
if (!parse) {
sprintf(source, "obj%d", idx++);
String *input = NewString(source);
Setattr(p, "emit:directorinput", input);
Replaceall(tm, "$input", input);
Delete(input);
Replaceall(tm, "$owner", "0");
Printv(wrap_args, "swig::SwigVar_PyObject ", source, ";\n", NIL);
Printv(wrap_args, tm, "\n", NIL);
Printv(arglist, "(PyObject *)", source, NIL);
Putc('O', parse_args);
} else {
use_parse = 1;
Append(parse_args, parse);
Setattr(p, "emit:directorinput", pname);
Replaceall(tm, "$input", pname);
Replaceall(tm, "$owner", "0");
if (Len(tm) == 0)
Append(tm, pname);
Append(arglist, tm);
}
p = Getattr(p, "tmap:directorin:next");
continue;
} else if (Cmp(ptype, "void")) {
* ideally this would be left to a typemap, but there is currently no
* way to selectively apply the dynamic_cast<> to classes that have
* directors. in other words, the type "SwigDirector_$1_lname" only exists
* for classes with directors. we avoid the problem here by checking
* module.wrap::directormap, but it's not clear how to get a typemap to
* do something similar. perhaps a new default typemap (in addition
* to SWIGTYPE) called DIRECTORTYPE?
*/
if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
Node *module = Getattr(parent, "module");
Node *target = Swig_directormap(module, ptype);
sprintf(source, "obj%d", idx++);
String *nonconst = 0;
String *nptype = NewString(Char(ptype) + 2);
String *ppname = Copy(pname);
if (SwigType_isreference(ptype)) {
Insert(ppname, 0, "&");
}
if (SwigType_isconst(nptype)) {
nonconst = NewStringf("nc_tmp_%s", pname);
String *nonconst_i = NewStringf("= const_cast< %s >(%s)", SwigType_lstr(ptype, 0), ppname);
Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
Delete(nonconst_i);
Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
"Target language argument '%s' discards const in director method %s::%s.\n",
SwigType_str(ptype, pname), SwigType_namestr(c_classname), SwigType_namestr(name));
} else {
nonconst = Copy(ppname);
}
Delete(nptype);
Delete(ppname);
String *mangle = SwigType_manglestr(ptype);
if (target) {
String *director = NewStringf("director_%s", mangle);
Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL);
Printf(wrap_args, "%s = SWIG_DIRECTOR_CAST(%s);\n", director, nonconst);
Printf(wrap_args, "if (!%s) {\n", director);
Printf(wrap_args, "%s = SWIG_InternalNewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
Append(wrap_args, "} else {\n");
Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
Printf(wrap_args, "SWIG_Py_INCREF((PyObject *)%s);\n", source);
Append(wrap_args, "}\n");
Delete(director);
Printv(arglist, source, NIL);
} else {
Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL);
Printf(wrap_args, "%s = SWIG_InternalNewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
Printv(arglist, source, NIL);
}
Putc('O', parse_args);
Delete(mangle);
Delete(nonconst);
} else {
Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
"Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
SwigType_namestr(c_classname), SwigType_namestr(name));
status = SWIG_NOWRAP;
break;
}
}
p = nextSibling(p);
}
String *pyname = Getattr(n, "sym:name");
int allow_thread = threads_enable(n);
if (allow_thread) {
thread_begin_block(n, w->code);
Append(w->code, "{\n");
}
Printv(w->code, wrap_args, NIL);
if (dirprot_mode() && !is_public(n)) {
Printf(w->code, "swig_set_inner(\"%s\", true);\n", name);
}
Append(w->code, "if (!swig_get_self()) {\n");
Printf(w->code, " Swig::DirectorException::raise(\"'self' uninitialized, maybe you forgot to call %s.__init__.\");\n", classname);
Append(w->code, "}\n");
Append(w->code, "#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n");
Printf(w->code, "const size_t swig_method_index = %d;\n", director_method_index++);
Printf(w->code, "const char *const swig_method_name = \"%s\";\n", pyname);
Append(w->code, "PyObject *method = swig_get_method(swig_method_index, swig_method_name);\n");
if (Len(parse_args) > 0) {
if (use_parse) {
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", Swig_cresult_name(), parse_args, arglist);
} else {
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunctionObjArgs(method %s, NULL);\n", Swig_cresult_name(), arglist);
}
} else {
Append(w->code, "swig::SwigVar_PyObject args = PyTuple_New(0);\n");
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_Call(method, (PyObject *) args, NULL);\n", Swig_cresult_name());
}
Append(w->code, "#else\n");
if (Len(parse_args) > 0) {
if (use_parse) {
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", (char *)\"(%s)\" %s);\n", Swig_cresult_name(), pyname, parse_args, arglist);
} else {
Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar(\"%s\");\n", pyname);
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name %s, NULL);\n", Swig_cresult_name(), arglist);
}
} else {
Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar(\"%s\");\n", pyname);
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n", Swig_cresult_name());
}
Append(w->code, "#endif\n");
if (dirprot_mode() && !is_public(n))
Printf(w->code, "swig_set_inner(\"%s\", false);\n", name);
tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
if (!tm) {
tm = Getattr(n, "feature:director:except");
if (tm)
tm = Copy(tm);
}
Printf(w->code, "if (!%s) {\n", Swig_cresult_name());
Append(w->code, " PyObject *error = PyErr_Occurred();\n");
if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
Replaceall(tm, "$error", "error");
Printv(w->code, Str(tm), "\n", NIL);
} else {
Append(w->code, " if (error) {\n");
Printf(w->code, " Swig::DirectorMethodException::raise(\"Error detected when calling '%s.%s'\");\n", classname, pyname);
Append(w->code, " }\n");
}
Append(w->code, "}\n");
Delete(tm);
* Python method may return a simple object, or a tuple.
* for in/out arguments, we have to extract the appropriate PyObjects from the tuple,
* then marshal everything back to C/C++ (return value and output arguments).
*
*/
String *cleanup = NewString("");
String *outarg = NewString("");
if (outputs > 1) {
Wrapper_add_local(w, "output", "PyObject *output");
Printf(w->code, "if (!PyTuple_Check(%s)) {\n", Swig_cresult_name());
Printf(w->code, " Swig::DirectorTypeMismatchException::raise(\"Python method %s.%sfailed to return a tuple.\");\n", classname, pyname);
Append(w->code, "}\n");
}
idx = 0;
if (!is_void) {
tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w);
if (tm != 0) {
if (outputs > 1) {
Printf(w->code, "output = PyTuple_GetItem(%s, %d);\n", Swig_cresult_name(), idx++);
Replaceall(tm, "$input", "output");
} else {
Replaceall(tm, "$input", Swig_cresult_name());
}
char temp[24];
sprintf(temp, "%d", idx);
Replaceall(tm, "$argnum", temp);
if (Getattr(n, "wrap:disown")) {
Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
} else {
Replaceall(tm, "$disown", "0");
}
if (Getattr(n, "tmap:directorout:implicitconv")) {
Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
}
Replaceall(tm, "$result", "c_result");
Printv(w->code, tm, "\n", NIL);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
"Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0), SwigType_namestr(c_classname),
SwigType_namestr(name));
status = SWIG_ERROR;
}
}
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
if (outputs > 1) {
Printf(w->code, "output = PyTuple_GetItem(%s, %d);\n", Swig_cresult_name(), idx++);
Replaceall(tm, "$result", "output");
} else {
Replaceall(tm, "$result", Swig_cresult_name());
}
Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
Printv(w->code, tm, "\n", NIL);
p = Getattr(p, "tmap:directorargout:next");
} else {
p = nextSibling(p);
}
}
if (allow_thread) {
Append(w->code, "}\n");
thread_end_block(n, w->code);
}
Delete(parse_args);
Delete(arglist);
Delete(cleanup);
Delete(outarg);
}
if (!is_void) {
if (!(ignored_method && !pure_virtual)) {
String *rettype = SwigType_str(returntype, 0);
if (!SwigType_isreference(returntype)) {
Printf(w->code, "return (%s) c_result;\n", rettype);
} else {
Printf(w->code, "return (%s) *c_result;\n", rettype);
}
Delete(rettype);
}
}
Append(w->code, "}\n");
String *inline_extra_method = NewString("");
if (dirprot_mode() && !is_public(n) && !pure_virtual) {
Printv(inline_extra_method, declaration, NIL);
String *extra_method_name = NewStringf("%sSwigPublic", name);
Replaceall(inline_extra_method, name, extra_method_name);
Replaceall(inline_extra_method, ";\n", " {\n ");
if (!is_void)
Printf(inline_extra_method, "return ");
String *methodcall = Swig_method_call(super, l);
Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
Delete(methodcall);
Delete(extra_method_name);
}
if (status == SWIG_OK) {
Replaceall(w->code, "$isvoid", is_void ? "1" : "0");
if (!Getattr(n, "defaultargs")) {
Replaceall(w->code, "$symname", symname);
Wrapper_print(w, f_directors);
Printv(f_directors_h, declaration, NIL);
Printv(f_directors_h, inline_extra_method, NIL);
}
}
Delete(wrap_args);
Delete(pclassname);
DelWrapper(w);
return status;
}
* swig_python() - Instantiate module
* ----------------------------------------------------------------------------- */
static Language *new_swig_python() {
return new PYTHON();
}
extern "C" Language *swig_python(void) {
return new_swig_python();
}