gzdoom/tools/re2c/mbo_getopt.cc
Randy Heit ec17f5a5b9 - Undid some of the changes from lempar.c v1.30->v1.31, because it broke
error handling.
- Fixed: dehsupp/scanner.re defined "}" as the token RPAREN. dehsupp/parse.y
  also defined action_list_def as needing a RBARCE. I'm surprised it worked
  at all before. I guess Lemon really was too accepting.
- Changed the way that xlatcc handles include statements so that I don't need
  to modify the logic of lempar.c. I also discovered that the grammar was
  improperly defined and only accepted the first statement. It worked before
  because Lemon used to accept multiple times before reaching the EOF token.
  I have also verified that it is still generating the proper lumps.
- Removed some unused wadsrc files from the repository.
- Fixed my re2c upgrade.
- Updated lemon.c to v1.53.

SVN r711 (trunk)
2008-01-26 04:33:34 +00:00

210 lines
3.5 KiB
C++

/*
Author: Marcus Boerger <helly@users.sourceforge.net>
*/
/* $Id: mbo_getopt.cc 698 2007-04-23 21:06:56Z helly $ */
#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)
namespace re2c
{
static int mbo_opt_error(int, 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 */
if (argv[*optind][2] == '\0') {
(*optind)++;
return(EOF);
}
while (1)
{
opts_idx++;
if (opts[opts_idx].opt_char == '-')
{
(*optind)++;
return (mbo_opt_error(argc, argv, *optind - 1, optchr, OPTERRARG, show_err));
}
else if (opts[opts_idx].opt_name && !strcmp(&argv[*optind][2], opts[opts_idx].opt_name))
{
break;
}
}
optchr = 0;
dash = 0;
arg_start = 2 + strlen(opts[opts_idx].opt_name);
}
else
{
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));
}
arg_start = 1 + optchr;
}
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++;
arg_start++;
}
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 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-')))
{
if (!argv[*optind][optchr + 1])
{
dash = 0;
(*optind)++;
}
else
{
optchr++;
}
}
else
{
(*optind)++;
}
return opts[opts_idx].opt_char;
}
assert(0);
return (0); /* never reached */
}
} // end namespace re2c