From: helly Date: Mon, 19 Apr 2004 21:14:46 +0000 (+0000) Subject: Add -- style options. X-Git-Tag: 0.13.6~717 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fe0c61a895acc34bfe3279c2c037dfbede82ffdf;p=re2c Add -- style options. --- diff --git a/Makefile.am b/Makefile.am index 4f39850f..eb43ca64 100755 --- a/Makefile.am +++ b/Makefile.am @@ -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 901e3454..02c2d3b3 100644 --- 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 = ""; 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 index 00000000..89f5b291 --- /dev/null +++ b/mbo_getopt.cc @@ -0,0 +1,142 @@ +/* + Author: Marcus Boerger +*/ + +/* $Id$ */ + +#include +#include +#include +#include +#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 - or in the form - */ + 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 index 00000000..3a8dc2f4 --- /dev/null +++ b/mbo_getopt.h @@ -0,0 +1,16 @@ +/* + Author: Marcus Boerger +*/ + +/* $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);