]> granicus.if.org Git - re2c/commitdiff
Add -- style options.
authorhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Mon, 19 Apr 2004 21:14:46 +0000 (21:14 +0000)
committerhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Mon, 19 Apr 2004 21:14:46 +0000 (21:14 +0000)
Makefile.am
main.cc
mbo_getopt.cc [new file with mode: 0755]
mbo_getopt.h [new file with mode: 0755]

index 4f39850fac404cfd497ce83831333adfb627de05..eb43ca641dea8d272fd0828620a5e150b31d5f65 100755 (executable)
@@ -2,7 +2,7 @@
 
 bin_PROGRAMS = re2c
 re2c_SOURCES = code.cc dfa.cc main.cc parser.cc actions.cc scanner.re substr.cc\
-       translate.cc scanner.cc \
+       translate.cc scanner.cc mbo_getopt.cc \
        basics.h dfa.h globals.h ins.h parser.h re.h scanner.h \
        substr.h token.h
 man_MANS     = re2c.1
diff --git a/main.cc b/main.cc
index 901e3454b3b48e9a38599bb4331918da939da9cf..02c2d3b3619608f40cb1dcdcfbe42d596bb61070 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -12,6 +12,7 @@
 #include "globals.h"
 #include "parser.h"
 #include "dfa.h"
+#include "mbo_getopt.h"
 
 char *fileName;
 bool sFlag = false;
@@ -20,59 +21,83 @@ unsigned int oline = 1;
 
 using namespace std;
 
-int main(unsigned argc, char *argv[])
+static char *opt_arg = NULL;
+static int opt_ind = 1;
+
+static const mbo_opt_struct OPTIONS[] = {
+       {'?', 0, "help"},
+       {'b', 0, "bit-vectors"},
+       {'e', 0, "ecb"},
+       {'h', 0, "help"},
+       {'s', 0, "nested-ifs"},
+       {'v', 0, "version"}
+};
+
+int main(int argc, char *argv[])
 {
+       int c;
     fileName = NULL;
+    outputFileName = NULL;
+
     if (argc == 1) {
                goto usage;
        }
-    while(--argc > 1) {
-               char *p = *++argv;
-               if (*p != '-' || *(p+1) == '\0') {
+
+       while ((c = mbo_getopt(argc, argv, OPTIONS, &opt_arg, &opt_ind, 0))!=-1) {
+               switch (c) {
+           case '?':
+                       goto usage;
+           case 'b':
+                       sFlag = true;
+                       bFlag = true;
+                       break;
+           case 'e':
+                       xlat = asc2ebc;
+                       talx = ebc2asc;
+                       break;
+           case 'h':
+                       goto usage;
+               case 'f':
+                       outputFileName = opt_arg;
+                       break;
+           case 's':
+                       sFlag = true;
+                       break;
+               case 'v':
+                       goto version;
+               default:
                        goto usage;
                }
-               while (*++p != '\0') {
-                   switch(*p){
-                   case 'e':
-                               xlat = asc2ebc;
-                               talx = ebc2asc;
-                               break;
-                   case 's':
-                               sFlag = true;
-                               break;
-                   case 'b':
-                               sFlag = true;
-                               bFlag = true;
-                               break;
-                       case '-':
-                               if (!strcmp(p, "-version")) {
-                                       goto version;
-                               }
-                               goto usage;
-                   default:
-                               goto usage;
-                   }
-               }
-    }
-    fileName = *++argv;
-    if (!strcmp(fileName, "--version")) {
-       goto version;
-    }
+       }
+
+       if (argc == opt_ind + 1)
+       {
+               fileName = argv[opt_ind];
+       }
+       else
+       {
+               goto usage;
+       }
+
     int fd;
-    if (fileName[0] == '-' && fileName[1] == '\0') {
+    if (fileName[0] == '-' && fileName[1] == '\0')
+    {
                fileName = "<stdin>";
                fd = 0;
-    } else {
-               if ((fd = open(fileName, O_RDONLY)) < 0) {
+    }
+    else
+    {
+               if ((fd = open(fileName, O_RDONLY)) < 0)
+               {
                    cerr << "can't open " << fileName << "\n";
                    return 1;
                }
     }
-    parse(fd, cout);
+       parse(fd, cout);
     return 0;
 
 usage:
-    cerr << "usage: re2c [-esb] name\n";
+    cerr << "usage: re2c [-esbvh] file\n";
     return 2;
 
 version:
diff --git a/mbo_getopt.cc b/mbo_getopt.cc
new file mode 100755 (executable)
index 0000000..89f5b29
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+   Author: Marcus Boerger <helly@users.sourceforge.net>
+*/
+
+/* $Id$ */
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include "mbo_getopt.h"
+#define OPTERRCOLON (1)
+#define OPTERRNF (2)
+#define OPTERRARG (3)
+
+
+static int mbo_opt_error(int argc, char * const *argv, int oint, int optchr, int err, int show_err)
+{
+       if (show_err)
+       {
+               fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
+               switch(err)
+               {
+               case OPTERRCOLON:
+                       fprintf(stderr, ": in flags\n");
+                       break;
+               case OPTERRNF:
+                       fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
+                       break;
+               case OPTERRARG:
+                       fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
+                       break;
+               default:
+                       fprintf(stderr, "unknown\n");
+                       break;
+               }
+       }
+       return('?');
+}
+
+int mbo_getopt(int argc, char* const *argv, const mbo_opt_struct opts[], char **optarg, int *optind, int show_err)
+{
+       static int optchr = 0;
+       static int dash = 0; /* have already seen the - */
+       int arg_start = 2;
+
+       int opts_idx = -1;
+
+       if (*optind >= argc) {
+               return(EOF);
+       }
+       if (!dash) {
+               if ((argv[*optind][0] !=  '-')) {
+                       return(EOF);
+               } else {
+                       if (!argv[*optind][1])
+                       {
+                               /*
+                               * use to specify stdin. Need to let pgm process this and
+                               * the following args
+                               */
+                               return(EOF);
+                       }
+               }
+       }
+       if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) {
+               /* '--' indicates end of args if not followed by a known long option name */
+               while (1) {
+                       opts_idx++;
+                       if (opts[opts_idx].opt_char == '-') {
+                               (*optind)++;
+                               return(EOF);
+                       } else if (opts[opts_idx].opt_name && !strcmp(&argv[*optind][2], opts[opts_idx].opt_name)) {
+                               break;
+                       }
+               }
+               optchr = 0;
+               dash = 1;
+               arg_start = 2 + strlen(opts[opts_idx].opt_name);
+       }
+       if (!dash) {
+               dash = 1;
+               optchr = 1;
+       }
+
+       /* Check if the guy tries to do a -: kind of flag */
+       if (argv[*optind][optchr] == ':') {
+               dash = 0;
+               (*optind)++;
+               return (mbo_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
+       }
+       if (opts_idx < 0) {
+               while (1) {
+                       opts_idx++;
+                       if (opts[opts_idx].opt_char == '-') {
+                               int errind = *optind;
+                               int errchr = optchr;
+               
+                               if (!argv[*optind][optchr+1]) {
+                                       dash = 0;
+                                       (*optind)++;
+                               } else {
+                                       optchr++;
+                               }
+                               return(mbo_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
+                       } else if (argv[*optind][optchr] == opts[opts_idx].opt_char) {
+                               break;
+                       }
+               }
+       }
+       if (opts[opts_idx].need_param) {
+               /* Check for cases where the value of the argument
+               is in the form -<arg> <val> or in the form -<arg><val> */
+               dash = 0;
+               if(!argv[*optind][arg_start]) {
+                       (*optind)++;
+                       if (*optind == argc) {
+                               return(mbo_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
+                       }
+                       *optarg = argv[(*optind)++];
+               } else {
+                       *optarg = &argv[*optind][arg_start];
+                       (*optind)++;
+               }
+               return opts[opts_idx].opt_char;
+       } else {
+               if (arg_start == 2) {
+                       if (!argv[*optind][optchr+1])
+                       {
+                               dash = 0;
+                               (*optind)++;
+                       } else {
+                               optchr++;
+                       }
+               } else {
+                       (*optind)++;
+               }
+               return opts[opts_idx].opt_char;
+       }
+       assert(0);
+       return(0);      /* never reached */
+}
diff --git a/mbo_getopt.h b/mbo_getopt.h
new file mode 100755 (executable)
index 0000000..3a8dc2f
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+   Author: Marcus Boerger <helly@users.sourceforge.net>
+*/
+
+/* $Id$ */
+
+/* Define structure for one recognized option (both single char and long name).
+ * If short_open is '-' this is the last option.
+ */
+typedef struct _mbo_opt_struct {
+       const char opt_char;
+       const int  need_param;
+       const char * opt_name;
+} mbo_opt_struct;
+
+int mbo_getopt(int argc, char* const *argv, const mbo_opt_struct opts[], char **optarg, int *optind, int show_err);