int main(int argc, char *argv[]) { ClassInfo *wrappedClasses[MAX_WRAPPED_CLASSES]; unsigned char wrapAsVTKObject[MAX_WRAPPED_CLASSES]; ClassInfo *data = NULL; NamespaceInfo *contents; OptionInfo *options; HierarchyInfo *hinfo = NULL; FileInfo *file_info; FILE *fp; const char *module = "vtkCommonCore"; const char *name; char *name_from_file = NULL; int numberOfWrappedClasses = 0; int numberOfWrappedNamespaces = 0; int wrapped_anything = 0; int i, j; size_t k, m; int is_vtkobject; /* pre-define a macro to identify the language */ vtkParse_DefineMacro("__VTK_WRAP_PYTHON__", 0); /* get command-line args and parse the header file */ file_info = vtkParse_Main(argc, argv); /* get the command-line options */ options = vtkParse_GetCommandLineOptions(); /* get the output file */ fp = fopen(options->OutputFileName, "w"); if (!fp) { fprintf(stderr, "Error opening output file %s\n", options->OutputFileName); exit(1); } /* get the hierarchy info for accurate typing */ if (options->HierarchyFileNames) { hinfo = vtkParseHierarchy_ReadFiles( options->NumberOfHierarchyFileNames, options->HierarchyFileNames); } /* get the filename without the extension */ name = file_info->FileName; m = strlen(name); for (k = m; k > 0; k--) { if (name[k] == '.') { break; } } if (k > 0) { m = k; } for (k = m; k > 0; k--) { if (!((name[k-1] >= 'a' && name[k-1] <= 'z') || (name[k-1] >= 'A' && name[k-1] <= 'Z') || (name[k-1] >= '0' && name[k-1] <= '9') || name[k-1] == '_')) { break; } } name_from_file = (char *)malloc(m - k + 1); strncpy(name_from_file, &name[k], m - k); name_from_file[m-k] = '\0'; name = name_from_file; /* get the global namespace */ contents = file_info->Contents; /* use the hierarchy file to expand typedefs */ if (hinfo) { for (i = 0; i < contents->NumberOfClasses; i++) { vtkWrap_ApplyUsingDeclarations(contents->Classes[i], file_info, hinfo); } for (i = 0; i < contents->NumberOfClasses; i++) { vtkWrap_ExpandTypedefs(contents->Classes[i], file_info, hinfo); } } /* the VTK_WRAPPING_CXX tells header files where they're included from */ fprintf(fp, "// python wrapper for %s\n//\n" "#define VTK_WRAPPING_CXX\n", name); /* unless this is vtkObjectBase.h, define VTK_STREAMS_FWD_ONLY */ if (strcmp("vtkObjectBase", name) != 0) { /* Block inclusion of full streams. */ fprintf(fp, "#define VTK_STREAMS_FWD_ONLY\n"); } /* lots of important utility functions are defined in vtkPythonArgs.h */ fprintf(fp, "#include \"vtkPythonArgs.h\"\n" "#include \"vtkPythonOverload.h\"\n" "#include \"vtkConfigure.h\"\n" "#include <cstddef>\n" "#include <sstream>\n"); /* vtkPythonCommand is needed to wrap vtkObject.h */ if (strcmp("vtkObject", name) == 0) { fprintf(fp, "#include \"vtkPythonCommand.h\"\n"); } /* generate includes for any special types that are used */ vtkWrapPython_GenerateSpecialHeaders(fp, file_info, hinfo); /* the header file for the wrapped class */ fprintf(fp, "#include \"%s.h\"\n\n", name); /* do the export of the main entry point */ fprintf(fp, "extern \"C\" { %s void PyVTKAddFile_%s(PyObject *); }\n", "VTK_ABI_EXPORT", name); /* get the module that is being wrapped */ data = file_info->MainClass; if (!data && file_info->Contents->NumberOfClasses > 0) { data = file_info->Contents->Classes[0]; } if (data && hinfo) { module = vtkWrapPython_ClassModule(hinfo, data->Name); } /* Identify all enum types that are used by methods */ vtkWrapPython_MarkAllEnums(file_info->Contents, hinfo); /* Wrap any enum types defined in the global namespace */ for (i = 0; i < contents->NumberOfEnums; i++) { vtkWrapPython_GenerateEnumType(fp, module, NULL, contents->Enums[i]); } /* Wrap any namespaces */ for (i = 0; i < contents->NumberOfNamespaces; i++) { if (contents->Namespaces[i]->NumberOfConstants > 0) { vtkWrapPython_WrapNamespace(fp, module, contents->Namespaces[i]); numberOfWrappedNamespaces++; } } /* Check for all special classes before any classes are wrapped */ for (i = 0; i < contents->NumberOfClasses; i++) { data = contents->Classes[i]; /* guess whether type is a vtkobject */ is_vtkobject = (data == file_info->MainClass ? 1 : 0); if (hinfo) { is_vtkobject = vtkWrap_IsTypeOf(hinfo, data->Name, "vtkObjectBase"); } if (!is_vtkobject) { /* mark class as abstract only if it has pure virtual methods */ /* (does not check for inherited pure virtual methods) */ data->IsAbstract = 0; for (j = 0; j < data->NumberOfFunctions; j++) { FunctionInfo *func = data->Functions[j]; if (func && func->IsPureVirtual) { data->IsAbstract = 1; break; } } } wrapAsVTKObject[i] = (is_vtkobject ? 1 : 0); } /* Wrap all of the classes in the file */ for (i = 0; i < contents->NumberOfClasses; i++) { data = contents->Classes[i]; is_vtkobject = wrapAsVTKObject[i]; /* if "hinfo" is present, wrap everything, else just the main class */ if (hinfo || data == file_info->MainClass) { if (vtkWrapPython_WrapOneClass( fp, module, data->Name, data, file_info, hinfo, is_vtkobject)) { /* re-index wrapAsVTKObject for wrapped classes */ wrapAsVTKObject[numberOfWrappedClasses] = (is_vtkobject ? 1 : 0); wrappedClasses[numberOfWrappedClasses++] = data; } } } /* The function for adding everything to the module dict */ wrapped_anything = (numberOfWrappedClasses || numberOfWrappedNamespaces || contents->NumberOfConstants); fprintf(fp, "void PyVTKAddFile_%s(\n" " PyObject *%s)\n" "{\n" "%s", name, (wrapped_anything ? "dict" : ""), (wrapped_anything ? " PyObject *o;\n" : "")); /* Add all of the namespaces */ for (j = 0; j < contents->NumberOfNamespaces; j++) { if (contents->Namespaces[j]->NumberOfConstants > 0) { fprintf(fp, " o = PyVTKNamespace_%s();\n" " if (o && PyDict_SetItemString(dict, \"%s\", o) != 0)\n" " {\n" " Py_DECREF(o);\n" " }\n" "\n", contents->Namespaces[j]->Name, contents->Namespaces[j]->Name); } } /* Add all of the classes that have been wrapped */ for (i = 0; i < numberOfWrappedClasses; i++) { data = wrappedClasses[i]; is_vtkobject = wrapAsVTKObject[i]; if (data->Template) { /* Template generator */ fprintf(fp, " o = Py%s_TemplateNew();\n" "\n", data->Name); /* Add template specializations to dict */ fprintf(fp, " if (o)\n" " {\n" " PyObject *l = PyObject_CallMethod(o, (char *)\"values\", 0);\n" " Py_ssize_t n = PyList_GET_SIZE(l);\n" " for (Py_ssize_t i = 0; i < n; i++)\n" " {\n" " PyObject *ot = PyList_GET_ITEM(l, i);\n" " const char *nt = NULL;\n" " if (PyType_Check(ot))\n" " {\n" " nt = ((PyTypeObject *)ot)->tp_name;\n" " }\n" " else if (PyCFunction_Check(ot))\n" " {\n" " nt = ((PyCFunctionObject *)ot)->m_ml->ml_name;\n" " }\n" " if (nt)\n" " {\n" " PyDict_SetItemString(dict, nt, ot);\n" " }\n" " }\n" " Py_DECREF(l);\n" " }\n" "\n"); } else if (is_vtkobject) { /* Class is derived from vtkObjectBase */ fprintf(fp, " o = Py%s_ClassNew();\n" "\n", data->Name); } else { /* Classes that are not derived from vtkObjectBase */ fprintf(fp, " o = Py%s_TypeNew();\n" "\n", data->Name); } fprintf(fp, " if (o && PyDict_SetItemString(dict, \"%s\", o) != 0)\n" " {\n" " Py_DECREF(o);\n" " }\n" "\n", data->Name); } /* add any enum types defined in the file */ vtkWrapPython_AddPublicEnumTypes(fp, " ", "dict", "o", contents); /* add any constants defined in the file */ vtkWrapPython_AddPublicConstants(fp, " ", "dict", "o", contents); /* close the AddFile function */ fprintf(fp, "}\n\n"); free(name_from_file); vtkParse_Free(file_info); return 0; }
/* Wrap a templated class */ int vtkWrapPython_WrapTemplatedClass( FILE *fp, ClassInfo *data, FileInfo *file_info, HierarchyInfo *hinfo) { char classname[1024]; const char *instantiations[1024]; int ninstantiations = 0; int i, j, k, nargs; ClassInfo *sdata; ValueInfo *tdef; HierarchyEntry *entry; const char *name; char *cp; const char **args; const char **defaults; const char *modulename; const char *name_with_args; int is_vtkobject = 0; const char **types; /* do not directly wrap vtkTypeTemplate */ if (strcmp(data->Name, "vtkTypeTemplate") == 0) { return 0; } if (hinfo == 0) { return 0; } entry = vtkParseHierarchy_FindEntry(hinfo, data->Name); if (entry == 0) { return 0; } modulename = entry->Module; defaults = entry->TemplateDefaults; /* find all instantiations from derived classes */ for (j = 0; j < hinfo->NumberOfEntries; j++) { entry = &hinfo->Entries[j]; classname[0] = '\0'; /* skip enum entries */ if (entry->IsEnum) { continue; } /* look for typedefs of template instantiations */ if (entry->IsTypedef) { tdef = entry->Typedef; if ((tdef->Type & VTK_PARSE_BASE_TYPE) == VTK_PARSE_OBJECT && entry->NumberOfTemplateParameters == 0) { if (tdef->Class && tdef->Class[0] != '\0' && tdef->Class[strlen(tdef->Class) - 1] == '>') { strcpy(classname, tdef->Class); entry = vtkParseHierarchy_FindEntry(hinfo, classname); } } if (!entry || entry->IsTypedef || entry->IsEnum) { continue; } } nargs = entry->NumberOfTemplateParameters; args = entry->TemplateParameters; if (strcmp(entry->Module, modulename) == 0 && (entry->NumberOfSuperClasses == 1 || strcmp(entry->Name, data->Name) == 0)) { types = NULL; /* only do these classes directly */ if (strcmp(entry->Name, "vtkDenseArray") == 0 || strcmp(entry->Name, "vtkSparseArray") == 0) { types = vtkParse_GetArrayTypes(); } else if (strcmp(entry->Name, "vtkTuple") == 0) { static const char *tuple_types[13] = { "unsigned char, 2", "unsigned char, 3", "unsigned char, 4", "int, 2", "int, 3", "int, 4", "float, 2", "float, 3", "float, 4", "double, 2", "double, 3", "double, 4", NULL }; types = tuple_types; } /* do all other templated classes indirectly */ else if (nargs > 0) { continue; } for (i = 0; i == 0 || (types && types[i] != NULL); i++) { /* make the classname, with template args if present */ if (classname[0] == '\0') { if (nargs == 0) { sprintf(classname, "%s", entry->Name); } else { sprintf(classname, "%s<%s>", entry->Name, types[i]); } } name_with_args = NULL; if (strcmp(data->Name, entry->Name) == 0) { /* entry is the same as data */ cp = (char *)malloc(strlen(classname) + 1); strcpy(cp, classname); name_with_args = cp; } else { /* entry is not data, see if it is a subclass, and if so, * what template args of 'data' it corresponds to */ vtkParseHierarchy_IsTypeOfTemplated( hinfo, entry, classname, data->Name, &name_with_args); } if (name_with_args) { /* append to the list of instantiations if not present yet */ for (k = 0; k < ninstantiations; k++) { if (strcmp(name_with_args, instantiations[k]) == 0) { break; } } if (k == ninstantiations) { instantiations[ninstantiations++] = name_with_args; } else { free((char *)name_with_args); } } classname[0] = '\0'; } } } if (ninstantiations) { for (k = 0; k < ninstantiations; k++) { entry = vtkParseHierarchy_FindEntry(hinfo, instantiations[k]); is_vtkobject = vtkParseHierarchy_IsTypeOfTemplated( hinfo, entry, instantiations[k], "vtkObjectBase", NULL); nargs = data->Template->NumberOfParameters; vtkParse_DecomposeTemplatedType(instantiations[k], &name, nargs, &args, defaults); sdata = (ClassInfo *)malloc(sizeof(ClassInfo)); vtkParse_CopyClass(sdata, data); vtkParse_InstantiateClassTemplate(sdata, file_info->Strings, nargs, args); vtkWrapText_PythonName(instantiations[k], classname); vtkWrapPython_WrapOneClass( fp, modulename, classname, sdata, file_info, hinfo, is_vtkobject); vtkParse_FreeClass(sdata); vtkParse_FreeTemplateDecomposition(name, nargs, args); } /* the docstring for the templated class */ fprintf(fp, "static const char *Py%s_Doc[] = {\n", data->Name); vtkWrapPython_ClassDoc(fp, file_info, data, hinfo, is_vtkobject); fprintf(fp, " \"\\nProvided Types:\\n\\n\",\n"); for (k = 0; k < ninstantiations; k++) { vtkWrapPython_PyTemplateName(instantiations[k], classname); fprintf(fp, " \" %s => %s\\n\",\n", classname, instantiations[k]); } fprintf(fp, " NULL\n" "};\n" "\n"); fprintf(fp, "PyObject *Py%s_TemplateNew()\n" "{\n" " PyObject *o;\n" "\n" " PyObject *temp = PyVTKTemplate_New(\"%sPython.%s\",\n" " Py%s_Doc);\n" "\n", data->Name, modulename, data->Name, data->Name); for (k = 0; k < ninstantiations; k++) { vtkWrapText_PythonName(instantiations[k], classname); entry = vtkParseHierarchy_FindEntry(hinfo, instantiations[k]); if (vtkParseHierarchy_IsTypeOfTemplated( hinfo, entry, instantiations[k], "vtkObjectBase", NULL)) { fprintf(fp, " o = Py%s_ClassNew();\n", classname); } else { fprintf(fp, " o = Py%s_TypeNew();\n", classname); } fprintf(fp, " if (o && PyVTKTemplate_AddItem(temp, o) != 0)\n" " {\n" " Py_DECREF(o);\n" " }\n" "\n"); free((char *)instantiations[k]); } fprintf(fp, " return temp;\n" "}\n" "\n"); return 1; } return 0; }