/* get the true superclass */ const char *vtkWrapPython_GetSuperClass( ClassInfo *data, HierarchyInfo *hinfo) { int i; const char *supername = NULL; const char *name; const char **args; const char *defaults[2] = { NULL, NULL }; char *cp; for (i = 0; i < data->NumberOfSuperClasses; i++) { supername = data->SuperClasses[i]; if (strncmp(supername, "vtkTypeTemplate<", 16) == 0) { vtkParse_DecomposeTemplatedType(supername, &name, 2, &args, defaults); cp = (char *)malloc(strlen(args[1])+1); strcpy(cp, args[1]); vtkParse_FreeTemplateDecomposition(name, 2, args); supername = cp; } /* Add QVTKInteractor as the sole exception: It is derived * from vtkObject but does not start with "vtk". Given its * name, it would be expected to be derived from QObject. */ if (vtkWrap_IsVTKObjectBaseType(hinfo, data->Name) || strcmp(data->Name, "QVTKInteractor") == 0) { if (vtkWrap_IsClassWrapped(hinfo, supername) && vtkWrap_IsVTKObjectBaseType(hinfo, supername)) { return supername; } } else if (vtkWrapPython_HasWrappedSuperClass(hinfo, data->Name, NULL)) { return supername; } } return NULL; }
/* 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; }
/* Recursive suproutine to add the methods of "classname" and all its * superclasses to "merge" */ void vtkParseMerge_MergeHelper( FileInfo *finfo, const NamespaceInfo *data, const HierarchyInfo *hinfo, const char *classname, FILE *hintfile, MergeInfo *info, ClassInfo *merge) { FILE *fp = NULL; ClassInfo *cinfo = NULL; ClassInfo *new_cinfo = NULL; HierarchyEntry *entry = NULL; char *new_classname = NULL; const char **template_args = NULL; unsigned long template_arg_count = 0; const char *nspacename = NULL; const char *header; const char *filename; unsigned long i, j, n, m; int recurse; /* Note: this method does not deal with scoping yet. * "classname" might be a scoped name, in which case the * part before the colon indicates the class or namespace * (or combination thereof) where the class resides. * Each containing namespace or class for the "merge" * must be searched, taking the "using" directives that * have been applied into account. */ /* get extra class info from the hierarchy file */ nspacename = data->Name; if (nspacename && classname[0] != ':') { size_t l1 = strlen(nspacename); size_t l2 = strlen(classname); char *ncp = (char *)malloc(l1 + l2 + 3); strcpy(ncp, data->Name); ncp[l1] = ':'; ncp[l1 + 1] = ':'; strcpy(&ncp[l1+2], classname); entry = vtkParseHierarchy_FindEntry(hinfo, ncp); free(ncp); } if (!entry && classname[0] == ':' && classname[1] == ':') { entry = vtkParseHierarchy_FindEntry(hinfo, &classname[2]); } if (!entry) { entry = vtkParseHierarchy_FindEntry(hinfo, classname); } if (entry && entry->NumberOfTemplateParameters > 0) { /* extract the template arguments */ template_arg_count = (unsigned long)entry->NumberOfTemplateParameters; vtkParse_DecomposeTemplatedType( classname, &classname, template_arg_count, &template_args, entry->TemplateDefaults); } /* find out if "classname" is in the current namespace */ n = data->NumberOfClasses; for (i = 0; i < n; i++) { if (strcmp(data->Classes[i]->Name, classname) == 0) { cinfo = data->Classes[i]; break; } } if (n > 0 && !cinfo) { if (!entry) { if (new_classname) { free(new_classname); } return; } header = entry->HeaderFile; if (!header) { if (hintfile) { fclose(hintfile); } fprintf(stderr, "Null header file for class %s!\n", classname); exit(1); } filename = vtkParse_FindIncludeFile(header); if (!filename) { if (hintfile) { fclose(hintfile); } fprintf(stderr, "Couldn't locate header file %s\n", header); exit(1); } fp = fopen(filename, "r"); if (!fp) { if (hintfile) { fclose(hintfile); } fprintf(stderr, "Couldn't open header file %s\n", header); exit(1); } finfo = vtkParse_ParseFile(filename, fp, stderr); fclose(fp); if (!finfo) { if (hintfile) { fclose(hintfile); } exit(1); } if (hintfile) { rewind(hintfile); vtkParse_ReadHints(finfo, hintfile, stderr); } data = finfo->Contents; if (nspacename) { m = data->NumberOfNamespaces; for (j = 0; j < m; j++) { NamespaceInfo *ni = data->Namespaces[j]; if (ni->Name && strcmp(ni->Name, nspacename) == 0) { n = ni->NumberOfClasses; for (i = 0; i < n; i++) { if (strcmp(ni->Classes[i]->Name, classname) == 0) { cinfo = ni->Classes[i]; data = ni; break; } } if (i < n) { break; } } } } else { n = data->NumberOfClasses; for (i = 0; i < n; i++) { if (strcmp(data->Classes[i]->Name, classname) == 0) { cinfo = data->Classes[i]; break; } } } } if (cinfo) { if (template_args) { new_cinfo = (ClassInfo *)malloc(sizeof(ClassInfo)); vtkParse_CopyClass(new_cinfo, cinfo); vtkParse_InstantiateClassTemplate( new_cinfo, finfo->Strings, template_arg_count, template_args); cinfo = new_cinfo; } recurse = 0; if (info) { vtkParseMerge_Merge(finfo, info, merge, cinfo); recurse = 1; } else { vtkParseMerge_MergeUsing(finfo, info, merge, cinfo, 0); n = merge->NumberOfUsings; for (i = 0; i < n; i++) { if (merge->Usings[i]->Name) { recurse = 1; break; } } } if (recurse) { n = cinfo->NumberOfSuperClasses; for (i = 0; i < n; i++) { vtkParseMerge_MergeHelper(finfo, data, hinfo, cinfo->SuperClasses[i], hintfile, info, merge); } } } if (template_arg_count > 0) { vtkParse_FreeTemplateDecomposition( classname, template_arg_count, template_args); } }