Salome HOME
Minor: removing annoying print message
[modules/paravis.git] / src / VTKWrapping / ParaView / vtkParseMain.c
1 /*=========================================================================
2
3   Program:   Visualization Toolkit
4   Module:    vtkParseMain.c
5
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13
14 =========================================================================*/
15
16 /*
17
18 This file provides a unified front-end for the wrapper generators.
19
20 */
21
22 #include "vtkParse.h"
23 #include "vtkParseData.h"
24 #include "vtkParseMain.h"
25 #include <ctype.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 /* This is the struct that contains the options */
31 OptionInfo options;
32
33 /* Get the base filename */
34 static const char *parse_exename(const char *cmd)
35 {
36   const char *exename;
37
38   /* remove directory part of exe name */
39   for (exename = cmd + strlen(cmd); exename > cmd; --exename)
40     {
41     char pc = exename[-1];
42     if (pc == ':' || pc == '/' || pc == '\\')
43       {
44       break;
45       }
46     }
47
48   return exename;
49 }
50
51 /* Print the help */
52 static void parse_print_help(FILE *fp, const char *cmd, int multi)
53 {
54   fprintf(fp,
55     "Usage: %s [options] infile... \n"
56     "  --help            print this help message\n"
57     "  --version         print the VTK version\n"
58     "  -o <file>         the output file\n"
59     "  -I <dir>          add an include directory\n"
60     "  -D <macro[=def]>  define a preprocessor macro\n"
61     "  -U <macro>        undefine a preprocessor macro\n"
62     "  @<file>           read arguments from a file\n",
63     parse_exename(cmd));
64
65   /* args for describing a singe header file input */
66   if (!multi)
67     {
68     fprintf(fp,
69     "  --hints <file>    the hints file to use\n"
70     "  --types <file>    the type hierarchy file to use\n"
71     "  --concrete        force concrete class (ignored, deprecated)\n"
72     "  --abstract        force abstract class (ignored, deprecated)\n"
73     "  --vtkobject       vtkObjectBase-derived class (ignored, deprecated)\n"
74     "  --special         non-vtkObjectBase class (ignored, deprecated)\n");
75     }
76 }
77
78 /* append an arg to the arglist */
79 static void parse_append_arg(int *argn, char ***args, char *arg)
80 {
81   /* if argn is a power of two, allocate more space */
82   if (*argn > 0 && (*argn & (*argn - 1)) == 0)
83     {
84     *args = (char **)realloc(*args, 2*(*argn)*sizeof(char *));
85     }
86   /* append argument to list */
87   (*args)[*argn] = arg;
88   (*argn)++;
89 }
90
91 /* read options from a file, return zero on error */
92 static int read_option_file(
93   StringCache *strings, const char *filename, int *argn, char ***args)
94 {
95   static int option_file_stack_max = 10;
96   static int option_file_stack_size = 0;
97   static const char *option_file_stack[10];
98   FILE *fp;
99   char *line;
100   const char *ccp;
101   char *argstring;
102   char *arg;
103   size_t maxlen = 15;
104   size_t i, n;
105   int j;
106   int in_string;
107
108   line = (char *)malloc(maxlen);
109
110   fp = fopen(filename, "r");
111
112   if (fp == NULL)
113     {
114     return 0;
115     }
116
117   /* read the file line by line */
118   while (fgets(line, (int)maxlen, fp))
119     {
120     n = strlen(line);
121
122     /* if buffer not long enough, increase it */
123     while (n == maxlen-1 && line[n-1] != '\n' && !feof(fp))
124       {
125       maxlen *= 2;
126       line = (char *)realloc(line, maxlen);
127       if (!fgets(&line[n], (int)(maxlen-n), fp)) { break; }
128       n += strlen(&line[n]);
129       }
130
131     /* allocate a string to hold the parsed arguments */
132     argstring = vtkParse_NewString(strings, n);
133     arg = argstring;
134     i = 0;
135
136     /* break the line into individual options */
137     ccp = line;
138     in_string = 0;
139     while (*ccp != '\0')
140       {
141       for (;;)
142         {
143         if (*ccp == '\\')
144           {
145           ccp++;
146           }
147         else if (*ccp == '\"' || *ccp == '\'')
148           {
149           if (!in_string)
150             {
151             in_string = *ccp++;
152             continue;
153             }
154           else if (*ccp == in_string)
155             {
156             in_string = 0;
157             ccp++;
158             continue;
159             }
160           }
161         else if (!in_string && isspace(*ccp))
162           {
163           do { ccp++; } while (isspace(*ccp));
164           break;
165           }
166         if (*ccp == '\0')
167           {
168           break;
169           }
170         /* append character to argument */
171         arg[i++] = *ccp++;
172         }
173       arg[i++] = '\0';
174
175       if (arg[0] == '@')
176         {
177         /* recursively expand '@file' option */
178         if (option_file_stack_size == option_file_stack_max)
179           {
180           fprintf(stderr, "%s: @file recursion is too deep.\n",
181                   (*args)[0]);
182           exit(1);
183           }
184         /* avoid reading the same file recursively */
185         option_file_stack[option_file_stack_size++] = filename;
186         for (j = 0; j < option_file_stack_size; j++)
187           {
188           if (strcmp(&arg[1], option_file_stack[j]) == 0)
189             {
190             break;
191             }
192           }
193         if (j < option_file_stack_size)
194           {
195           parse_append_arg(argn, args, arg);
196           }
197         else if (read_option_file(strings, &arg[1], argn, args) == 0)
198           {
199           parse_append_arg(argn, args, arg);
200           }
201         option_file_stack_size--;
202         }
203       else if (arg[0] != '\0')
204         {
205         parse_append_arg(argn, args, arg);
206         }
207       /* prepare for next arg */
208       arg += i;
209       i = 0;
210       }
211     }
212
213   return 1;
214 }
215
216 /* expand any "@file" args that occur in the command-line args */
217 static void parse_expand_args(
218   StringCache *strings, int argc, char *argv[], int *argn, char ***args)
219 {
220   int i;
221
222   *argn = 0;
223   *args = (char **)malloc(sizeof(char *));
224
225   for (i = 0; i < argc; i++)
226     {
227     /* check for "@file" unless this is the command name */
228     if (i > 0 || argv[i][0] == '@')
229       {
230       /* if read_option_file returns null, add "@file" to the args */
231       /* (this mimics the way that gcc expands @file arguments) */
232       if (read_option_file(strings, &argv[i][1], argn, args) == 0)
233         {
234         parse_append_arg(argn, args, argv[i]);
235         }
236       }
237     else
238       {
239       /* append any other arg */
240       parse_append_arg(argn, args, argv[i]);
241       }
242     }
243 }
244
245 /* Check the options: "multi" should be zero for wrapper tools that
246  * only take one input file, or one for wrapper tools that take multiple
247  * input files.  Returns zero for "--version" or "--help", or returns -1
248  * if an error occurred.  Otherwise, it returns the number of args
249  * that were successfully parsed. */
250 static int parse_check_options(int argc, char *argv[], int multi)
251 {
252   int i;
253   size_t j;
254   char *cp;
255   char c;
256
257   options.NumberOfFiles = 0;
258   options.Files = NULL;
259   options.InputFileName = NULL;
260   options.OutputFileName = NULL;
261   options.HierarchyFileName = 0;
262   options.HintFileName = 0;
263
264   for (i = 1; i < argc; i++)
265     {
266     if (strcmp(argv[i], "--help") == 0)
267       {
268       parse_print_help(stdout, argv[0], multi);
269       return 0;
270       }
271     else if (strcmp(argv[i], "--version") == 0)
272       {
273       const char *ver = VTK_PARSE_VERSION;
274       fprintf(stdout, "%s %s\n", parse_exename(argv[0]), ver);
275       return 0;
276       }
277     else if (argv[i][0] != '-')
278       {
279       if (options.NumberOfFiles == 0)
280         {
281         options.Files = (char **)malloc(sizeof(char *));
282         }
283       else if ((options.NumberOfFiles & (options.NumberOfFiles - 1)) == 0)
284         {
285         options.Files = (char **)realloc(
286           options.Files, 2*options.NumberOfFiles*sizeof(char *));
287         }
288       options.Files[options.NumberOfFiles++] = argv[i];
289       }
290     else if (argv[i][0] == '-' && isalpha(argv[i][1]))
291       {
292       c = argv[i][1];
293       cp = &argv[i][2];
294       if (*cp == '\0')
295         {
296         i++;
297         if (i >= argc || argv[i][0] == '-')
298           {
299           return -1;
300           }
301         cp = argv[i];
302         }
303
304       if (c == 'o')
305         {
306         options.OutputFileName = cp;
307         }
308       else if (c == 'I')
309         {
310         vtkParse_IncludeDirectory(cp);
311         }
312       else if (c == 'D')
313         {
314         j = 0;
315         while (cp[j] != '\0' && cp[j] != '=') { j++; }
316         if (cp[j] == '=') { j++; }
317         vtkParse_DefineMacro(cp, &cp[j]);
318         }
319       else if (c == 'U')
320         {
321         vtkParse_UndefineMacro(cp);
322         }
323       }
324     else if (!multi && strcmp(argv[i], "--hints") == 0)
325       {
326       i++;
327       if (i >= argc || argv[i][0] == '-')
328         {
329         return -1;
330         }
331       options.HintFileName = argv[i];
332       }
333     else if (!multi && strcmp(argv[i], "--types") == 0)
334       {
335       i++;
336       if (i >= argc || argv[i][0] == '-')
337         {
338         return -1;
339         }
340       options.HierarchyFileName = argv[i];
341       }
342     else if (strcmp(argv[i], "--vtkobject") == 0 ||
343              strcmp(argv[i], "--special") == 0 ||
344              strcmp(argv[i], "--abstract") == 0 ||
345              strcmp(argv[i], "--concrete") == 0)
346       {
347       fprintf(stderr, "Warning: the %s option is deprecated "
348               "and will be ignored.\n", argv[i]);
349       }
350     }
351
352   return i;
353 }
354
355 /* Return a pointer to the static OptionInfo struct */
356 OptionInfo *vtkParse_GetCommandLineOptions()
357 {
358   return &options;
359 }
360
361 /* Command-line argument handler for wrapper tools */
362 FileInfo *vtkParse_Main(int argc, char *argv[])
363 {
364   int argi;
365   int expected_files;
366   FILE *ifile;
367   FILE *hfile = 0;
368   FileInfo *data;
369   StringCache strings;
370   int argn;
371   char **args;
372
373   /* expand any "@file" args */
374   vtkParse_InitStringCache(&strings);
375   parse_expand_args(&strings, argc, argv, &argn, &args);
376
377   /* read the args into the static OptionInfo struct */
378   argi = parse_check_options(argn, args, 0);
379
380   /* was output file already specified by the "-o" option? */
381   expected_files = (options.OutputFileName == NULL ? 2 : 1);
382
383   /* verify number of args, print usage if not valid */
384   if (argi == 0)
385     {
386     free(args);
387     exit(0);
388     }
389   else if (argi < 0 || options.NumberOfFiles != expected_files)
390     {
391     parse_print_help(stderr, args[0], 0);
392     exit(1);
393     }
394
395   /* open the input file */
396   options.InputFileName = options.Files[0];
397
398   if (!(ifile = fopen(options.InputFileName, "r")))
399     {
400     fprintf(stderr, "Error opening input file %s\n", options.InputFileName);
401     exit(1);
402     }
403
404   if (options.OutputFileName == NULL &&
405       options.NumberOfFiles > 1)
406     {
407     /* allow outfile to be given after infile, if "-o" option not used */
408     options.OutputFileName = options.Files[1];
409     fprintf(stderr, "Deprecated: specify output file with \"-o\".\n");
410     }
411
412   /* free the expanded args */
413   free(args);
414
415   /* open the hint file, if given on the command line */
416   if (options.HintFileName && options.HintFileName[0] != '\0')
417     {
418     if (!(hfile = fopen(options.HintFileName, "r")))
419       {
420       fprintf(stderr, "Error opening hint file %s\n", options.HintFileName);
421       fclose(ifile);
422       exit(1);
423       }
424     }
425
426   /* make sure than an output file was given on the command line */
427   if (options.OutputFileName == NULL)
428     {
429     fprintf(stderr, "No output file was specified\n");
430     fclose(ifile);
431     if (hfile)
432       {
433       fclose(hfile);
434       }
435     exit(1);
436     }
437
438   /* if a hierarchy is was given, then BTX/ETX can be ignored */
439   vtkParse_SetIgnoreBTX(0);
440   if (options.HierarchyFileName)
441     {
442     vtkParse_SetIgnoreBTX(1);
443     }
444
445   /* parse the input file */
446   data = vtkParse_ParseFile(options.InputFileName, ifile, stderr);
447
448   if (!data)
449     {
450     exit(1);
451     }
452
453   /* fill in some blanks by using the hints file */
454   if (hfile)
455     {
456     vtkParse_ReadHints(data, hfile, stderr);
457     }
458
459   if (data->MainClass)
460     {
461     /* mark class as abstract unless it has New() method */
462     int nfunc = data->MainClass->NumberOfFunctions;
463     int ifunc;
464     for (ifunc = 0; ifunc < nfunc; ifunc++)
465       {
466       FunctionInfo *func = data->MainClass->Functions[ifunc];
467       if (func && func->Access == VTK_ACCESS_PUBLIC &&
468           func->Name && strcmp(func->Name, "New") == 0 &&
469           func->NumberOfParameters == 0)
470         {
471         break;
472         }
473       }
474     data->MainClass->IsAbstract = ((ifunc == nfunc) ? 1 : 0);
475     }
476
477   return data;
478 }
479
480 /* Command-line argument handler for wrapper tools */
481 void vtkParse_MainMulti(int argc, char *argv[])
482 {
483   int argi;
484   int argn;
485   char **args;
486   StringCache strings;
487
488   /* expand any "@file" args */
489   vtkParse_InitStringCache(&strings);
490   parse_expand_args(&strings, argc, argv, &argn, &args);
491
492   /* read the args into the static OptionInfo struct */
493   argi = parse_check_options(argn, args, 1);
494   free(args);
495
496   if (argi == 0)
497     {
498     exit(0);
499     }
500   else if (argi < 0 || options.NumberOfFiles == 0)
501     {
502     parse_print_help(stderr, argv[0], 1);
503     exit(1);
504     }
505
506   /* the input file */
507   options.InputFileName = options.Files[0];
508 }