]> Creatis software - clitk.git/blob - cmake/gengetopt/parser.yy
Added FindGengetopt.cmake which compiles gengetopt if not installed.
[clitk.git] / cmake / gengetopt / parser.yy
1 /**
2  * Copyright (C) 1999-2007  Free Software Foundation, Inc.
3  *
4  * This file is part of GNU gengetopt
5  *
6  * GNU gengetopt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  *
11  * GNU gengetopt is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14  * Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with gengetopt; see the file COPYING. If not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20
21
22 %{
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <string>
32
33 #include "my_sstream.h"
34
35 #include "acceptedvalues.h"
36
37 #include "argsdef.h"
38
39 #include "gengetopt.h"
40 #include "errorcodes.h"
41 #include "ggos.h"
42 #include "yyerror.h"
43
44 extern int gengetopt_count_line;
45 extern char * gengetopt_input_filename;
46
47 static int gengetopt_package_given = 0;
48 static int gengetopt_version_given = 0;
49 static int gengetopt_purpose_given = 0;
50 static int gengetopt_usage_given = 0;
51 static int gengetopt_description_given = 0;
52
53 /// the last option parsed
54 static gengetopt_option *current_option = 0;
55
56 extern int yylex (void) ;
57
58 //#define YYERROR_VERBOSE 1
59
60 void check_result(int o, gengetopt_option *opt)
61 {
62   if (o)
63     {
64         ostringstream err;
65
66     switch (o)
67     {
68     case NOT_ENOUGH_MEMORY:
69         yyerror (opt, "not enough memory");
70         break;
71     case REQ_LONG_OPTION:
72         err << "long option redefined \'" << opt->long_opt << "\'";
73         yyerror (opt, err.str().c_str());
74                 break;
75     case REQ_SHORT_OPTION:
76         err << "short option redefined \'" << opt->short_opt << "\'";
77         yyerror (opt, err.str().c_str());
78         break;
79     case FOUND_BUG:
80         yyerror (opt, "bug found!!");
81         break;
82     case GROUP_UNDEFINED:
83         yyerror (opt, "group undefined");
84         break;
85     case MODE_UNDEFINED:
86         yyerror (opt, "mode undefined");
87         break;
88     case INVALID_DEFAULT_VALUE:
89         yyerror (opt, "invalid default value");
90         break;
91     case NOT_REQUESTED_TYPE:
92         yyerror (opt, "type specification not requested");
93         break;
94     case NOT_VALID_SPECIFICATION:
95       yyerror (opt, "invalid specification for this kind of option");
96       break;
97     case SPECIFY_FLAG_STAT:
98       yyerror (opt, "you must specify the default flag status");
99       break;
100     case NOT_GROUP_OPTION:
101       yyerror (opt, "group specification for a non group option");
102       break;
103     case NOT_MODE_OPTION:
104       yyerror (opt, "mode specification for an option not belonging to a mode");
105       break;
106     case SPECIFY_GROUP:
107       yyerror (opt, "missing group specification");
108       break;
109     case SPECIFY_MODE:
110       yyerror (opt, "missing mode specification");
111       break;
112     case INVALID_NUMERIC_VALUE:
113         yyerror (opt, "invalid numeric value");
114         break;
115     case INVALID_ENUM_TYPE_USE:
116         yyerror (opt, "enum type can only be specified for options with values");
117         break;
118     case HELP_REDEFINED:
119         yyerror (opt, "if you want to redefine --help, please use option --no-help");
120         break;
121     case VERSION_REDEFINED:
122         yyerror (opt, "if you want to redefine --version, please use option --no-version");
123         break;
124     }
125   }
126 }
127
128 /* the number of allowed occurrences of a multiple option */
129 struct multiple_size
130 {
131     /* these strings are allocated dynamically and NOT
132       automatically freed upon destruction */
133     char *min;
134     char *max;
135
136     /* if no limit is specified then initialized to 0.
137        if the same size is specified for min and max, it means that an exact
138        number of occurrences is required*/
139     multiple_size(const char *m = "0", const char *M = "0") :
140         min(strdup(m)), max(strdup(M))
141     {}
142 };
143
144 #define check_error if (o) YYERROR;
145
146 %}
147
148 %union {
149     char   *str;
150     char    chr;
151     int     argtype;
152     int     boolean;
153     class AcceptedValues *ValueList;
154     struct gengetopt_option *gengetopt_option;
155     struct multiple_size *multiple_size;
156 }
157
158 %token              TOK_PACKAGE         "package"
159 %token              TOK_VERSION         "version"
160 %token              TOK_OPTION          "option"
161 %token              TOK_DEFGROUP        "defgroup"
162 %token              TOK_GROUPOPTION     "groupoption"
163 %token              TOK_DEFMODE         "defmode"
164 %token              TOK_MODEOPTION      "modeoption"
165 %token              TOK_YES             "yes"
166 %token              TOK_NO              "no"
167 %token              TOK_ON              "on"
168 %token              TOK_OFF             "off"
169 %token              TOK_FLAG            "flag"
170 %token              TOK_PURPOSE         "purpose"
171 %token              TOK_DESCRIPTION     "description"
172 %token              TOK_USAGE           "usage"
173 %token              TOK_DEFAULT         "default"
174 %token              TOK_GROUP           "group"
175 %token              TOK_GROUPDESC       "groupdesc"
176 %token              TOK_MODE            "mode"
177 %token              TOK_MODEDESC        "modedesc"
178 %token              TOK_MULTIPLE        "multiple"
179 %token              TOK_ARGOPTIONAL     "argoptional"
180 %token              TOK_TYPESTR         "typestr"
181 %token              TOK_SECTION         "section"
182 %token              TOK_DETAILS         "details"
183 %token              TOK_SECTIONDESC     "sectiondesc"
184 %token              TOK_TEXT            "text"
185 %token              TOK_ARGS            "args"
186 %token              TOK_VALUES          "values"
187 %token              TOK_HIDDEN      "hidden"
188 %token              TOK_DEPENDON      "dependon"
189 %token <str>        TOK_STRING
190 %token <chr>        TOK_CHAR
191 %token <argtype>    TOK_ARGTYPE
192 %token <str>        TOK_SIZE
193
194 %type  <boolean>    req_onoff
195 %type  <boolean>    opt_yesno optional_yesno
196 %type  <str>        quoted_string
197 %type  <str>        opt_groupdesc
198 %type  <str>        opt_sectiondesc
199 %type  <str>        opt_modedesc
200 %type  <ValueList>  listofvalues
201 %type  <str>        acceptedvalue
202 %type  <gengetopt_option> option_parts
203 %type  <multiple_size> multiple_size
204
205
206 %% /* ====================================================================== */
207
208
209 input
210         : /* empty */
211         | statement input
212         ;
213
214
215 statement
216         : package
217         | version
218         | args
219         | purpose
220         | description
221         | usage
222         | sectiondef
223         | option
224         | text
225         | groupoption
226         | groupdef
227         | modeoption
228         | modedef
229         ;
230
231
232 package
233         : TOK_PACKAGE TOK_STRING
234             {
235               if (gengetopt_package_given)
236                 {
237                   yyerror ("package redefined");
238                   YYERROR;
239                 }
240               else
241                 {
242                   gengetopt_package_given = 1;
243                   if (gengetopt_define_package ($2))
244                     {
245                       yyerror ("not enough memory");
246                       YYERROR;
247                     }
248                 }
249             }
250         ;
251
252 version
253         : TOK_VERSION TOK_STRING
254             {
255               if (gengetopt_version_given)
256                 {
257                   yyerror ("version redefined");
258                   YYERROR;
259                 }
260               else
261                 {
262                   gengetopt_version_given = 1;
263                   if (gengetopt_define_version ($2))
264                     {
265                       yyerror ("not enough memory");
266                       YYERROR;
267                     }
268                 }
269             }
270         ;
271
272 purpose
273         : TOK_PURPOSE quoted_string
274             {
275               if (gengetopt_purpose_given)
276                 {
277                   yyerror ("purpose redefined");
278                   YYERROR;
279                 }
280               else
281                 {
282                   gengetopt_purpose_given = 1;
283                   if (gengetopt_define_purpose ($2))
284                     {
285                       yyerror ("not enough memory");
286                       YYERROR;
287                     }
288                 }
289             }
290         ;
291
292 description
293         : TOK_DESCRIPTION quoted_string
294             {
295               if (gengetopt_description_given)
296                 {
297                   yyerror ("description redefined");
298                   YYERROR;
299                 }
300               else
301                 {
302                   gengetopt_description_given = 1;
303                   if (gengetopt_define_description ($2))
304                     {
305                       yyerror ("not enough memory");
306                       YYERROR;
307                     }
308                 }
309             }
310         ;
311
312 usage
313   : TOK_USAGE quoted_string
314   {
315       if (gengetopt_usage_given)
316       {
317           yyerror ("usage redefined");
318           YYERROR;
319       }
320       else
321       {
322           gengetopt_usage_given = 1;
323           if (gengetopt_define_usage ($2))
324           {
325               yyerror ("not enough memory");
326               YYERROR;
327           }
328       }
329   }
330         ;
331
332
333 sectiondef
334           : TOK_SECTION quoted_string opt_sectiondesc
335               {
336                 gengetopt_set_section ($2, $3);
337               }
338           ;
339
340 text
341   : TOK_TEXT quoted_string
342             {
343                 if (current_option) {
344                         std::string current_option_text;
345                         if (current_option->text_after) {
346                                 current_option_text = std::string(current_option->text_after) + $2;
347                                 current_option->text_after = strdup(current_option_text.c_str()); 
348                         } else {
349                                 current_option->text_after = strdup($2);
350                         }
351                 } else {
352                                         gengetopt_set_text($2);
353                                 }
354             }
355         ;
356
357 args
358   : TOK_ARGS TOK_STRING
359             {
360   gengetopt_set_args($2);
361             }
362         ;
363
364 groupdef
365         : TOK_DEFGROUP TOK_STRING opt_groupdesc optional_yesno
366             {
367               if (gengetopt_add_group ($2, $3, $4))
368                 {
369                         yyerror ("group redefined");
370                         YYERROR;
371                   }
372             }
373         ;
374
375 modedef
376         : TOK_DEFMODE TOK_STRING opt_modedesc
377             {
378               if (gengetopt_add_mode ($2, $3))
379                 {
380                         yyerror ("mode redefined");
381                         YYERROR;
382                   }
383             }
384         ;
385
386 option
387         : TOK_OPTION TOK_STRING TOK_CHAR quoted_string
388                 option_parts
389             {
390           $5->filename = gengetopt_input_filename;
391           $5->linenum = @1.first_line;
392               $5->long_opt = strdup($2);
393               if ($3 != '-')
394                 $5->short_opt = $3;
395               $5->desc = strdup($4);
396               int o = gengetopt_check_option ($5, false);
397               check_result(o, $5);
398           check_error;
399               o = gengetopt_add_option ($5);
400               check_result(o, $5);
401               check_error;
402               current_option = $5;
403             }
404         ;
405
406 groupoption
407         : TOK_GROUPOPTION TOK_STRING TOK_CHAR quoted_string
408                 option_parts
409             {
410           $5->filename = gengetopt_input_filename;
411           $5->linenum = @1.first_line;
412               $5->long_opt = strdup($2);
413           if ($3 != '-')
414             $5->short_opt = $3;
415           $5->desc = strdup($4);
416           int o = gengetopt_check_option ($5, true);
417           check_result(o, $5);
418           check_error;
419           o = gengetopt_add_option ($5);
420           check_result(o, $5);
421           check_error;
422             }
423         ;
424
425 modeoption
426         : TOK_MODEOPTION TOK_STRING TOK_CHAR quoted_string
427                 option_parts
428             {
429           $5->filename = gengetopt_input_filename;
430           $5->linenum = @1.first_line;
431               $5->long_opt = strdup($2);
432           if ($3 != '-')
433             $5->short_opt = $3;
434           $5->desc = strdup($4);
435           int o = gengetopt_check_option ($5, false, true);
436           check_result(o, $5);
437           check_error;
438           o = gengetopt_add_option ($5);
439           check_result(o, $5);
440           check_error;
441             }
442         ;
443
444
445 /* ---------------------------------------------------------------------- */
446
447 quoted_string
448         : TOK_STRING
449         ;
450
451 option_parts: option_parts opt_yesno
452                           {
453                                 $$ = $1;
454                                 $$->required = $2;
455                                 $$->required_set = true;
456                           }
457                         | option_parts TOK_ARGTYPE
458                           {
459                                 $$ = $1;
460                                 $$->type = $2;
461                           }
462                         | option_parts TOK_TYPESTR '=' TOK_STRING
463                           {
464                                 $$ = $1;
465                                 $$->type_str = strdup($4);
466                           }
467                         | option_parts TOK_DETAILS '=' quoted_string
468                           {
469                                 $$ = $1;
470                                 $$->details = strdup($4);
471                           }
472                         | option_parts TOK_VALUES '=' listofvalues
473                           {
474                                 $$ = $1;
475                                 $$->acceptedvalues = $4;
476                           }
477                         | option_parts TOK_DEFAULT '=' TOK_STRING
478                           {
479                                 $$ = $1;
480                                 $$->default_string = strdup($4);
481                           }
482             | option_parts TOK_GROUP '=' TOK_STRING
483               {
484                 $$ = $1;
485                 $$->group_value = strdup($4);
486               }
487             | option_parts TOK_MODE '=' TOK_STRING
488               {
489                 $$ = $1;
490                 $$->mode_value = strdup($4);
491               }
492             | option_parts TOK_DEPENDON '=' TOK_STRING
493               {
494                 $$ = $1;
495                 $$->dependon = strdup($4);
496               }
497                         | option_parts TOK_ARGOPTIONAL
498                           {
499                                 $$ = $1;
500                                 $$->arg_is_optional = true;
501                           }
502                         | option_parts TOK_MULTIPLE multiple_size
503                           {
504                                 $$ = $1;
505                                 $$->multiple = true;
506                 $$->multiple_min = $3->min;
507                 $$->multiple_max = $3->max;
508                 delete $3;
509                           }
510       | option_parts TOK_FLAG
511         {
512           $$ = $1;
513           $$->type = ARG_FLAG;
514         }
515       | option_parts TOK_HIDDEN
516         {
517           $$ = $1;
518           $$->hidden = true;
519         }
520       | option_parts req_onoff
521         {
522           $$ = $1;
523           $$->flagstat = $2;
524         }
525       | { $$ = new gengetopt_option; }
526       ;
527
528 req_onoff
529         : TOK_ON        { $$ = 1; }
530         | TOK_OFF       { $$ = 0; }
531         ;
532
533 optional_yesno
534         : /* empty */   { $$ = 0; }
535         | TOK_YES       { $$ = 1; }
536         | TOK_NO        { $$ = 0; }
537         ;
538
539 opt_yesno
540     : TOK_YES   { $$ = 1; }
541     | TOK_NO    { $$ = 0; }
542     ;
543
544 opt_groupdesc
545         : /* empty */                   { $$ = 0; }
546         | TOK_GROUPDESC '=' TOK_STRING  { $$ = $3; }
547         ;
548
549 opt_modedesc
550         : /* empty */                   { $$ = 0; }
551         | TOK_MODEDESC '=' TOK_STRING   { $$ = $3; }
552         ;
553
554 opt_sectiondesc
555         : /* empty */                   { $$ = 0; }
556         | TOK_SECTIONDESC '=' TOK_STRING        { $$ = $3; }
557         ;
558
559 listofvalues
560         : acceptedvalue { $$ = new AcceptedValues; $$->insert($1); }
561         | listofvalues ',' acceptedvalue { $1->insert($3); $$ = $1; }
562         ;
563
564 acceptedvalue
565         : TOK_STRING { $$ = $1; }
566         ;
567
568 multiple_size
569     : { $$ = new multiple_size; }
570     | '(' TOK_SIZE ')' { $$ = new multiple_size($2, $2); }
571     | '(' TOK_SIZE '-' ')' { $$ = new multiple_size($2, "0"); free($2); }
572     | '(' '-' TOK_SIZE  ')' { $$ = new multiple_size("0", $3); free($3); }
573     | '(' TOK_SIZE '-' TOK_SIZE  ')' { $$ = new multiple_size($2, $4); free($2); free($4); }
574     ;
575
576 %%