2 * Copyright (C) 1999-2007 Free Software Foundation, Inc.
4 * This file is part of GNU gengetopt
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)
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.
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.
33 #include "my_sstream.h"
35 #include "acceptedvalues.h"
39 #include "gengetopt.h"
40 #include "errorcodes.h"
44 extern int gengetopt_count_line;
45 extern char * gengetopt_input_filename;
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;
53 /// the last option parsed
54 static gengetopt_option *current_option = 0;
56 extern int yylex (void) ;
58 //#define YYERROR_VERBOSE 1
60 void check_result(int o, gengetopt_option *opt)
68 case NOT_ENOUGH_MEMORY:
69 yyerror (opt, "not enough memory");
72 err << "long option redefined \'" << opt->long_opt << "\'";
73 yyerror (opt, err.str().c_str());
75 case REQ_SHORT_OPTION:
76 err << "short option redefined \'" << opt->short_opt << "\'";
77 yyerror (opt, err.str().c_str());
80 yyerror (opt, "bug found!!");
83 yyerror (opt, "group undefined");
86 yyerror (opt, "mode undefined");
88 case INVALID_DEFAULT_VALUE:
89 yyerror (opt, "invalid default value");
91 case NOT_REQUESTED_TYPE:
92 yyerror (opt, "type specification not requested");
94 case NOT_VALID_SPECIFICATION:
95 yyerror (opt, "invalid specification for this kind of option");
97 case SPECIFY_FLAG_STAT:
98 yyerror (opt, "you must specify the default flag status");
100 case NOT_GROUP_OPTION:
101 yyerror (opt, "group specification for a non group option");
103 case NOT_MODE_OPTION:
104 yyerror (opt, "mode specification for an option not belonging to a mode");
107 yyerror (opt, "missing group specification");
110 yyerror (opt, "missing mode specification");
112 case INVALID_NUMERIC_VALUE:
113 yyerror (opt, "invalid numeric value");
115 case INVALID_ENUM_TYPE_USE:
116 yyerror (opt, "enum type can only be specified for options with values");
119 yyerror (opt, "if you want to redefine --help, please use option --no-help");
121 case VERSION_REDEFINED:
122 yyerror (opt, "if you want to redefine --version, please use option --no-version");
128 /* the number of allowed occurrences of a multiple option */
131 /* these strings are allocated dynamically and NOT
132 automatically freed upon destruction */
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))
144 #define check_error if (o) YYERROR;
153 class AcceptedValues *ValueList;
154 struct gengetopt_option *gengetopt_option;
155 struct multiple_size *multiple_size;
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"
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
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
206 %% /* ====================================================================== */
233 : TOK_PACKAGE TOK_STRING
235 if (gengetopt_package_given)
237 yyerror ("package redefined");
242 gengetopt_package_given = 1;
243 if (gengetopt_define_package ($2))
245 yyerror ("not enough memory");
253 : TOK_VERSION TOK_STRING
255 if (gengetopt_version_given)
257 yyerror ("version redefined");
262 gengetopt_version_given = 1;
263 if (gengetopt_define_version ($2))
265 yyerror ("not enough memory");
273 : TOK_PURPOSE quoted_string
275 if (gengetopt_purpose_given)
277 yyerror ("purpose redefined");
282 gengetopt_purpose_given = 1;
283 if (gengetopt_define_purpose ($2))
285 yyerror ("not enough memory");
293 : TOK_DESCRIPTION quoted_string
295 if (gengetopt_description_given)
297 yyerror ("description redefined");
302 gengetopt_description_given = 1;
303 if (gengetopt_define_description ($2))
305 yyerror ("not enough memory");
313 : TOK_USAGE quoted_string
315 if (gengetopt_usage_given)
317 yyerror ("usage redefined");
322 gengetopt_usage_given = 1;
323 if (gengetopt_define_usage ($2))
325 yyerror ("not enough memory");
334 : TOK_SECTION quoted_string opt_sectiondesc
336 gengetopt_set_section ($2, $3);
341 : TOK_TEXT quoted_string
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());
349 current_option->text_after = strdup($2);
352 gengetopt_set_text($2);
358 : TOK_ARGS TOK_STRING
360 gengetopt_set_args($2);
365 : TOK_DEFGROUP TOK_STRING opt_groupdesc optional_yesno
367 if (gengetopt_add_group ($2, $3, $4))
369 yyerror ("group redefined");
376 : TOK_DEFMODE TOK_STRING opt_modedesc
378 if (gengetopt_add_mode ($2, $3))
380 yyerror ("mode redefined");
387 : TOK_OPTION TOK_STRING TOK_CHAR quoted_string
390 $5->filename = gengetopt_input_filename;
391 $5->linenum = @1.first_line;
392 $5->long_opt = strdup($2);
395 $5->desc = strdup($4);
396 int o = gengetopt_check_option ($5, false);
399 o = gengetopt_add_option ($5);
407 : TOK_GROUPOPTION TOK_STRING TOK_CHAR quoted_string
410 $5->filename = gengetopt_input_filename;
411 $5->linenum = @1.first_line;
412 $5->long_opt = strdup($2);
415 $5->desc = strdup($4);
416 int o = gengetopt_check_option ($5, true);
419 o = gengetopt_add_option ($5);
426 : TOK_MODEOPTION TOK_STRING TOK_CHAR quoted_string
429 $5->filename = gengetopt_input_filename;
430 $5->linenum = @1.first_line;
431 $5->long_opt = strdup($2);
434 $5->desc = strdup($4);
435 int o = gengetopt_check_option ($5, false, true);
438 o = gengetopt_add_option ($5);
445 /* ---------------------------------------------------------------------- */
451 option_parts: option_parts opt_yesno
455 $$->required_set = true;
457 | option_parts TOK_ARGTYPE
462 | option_parts TOK_TYPESTR '=' TOK_STRING
465 $$->type_str = strdup($4);
467 | option_parts TOK_DETAILS '=' quoted_string
470 $$->details = strdup($4);
472 | option_parts TOK_VALUES '=' listofvalues
475 $$->acceptedvalues = $4;
477 | option_parts TOK_DEFAULT '=' TOK_STRING
480 $$->default_string = strdup($4);
482 | option_parts TOK_GROUP '=' TOK_STRING
485 $$->group_value = strdup($4);
487 | option_parts TOK_MODE '=' TOK_STRING
490 $$->mode_value = strdup($4);
492 | option_parts TOK_DEPENDON '=' TOK_STRING
495 $$->dependon = strdup($4);
497 | option_parts TOK_ARGOPTIONAL
500 $$->arg_is_optional = true;
502 | option_parts TOK_MULTIPLE multiple_size
506 $$->multiple_min = $3->min;
507 $$->multiple_max = $3->max;
510 | option_parts TOK_FLAG
515 | option_parts TOK_HIDDEN
520 | option_parts req_onoff
525 | { $$ = new gengetopt_option; }
530 | TOK_OFF { $$ = 0; }
534 : /* empty */ { $$ = 0; }
535 | TOK_YES { $$ = 1; }
540 : TOK_YES { $$ = 1; }
545 : /* empty */ { $$ = 0; }
546 | TOK_GROUPDESC '=' TOK_STRING { $$ = $3; }
550 : /* empty */ { $$ = 0; }
551 | TOK_MODEDESC '=' TOK_STRING { $$ = $3; }
555 : /* empty */ { $$ = 0; }
556 | TOK_SECTIONDESC '=' TOK_STRING { $$ = $3; }
560 : acceptedvalue { $$ = new AcceptedValues; $$->insert($1); }
561 | listofvalues ',' acceptedvalue { $1->insert($3); $$ = $1; }
565 : TOK_STRING { $$ = $1; }
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); }