X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/eb6a4098a0f2e9ae55e72ad960b3dfc134d177c9..d14a1e28567de23c586bc80017073d0c39f8d18f:/wxPython/wxSWIG/Modules/python.cxx?ds=inline diff --git a/wxPython/wxSWIG/Modules/python.cxx b/wxPython/wxSWIG/Modules/python.cxx deleted file mode 100644 index 9abad191f2..0000000000 --- a/wxPython/wxSWIG/Modules/python.cxx +++ /dev/null @@ -1,1644 +0,0 @@ -/******************************************************************************* - * Simplified Wrapper and Interface Generator (SWIG) - * - * Author : David Beazley - * - * Department of Computer Science - * University of Chicago - * 1100 E 58th Street - * Chicago, IL 60637 - * beazley@cs.uchicago.edu - * - * Please read the file LICENSE for the copyright and terms by which SWIG - * can be used and distributed. - *******************************************************************************/ - -/********************************************************************** - * $Header$ - * - * python.cxx - * - * Python module. - **************************************************************************/ - - -#include "swig.h" -#include "python.h" - -// Structures for managing doc strings - -struct DocString { - DocEntry *de; - char *name; - DocString *next; -}; - -static int doc_index = 0; -static DocString *doc_strings = 0; - -static char *usage = "\ -Python Options (available with -python)\n\ - -docstring - Produce docstrings (only applies to shadow classes)\n\ - -globals name - Set name used to access C global variable ('cvar' by default).\n\ - -module name - Set module name\n\ - -keyword - Use keyword arguments\n\ - -shadow - Generate shadow classes. \n\n"; - -static String pragma_include; - -// --------------------------------------------------------------------- -// PYTHON::parse_args(int argc, char *argv[]) -// -// --------------------------------------------------------------------- - -void PYTHON::parse_args(int argc, char *argv[]) { - - int i = 1; - - sprintf(LibDir,"%s",path); - - docstring = 0; - - // Look for additional command line options. - for (i = 1; i < argc; i++) { - if (argv[i]) { - if(strcmp(argv[i],"-module") == 0) { - if (argv[i+1]) { - module = new char[strlen(argv[i+1])+2]; - strcpy(module, argv[i+1]); - mark_arg(i); - mark_arg(i+1); - i+=1; - } else { - arg_error(); - } - } else if (strcmp(argv[i],"-globals") == 0) { - if (argv[i+1]) { - global_name = new char[strlen(argv[i+1])+1]; - strcpy(global_name, argv[i+1]); - mark_arg(i); - mark_arg(i+1); - i++; - } else { - arg_error(); - } - } else if (strcmp(argv[i],"-shadow") == 0) { - shadow = 1; - mark_arg(i); - } else if (strcmp(argv[i],"-docstring") == 0) { - docstring = 1; - mark_arg(i); - } else if (strcmp(argv[i],"-keyword") == 0) { - use_kw = 1; - mark_arg(i); - } else if (strcmp(argv[i],"-help") == 0) { - fputs(usage,stderr); - } - } - } - // Create a symbol for this language - add_symbol("SWIGPYTHON",0,0); - - // Set name of typemaps - - typemap_lang = "python"; - -} - -// --------------------------------------------------------------------- -// PYTHON::parse() -// -// Parse the interface file -// --------------------------------------------------------------------- - -void -PYTHON::parse() { - - printf("Generating wrappers for Python\n"); - headers(); - - // Run the SWIG parser - - yyparse(); -} - -// --------------------------------------------------------------------- -// PYTHON::set_module(char *mod_name, char **mod_list) -// -// Sets the module name. -// Does nothing if it's already set (so it can be overridden as a command -// line option). -// -//---------------------------------------------------------------------- - -void PYTHON::set_module(char *mod_name, char **mod_list) { - int i; - - // If an "import" method has been set and we're in shadow class mode, - // output a python command to load the module - - if (import_file) { - if (!(strcmp(import_file,input_file+strlen(input_file)-strlen(import_file)))) { - if (shadow) { - fprintf(f_shadow,"\nfrom %s import *\n", mod_name); - } - delete import_file; - import_file = 0; - } - } - - if (module) return; - - module = new char[strlen(mod_name)+1]; - strcpy(module,mod_name); - - // If there was a mod_list specified, make this incredible hack - if (mod_list) { - modinit << "#define SWIGMODINIT "; - modextern << "#ifdef __cplusplus\n" - << "extern \"C\" {\n" - << "#endif\n"; - i = 0; - while(mod_list[i]) { - modinit << "swig_add_module(\"" << mod_list[i] << "\",init" - << mod_list[i] << "); \\\n"; - - modextern << "extern void init" << mod_list[i] << "();\n"; - i++; - } - modextern << "#ifdef __cplusplus\n" - << "}\n" - << "#endif\n"; - modinit << "/* End of extern module initialization */\n"; - - } -} - -// --------------------------------------------------------------------- -// PYTHON::set_init(char *iname) -// -// Sets the initialization function name. -// Does nothing if it's already set -// -//---------------------------------------------------------------------- - -void PYTHON::set_init(char *iname) { - set_module(iname,0); -} - - -// --------------------------------------------------------------------- -// PYTHON::import(char *filename) -// -// Imports a SWIG module as a separate file. -//---------------------------------------------------------------------- - -void PYTHON::import(char *filename) { - if (import_file) delete import_file; - import_file = copy_string(filename); -} - -// ---------------------------------------------------------------------- -// PYTHON::add_method(char *name, char *function) -// -// Add some symbols to the methods table -// ---------------------------------------------------------------------- - -void PYTHON::add_method(char *name, char *function) { - - Method *n; - - n = new Method; - n->name = new char[strlen(name)+1]; - strcpy(n->name,name); - n->function = new char[strlen(function)+1]; - strcpy(n->function, function); - - n->next = head; - head = n; -} - -// --------------------------------------------------------------------- -// PYTHON::print_methods() -// -// Prints out the method array. -// --------------------------------------------------------------------- - -void PYTHON::print_methods() { - - Method *n; - - fprintf(f_wrappers,"static PyMethodDef %sMethods[] = {\n", module); - n = head; - while (n) { - if (!use_kw) { - fprintf(f_wrappers,"\t { \"%s\", %s, METH_VARARGS },\n", n->name, n->function); - } else { - fprintf(f_wrappers,"\t { \"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS },\n", n->name, n->function); - } - n = n->next; - } - fprintf(f_wrappers,"\t { NULL, NULL }\n"); - fprintf(f_wrappers,"};\n"); - fprintf(f_wrappers,"#ifdef __cplusplus\n"); - fprintf(f_wrappers,"}\n"); - fprintf(f_wrappers,"#endif\n"); -} - -// --------------------------------------------------------------------- -// char *PYTHON::add_docstring(DocEntry *de) -// -// Adds a documentation entry to the doc-string generator. Returns a -// unique character symbol that will be used to fill in the doc-string -// at a later time. -// --------------------------------------------------------------------- - -char *PYTHON::add_docstring(DocEntry *de) { - DocString *s; - String str; - - str = "@doc"; - str << doc_index << "@"; - - s = new DocString(); - s->de = de; - s->name = copy_string(str); - s->next = doc_strings; - doc_strings = s; - doc_index++; - return s->name; -} - -// --------------------------------------------------------------------- -// PYTHON::headers(void) -// -// ---------------------------------------------------------------------- - -void PYTHON::headers(void) -{ - - emit_banner(f_header); - - fprintf(f_header,"/* Implementation : PYTHON */\n\n"); - fprintf(f_header,"#define SWIGPYTHON\n"); - - if (!NoInclude) { - if (insert_file("python.swg", f_header) == -1) { - fprintf(stderr,"SWIG : Fatal error. Unable to locate python.swg. (Possible installation problem).\n"); - SWIG_exit(1); - } - } else { - if (insert_file("pyexp.swg", f_header) == -1) { - fprintf(stderr,"SWIG : Fatal error. Unable to locate pyexp.swg. (Possible installation problem).\n"); - SWIG_exit(1); - } - } -} - - -// -------------------------------------------------------------------- -// PYTHON::initialize(void) -// -// This function outputs the starting code for a function to initialize -// your interface. It is only called once by the parser. -// -// --------------------------------------------------------------------- - -void PYTHON::initialize(void) -{ - - char filen[256]; - char *temp; - char *oldmodule = 0; - - if (!module) { - module = "swig"; - fprintf(stderr,"SWIG : *** Warning. No module name specified.\n"); - } - - // If shadow classing is enabled, we're going to change the module - // name to "modulec" - - if (shadow) { - temp = new char[strlen(module)+2]; - sprintf(temp,"%sc",module); - oldmodule = module; - module = temp; - } - /* Initialize the C code for the module */ - initialize_cmodule(); - /* Create a shadow file (if enabled).*/ - if (shadow) { - sprintf(filen,"%s%s.py", output_dir, oldmodule); - if ((f_shadow = fopen(filen,"w")) == 0) { - fprintf(stderr,"Unable to open %s\n", filen); - SWIG_exit(0); - } - fprintf(f_shadow,"# This file was created automatically by SWIG.\n"); - fprintf(f_shadow,"import %s\n", module); - } - - // Dump out external module declarations - - if (strlen(modinit.get()) > 0) { - fprintf(f_header,"%s\n",modinit.get()); - } - if (strlen(modextern.get()) > 0) { - fprintf(f_header,"%s\n",modextern.get()); - } - fprintf(f_wrappers,"#ifdef __cplusplus\n"); - fprintf(f_wrappers,"extern \"C\" {\n"); - fprintf(f_wrappers,"#endif\n"); -} - -// --------------------------------------------------------------------- -// PYTHON::initialize_cmodule(void) -// -// Initializes the C module. -// -// --------------------------------------------------------------------- -void PYTHON::initialize_cmodule(void) -{ - int i; - fprintf(f_header,"#define SWIG_init init%s\n\n", module); - fprintf(f_header,"#define SWIG_name \"%s\"\n", module); - - // Output the start of the init function. - // Modify this to use the proper return type and arguments used - // by the target Language - - fprintf(f_init,"static PyObject *SWIG_globals;\n"); - - fprintf(f_init,"#ifdef __cplusplus\n"); - fprintf(f_init,"extern \"C\" \n"); - fprintf(f_init,"#endif\n"); - - fprintf(f_init,"SWIGEXPORT(void) init%s() {\n",module); - fprintf(f_init,"\t PyObject *m, *d;\n"); - - if (InitNames) { - i = 0; - while (InitNames[i]) { - fprintf(f_init,"\t %s();\n", InitNames[i]); - i++; - } - } - fprintf(f_init,"\t SWIG_globals = SWIG_newvarlink();\n"); - fprintf(f_init,"\t m = Py_InitModule(\"%s\", %sMethods);\n", module, module); - fprintf(f_init,"\t d = PyModule_GetDict(m);\n"); -} - - -// --------------------------------------------------------------------- -// PYTHON::close(void) -// -// Called when the end of the interface file is reached. Closes the -// initialization function and performs cleanup as necessary. -// --------------------------------------------------------------------- - -void PYTHON::close(void) -{ - - print_methods(); - close_cmodule(); - if ((doc_entry) && (module)){ - String temp; - temp << "Python Module : "; - if (shadow) { - module[strlen(module)-1] = 0; - } - temp << module; - doc_entry->cinfo << temp; - } - if (shadow) { - String fullshadow; - fullshadow << classes - << "\n\n#-------------- FUNCTION WRAPPERS ------------------\n\n" - << func - << "\n\n#-------------- VARIABLE WRAPPERS ------------------\n\n" - << vars; - - if (strlen(pragma_include) > 0) { - fullshadow << "\n\n#-------------- USER INCLUDE -----------------------\n\n" - << pragma_include; - } - - // Go through all of the docstrings and replace the docstrings - - DocString *s; - s = doc_strings; - while (s) { - fullshadow.replace(s->name, s->de->text); - s = s->next; - } - /* - fprintf(f_shadow,"\n\n#-------------- FUNCTION WRAPPERS ------------------\n\n"); - fprintf(f_shadow,"%s",func.get()); - fprintf(f_shadow,"\n\n#-------------- VARIABLE WRAPPERS ------------------\n\n"); - fprintf(f_shadow,"%s",vars.get()); - if (strlen(pragma_include) > 0) { - fprintf(f_shadow,"\n\n#-------------- USER INCLUDE -----------------------\n\n"); - fprintf(f_shadow,"%s",pragma_include.get()); - } - */ - fprintf(f_shadow, "%s", fullshadow.get()); - fclose(f_shadow); - } -} - -// -------------------------------------------------------------------- -// PYTHON::close_cmodule(void) -// -// Called to cleanup the C module code -// -------------------------------------------------------------------- -void PYTHON::close_cmodule(void) -{ - emit_ptr_equivalence(f_init); - fprintf(f_init,"}\n"); -} - -// ---------------------------------------------------------------------- -// PYTHON::get_pointer(char *iname, char *srcname, char *src, char *target, -// DataType *t, WrapperFunction &f, char *ret) -// -// Emits code to get a pointer and do type checking. -// iname = name of the function/method (used for error messages) -// srcname = Name of source (used for error message reporting). -// src = name of variable where source string is located. -// dest = name of variable where pointer value is stored. -// t = Expected datatype of the parameter -// f = Wrapper function object being used to generate code. -// ret = return code upon failure. -// -// Note : pointers are stored as strings so you first need to get -// a string and then call _swig_get_hex() to extract a point. -// -// This module is pretty ugly, but type checking is kind of nasty -// anyways. -// ---------------------------------------------------------------------- - -void -PYTHON::get_pointer(char *iname, char *srcname, char *src, char *dest, - DataType *t, String &f, char *ret) -{ - - // Now get the pointer value from the string and save in dest - - if (t->is_reference) - f << tab4 << "if (" << src << ") {\n" - << tab8 << "if (SWIG_GetPtrObj(" << src << ",(void **) &" << dest << ","; - else - f << tab4 << "if (" << src << ") {\n" - << tab8 << "if (" << src << " == Py_None) { " << dest << " = NULL; }\n" - << tab8 << "else if (SWIG_GetPtrObj(" << src << ",(void **) &" << dest << ","; - - // If we're passing a void pointer, we give the pointer conversion a NULL - // pointer, otherwise pass in the expected type. - - if (t->type == T_VOID) f << "(char *) 0 )) {\n"; - else - f << "\"" << t->print_mangle() << "\")) {\n"; - - // This part handles the type checking according to three different - // levels. 0 = no checking, 1 = warning message, 2 = strict. - - switch(TypeStrict) { - case 0: // No type checking - f << tab8 << "}\n"; - break; - - case 1: // Warning message only - - // Change this part to how you want to handle a type-mismatch warning. - // By default, it will just print to stderr. - - f << tab8 << tab4 << "fprintf(stderr,\"Warning : type mismatch in " << srcname - << " of " << iname << ". Expected " << t->print_mangle() - << ", received %s\\n\"," << src << ");\n" - << tab8 << "}\n"; - - break; - case 2: // Super strict mode. - - // Change this part to return an error. - - f << tab8 << tab4 << "PyErr_SetString(PyExc_TypeError,\"Type error in " << srcname - << " of " << iname << ". Expected " << t->print_mangle() << ".\");\n" - << tab8 << "return " << ret << ";\n" - << tab8 << "}\n"; - break; - - default : - fprintf(stderr,"SWIG Error. Unknown strictness level\n"); - break; - } - f << tab4 << "}\n"; -} - -// ---------------------------------------------------------------------- -// PYTHON::emit_function_header() -// -// Return the code to be used as a function header -// ---------------------------------------------------------------------- -void PYTHON::emit_function_header(WrapperFunction &emit_to, char *wname) -{ - if (!use_kw) { - emit_to.def << "static PyObject *" << wname - << "(PyObject *self, PyObject *args) {"; - } else { - emit_to.def << "static PyObject *" << wname - << "(PyObject *self, PyObject *args, PyObject *kwargs) {"; - } - emit_to.code << tab4 << "self = self;\n"; -} - -// ---------------------------------------------------------------------- -// PYTHON::convert_self() -// -// Called during the function generation process, to determine what to -// use as the "self" variable during the call. Derived classes may emit code -// to convert the real self pointer into a usable pointer. -// -// Returns the name of the variable to use as the self pointer -// ---------------------------------------------------------------------- -char *PYTHON::convert_self(WrapperFunction &) -{ - // Default behaviour is no translation - return ""; -} - -// ---------------------------------------------------------------------- -// PYTHON::make_funcname_wrapper() -// -// Called to create a name for a wrapper function -// ---------------------------------------------------------------------- -char *PYTHON::make_funcname_wrapper(char *fnName) -{ - return name_wrapper(fnName,""); -} - -// ---------------------------------------------------------------------- -// PYTHON::create_command(char *cname, char *iname) -// -// Create a new command in the interpreter. Used for C++ inheritance -// stuff. -// ---------------------------------------------------------------------- - -void PYTHON::create_command(char *cname, char *iname) { - - // Create the name of the wrapper function - - char *wname = name_wrapper(cname,""); - - // Now register the function with the interpreter. - - add_method(iname, wname); - -} - -// ---------------------------------------------------------------------- -// PYTHON::create_function(char *name, char *iname, DataType *d, -// ParmList *l) -// -// This function creates a wrapper function and registers it with the -// interpreter. -// -// Inputs : -// name = actual name of the function that's being wrapped -// iname = name of the function in the interpreter (may be different) -// d = Return datatype of the functions. -// l = A linked list containing function parameter information. -// -// ---------------------------------------------------------------------- - -void PYTHON::create_function(char *name, char *iname, DataType *d, ParmList *l) -{ - Parm *p; - int pcount,i,j; - String wname, self_name, call_name; - char source[64], target[64], temp[256], argnum[20]; - char *usage = 0; - WrapperFunction f; - String parse_args; - String arglist; - String get_pointers; - String cleanup, outarg; - String check; - String build; - String kwargs; - - int have_build = 0; - char *tm; - int numopt = 0; - - have_output = 0; - - // Make a valid name for this function. This removes special symbols - // that would cause problems in the C compiler. - - wname = make_funcname_wrapper(iname); - - // Now emit the function declaration for the wrapper function. You - // should modify this to return the appropriate types and use the - // appropriate parameters. - - emit_function_header(f, wname); - - f.add_local("PyObject *","_resultobj"); - - // Get the function usage string for later use - - usage = usage_func(iname,d,l); - - // Write code to extract function parameters. - // This is done in one pass, but we need to construct three independent - // pieces. - // 1. Python format string such as "iis" - // 2. The actual arguments to put values into - // 3. Pointer conversion code. - // - // If there is a type mapping, we will extract the Python argument - // as a raw PyObject and let the user deal with it. - // - - pcount = emit_args(d, l, f); - if (!use_kw) { - parse_args << tab4 << "if(!PyArg_ParseTuple(args,\""; - } else { - parse_args << tab4 << "if(!PyArg_ParseTupleAndKeywords(args,kwargs,\""; - arglist << ",_kwnames"; - } - - i = 0; - j = 0; - numopt = l->numopt(); // Get number of optional arguments - if (numopt) have_defarg = 1; - p = l->get_first(); - - kwargs << "{ "; - while (p != 0) { - - // Generate source and target strings - sprintf(source,"_obj%d",i); - sprintf(target,"_arg%d",i); - sprintf(argnum,"%d",j+1); - - // Only consider this argument if it's not ignored - - if (!p->ignore) { - arglist << ","; - // Add an optional argument separator if needed - - if (j == pcount-numopt) { - parse_args << "|"; - } - - if (strlen(p->name)) { - kwargs << "\"" << p->name << "\","; - } else { - kwargs << "\"arg" << j+1 << "\","; - // kwargs << "\"\","; - } - - // Look for input typemap - - if ((tm = typemap_lookup("in","python",p->t,p->name,source,target,&f))) { - parse_args << "O"; // Grab the argument as a raw PyObject - f.add_local("PyObject *",source,"0"); - arglist << "&" << source; - if (i >= (pcount-numopt)) - get_pointers << tab4 << "if (" << source << ")\n"; - get_pointers << tm << "\n"; - get_pointers.replace("$argnum", argnum); - get_pointers.replace("$arg",source); - } else { - - // Check if this parameter is a pointer. If not, we'll get values - - if (!p->t->is_pointer) { - // Extract a parameter by "value" - - switch(p->t->type) { - - // Handle integers here. Usually this can be done as a single - // case if you appropriate cast things. However, if you have - // special cases, you'll need to add more code. - - case T_INT : case T_UINT: case T_SINT: - parse_args << "i"; - break; - case T_SHORT: case T_USHORT: case T_SSHORT: - parse_args << "h"; - break; - case T_LONG : case T_ULONG: case T_SLONG : - parse_args << "l"; - break; - case T_SCHAR : case T_UCHAR : - parse_args << "b"; - break; - case T_CHAR: - parse_args << "c"; - break; - case T_FLOAT : - parse_args << "f"; - break; - case T_DOUBLE: - parse_args << "d"; - break; - - case T_BOOL: - { - String tempb; - String tempval; - if (p->defvalue) { - tempval << "(int) " << p->defvalue; - } - tempb << "tempbool" << i; - parse_args << "i"; - if (!p->defvalue) - f.add_local("int",tempb.get()); - else - f.add_local("int",tempb.get(),tempval.get()); - get_pointers << tab4 << target << " = " << p->t->print_cast() << " " << tempb << ";\n"; - arglist << "&" << tempb; - } - break; - - // Void.. Do nothing. - - case T_VOID : - break; - - // User defined. This is usually invalid. No way to pass a - // complex type by "value". We'll just pass into the unsupported - // datatype case. - - case T_USER: - - // Unsupported data type - - default : - fprintf(stderr,"%s : Line %d. Unable to use type %s as a function argument.\n",input_file, line_number, p->t->print_type()); - break; - } - - // Emit code for parameter list - - if ((p->t->type != T_VOID) && (p->t->type != T_BOOL)) - arglist << "&_arg" << i; - - } else { - - // Is some other kind of variable. - - if ((p->t->type == T_CHAR) && (p->t->is_pointer == 1)) { - parse_args << "s"; - arglist << "&_arg" << i; - } else { - - // Have some sort of pointer variable. Create a temporary local - // variable for the string and read the pointer value into it. - - parse_args << "O"; - sprintf(source,"_argo%d", i); - sprintf(target,"_arg%d", i); - sprintf(temp,"argument %d",i+1); - - f.add_local("PyObject *", source,"0"); - arglist << "&" << source; - get_pointer(iname, temp, source, target, p->t, get_pointers, "NULL"); - } - } - } - j++; - } - // Check if there was any constraint code - if ((tm = typemap_lookup("check","python",p->t,p->name,source,target))) { - check << tm << "\n"; - check.replace("$argnum", argnum); - } - // Check if there was any cleanup code - if ((tm = typemap_lookup("freearg","python",p->t,p->name,target,source))) { - cleanup << tm << "\n"; - cleanup.replace("$argnum", argnum); - cleanup.replace("$arg",source); - } - if ((tm = typemap_lookup("argout","python",p->t,p->name,target,"_resultobj"))) { - outarg << tm << "\n"; - outarg.replace("$argnum", argnum); - outarg.replace("$arg",source); - have_output++; - } - if ((tm = typemap_lookup("build","python",p->t,p->name,source,target))) { - build << tm << "\n"; - have_build = 1; - } - p = l->get_next(); - i++; - } - - kwargs << " NULL }"; - if (use_kw) { - f.locals << tab4 << "char *_kwnames[] = " << kwargs << ";\n"; - } - - parse_args << ":" << iname << "\""; // No additional arguments - parse_args << arglist << ")) \n" - << tab8 << "return NULL;\n"; - - self_name = convert_self(f); - - /* Now slap the whole first part of the wrapper function together */ - - f.code << parse_args << get_pointers << check; - - - // Special handling for build values - - if (have_build) { - char temp1[256]; - char temp2[256]; - l->sub_parmnames(build); // Replace all parameter names - for (i = 0; i < l->nparms; i++) { - p = l->get(i); - if (strlen(p->name) > 0) { - sprintf(temp1,"_in_%s", p->name); - } else { - sprintf(temp1,"_in_arg%d", i); - } - sprintf(temp2,"_obj%d",i); - build.replaceid(temp1,temp2); - } - f.code << build; - } - - // This function emits code to call the real function. Assuming you read - // the parameters in correctly, this will work. - - call_name = ""; - call_name << self_name << name; - emit_func_call(call_name,d,l,f); - - // Now emit code to return the functions return value (if any). - // If there was a result, it was saved in _result. - // If the function is a void type, don't do anything. - - if ((strncmp(name, "new_", 4) != 0) && // don't use the out typemap for constructors - (tm = typemap_lookup("out","python",d,iname,"_result","_resultobj"))) { - // Yep. Use it instead of the default - f.code << tm << "\n"; - } else { - - if ((d->type != T_VOID) || (d->is_pointer)) { - // Now have return value, figure out what to do with it. - - if (!d->is_pointer) { - - // Function returns a "value" - - switch(d->type) { - - // Return an integer type - - case T_INT: case T_SINT: case T_UINT: case T_BOOL: - f.code << tab4 << "_resultobj = Py_BuildValue(\"i\",_result);\n"; - break; - case T_SHORT: case T_SSHORT: case T_USHORT: - f.code << tab4 << "_resultobj = Py_BuildValue(\"h\",_result);\n"; - break; - case T_LONG : case T_SLONG : case T_ULONG: - f.code << tab4 << "_resultobj = Py_BuildValue(\"l\",_result);\n"; - break; - case T_SCHAR: case T_UCHAR : - f.code << tab4 << "_resultobj = Py_BuildValue(\"b\",_result);\n"; - break; - - // Return a floating point value - - case T_DOUBLE : - f.code << tab4 << "_resultobj = Py_BuildValue(\"d\",_result);\n"; - break; - case T_FLOAT : - f.code << tab4 << "_resultobj = Py_BuildValue(\"f\",_result);\n"; - break; - - // Return a single ASCII value. Usually we need to convert - // it to a NULL-terminate string and return that instead. - - case T_CHAR : - f.code << tab4 << "_resultobj = Py_BuildValue(\"c\",_result);\n"; - break; - - case T_USER : - - // Return something by value - // We're living dangerously here, but life is short...play hard - - // Oops. Need another local variable - f.add_local("char","_ptemp[128]"); - - d->is_pointer++; - f.code << tab4 << "SWIG_MakePtr(_ptemp, (void *) _result,\"" - << d->print_mangle() << "\");\n"; - d->is_pointer--; - // Return a character string containing our pointer. - - f.code << tab4 << "_resultobj = Py_BuildValue(\"s\",_ptemp);\n"; - break; - default : - fprintf(stderr,"%s: Line %d. Unable to use return type %s in function %s.\n", input_file, line_number, d->print_type(), name); - break; - } - } else { - - // Return type is a pointer. We'll see if it's a char * and return - // a string. Otherwise, we'll convert it into a SWIG pointer and return - // that. - - if ((d->type == T_CHAR) && (d->is_pointer == 1)) { - - // Return a character string - f.code << tab4 << "_resultobj = Py_BuildValue(\"s\", _result);\n"; - - // If declared as a new object, free the result - - } else { - - // Build a SWIG pointer. - f.add_local("char","_ptemp[128]"); - f.code << tab4 << "if (_result) {\n" - << tab8 << "SWIG_MakePtr(_ptemp, (char *) _result,\"" - << d->print_mangle() << "\");\n"; - - // Return a character string containing our pointer. - f.code << tab8 << "_resultobj = Py_BuildValue(\"s\",_ptemp);\n"; - f.code << tab4 << "} else {\n" - << tab8 << "Py_INCREF(Py_None);\n" - << tab8 << "_resultobj = Py_None;\n" - << tab4 << "}\n"; - } - } - } else { - // no return value and no output args - //if (!have_output) { - f.code << tab4 << "Py_INCREF(Py_None);\n"; - f.code << tab4 << "_resultobj = Py_None;\n"; - //} - } - } - - // Check to see if there were any output arguments, if so we're going to - // create a Python list object out of the current result - - f.code << outarg; - - // If there was any other cleanup needed, do that - - f.code << cleanup; - - // Look to see if there is any newfree cleanup code - - if (NewObject) { - if ((tm = typemap_lookup("newfree","python",d,iname,"_result",""))) { - f.code << tm << "\n"; - } - } - - // See if there is any argument cleanup code - - if ((tm = typemap_lookup("ret","python",d,iname,"_result",""))) { - // Yep. Use it instead of the default - f.code << tm << "\n"; - } - - f.code << tab4 << "return _resultobj;\n"; - f.code << "}\n"; - - // Substitute the cleanup code - f.code.replace("$cleanup",cleanup); - - // Substitute the function name - f.code.replace("$name",iname); - - // Dump the function out - f.print(f_wrappers); - - // Now register the function with the interpreter. - - add_method(iname, wname); - - // Create a documentation entry for this - - if (doc_entry) { - static DocEntry *last_doc_entry = 0; - doc_entry->usage << usage; - if (last_doc_entry != doc_entry) { - doc_entry->cinfo << "returns " << d->print_type(); - last_doc_entry = doc_entry; - } - } - - // --------------------------------------------------------------------------- - // Create a shadow for this function (if enabled and not in a member function) - // --------------------------------------------------------------------------- - - if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { - String translate; - - int need_wrapper = 0; - int munge_return = 0; - int have_optional = 0; - - // Check return code for modification - if ((hash.lookup(d->name)) && (d->is_pointer <=1)) { - need_wrapper = 1; - munge_return = 1; - } - - if (docstring && doc_entry) - need_wrapper = 1; - - // If no modification is needed. We're just going to play some - // symbol table games instead - - if (!need_wrapper) { - func << iname << " = " << module << "." << iname << "\n\n"; - } else { - func << "def " << iname << "(*_args, **_kwargs):\n"; - - // Create a docstring for this - if (docstring && doc_entry) { - func << tab4 << "\"\"\"" << add_docstring(doc_entry) << "\"\"\"\n"; - } - - func << tab4 << "val = " << module << "." << iname << "(*_args,**_kwargs)\n"; - - if (munge_return) { - // If the output of this object has been remapped in any way, we're - // going to return it as a bare object. - - if (!typemap_check("out",typemap_lang,d,iname)) { - - // If there are output arguments, we are going to return the value - // unchanged. Otherwise, emit some shadow class conversion code. - - if (!have_output) { - func << tab4 << "if val: val = " << (char *) hash.lookup(d->name) << "Ptr(val)"; - if (((hash.lookup(d->name)) && (d->is_pointer < 1)) || - ((hash.lookup(d->name)) && (d->is_pointer == 1) && NewObject)) - func << "; val.thisown = 1\n"; - else - func << "\n"; - } else { - // Does nothing--returns the value unmolested - } - } - } - func << tab4 << "return val\n\n"; - } - } -} - -// ----------------------------------------------------------------------- -// PYTHON::link_variable(char *name, char *iname, DataType *d) -// -// Input variables: -// name = the real name of the variable being linked -// iname = Name of the variable in the interpreter (may be different) -// d = Datatype of the variable. -// -// This creates a pair of functions for evaluating/setting the value -// of a variable. These are then added to the special SWIG global -// variable type. -// ----------------------------------------------------------------------- - -void PYTHON::link_variable(char *name, char *iname, DataType *t) { - - char *wname; - static int have_globals = 0; - char *tm; - - WrapperFunction getf, setf; - - // If this is our first call, add the globals variable to the - // Python dictionary. - - if (!have_globals) { - fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", SWIG_globals);\n",global_name); - have_globals=1; - if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { - vars << global_name << " = " << module << "." << global_name << "\n"; - } - } - // First make a sanitized version of the function name (in case it's some - // funky C++ thing). - - wname = name_wrapper(name,""); - - // --------------------------------------------------------------------- - // Create a function for setting the value of the variable - // --------------------------------------------------------------------- - - setf.def << "static int " << wname << "_set(PyObject *val) {"; - if (!(Status & STAT_READONLY)) { - if ((tm = typemap_lookup("varin","python",t,name,"val",name))) { - setf.code << tm << "\n"; - setf.code.replace("$name",iname); - } else { - if ((t->type != T_VOID) || (t->is_pointer)) { - if (!t->is_pointer) { - - // Have a real value here - - switch(t->type) { - case T_INT: case T_SHORT: case T_LONG : - case T_UINT: case T_USHORT: case T_ULONG: - case T_SINT: case T_SSHORT: case T_SLONG: - case T_SCHAR: case T_UCHAR: case T_BOOL: - // Get an integer value - setf.add_local(t->print_type(), "tval"); - setf.code << tab4 << "tval = " << t->print_cast() << "PyInt_AsLong(val);\n" - << tab4 << "if (PyErr_Occurred()) {\n" - << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" - << iname << "'(" << t->print_type() << ")\");\n" - << tab8 << "return 1; \n" - << tab4 << "}\n" - << tab4 << name << " = tval;\n"; - break; - - case T_FLOAT: case T_DOUBLE: - // Get a floating point value - setf.add_local(t->print_type(), "tval"); - setf.code << tab4 << "tval = " << t->print_cast() << "PyFloat_AsDouble(val);\n" - << tab4 << "if (PyErr_Occurred()) {\n" - << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" - << iname << "'(" << t->print_type() << ")\");\n" - << tab8 << "return 1; \n" - << tab4 << "}\n" - << tab4 << name << " = tval;\n"; - break; - - // A single ascii character - - case T_CHAR: - setf.add_local("char *", "tval"); - setf.code << tab4 << "tval = (char *) PyString_AsString(val);\n" - << tab4 << "if (PyErr_Occurred()) {\n" - << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" - << iname << "'(" << t->print_type() << ")\");\n" - << tab8 << "return 1; \n" - << tab4 << "}\n" - << tab4 << name << " = *tval;\n"; - break; - case T_USER: - t->is_pointer++; - setf.add_local(t->print_type(),"temp"); - get_pointer(iname,"value","val","temp",t,setf.code,"1"); - setf.code << tab4 << name << " = *temp;\n"; - t->is_pointer--; - break; - default: - fprintf(stderr,"%s : Line %d. Unable to link with type %s.\n", input_file, line_number, t->print_type()); - } - } else { - - // Parse a pointer value - - if ((t->type == T_CHAR) && (t->is_pointer == 1)) { - setf.add_local("char *", "tval"); - setf.code << tab4 << "tval = (char *) PyString_AsString(val);\n" - << tab4 << "if (PyErr_Occurred()) {\n" - << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" - << iname << "'(" << t->print_type() << ")\");\n" - << tab8 << "return 1; \n" - << tab4 << "}\n"; - - if (CPlusPlus) { - setf.code << tab4 << "if (" << name << ") delete [] " << name << ";\n" - << tab4 << name << " = new char[strlen(tval)+1];\n" - << tab4 << "strcpy((char *)" << name << ",tval);\n"; - } else { - setf.code << tab4 << "if (" << name << ") free(" << name << ");\n" - << tab4 << name << " = (char *) malloc(strlen(tval)+1);\n" - << tab4 << "strcpy((char *)" << name << ",tval);\n"; - } - } else { - - // Is a generic pointer value. - - setf.add_local(t->print_type(),"temp"); - get_pointer(iname,"value","val","temp",t,setf.code,"1"); - setf.code << tab4 << name << " = temp;\n"; - } - } - } - } - setf.code << tab4 << "return 0;\n"; - } else { - // Is a readonly variable. Issue an error - setf.code << tab4 << "PyErr_SetString(PyExc_TypeError,\"Variable " << iname - << " is read-only.\");\n" - << tab4 << "return 1;\n"; - } - - setf.code << "}\n"; - - // Dump out function for setting value - - setf.print(f_wrappers); - - // ---------------------------------------------------------------- - // Create a function for getting the value of a variable - // ---------------------------------------------------------------- - - getf.def << "static PyObject *" << wname << "_get() {"; - getf.add_local("PyObject *","pyobj"); - if ((tm = typemap_lookup("varout","python",t,name,name,"pyobj"))) { - getf.code << tm << "\n"; - getf.code.replace("$name",iname); - } else if ((tm = typemap_lookup("out","python",t,name,name,"pyobj"))) { - getf.code << tm << "\n"; - getf.code.replace("$name",iname); - } else { - if ((t->type != T_VOID) || (t->is_pointer)) { - if (!t->is_pointer) { - - /* Is a normal datatype */ - switch(t->type) { - case T_INT: case T_SINT: case T_UINT: - case T_SHORT: case T_SSHORT: case T_USHORT: - case T_LONG: case T_SLONG: case T_ULONG: - case T_SCHAR: case T_UCHAR: case T_BOOL: - getf.code << tab4 << "pyobj = PyInt_FromLong((long) " << name << ");\n"; - break; - case T_FLOAT: case T_DOUBLE: - getf.code << tab4 << "pyobj = PyFloat_FromDouble((double) " << name << ");\n"; - break; - case T_CHAR: - getf.add_local("char","ptemp[2]"); - getf.code << tab4 << "ptemp[0] = " << name << ";\n" - << tab4 << "ptemp[1] = 0;\n" - << tab4 << "pyobj = PyString_FromString(ptemp);\n"; - break; - case T_USER: - // Hack this into a pointer - getf.add_local("char", "ptemp[128]"); - t->is_pointer++; - getf.code << tab4 << "SWIG_MakePtr(ptemp,(char *) &" << name - << "," << quote << t->print_mangle() << quote << ");\n" - << tab4 << "pyobj = PyString_FromString(ptemp);\n"; - t->is_pointer--; - break; - default: - fprintf(stderr,"Unable to link with type %s\n", t->print_type()); - break; - } - } else { - - // Is some sort of pointer value - if ((t->type == T_CHAR) && (t->is_pointer == 1)) { - getf.code << tab4 << "if (" << name << ")\n" - << tab8 << "pyobj = PyString_FromString(" << name << ");\n" - << tab4 << "else pyobj = PyString_FromString(\"(NULL)\");\n"; - } else { - getf.add_local("char","ptemp[128]"); - getf.code << tab4 << "SWIG_MakePtr(ptemp, (char *) " << name << ",\"" - << t->print_mangle() << "\");\n" - << tab4 << "pyobj = PyString_FromString(ptemp);\n"; - } - } - } - } - - getf.code << tab4 << "return pyobj;\n" - << "}\n"; - - getf.print(f_wrappers); - - // Now add this to the variable linking mechanism - - fprintf(f_init,"\t SWIG_addvarlink(SWIG_globals,\"%s\",%s_get, %s_set);\n", iname, wname, wname); - - - // Fill in the documentation entry - - if (doc_entry) { - doc_entry->usage << usage_var(iname, t); - doc_entry->cinfo << "Global : " << t->print_type() << " " << name; - } - - // ---------------------------------------------------------- - // Output a shadow variable. (If applicable and possible) - // ---------------------------------------------------------- - if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { - if ((hash.lookup(t->name)) && (t->is_pointer <= 1)) { - vars << iname << " = " << (char *) hash.lookup(t->name) << "Ptr(" << module << "." << global_name - << "." << iname << ")\n"; - } - } -} - -// ----------------------------------------------------------------------- -// PYTHON::declare_const(char *name, char *iname, DataType *type, char *value) -// -// Makes a constant as defined with #define. Constants are added to the -// module's dictionary and are **NOT** guaranteed to be read-only, -// sorry. -// -// ------------------------------------------------------------------------ - -void PYTHON::declare_const(char *name, char *, DataType *type, char *value) { - - char *tm; - - // Make a static python object - - if ((tm = typemap_lookup("const","python",type,name,value,name))) { - fprintf(f_init,"%s\n",tm); - } else { - - if ((type->type == T_USER) && (!type->is_pointer)) { - fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); - return; - } - - if (type->is_pointer == 0) { - switch(type->type) { - case T_INT:case T_SINT: case T_UINT: case T_BOOL: - case T_SHORT: case T_SSHORT: case T_USHORT: - case T_LONG: case T_SLONG: case T_ULONG: - case T_SCHAR: case T_UCHAR: - fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyInt_FromLong((long) %s));\n",name,value); - break; - case T_DOUBLE: - case T_FLOAT: - fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyFloat_FromDouble((double) %s));\n",name,value); - break; - case T_CHAR : - fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyString_FromString(\"%s\"));\n",name,value); - break; - default: - fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); - break; - } - } else { - if ((type->type == T_CHAR) && (type->is_pointer == 1)) { - fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyString_FromString(\"%s\"));\n",name,value); - } else { - // A funky user-defined type. We're going to munge it into a string pointer value - fprintf(f_init,"\t {\n"); - fprintf(f_init,"\t\t char %s_char[%d];\n", name, (int) strlen(type->print_mangle()) + 20); - fprintf(f_init,"\t\t SWIG_MakePtr(%s_char, (void *) (%s),\"%s\");\n", - name, value, type->print_mangle()); - fprintf(f_init,"\t\t PyDict_SetItemString(d,\"%s\", PyString_FromString(%s_char));\n",name,name); - fprintf(f_init,"\t }\n"); - } - } - } - if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { - vars << name << " = " << module << "." << name << "\n"; - } - if (doc_entry) { - doc_entry->usage = ""; - doc_entry->usage << usage_const(name,type,value); - doc_entry->cinfo = ""; - doc_entry->cinfo << "Constant: " << type->print_type(); - } -} - -// ---------------------------------------------------------------------- -// PYTHON::usage_var(char *iname, DataType *t) -// -// This function produces a string indicating how to use a variable. -// It is called by the documentation system to produce syntactically -// correct documentation entires. -// -// s is a pointer to a character pointer. You should create -// a string and set this pointer to point to it. -// ---------------------------------------------------------------------- - -char *PYTHON::usage_var(char *iname, DataType *) { - - static String temp; - - temp = ""; - temp << global_name << "." << iname; - - // Create result. Don't modify this - - return temp.get(); -} - -// --------------------------------------------------------------------------- -// PYTHON::usage_func(char *iname, DataType *t, ParmList *l) -// -// Produces a string indicating how to call a function in the target -// language. -// -// --------------------------------------------------------------------------- - -char *PYTHON::usage_func(char *iname, DataType *, ParmList *l) { - - static String temp; - Parm *p; - int i; - - temp = ""; - temp << iname << "("; - - // Now go through and print parameters - // You probably don't need to change this - - i = 0; - p = l->get_first(); - while (p != 0) { - if (!p->ignore) { - i++; - /* If parameter has been named, use that. Otherwise, just print a type */ - - if ((p->t->type != T_VOID) || (p->t->is_pointer)) { - if (strlen(p->name) > 0) { - temp << p->name; - } else { - temp << p->t->print_type(); - } - } - p = l->get_next(); - if (p != 0) { - if (!p->ignore) - temp << ","; - } - } else { - p = l->get_next(); - if (p) { - if ((!p->ignore) && (i > 0)) - temp << ","; - } - } - } - - temp << ")"; - - // Create result. Don't change this - - return temp.get(); - -} - - -// ---------------------------------------------------------------------- -// PYTHON::usage_const(char *iname, DataType *type, char *value) -// -// Produces a string for a constant. Really about the same as -// usage_var() except we'll indicate the value of the constant. -// ---------------------------------------------------------------------- - -char *PYTHON::usage_const(char *iname, DataType *, char *value) { - - static String temp; - temp = ""; - temp << iname << " = " << value; - - return temp.get(); -} - -// ----------------------------------------------------------------------- -// PYTHON::add_native(char *name, char *funcname) -// -// Add a native module name to the methods list. -// ----------------------------------------------------------------------- - -void PYTHON::add_native(char *name, char *funcname) { - add_method(name, funcname); - if (shadow) { - func << name << " = " << module << "." << name << "\n\n"; - } -} - -// ----------------------------------------------------------------------- -// PYTHON::cpp_class_decl(char *name, char *rename, char *type) -// -// Treatment of an empty class definition. Used to handle -// shadow classes across modules. -// ----------------------------------------------------------------------- - -void PYTHON::cpp_class_decl(char *name, char *rename, char *type) { - char temp[256]; - if (shadow) { - hash.add(name,copy_string(rename)); - // Add full name of datatype to the hash table - if (strlen(type) > 0) { - sprintf(temp,"%s %s", type, name); - hash.add(temp,copy_string(rename)); - } - } -} - -// ----------------------------------------------------------------------- -// PYTHON::pragma(char *name, char *type) -// -// Pragma directive. Used to do various python specific things -// ----------------------------------------------------------------------- - -void PYTHON::pragma(char *lang, char *cmd, char *value) { - - if (strcmp(lang,"python") == 0) { - if (strcmp(cmd,"CODE") == 0) { - if (shadow) { - fprintf(f_shadow,"%s\n",value); - } - } else if (strcmp(cmd,"code") == 0) { - if (shadow) { - fprintf(f_shadow,"%s\n",value); - } - } else if (strcmp(cmd,"include") == 0) { - if (shadow) { - if (value) { - if (get_file(value,pragma_include) == -1) { - fprintf(stderr,"%s : Line %d. Unable to locate file %s\n", input_file, line_number, value); - } - } - } - } else { - fprintf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number); - } - } -} - - -struct PyPragma { - PyPragma(char *method, char *text) : m_method(method), m_text(text), next(0) { } - ~PyPragma() { if (next) delete next; } - String m_method; - String m_text; - PyPragma *next; -}; - -static PyPragma *pragmas = 0; - -// ----------------------------------------------------------------------------- -// PYTHON::cpp_pragma(Pragma *plist) -// -// Handle C++ pragmas -// ----------------------------------------------------------------------------- - -void PYTHON::cpp_pragma(Pragma *plist) { - PyPragma *pyp1 = 0, *pyp2 = 0; - if (pragmas) { - delete pragmas; - pragmas = 0; - } - while (plist) { - if (strcmp(plist->lang,"python") == 0) { - if (strcmp(plist->name,"addtomethod") == 0) { - // parse value, expected to be in the form "methodName:line" - String temp = plist->value; - char* txtptr = strchr(temp.get(), ':'); - if (txtptr) { - // add name and line to a list in current_class - *txtptr = 0; - txtptr++; - pyp1 = new PyPragma(temp,txtptr); - if (pyp2) { - pyp2->next = pyp1; - pyp2 = pyp1; - } else { - pragmas = pyp1; - pyp2 = pragmas; - } - } else { - fprintf(stderr,"%s : Line %d. Malformed addtomethod pragma. Should be \"methodName:text\"\n", - plist->filename.get(),plist->lineno); - } - } else if (strcmp(plist->name, "addtoclass") == 0) { - pyp1 = new PyPragma("__class__",plist->value); - if (pyp2) { - pyp2->next = pyp1; - pyp2 = pyp1; - } else { - pragmas = pyp1; - pyp2 = pragmas; - } - } - } - plist = plist->next; - } -} - -// -------------------------------------------------------------------------------- -// PYTHON::emitAddPragmas(String& output, char* name, char* spacing); -// -// Search the current class pragma for any text belonging to name. -// Append the text properly spaced to the output string. -// -------------------------------------------------------------------------------- - -void PYTHON::emitAddPragmas(String& output, char* name, char* spacing) -{ - PyPragma *p = pragmas; - while (p) { - if (strcmp(p->m_method,name) == 0) { - output << spacing << p->m_text << "\n"; - } - p = p->next; - } -}