Commit 9e0906e5 authored by David Gobbi's avatar David Gobbi Committed by Marcus D. Hanwell
Browse files

ENH: some much-needed code reorganization in vtkWraPython.c

parent 84beb47c
......@@ -2579,99 +2579,11 @@ static void vtkWrapPython_GenerateSpecialHeaders(
}
/* -------------------------------------------------------------------- */
/* This is the main entry point for the python wrappers. When called,
* it will print the vtkXXPython.c file contents to "fp". */
void vtkParseOutput(FILE *fp, FileInfo *data)
/* generate code for custom methods for some classes */
static void vtkWrapPython_CustomMethods(FILE *fp, FileInfo *data)
{
static const char *compare_consts[6] = {
"Py_LT", "Py_LE", "Py_EQ", "Py_NE", "Py_GT", "Py_GE" };
static const char *compare_tokens[6] = {
"<", "<=", "==", "!=", ">", ">=" };
int compare_ops = 0;
int has_hash = 0;
int class_has_new = 0;
int i;
/* the VTK_WRAPPING_CXX tells header files where they're included from */
fprintf(fp,
"// python wrapper for %s object\n//\n"
"#define VTK_WRAPPING_CXX\n",
data->ClassName);
/* unless this is vtkObjectBase, define VTK_STREAMS_FWD_ONLY */
if (strcmp("vtkObjectBase",data->ClassName) != 0)
{
/* Block inclusion of full streams. */
fprintf(fp,
"#define VTK_STREAMS_FWD_ONLY\n");
}
/* include vtkPython.h on all platforms but apple */
fprintf(fp,
"#if !defined(__APPLE__)\n"
"#include \"vtkPython.h\"\n"
"#undef _XOPEN_SOURCE /* Conflicts with standards.h. */\n"
"#undef _THREAD_SAFE /* Conflicts with pthread.h. */\n"
"#endif\n");
/* lots of important utility functions are defined in vtkPythonUtil.h */
fprintf(fp,
"#include \"vtkPythonUtil.h\"\n");
/* vtkPythonCommand is needed to wrap vtkObject.h */
if (strcmp("vtkObject", data->ClassName) == 0)
{
fprintf(fp,
"#include \"vtkPythonCommand.h\"\n");
}
/* generate includes for any special types that are used */
vtkWrapPython_GenerateSpecialHeaders(fp, data);
/* the header file for the wrapped class */
fprintf(fp,
"#include \"%s.h\"\n",
data->ClassName);
if ((data->NumberOfSuperClasses == 0) && !(data->IsAbstract))
{
fprintf(fp,
"\n"
"#include <vtksys/ios/sstream>\n");
}
/* do the export of the main entry point */
fprintf(fp,
"\n"
"#if defined(WIN32)\n"
"extern \"C\" { __declspec( dllexport ) PyObject *PyVTKClass_%sNew(const char *); }\n"
"#else\n"
"extern \"C\" { PyObject *PyVTKClass_%sNew(const char *); }\n"
"#endif\n"
"\n",
data->ClassName, data->ClassName);
/* bring in all the superclasses */
for (i = 0; i < data->NumberOfSuperClasses; i++)
{
fprintf(fp,
"extern \"C\" { PyObject *PyVTKClass_%sNew(const char *); }\n",
data->SuperClasses[i]);
}
/* prototype for the docstring function */
if (data->NumberOfSuperClasses || !data->IsAbstract)
{
fprintf(fp,
"\n"
"static const char **%sDoc();\n"
"\n",
data->ClassName);
}
/* the python vtkObject needs special hooks for observers */
if (!strcmp("vtkObject",data->ClassName))
if (strcmp("vtkObject",data->ClassName) == 0)
{
/* Add the AddObserver method to vtkObject. */
fprintf(fp,
......@@ -2681,7 +2593,7 @@ void vtkParseOutput(FILE *fp, FileInfo *data)
" char *temp0;\n"
" PyObject *temp1;\n"
" float temp2;\n"
" unsigned long temp20 = 0;\n");
" unsigned long temp20 = 0;\n");
fprintf(fp,
" op = static_cast<vtkObject *>(vtkPythonUtil::VTKParseTuple(self, args, \"zO\", &temp0, &temp1));\n"
......@@ -2766,178 +2678,142 @@ void vtkParseOutput(FILE *fp, FileInfo *data)
"\n",
data->ClassName, data->ClassName);
}
}
/* check for New() function */
for (i = 0; i < data->NumberOfFunctions; i++)
{
if (data->Functions[i].Name &&
strcmp("New",data->Functions[i].Name) == 0 &&
data->Functions[i].NumberOfArguments == 0)
{
class_has_new = 1;
}
}
/* now output all the methods are wrappable */
if (data->NumberOfSuperClasses || !data->IsAbstract)
/* -------------------------------------------------------------------- */
/* generate the New method for a vtkObjectBase object */
static void vtkWrapPython_GenerateObjectNew(
FILE *fp, FileInfo *data, int class_has_new)
{
if (class_has_new)
{
vtkWrapPython_GenerateMethods(fp, data, class_has_new, 0);
fprintf(fp,
"static vtkObjectBase *%sStaticNew()\n"
"{\n"
" return %s::New();\n"
"}\n"
"\n",
data->ClassName, data->ClassName);
}
/* output the class initilization function */
fprintf(fp,
"PyObject *PyVTKClass_%sNew(const char *modulename)\n"
"{\n",
data->ClassName);
/* the New method for vtkObjectBase */
if (strcmp(data->ClassName,"vtkObjectBase") == 0)
if (class_has_new)
{
if (class_has_new)
{
fprintf(fp,
"static vtkObjectBase *%sStaticNew()\n"
"{\n"
" return %s::New();\n"
"}\n"
"\n",
data->ClassName, data->ClassName);
}
fprintf(fp,
"PyObject *PyVTKClass_%sNew(const char *modulename)\n"
"{\n",
" return PyVTKClass_New(&%sStaticNew,\n",
data->ClassName);
if (class_has_new)
{
fprintf(fp,
" return PyVTKClass_New(&%sStaticNew,\n",
data->ClassName);
}
else
{
fprintf(fp,
" return PyVTKClass_New(NULL,\n");
}
fprintf(fp,
" Py%sMethods,\n"
" \"%s\",modulename,\n"
" %sDoc(),0);\n"
"}\n"
"\n",
data->ClassName, data->ClassName, data->ClassName);
}
/* the New method for descendants of vtkObjectBase */
else if (data->NumberOfSuperClasses)
else
{
if (class_has_new)
{
fprintf(fp,
"static vtkObjectBase *%sStaticNew()\n"
"{\n"
" return %s::New();\n"
"}\n"
"\n",
data->ClassName, data->ClassName);
}
fprintf(fp,
"PyObject *PyVTKClass_%sNew(const char *modulename)\n"
"{\n",
data->ClassName);
" return PyVTKClass_New(NULL,\n");
}
if (class_has_new)
{
fprintf(fp,
" return PyVTKClass_New(&%sStaticNew,\n",
data->ClassName);
}
else
{
fprintf(fp,
" return PyVTKClass_New(NULL,\n");
}
fprintf(fp,
" Py%sMethods,\n"
" \"%s\",modulename,\n"
" %sDoc(),",
data->ClassName, data->ClassName, data->ClassName);
fprintf(fp,
" Py%sMethods,\n"
" \"%s\",modulename,\n"
" %sDoc(),\n"
" PyVTKClass_%sNew(modulename));\n"
"}\n"
"\n",
data->ClassName, data->ClassName, data->ClassName,
if (strcmp(data->ClassName,"vtkObjectBase") == 0)
{
fprintf(fp, "0);\n");
}
else
{
fprintf(fp, "\n"
" PyVTKClass_%sNew(modulename));\n",
data->SuperClasses[0]);
}
/* the New method of 'special' non-vtkObject classes */
else if (!data->IsAbstract)
{
/* handle all constructors */
vtkWrapPython_GenerateMethods(fp, data, class_has_new, 1);
fprintf(fp,
"}\n"
"\n");
}
/* the method table for the New method */
fprintf(fp,
"static PyMethodDef Py%sNewMethod = \\\n"
"{ (char*)\"%s\", (PyCFunction)Py%s_%s, 1,\n"
" (char*)\"\" };\n"
"\n",
data->ClassName, data->ClassName, data->ClassName,
data->ClassName);
/* -------------------------------------------------------------------- */
/* generate extra functions for a special object */
static void vtkWrapPython_GenerateSpecialObjectNew(
FILE *fp, FileInfo *data, int class_has_new)
{
static const char *compare_consts[6] = {
"Py_LT", "Py_LE", "Py_EQ", "Py_NE", "Py_GT", "Py_GE" };
static const char *compare_tokens[6] = {
"<", "<=", "==", "!=", ">", ">=" };
int compare_ops = 0;
int has_hash = 0;
int i;
/* the copy constructor */
fprintf(fp,
"static void *vtkSpecial_%sCopy(const void *obj)\n"
"{\n"
" if (obj)\n"
" {\n"
" return new %s(*static_cast<const %s*>(obj));\n"
" }\n"
" return 0;\n"
"}\n"
"\n",
data->ClassName, data->ClassName, data->ClassName);
/* handle all constructors */
vtkWrapPython_GenerateMethods(fp, data, class_has_new, 1);
/* the destructor */
fprintf(fp,
"static void vtkSpecial_%sDelete(void *obj)\n"
"{\n"
" if (obj)\n"
" {\n"
" delete static_cast<%s *>(obj);\n"
" }\n"
"}\n"
"\n",
data->ClassName, data->ClassName);
/* the method table for the New method */
fprintf(fp,
"static PyMethodDef Py%sNewMethod = \\\n"
"{ (char*)\"%s\", (PyCFunction)Py%s_%s, 1,\n"
" (char*)\"\" };\n"
"\n",
data->ClassName, data->ClassName, data->ClassName,
data->ClassName);
/* the printer */
fprintf(fp,
"static void vtkSpecial_%sPrint(ostream &os, const void *obj)\n"
"{\n"
" if (obj)\n"
" {\n"
" os << *static_cast<const %s *>(obj);\n"
" }\n"
"}\n"
"\n",
data->ClassName, data->ClassName);
/* the copy constructor */
fprintf(fp,
"static void *vtkSpecial_%sCopy(const void *obj)\n"
"{\n"
" if (obj)\n"
" {\n"
" return new %s(*static_cast<const %s*>(obj));\n"
" }\n"
" return 0;\n"
"}\n"
"\n",
data->ClassName, data->ClassName, data->ClassName);
/* hard-code comparison operators until vtkParse provides
* operator information */
if (strcmp(data->ClassName, "vtkVariant") == 0)
{
compare_ops =
( (1 << Py_LT) | (1 << Py_LE) | (1 << Py_EQ) |
(1 << Py_NE) | (1 << Py_GT) | (1 << Py_GE));
}
else if (strcmp(data->ClassName, "vtkTimeStamp") == 0)
{
compare_ops =
( (1 << Py_LT) | (1 << Py_GT) );
}
/* the destructor */
fprintf(fp,
"static void vtkSpecial_%sDelete(void *obj)\n"
"{\n"
" if (obj)\n"
" {\n"
" delete static_cast<%s *>(obj);\n"
" }\n"
"}\n"
"\n",
data->ClassName, data->ClassName);
/* the compare function */
if (compare_ops != 0)
{
fprintf(fp,
/* the printer */
fprintf(fp,
"static void vtkSpecial_%sPrint(ostream &os, const void *obj)\n"
"{\n"
" if (obj)\n"
" {\n"
" os << *static_cast<const %s *>(obj);\n"
" }\n"
"}\n"
"\n",
data->ClassName, data->ClassName);
/* hard-code comparison operators until vtkParse provides
* operator information */
if (strcmp(data->ClassName, "vtkVariant") == 0)
{
compare_ops =
( (1 << Py_LT) | (1 << Py_LE) | (1 << Py_EQ) |
(1 << Py_NE) | (1 << Py_GT) | (1 << Py_GE));
}
else if (strcmp(data->ClassName, "vtkTimeStamp") == 0)
{
compare_ops = ( (1 << Py_LT) | (1 << Py_GT) );
}
/* the compare function */
if (compare_ops != 0)
{
fprintf(fp,
"static int vtkSpecial_%sCompare(const void *o1, const void *o2, int opid)\n"
"{\n"
" const %s &so1 = *static_cast<const %s *>(o1);\n"
......@@ -2947,30 +2823,30 @@ void vtkParseOutput(FILE *fp, FileInfo *data)
data->ClassName, data->ClassName, data->ClassName,
data->ClassName, data->ClassName);
for (i = Py_LT; i <= Py_GE; i++)
for (i = Py_LT; i <= Py_GE; i++)
{
if ( ((compare_ops >> i) & 1) != 0 )
{
if ( ((compare_ops >> i) & 1) != 0 )
{
fprintf(fp,
" case %s:\n"
" return (so1 %s so2);\n",
compare_consts[i-Py_LT], compare_tokens[i-Py_LT]);
}
fprintf(fp,
" case %s:\n"
" return (so1 %s so2);\n",
compare_consts[i-Py_LT], compare_tokens[i-Py_LT]);
}
fprintf(fp,
" }"
" return -1;\n"
"}\n"
"\n");
}
/* the hash function for vtkTimeStamp */
if (strcmp(data->ClassName, "vtkTimeStamp") == 0)
{
has_hash = 1;
fprintf(fp,
" }"
" return -1;\n"
"}\n"
"\n");
}
fprintf(fp,
/* the hash function for vtkTimeStamp */
if (strcmp(data->ClassName, "vtkTimeStamp") == 0)
{
has_hash = 1;
fprintf(fp,
"static long vtkSpecial_%sHash(const void *self, int *immutable)\n"
"{\n"
" unsigned long mtime = *(static_cast<const vtkTimeStamp *>(self));\n"
......@@ -2981,14 +2857,14 @@ void vtkParseOutput(FILE *fp, FileInfo *data)
"}\n"
"\n",
data->ClassName);
}
}
/* the hash function for vtkVariant */
if (strcmp(data->ClassName, "vtkVariant") == 0)
{
has_hash = 1;
/* the hash function for vtkVariant */
if (strcmp(data->ClassName, "vtkVariant") == 0)
{
has_hash = 1;
fprintf(fp,
fprintf(fp,
"static long vtkSpecial_%sHash(const void *self, int *immutable)\n"
"{\n"
" long h = vtkPythonUtil::VariantHash(static_cast<const vtkVariant *>(self));\n"
......@@ -2997,10 +2873,10 @@ void vtkParseOutput(FILE *fp, FileInfo *data)
"}\n"
"\n",
data->ClassName);
}
}
/* the table to hold these special methods */
fprintf(fp,
/* the table to hold these special methods */
fprintf(fp,
"static PyVTKSpecialMethods vtkSpecial_%sSpecialMethods =\n"
"{\n"
" &vtkSpecial_%sCopy,\n"
......@@ -3009,47 +2885,175 @@ void vtkParseOutput(FILE *fp, FileInfo *data)
data->ClassName, data->ClassName, data->ClassName,
data->ClassName);
if (compare_ops != 0)
{
fprintf(fp,
if (compare_ops != 0)
{
fprintf(fp,
" &vtkSpecial_%sCompare,\n",
data->ClassName);
}
else
{
fprintf(fp,
}
else
{
fprintf(fp,
" 0,\n");
}
}
if (has_hash)
{
fprintf(fp,
if (has_hash)
{
fprintf(fp,
" &vtkSpecial_%sHash,\n",
data->ClassName);
}
else
{
fprintf(fp,
}
else
{
fprintf(fp,
" 0,\n");
}
}
fprintf(fp,
"};\n"
"\n");
/* the exported New method */
fprintf(fp,
"PyObject *PyVTKClass_%sNew(const char *)\n"
"{\n"
" return PyVTKSpecialType_New(\n"
" &Py%sNewMethod, Py%sMethods, Py%s_%sMethods,"
" \"%s\", %sDoc(),\n"
" &vtkSpecial_%sSpecialMethods);\n"
"}\n"
"\n",
data->ClassName, data->ClassName, data->ClassName,
data->ClassName, data->ClassName, data->ClassName,
data->ClassName, data->ClassName);
}
/* -------------------------------------------------------------------- */
/* This is the main entry point for the python wrappers. When called,
* it will print the vtkXXPython.c file contents to "fp". */
void vtkParseOutput(FILE *fp, FileInfo *data)
{
int class_has_new = 0;
int is_vtk_object = 1;
int i;
/* the VTK_WRAPPING_CXX tells header files where they're included from */
fprintf(fp,
"// python wrapper for %s object\n//\n"
"#define VTK_WRAPPING_CXX\n",
data->ClassName);
/* unless this is vtkObjectBase, define VTK_STREAMS_FWD_ONLY */
if (strcmp("vtkObjectBase",data->ClassName) != 0)
{
/* Block inclusion of full streams. */
fprintf(fp,
"};\n"
"\n");
"#define VTK_STREAMS_FWD_ONLY\n");
}
/* the exported New method */
/* include vtkPython.h on all platforms but apple */
fprintf(fp,
"#if !defined(__APPLE__)\n"
"#include \"vtkPython.h\"\n"
"#undef _XOPEN_SOURCE /* Conflicts with standards.h. */\n"
"#undef _THREAD_SAFE /* Conflicts with pthread.h. */\n"
"#endif\n");
/* lots of important utility functions are defined in vtkPythonUtil.h */
fprintf(fp,
"#include \"vtkPythonUtil.h\"\n");
/* vtkPythonCommand is needed to wrap vtkObject.h */
if (strcmp("vtkObject", data->ClassName) == 0)
{
fprintf(fp,
"PyObject *PyVTKClass_%sNew(const char *)\n"
"{\n"
" return PyVTKSpecialType_New(\n"
" &Py%sNewMethod, Py%sMethods, Py%s_%sMethods,"
" \"%s\", %sDoc(),\n"
" &vtkSpecial_%sSpecialMethods);\n"
"}\n"
"#include \"vtkPythonCommand.h\"\n");
}
/* generate includes for any special types that are used */
vtkWrapPython_GenerateSpecialHeaders(fp, data);
/* the header file for the wrapped class */
fprintf(fp,
"#include \"%s.h\"\n",
data->ClassName);
/* is this isn't a vtkObjectBase-derived object, then it is special */
if (strcmp(data->ClassName,"vtkObjectBase") != 0 &&
data->NumberOfSuperClasses == 0)
{
is_vtk_object = 0;