Example #1
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);
    }
}
Example #2
0
/* Command-line argument handler for wrapper tools */
FileInfo *vtkParse_Main(int argc, char *argv[])
{
  int argi;
  int expected_files;
  FILE *ifile;
  FILE *hfile = 0;
  const char *cp;
  char *classname;
  size_t i;
  FileInfo *data;
  StringCache strings;
  int argn;
  char **args;

  /* set the command name for diagnostics */
  vtkParse_SetCommandName(parse_exename(argv[0]));

  /* expand any "@file" args */
  vtkParse_InitStringCache(&strings);
  parse_expand_args(&strings, argc, argv, &argn, &args);

  /* read the args into the static OptionInfo struct */
  argi = parse_check_options(argn, args, 0);

  /* was output file already specified by the "-o" option? */
  expected_files = (options.OutputFileName == NULL ? 2 : 1);

  /* verify number of args, print usage if not valid */
  if (argi == 0)
    {
    free(args);
    exit(0);
    }
  else if (argi < 0 || options.NumberOfFiles != expected_files)
    {
    parse_print_help(stderr, args[0], 0);
    exit(1);
    }

  /* open the input file */
  options.InputFileName = options.Files[0];

  if (!(ifile = fopen(options.InputFileName, "r")))
    {
    fprintf(stderr, "Error opening input file %s\n", options.InputFileName);
    exit(1);
    }

  if (options.OutputFileName == NULL &&
      options.NumberOfFiles > 1)
    {
    /* allow outfile to be given after infile, if "-o" option not used */
    options.OutputFileName = options.Files[1];
    fprintf(stderr, "Deprecated: specify output file with \"-o\".\n");
    }

  /* free the expanded args */
  free(args);

  /* open the hint file, if given on the command line */
  if (options.HintFileName && options.HintFileName[0] != '\0')
    {
    if (!(hfile = fopen(options.HintFileName, "r")))
      {
      fprintf(stderr, "Error opening hint file %s\n", options.HintFileName);
      fclose(ifile);
      exit(1);
      }
    }

  /* make sure than an output file was given on the command line */
  if (options.OutputFileName == NULL)
    {
    fprintf(stderr, "No output file was specified\n");
    fclose(ifile);
    if (hfile)
      {
      fclose(hfile);
      }
    exit(1);
    }

  /* if a hierarchy is was given, then BTX/ETX can be ignored */
  vtkParse_SetIgnoreBTX(0);
  if (options.HierarchyFileName)
    {
    vtkParse_SetIgnoreBTX(1);
    }

  /* parse the input file */
  data = vtkParse_ParseFile(options.InputFileName, ifile, stderr);

  if (!data)
    {
    exit(1);
    }

  /* fill in some blanks by using the hints file */
  if (hfile)
    {
    vtkParse_ReadHints(data, hfile, stderr);
    }

  if (!options.IsSpecialObject && data->MainClass)
    {
    /* mark class as abstract unless it has New() method */
    int nfunc = data->MainClass->NumberOfFunctions;
    int ifunc;
    for (ifunc = 0; ifunc < nfunc; ifunc++)
      {
      FunctionInfo *func = data->MainClass->Functions[ifunc];
      if (func && func->Access == VTK_ACCESS_PUBLIC &&
          func->Name && strcmp(func->Name, "New") == 0 &&
          func->NumberOfParameters == 0)
        {
        break;
        }
      }
    data->MainClass->IsAbstract = ((ifunc == nfunc) ? 1 : 0);
    }

  return data;
}
Example #3
0
int main(int argc, char *argv[])
{
  int argi;
  int has_options = 0;
  FILE *ifile;
  FILE *ofile;
  FILE *hfile = 0;
  const char *cp;
  char *classname;
  size_t i;
  FileInfo *data;

  argi = check_options(argc, argv);
  if (argi > 1 && argc - argi == 2)
    {
    has_options = 1;
    }
  else if (argi < 0 || argc < 3 || argc > 5)
    {
    fprintf(stderr,
            "Usage: %s [options] input_file output_file\n"
            "  --concrete      force concrete class\n"
            "  --abstract      force abstract class\n"
            "  --vtkobject     vtkObjectBase-derived class\n"
            "  --special       non-vtkObjectBase class\n"
            "  --hints <file>  hints file\n"
            "  --types <file>  type hierarchy file\n"
            "  -I <dir>        add an include directory\n"
            "  -D <macro>      define a preprocessor macro\n",
            argv[0]);
    exit(1);
    }

  options.InputFileName = argv[argi++];

  if (!(ifile = fopen(options.InputFileName, "r")))
    {
    fprintf(stderr,"Error opening input file %s\n", options.InputFileName);
    exit(1);
    }

  if (!has_options)
    {
    if (argc == 5)
      {
      options.HintFileName = argv[argi++];
      }
    if (argc >= 4)
      {
      options.IsConcrete = atoi(argv[argi++]);
      options.IsAbstract = !options.IsConcrete;
      }
    }

  if (options.HintFileName && options.HintFileName[0] != '\0')
    {
    if (!(hfile = fopen(options.HintFileName, "r")))
      {
      fprintf(stderr, "Error opening hint file %s\n", options.HintFileName);
      fclose(ifile);
      exit(1);
      }
    }

  options.OutputFileName = argv[argi++];
  ofile = fopen(options.OutputFileName, "w");

  if (!ofile)
    {
    fprintf(stderr, "Error opening output file %s\n", options.OutputFileName);
    fclose(ifile);
    if (hfile)
      {
      fclose(hfile);
      }
    exit(1);
    }

  if (options.IsConcrete)
    {
    cp = options.InputFileName;
    i = strlen(cp);
    classname = (char *)malloc(i+1);
    while (i > 0 &&
           cp[i-1] != '/' && cp[i-1] != '\\' && cp[i-1] != ':') { i--; }
    strcpy(classname, &cp[i]);
    i = 0;
    while (classname[i] != '\0' && classname[i] != '.') { i++; }
    classname[i] = '\0';

    vtkParse_SetClassProperty(classname, "concrete");
    }

  vtkParse_SetIgnoreBTX(0);
  if (options.HierarchyFileName)
    {
    vtkParse_SetIgnoreBTX(1);
    }

  data = vtkParse_ParseFile(options.InputFileName, ifile, stderr);

  if (!data)
    {
    fclose(ifile);
    fclose(ofile);
    if (hfile)
      {
      fclose(hfile);
      }
    exit(1);
    }

  if (hfile)
    {
    vtkParse_ReadHints(data, hfile, stderr);
    }

  if (options.IsConcrete && data->MainClass)
    {
    data->MainClass->IsAbstract = 0;
    }
  else if (options.IsAbstract && data->MainClass)
    {
    data->MainClass->IsAbstract = 1;
    }

  vtkParseOutput(ofile, data);

  fclose(ofile);

  vtkParse_Free(data);

  return 0;
}