/* 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); } }
/* 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; }
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; }