]> Creatis software - clitk.git/blobdiff - utilities/gengetopt/parser.yy
Sync gengetopt cmake files with rtk
[clitk.git] / utilities / gengetopt / parser.yy
diff --git a/utilities/gengetopt/parser.yy b/utilities/gengetopt/parser.yy
new file mode 100644 (file)
index 0000000..d0a60e0
--- /dev/null
@@ -0,0 +1,576 @@
+/**
+ * Copyright (C) 1999-2007  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+%{
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <string>
+
+#include "my_sstream.h"
+
+#include "acceptedvalues.h"
+
+#include "argsdef.h"
+
+#include "gengetopt.h"
+#include "errorcodes.h"
+#include "ggos.h"
+#include "yyerror.h"
+
+extern int gengetopt_count_line;
+extern char * gengetopt_input_filename;
+
+static int gengetopt_package_given = 0;
+static int gengetopt_version_given = 0;
+static int gengetopt_purpose_given = 0;
+static int gengetopt_usage_given = 0;
+static int gengetopt_description_given = 0;
+
+/// the last option parsed
+static gengetopt_option *current_option = 0;
+
+extern int yylex (void) ;
+
+//#define YYERROR_VERBOSE 1
+
+void check_result(int o, gengetopt_option *opt)
+{
+  if (o)
+    {
+        ostringstream err;
+
+    switch (o)
+    {
+    case NOT_ENOUGH_MEMORY:
+        yyerror (opt, "not enough memory");
+       break;
+    case REQ_LONG_OPTION:
+        err << "long option redefined \'" << opt->long_opt << "\'";
+        yyerror (opt, err.str().c_str());
+               break;
+    case REQ_SHORT_OPTION:
+        err << "short option redefined \'" << opt->short_opt << "\'";
+        yyerror (opt, err.str().c_str());
+        break;
+    case FOUND_BUG:
+        yyerror (opt, "bug found!!");
+        break;
+    case GROUP_UNDEFINED:
+        yyerror (opt, "group undefined");
+        break;
+    case MODE_UNDEFINED:
+        yyerror (opt, "mode undefined");
+        break;
+    case INVALID_DEFAULT_VALUE:
+        yyerror (opt, "invalid default value");
+        break;
+    case NOT_REQUESTED_TYPE:
+        yyerror (opt, "type specification not requested");
+        break;
+    case NOT_VALID_SPECIFICATION:
+      yyerror (opt, "invalid specification for this kind of option");
+      break;
+    case SPECIFY_FLAG_STAT:
+      yyerror (opt, "you must specify the default flag status");
+      break;
+    case NOT_GROUP_OPTION:
+      yyerror (opt, "group specification for a non group option");
+      break;
+    case NOT_MODE_OPTION:
+      yyerror (opt, "mode specification for an option not belonging to a mode");
+      break;
+    case SPECIFY_GROUP:
+      yyerror (opt, "missing group specification");
+      break;
+    case SPECIFY_MODE:
+      yyerror (opt, "missing mode specification");
+      break;
+    case INVALID_NUMERIC_VALUE:
+        yyerror (opt, "invalid numeric value");
+        break;
+    case INVALID_ENUM_TYPE_USE:
+       yyerror (opt, "enum type can only be specified for options with values");
+        break;
+    case HELP_REDEFINED:
+       yyerror (opt, "if you want to redefine --help, please use option --no-help");
+        break;
+    case VERSION_REDEFINED:
+       yyerror (opt, "if you want to redefine --version, please use option --no-version");
+        break;
+    }
+  }
+}
+
+/* the number of allowed occurrences of a multiple option */
+struct multiple_size
+{
+    /* these strings are allocated dynamically and NOT
+      automatically freed upon destruction */
+    char *min;
+    char *max;
+
+    /* if no limit is specified then initialized to 0.
+       if the same size is specified for min and max, it means that an exact
+       number of occurrences is required*/
+    multiple_size(const char *m = "0", const char *M = "0") :
+        min(strdup(m)), max(strdup(M))
+    {}
+};
+
+#define check_error if (o) YYERROR;
+
+%}
+
+%union {
+    char   *str;
+    char    chr;
+    int            argtype;
+    int            boolean;
+    class AcceptedValues *ValueList;
+    struct gengetopt_option *gengetopt_option;
+    struct multiple_size *multiple_size;
+}
+
+%token             TOK_PACKAGE         "package"
+%token              TOK_VERSION                "version"
+%token              TOK_OPTION         "option"
+%token              TOK_DEFGROUP       "defgroup"
+%token              TOK_GROUPOPTION    "groupoption"
+%token              TOK_DEFMODE                "defmode"
+%token              TOK_MODEOPTION     "modeoption"
+%token              TOK_YES            "yes"
+%token              TOK_NO             "no"
+%token              TOK_ON             "on"
+%token              TOK_OFF            "off"
+%token              TOK_FLAG           "flag"
+%token              TOK_PURPOSE                "purpose"
+%token              TOK_DESCRIPTION    "description"
+%token              TOK_USAGE          "usage"
+%token              TOK_DEFAULT                "default"
+%token              TOK_GROUP          "group"
+%token              TOK_GROUPDESC      "groupdesc"
+%token              TOK_MODE           "mode"
+%token              TOK_MODEDESC       "modedesc"
+%token              TOK_MULTIPLE       "multiple"
+%token              TOK_ARGOPTIONAL    "argoptional"
+%token              TOK_TYPESTR                "typestr"
+%token              TOK_SECTION                "section"
+%token              TOK_DETAILS                "details"
+%token              TOK_SECTIONDESC    "sectiondesc"
+%token              TOK_TEXT           "text"
+%token              TOK_ARGS           "args"
+%token              TOK_VALUES          "values"
+%token              TOK_HIDDEN      "hidden"
+%token              TOK_DEPENDON      "dependon"
+%token <str>        TOK_STRING
+%token <chr>        TOK_CHAR
+%token <argtype>    TOK_ARGTYPE
+%token <str>        TOK_SIZE
+
+%type  <boolean>    req_onoff
+%type  <boolean>    opt_yesno optional_yesno
+%type  <str>        quoted_string
+%type  <str>        opt_groupdesc
+%type  <str>        opt_sectiondesc
+%type  <str>        opt_modedesc
+%type  <ValueList>  listofvalues
+%type  <str>        acceptedvalue
+%type  <gengetopt_option> option_parts
+%type  <multiple_size> multiple_size
+
+
+%% /* ====================================================================== */
+
+
+input
+       : /* empty */
+       | statement input
+       ;
+
+
+statement
+       : package
+       | version
+       | args
+       | purpose
+       | description
+       | usage
+       | sectiondef
+       | option
+       | text
+       | groupoption
+       | groupdef
+       | modeoption
+       | modedef
+       ;
+
+
+package
+       : TOK_PACKAGE TOK_STRING
+           {
+             if (gengetopt_package_given)
+               {
+                 yyerror ("package redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_package_given = 1;
+                 if (gengetopt_define_package ($2))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+       ;
+
+version
+       : TOK_VERSION TOK_STRING
+           {
+             if (gengetopt_version_given)
+               {
+                 yyerror ("version redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_version_given = 1;
+                 if (gengetopt_define_version ($2))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+       ;
+
+purpose
+       : TOK_PURPOSE quoted_string
+           {
+             if (gengetopt_purpose_given)
+               {
+                 yyerror ("purpose redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_purpose_given = 1;
+                 if (gengetopt_define_purpose ($2))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+       ;
+
+description
+       : TOK_DESCRIPTION quoted_string
+           {
+             if (gengetopt_description_given)
+               {
+                 yyerror ("description redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_description_given = 1;
+                 if (gengetopt_define_description ($2))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+       ;
+
+usage
+  : TOK_USAGE quoted_string
+  {
+      if (gengetopt_usage_given)
+      {
+         yyerror ("usage redefined");
+         YYERROR;
+      }
+      else
+      {
+         gengetopt_usage_given = 1;
+         if (gengetopt_define_usage ($2))
+          {
+             yyerror ("not enough memory");
+             YYERROR;
+          }
+      }
+  }
+        ;
+
+
+sectiondef
+          : TOK_SECTION quoted_string opt_sectiondesc
+              {
+                gengetopt_set_section ($2, $3);
+              }
+          ;
+
+text
+  : TOK_TEXT quoted_string
+            {
+               if (current_option) {
+                       std::string current_option_text;
+                       if (current_option->text_after) {
+                               current_option_text = std::string(current_option->text_after) + $2;
+                               current_option->text_after = strdup(current_option_text.c_str()); 
+                       } else {
+                               current_option->text_after = strdup($2);
+                       }
+               } else {
+                                       gengetopt_set_text($2);
+                               }
+            }
+        ;
+
+args
+  : TOK_ARGS TOK_STRING
+            {
+  gengetopt_set_args($2);
+            }
+        ;
+
+groupdef
+       : TOK_DEFGROUP TOK_STRING opt_groupdesc optional_yesno
+           {
+              if (gengetopt_add_group ($2, $3, $4))
+                {
+                       yyerror ("group redefined");
+                       YYERROR;
+                 }
+           }
+       ;
+
+modedef
+       : TOK_DEFMODE TOK_STRING opt_modedesc
+           {
+              if (gengetopt_add_mode ($2, $3))
+                {
+                       yyerror ("mode redefined");
+                       YYERROR;
+                 }
+           }
+       ;
+
+option
+       : TOK_OPTION TOK_STRING TOK_CHAR quoted_string
+               option_parts
+           {
+          $5->filename = gengetopt_input_filename;
+          $5->linenum = @1.first_line;
+             $5->long_opt = strdup($2);
+             if ($3 != '-')
+               $5->short_opt = $3;
+             $5->desc = strdup($4);
+             int o = gengetopt_check_option ($5, false);
+             check_result(o, $5);
+          check_error;
+             o = gengetopt_add_option ($5);
+             check_result(o, $5);
+             check_error;
+             current_option = $5;
+           }
+       ;
+
+groupoption
+       : TOK_GROUPOPTION TOK_STRING TOK_CHAR quoted_string
+                option_parts
+           {
+          $5->filename = gengetopt_input_filename;
+          $5->linenum = @1.first_line;
+             $5->long_opt = strdup($2);
+          if ($3 != '-')
+            $5->short_opt = $3;
+          $5->desc = strdup($4);
+          int o = gengetopt_check_option ($5, true);
+          check_result(o, $5);
+          check_error;
+          o = gengetopt_add_option ($5);
+          check_result(o, $5);
+          check_error;
+           }
+        ;
+
+modeoption
+       : TOK_MODEOPTION TOK_STRING TOK_CHAR quoted_string
+                option_parts
+           {
+          $5->filename = gengetopt_input_filename;
+          $5->linenum = @1.first_line;
+             $5->long_opt = strdup($2);
+          if ($3 != '-')
+            $5->short_opt = $3;
+          $5->desc = strdup($4);
+          int o = gengetopt_check_option ($5, false, true);
+          check_result(o, $5);
+          check_error;
+          o = gengetopt_add_option ($5);
+          check_result(o, $5);
+          check_error;
+           }
+        ;
+
+
+/* ---------------------------------------------------------------------- */
+
+quoted_string
+       : TOK_STRING
+       ;
+
+option_parts: option_parts opt_yesno
+                         {
+                               $$ = $1;
+                               $$->required = $2;
+                               $$->required_set = true;
+                         }
+                       | option_parts TOK_ARGTYPE
+                         {
+                               $$ = $1;
+                               $$->type = $2;
+                         }
+                       | option_parts TOK_TYPESTR '=' TOK_STRING
+                         {
+                               $$ = $1;
+                               $$->type_str = strdup($4);
+                         }
+                       | option_parts TOK_DETAILS '=' quoted_string
+                         {
+                               $$ = $1;
+                               $$->details = strdup($4);
+                         }
+                       | option_parts TOK_VALUES '=' listofvalues
+                         {
+                               $$ = $1;
+                               $$->acceptedvalues = $4;
+                         }
+                       | option_parts TOK_DEFAULT '=' TOK_STRING
+                         {
+                               $$ = $1;
+                               $$->default_string = strdup($4);
+                         }
+            | option_parts TOK_GROUP '=' TOK_STRING
+              {
+                $$ = $1;
+                $$->group_value = strdup($4);
+              }
+            | option_parts TOK_MODE '=' TOK_STRING
+              {
+                $$ = $1;
+                $$->mode_value = strdup($4);
+              }
+            | option_parts TOK_DEPENDON '=' TOK_STRING
+              {
+                $$ = $1;
+                $$->dependon = strdup($4);
+              }
+                       | option_parts TOK_ARGOPTIONAL
+                         {
+                               $$ = $1;
+                               $$->arg_is_optional = true;
+                         }
+                       | option_parts TOK_MULTIPLE multiple_size
+                         {
+                               $$ = $1;
+                               $$->multiple = true;
+                $$->multiple_min = $3->min;
+                $$->multiple_max = $3->max;
+                delete $3;
+                         }
+      | option_parts TOK_FLAG
+        {
+          $$ = $1;
+          $$->type = ARG_FLAG;
+        }
+      | option_parts TOK_HIDDEN
+        {
+          $$ = $1;
+          $$->hidden = true;
+        }
+      | option_parts req_onoff
+        {
+          $$ = $1;
+          $$->flagstat = $2;
+        }
+      | { $$ = new gengetopt_option; }
+      ;
+
+req_onoff
+       : TOK_ON        { $$ = 1; }
+       | TOK_OFF       { $$ = 0; }
+       ;
+
+optional_yesno
+       : /* empty */   { $$ = 0; }
+       | TOK_YES       { $$ = 1; }
+       | TOK_NO        { $$ = 0; }
+       ;
+
+opt_yesno
+    : TOK_YES   { $$ = 1; }
+    | TOK_NO    { $$ = 0; }
+    ;
+
+opt_groupdesc
+       : /* empty */                   { $$ = 0; }
+        | TOK_GROUPDESC '=' TOK_STRING { $$ = $3; }
+       ;
+
+opt_modedesc
+       : /* empty */                   { $$ = 0; }
+        | TOK_MODEDESC '=' TOK_STRING  { $$ = $3; }
+       ;
+
+opt_sectiondesc
+        : /* empty */                  { $$ = 0; }
+        | TOK_SECTIONDESC '=' TOK_STRING       { $$ = $3; }
+        ;
+
+listofvalues
+        : acceptedvalue { $$ = new AcceptedValues; $$->insert($1); }
+        | listofvalues ',' acceptedvalue { $1->insert($3); $$ = $1; }
+        ;
+
+acceptedvalue
+        : TOK_STRING { $$ = $1; }
+        ;
+
+multiple_size
+    : { $$ = new multiple_size; }
+    | '(' TOK_SIZE ')' { $$ = new multiple_size($2, $2); }
+    | '(' TOK_SIZE '-' ')' { $$ = new multiple_size($2, "0"); free($2); }
+    | '(' '-' TOK_SIZE  ')' { $$ = new multiple_size("0", $3); free($3); }
+    | '(' TOK_SIZE '-' TOK_SIZE  ')' { $$ = new multiple_size($2, $4); free($2); free($4); }
+    ;
+
+%%