Пример #1
0
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;
}
Пример #2
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;
}