From 99b4921309f4651725ffe7e27fc69c6b703eaa8f Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Thu, 5 Aug 2010 15:06:03 +0200 Subject: [PATCH 1/2] New ACC version. --- src/miniacc.h | 272 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 253 insertions(+), 19 deletions(-) diff --git a/src/miniacc.h b/src/miniacc.h index 1d53268a..68b5172c 100644 --- a/src/miniacc.h +++ b/src/miniacc.h @@ -41,7 +41,7 @@ #ifndef __ACC_H_INCLUDED #define __ACC_H_INCLUDED 1 -#define ACC_VERSION 20100419L +#define ACC_VERSION 20100805L #if defined(__CYGWIN32__) && !defined(__CYGWIN__) # define __CYGWIN__ __CYGWIN32__ #endif @@ -4071,12 +4071,13 @@ struct acc_getopt_longopt_t { }; struct acc_getopt_t { void *user; + const char *progname; + int bad_option; char *optarg; void (*opterr)(acc_getopt_p, const char*, void *); int optind; int optopt; int errcount; - const char* progname; int argc; char** argv; int eof; int shortpos; int pending_rotate_first, pending_rotate_middle; @@ -5336,6 +5337,239 @@ ACCLIB_PUBLIC(int, acc_dos_free) (void __far* p) } #endif #endif +#if defined(ACC_WANT_ACCLIB_GETOPT) +# undef ACC_WANT_ACCLIB_GETOPT +#define __ACCLIB_GETOPT_CH_INCLUDED 1 +#if !defined(ACCLIB_PUBLIC) +# define ACCLIB_PUBLIC(r,f) r __ACCLIB_FUNCNAME(f) +#endif +ACCLIB_PUBLIC(void, acc_getopt_init) (acc_getopt_p g, + int start_argc, int argc, char** argv) +{ + memset(g, 0, sizeof(*g)); + g->optind = start_argc; + g->argc = argc; g->argv = argv; + g->optopt = -1; +} +static int __ACCLIB_FUNCNAME(acc_getopt_rotate) (char **p, int first, int middle, int last) +{ + int i = middle, n = middle - first; + if (first >= middle || middle >= last) return 0; + for (;;) + { + char* t = p[first]; p[first] = p[i]; p[i] = t; + if (++first == middle) + { + if (++i == last) break; + middle = i; + } + else if (++i == last) + i = middle; + } + return n; +} +static int __ACCLIB_FUNCNAME(acc_getopt_perror) (acc_getopt_p g, int ret, int flags, const char *f, ...) +{ + if (flags & 1) + { + if (g->shortpos == 0) + g->optind++; + else if (!g->argv[g->optind][++g->shortpos]) + g->optind++, g->shortpos = 0; + if (flags & 2) + return ret; + } + if (g->opterr) + { +#if defined(HAVE_STDARG_H) + struct { va_list ap; } s; + va_start(s.ap, f); + g->opterr(g, f, &s); + va_end(s.ap); +#else + g->opterr(g, f, NULL); +#endif + } + g->errcount++; + return ret; +} +ACCLIB_PUBLIC(int, acc_getopt) (acc_getopt_p g, + const char* shortopts, + const acc_getopt_longopt_p longopts, + int* longind) +{ +#define pe __ACCLIB_FUNCNAME(acc_getopt_perror) + int ordering = ACC_GETOPT_PERMUTE; + int missing_arg_ret = g->bad_option; + char *a; + if (shortopts) + { + if (*shortopts == '-' || *shortopts == '+') + ordering = *shortopts++ == '-' ? ACC_GETOPT_RETURN_IN_ORDER : ACC_GETOPT_REQUIRE_ORDER; + if (*shortopts == ':') + missing_arg_ret = *shortopts++; + } + g->optarg = NULL; + if (g->optopt == -1) + g->optopt = g->bad_option; + if (longind != NULL) + *longind = -1; + if (g->eof || g->optind < 0 || g->argv == NULL) + goto acc_label_out3; + if (g->shortpos) + goto acc_label_next_shortopt; + g->optind -= __ACCLIB_FUNCNAME(acc_getopt_rotate)(g->argv, g->pending_rotate_first, g->pending_rotate_middle, g->optind); + g->pending_rotate_first = g->pending_rotate_middle = g->optind; + if (ordering == ACC_GETOPT_PERMUTE) + { + while (g->optind < g->argc && !(g->argv[g->optind][0] == '-' && g->argv[g->optind][1])) + g->optind++; + g->pending_rotate_middle = g->optind; + } + if (g->optind >= g->argc) + goto acc_label_out1; + a = g->argv[g->optind]; + if (a[0] == '-' && a[1] == '-') + { + char *arg; + const acc_getopt_longopt_p lo = NULL; + const acc_getopt_longopt_p l2 = NULL; + size_t a_len; + int need_exact = 0; + int i; + a += 2; arg = a; + if (arg[0] == 0) + { + g->optind++; + goto acc_label_out2; + } + while (arg[0] && arg[0] != '=' && arg[0] != '#') + ++arg; + a_len = (size_t) (arg - a); + for (i = 0; a_len && longopts && longopts[i].name; ++i) + { + size_t l = strlen(longopts[i].name); + if (strncmp(a, longopts[i].name, a_len) != 0) + continue; + if (a_len == l) + { + lo = &longopts[i]; + goto acc_label_found_lo; + } + if (longopts[i].has_arg & ACC_GETOPT_EXACT_ARG) + need_exact = 1; + if (lo == NULL) + lo = &longopts[i]; + else + l2 = &longopts[i]; + } + if (lo == NULL || need_exact) + return pe(g, g->bad_option, 1, "unrecognized option '--%s'", a); + if (l2) + return pe(g, g->bad_option, 1, "option '--%s' is ambiguous (could be '--%s' or '--%s')", a, lo->name, l2->name); + acc_label_found_lo: + switch (lo->has_arg & 0x2f) + { + case ACC_GETOPT_OPTIONAL_ARG: + if (arg[0] && arg[1]) + g->optarg = arg + 1; + g->optind++; + break; + case ACC_GETOPT_REQUIRED_ARG: + if (arg[0]) + { + if (arg[1]) + g->optarg = arg + 1; + } + else if (g->optind + 1 < g->argc) + g->optarg = g->argv[++g->optind]; + if (!g->optarg) + return pe(g, missing_arg_ret, 1, "option '--%s' requires an argument", lo->name); + g->optind++; + break; + case ACC_GETOPT_REQUIRED_ARG | 0x20: + if (arg[0] && arg[1]) + g->optarg = arg + 1; + if (!g->optarg) + return pe(g, missing_arg_ret, 1, "option '--%s=' requires an argument", lo->name); + g->optind++; + break; + default: + if (arg[0]) + return pe(g, g->bad_option, 1, "option '--%s' doesn't allow an argument", lo->name); + g->optind++; + break; + } + if (longind != NULL) + *longind = (int) (lo - longopts); + if (lo->flag != NULL) + { + *lo->flag = lo->val; + return 0; + } + return lo->val; + } + if (a[0] == '-' && a[1]) + { + char *arg; + int has_arg; + const char *sp; + unsigned char sc; + g->shortpos = 1; + acc_label_next_shortopt: + a = g->argv[g->optind] + g->shortpos; + sp = NULL; sc = (unsigned char) *a; + if (sc != ':' && shortopts) + sp = strchr(shortopts, sc); + if (!sp) + { + g->optopt = sc; + return pe(g, g->bad_option, 1, "invalid option '-%c'", sc); + } + arg = a + 1; has_arg = 0; + if (sp[1] == ':') { has_arg++; if (sp[2] == ':') has_arg++; } + switch (has_arg) + { + case ACC_GETOPT_OPTIONAL_ARG: + if (arg[0]) + g->optarg = arg; + g->optind++, g->shortpos = 0; + break; + case ACC_GETOPT_REQUIRED_ARG: + if (arg[0]) + g->optarg = arg; + else if (g->optind + 1 < g->argc) + g->optarg = g->argv[++g->optind]; + else + { + g->optopt = sc; + return pe(g, missing_arg_ret, 1, "option '-%c' requires an argument", sc); + } + g->optind++, g->shortpos = 0; + break; + default: + pe(g, 0, 3, NULL); + break; + } + return sc; + } + if (ordering == ACC_GETOPT_RETURN_IN_ORDER) + { + g->optarg = a; + g->optind++; + return 1; + } + goto acc_label_out2; +acc_label_out1: + g->optind = g->pending_rotate_first; +acc_label_out2: + g->optind -= __ACCLIB_FUNCNAME(acc_getopt_rotate)(g->argv, g->pending_rotate_first, g->pending_rotate_middle, g->optind); +acc_label_out3: + g->eof = 1; + return -1; +#undef pe +} +#endif #if defined(ACC_WANT_ACCLIB_HALLOC) # undef ACC_WANT_ACCLIB_HALLOC #define __ACCLIB_HALLOC_CH_INCLUDED 1 @@ -5813,7 +6047,7 @@ static int acc_pclock_read_perfctr(acc_pclock_handle_p h, acc_pclock_p c) acc_perfctr_clock_t pcc; double secs; acc_uint64l_t nsecs; - acc_perfctr_read(&h->pch, &pcc); + __ACCLIB_FUNCNAME(acc_perfctr_read)(&h->pch, &pcc); if __acc_unlikely(h->ticks_base == 0) h->ticks_base = pcc.tsc; else @@ -5928,7 +6162,7 @@ ACCLIB_PUBLIC(int, acc_pclock_open) (acc_pclock_handle_p h, int mode) break; case ACC_PCLOCK_PROCESS_CPUTIME_ID: # if defined(acc_pclock_read_perfctr) - if (acc_perfctr_open(&h->pch) == 0) { + if (__ACCLIB_FUNCNAME(acc_perfctr_open)(&h->pch) == 0) { h->gettime = acc_pclock_read_perfctr; h->name = "perfctr"; break; @@ -5995,19 +6229,19 @@ ACCLIB_PUBLIC(int, acc_pclock_open) (acc_pclock_handle_p h, int mode) if (!h->name) h->name = "unknown"; for (i = 0; i < 10; i++) { - acc_pclock_read(h, &c); + __ACCLIB_FUNCNAME(acc_pclock_read)(h, &c); } return 0; } ACCLIB_PUBLIC(int, acc_pclock_open_default) (acc_pclock_handle_p h) { - if (acc_pclock_open(h, ACC_PCLOCK_PROCESS_CPUTIME_ID) == 0) + if (__ACCLIB_FUNCNAME(acc_pclock_open)(h, ACC_PCLOCK_PROCESS_CPUTIME_ID) == 0) return 0; - if (acc_pclock_open(h, ACC_PCLOCK_MONOTONIC) == 0) + if (__ACCLIB_FUNCNAME(acc_pclock_open)(h, ACC_PCLOCK_MONOTONIC) == 0) return 0; - if (acc_pclock_open(h, ACC_PCLOCK_REALTIME) == 0) + if (__ACCLIB_FUNCNAME(acc_pclock_open)(h, ACC_PCLOCK_REALTIME) == 0) return 0; - if (acc_pclock_open(h, ACC_PCLOCK_THREAD_CPUTIME_ID) == 0) + if (__ACCLIB_FUNCNAME(acc_pclock_open)(h, ACC_PCLOCK_THREAD_CPUTIME_ID) == 0) return 0; return -1; } @@ -6018,7 +6252,7 @@ ACCLIB_PUBLIC(int, acc_pclock_close) (acc_pclock_handle_p h) h->name = NULL; h->gettime = 0; #if (__ACCLIB_PCLOCK_USE_PERFCTR) - acc_perfctr_close(&h->pch); + __ACCLIB_FUNCNAME(acc_perfctr_close)(&h->pch); #endif return 0; } @@ -6059,7 +6293,7 @@ ACCLIB_PUBLIC(int, acc_pclock_flush_cpu_cache) (acc_pclock_handle_p h, unsigned { if (h->h) { #if (__ACCLIB_PCLOCK_USE_PERFCTR) - return acc_perfctr_flush_cpu_cache(&h->pch, flags); + return __ACCLIB_FUNCNAME(acc_perfctr_flush_cpu_cache)(&h->pch, flags); #endif } ACC_UNUSED(h); ACC_UNUSED(flags); @@ -6148,7 +6382,7 @@ ACCLIB_PUBLIC(int, acc_uclock_open) (acc_uclock_handle_p h) h->name = NULL; #if (__ACCLIB_UCLOCK_USE_PERFCTR) h->pch.h = 0; - if (h->mode == 0 && acc_perfctr_open(&h->pch) == 0) + if (h->mode == 0 && __ACCLIB_FUNCNAME(acc_perfctr_open)(&h->pch) == 0) h->mode = 2; #endif #if (__ACCLIB_UCLOCK_USE_QPC) @@ -6163,7 +6397,7 @@ ACCLIB_PUBLIC(int, acc_uclock_open) (acc_uclock_handle_p h) #endif for (i = 0; i < 10; i++) { acc_uclock_t c; - acc_uclock_read(h, &c); + __ACCLIB_FUNCNAME(acc_uclock_read)(h, &c); } return 0; } @@ -6173,18 +6407,18 @@ ACCLIB_PUBLIC(int, acc_uclock_close) (acc_uclock_handle_p h) h->mode = -1; h->name = NULL; #if (__ACCLIB_UCLOCK_USE_PERFCTR) - acc_perfctr_close(&h->pch); + __ACCLIB_FUNCNAME(acc_perfctr_close)(&h->pch); #endif return 0; } ACCLIB_PUBLIC(void, acc_uclock_read) (acc_uclock_handle_p h, acc_uclock_p c) { #if (__ACCLIB_UCLOCK_USE_RDTSC) - acc_tsc_read((acc_uint32e_t*) (void*) &c->tsc); + __ACCLIB_FUNCNAME(acc_tsc_read)((acc_uint32e_t*) (void*) &c->tsc); #endif #if (__ACCLIB_UCLOCK_USE_PERFCTR) if (h->pch.h) { - acc_perfctr_read(&h->pch, &c->pcc); + __ACCLIB_FUNCNAME(acc_perfctr_read)(&h->pch, &c->pcc); if (h->mode > 0 && h->mode <= 2) return; } @@ -6250,7 +6484,7 @@ ACCLIB_PUBLIC(double, acc_uclock_get_elapsed) (acc_uclock_handle_p h, const acc_ #if (__ACCLIB_UCLOCK_USE_PERFCTR) if (h->pch.h && h->mode == 2) { if (!h->name) h->name = "perfctr"; - return acc_perfctr_get_elapsed(&h->pch, &start->pcc, &stop->pcc); + return __ACCLIB_FUNCNAME(acc_perfctr_get_elapsed)(&h->pch, &start->pcc, &stop->pcc); } #endif #if (__ACCLIB_UCLOCK_USE_QPC) @@ -6305,7 +6539,7 @@ ACCLIB_PUBLIC(int, acc_uclock_flush_cpu_cache) (acc_uclock_handle_p h, unsigned { if (h->h) { #if (__ACCLIB_UCLOCK_USE_PERFCTR) - return acc_perfctr_flush_cpu_cache(&h->pch, flags); + return __ACCLIB_FUNCNAME(acc_perfctr_flush_cpu_cache)(&h->pch, flags); #endif } ACC_UNUSED(h); ACC_UNUSED(flags); @@ -6622,7 +6856,7 @@ ACCLIB_PUBLIC_NOINLINE(unsigned, acc_debug_running_on_qemu) (void) unsigned r = 0; #if (ACC_OS_POSIX_LINUX || ACC_OS_WIN32 || ACC_OS_WIN64) const char* p; - p = acc_getenv("ACC_ENV_RUNNING_ON_QEMU"); + p = __ACCLIB_FUNCNAME(acc_getenv)("ACC_ENV_RUNNING_ON_QEMU"); if (p) { if (p[0] == 0) r = 0; else if ((p[0] >= '0' && p[0] <= '9') && p[1] == 0) r = p[0] - '0'; From 6d8e1fe776d1c479e3fa3432d8a98099a8a9ced0 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Thu, 5 Aug 2010 15:08:06 +0200 Subject: [PATCH 2/2] Start using acc_getopt. --- src/main.cpp | 36 ++- src/mygetopt.cpp | 706 ----------------------------------------------- src/mygetopt.h | 102 ------- src/util.cpp | 1 + 4 files changed, 26 insertions(+), 819 deletions(-) delete mode 100644 src/mygetopt.cpp delete mode 100644 src/mygetopt.h diff --git a/src/main.cpp b/src/main.cpp index 66959030..e4ec5121 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,7 +27,6 @@ #include "conf.h" -#include "mygetopt.h" #include "file.h" #include "packer.h" #include "p_elf.h" @@ -90,6 +89,19 @@ static int done_script_name = 0; const char *argv0 = ""; const char *progname = ""; +static acc_getopt_t mfx_getopt; +#define mfx_optarg mfx_getopt.optarg +#define mfx_optind mfx_getopt.optind +#define mfx_option acc_getopt_longopt_t +static void handle_opterr(acc_getopt_p g, const char *f, void *v) +{ + struct A { va_list ap; }; + struct A *a = (struct A *) v; + fprintf( stderr, "%s: ", g->progname); + vfprintf(stderr, f, a->ap); + fprintf( stderr, "\n"); +} + static int num_files = -1; static int exit_code = EXIT_OK; @@ -1061,13 +1073,14 @@ static const struct mfx_option longopts[] = }; int optc, longind; - char buf[256]; + char shortopts[256]; - prepare_shortopts(buf,"123456789hH?V",longopts), - mfx_optind = 0; - mfx_opterr = 1; + prepare_shortopts(shortopts, "123456789hH?V", longopts), + acc_getopt_init(&mfx_getopt, 1, argc, argv); + mfx_getopt.progname = progname; + mfx_getopt.opterr = handle_opterr; opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX; - while ((optc = mfx_getopt_long(argc, argv, buf, longopts, &longind)) >= 0) + while ((optc = acc_getopt(&mfx_getopt, shortopts, longopts, &longind)) >= 0) { if (do_option(optc, argv[mfx_optind-1]) != 0) e_usage(); @@ -1153,7 +1166,7 @@ static const struct mfx_option longopts[] = int targc; char **targv = NULL; static const char sep[] = " \t"; - char buf[256]; + char shortopts[256]; var = getenv(OPTIONS_VAR); if (var == NULL || !var[0]) @@ -1209,10 +1222,11 @@ static const struct mfx_option longopts[] = e_envopt(targv[i]); /* handle options */ - prepare_shortopts(buf,"123456789",longopts); - mfx_optind = 0; - mfx_opterr = 1; - while ((optc = mfx_getopt_long(targc, targv, buf, longopts, &longind)) >= 0) + prepare_shortopts(shortopts, "123456789", longopts); + acc_getopt_init(&mfx_getopt, 1, targc, targv); + mfx_getopt.progname = progname; + mfx_getopt.opterr = handle_opterr; + while ((optc = acc_getopt(&mfx_getopt, shortopts, longopts, &longind)) >= 0) { if (do_option(optc, targv[mfx_optind-1]) != 0) e_envopt(NULL); diff --git a/src/mygetopt.cpp b/src/mygetopt.cpp deleted file mode 100644 index 22bf9a80..00000000 --- a/src/mygetopt.cpp +++ /dev/null @@ -1,706 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu - before changing it! - - Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 - Free Software Foundation, Inc. - - This program 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 2, or (at your option) any - later version. - - This program 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 this program; if not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - - -#undef PROGNAME -#if 0 -#ifndef EOF -#include -#include -#endif -#define PROGNAME(x) (x) -#else -#include "conf.h" -static const char *my_progname(const char *argv0) -{ - return progname ? progname : argv0; -} -#define PROGNAME(x) my_progname(x) -#endif - - -/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a - long-named option. Because this is not POSIX.2 compliant, it is - being phased out. */ -/* #define GETOPT_COMPAT */ -#undef GETOPT_COMPAT - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "mygetopt.h" -#define option mfx_option -#define optarg mfx_optarg -#define optind mfx_optind -#define opterr mfx_opterr -#define optopt mfx_optopt -#undef BAD_OPTION - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg = NULL; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* XXX 1003.2 says this must be 1 before any call. */ -int optind = 0; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -#define BAD_OPTION '\0' -int optopt = BAD_OPTION; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return EOF with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. - - To perform the swap, we first reverse the order of all elements. So - all options now come before all non options, but they are in the - wrong order. So we put back the options and non options in original - order by reversing them again. For example: - original input: a b c -x -y - reverse all: -y -x c b a - reverse options: -x -y c b a - reverse non options: -x -y a b c -*/ - - -static void exchange (char **argv) -{ - char *temp; char **first, **last; - - /* Reverse all the elements [first_nonopt, optind) */ - first = &argv[first_nonopt]; - last = &argv[optind-1]; - while (first < last) { - temp = *first; *first = *last; *last = temp; first++; last--; - } - /* Put back the options in order */ - first = &argv[first_nonopt]; - first_nonopt += (optind - last_nonopt); - last = &argv[first_nonopt - 1]; - while (first < last) { - temp = *first; *first = *last; *last = temp; first++; last--; - } - - /* Put back the non options in order */ - first = &argv[first_nonopt]; - last_nonopt = optind; - last = &argv[last_nonopt-1]; - while (first < last) { - temp = *first; *first = *last; *last = temp; first++; last--; - } -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns `EOF'. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return BAD_OPTION after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return BAD_OPTION. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -static int _getopt_internal (int argc, char **argv, const char *optstring, - const struct option *longopts, int *longind, - int long_only) -{ - static char empty_string[1]; - int option_index; - - if (longind != NULL) - *longind = -1; - - optarg = 0; - - /* Initialize the internal data when the first call is made. - Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - if (optind == 0) - { - first_nonopt = last_nonopt = optind = 1; - - nextchar = NULL; - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } -#if 0 - else if (getenv ("POSIXLY_CORRECT") != NULL) - ordering = REQUIRE_ORDER; -#endif - else - ordering = PERMUTE; - } - - if (nextchar == NULL || *nextchar == '\0') - { - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange (argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Now skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc - && (argv[optind][0] != '-' || argv[optind][1] == '\0') -#ifdef GETOPT_COMPAT - && (longopts == NULL - || argv[optind][0] != '+' || argv[optind][1] == '\0') -#endif /* GETOPT_COMPAT */ - ) - optind++; - last_nonopt = optind; - } - - /* Special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange (argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return EOF; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if ((argv[optind][0] != '-' || argv[optind][1] == '\0') -#ifdef GETOPT_COMPAT - && (longopts == NULL - || argv[optind][0] != '+' || argv[optind][1] == '\0') -#endif /* GETOPT_COMPAT */ - ) - { - if (ordering == REQUIRE_ORDER) - return EOF; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Start decoding its characters. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - if (longopts != NULL - && ((argv[optind][0] == '-' - && (argv[optind][1] == '-' || long_only)) -#ifdef GETOPT_COMPAT - || argv[optind][0] == '+' -#endif /* GETOPT_COMPAT */ - )) - { - const struct option *p; - char *s = nextchar; - int exact = 0; - int ambig = 0; - const struct option *pfound = NULL; - int indfound = 0; - int needexact = 0; - - /* allow `--option#value' because you cannout assign a '=' - to an environment variable under DOS command.com */ - while (*s && *s != '=' && * s != '#') - s++; - - /* Test all options for either exact match or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; - p++, option_index++) - if (!strncmp (p->name, nextchar, (unsigned) (s - nextchar))) - { - if (p->has_arg & 0x10) - needexact = 1; - if ((unsigned) (s - nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second nonexact match found. */ - ambig = 1; - } - - /* don't allow nonexact longoptions */ - if (needexact && !exact) - { - if (opterr) - fprintf (stderr, "%s: unrecognized option `%s'\n", - PROGNAME(argv[0]), argv[optind]); - nextchar += strlen (nextchar); - optind++; - return BAD_OPTION; - } - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `%s' is ambiguous\n", - PROGNAME(argv[0]), argv[optind]); - nextchar += strlen (nextchar); - optind++; - return BAD_OPTION; - } - - if (pfound != NULL) - { - int have_arg = (s[0] != '\0'); - if (have_arg && (pfound->has_arg & 0xf)) - have_arg = (s[1] != '\0'); - option_index = indfound; - optind++; - if (have_arg) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg & 0xf) - optarg = s + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - "%s: option `--%s' doesn't allow an argument\n", - PROGNAME(argv[0]), pfound->name); - else - /* +option or -option */ - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - PROGNAME(argv[0]), argv[optind - 1][0], pfound->name); - } - nextchar += strlen (nextchar); - return BAD_OPTION; - } - } - else if ((pfound->has_arg & 0xf) == 1) - { -#if 0 - if (optind < argc) -#else - if (optind < argc && (pfound->has_arg & 0x20) == 0) -#endif - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, "%s: option `--%s%s' requires an argument\n", - PROGNAME(argv[0]), pfound->name, - (pfound->has_arg & 0x20) ? "=" : ""); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : BAD_OPTION; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' -#ifdef GETOPT_COMPAT - || argv[optind][0] == '+' -#endif /* GETOPT_COMPAT */ - || strchr (optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, "%s: unrecognized option `--%s'\n", - PROGNAME(argv[0]), nextchar); - else - /* +option or -option */ - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - PROGNAME(argv[0]), argv[optind][0], nextchar); - } - nextchar = empty_string; - optind++; - return BAD_OPTION; - } - (void) &ambig; /* UNUSED */ - } - - /* Look at and handle the next option-character. */ - - { - char c = *nextchar++; - const char *temp = strchr (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { -#if 0 - if (c < 040 || c >= 0177) - fprintf (stderr, "%s: unrecognized option, character code 0%o\n", - PROGNAME(argv[0]), c); - else - fprintf (stderr, "%s: unrecognized option `-%c'\n", PROGNAME(argv[0]), c); -#else - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: illegal option -- %c\n", PROGNAME(argv[0]), c); -#endif - } - optopt = c; - return BAD_OPTION; - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = 0; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { -#if 0 - fprintf (stderr, "%s: option `-%c' requires an argument\n", - PROGNAME(argv[0]), c); -#else - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: option requires an argument -- %c\n", - PROGNAME(argv[0]), c); -#endif - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = BAD_OPTION; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int mfx_getopt(int argc, char **argv, const char *optstring) -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -int mfx_getopt_long(int argc, char **argv, const char *options, - const struct option *long_options, int *opt_index) -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); -} - - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == EOF) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case BAD_OPTION: - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ - - -/* -vi:ts=4:et:nowrap -*/ - diff --git a/src/mygetopt.h b/src/mygetopt.h deleted file mode 100644 index a0de9af3..00000000 --- a/src/mygetopt.h +++ /dev/null @@ -1,102 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - - This program 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 2, or (at your option) any - later version. - - This program 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 this program; if not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef __MFX_GETOPT_H -#define __MFX_GETOPT_H 1 - -#ifdef __cplusplus -/* extern "C" { */ -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *mfx_optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int mfx_optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int mfx_opterr; - -/* Set to an option character which was unrecognized. */ - -extern int mfx_optopt; - -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct mfx_option -{ - const char *name; - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -#define mfx_no_argument 0 -#define mfx_required_argument 1 -#define mfx_optional_argument 2 -#define mfx_exact_argument 0x10 /* no abbrev. */ - -int mfx_getopt(int argc, char **argv, const char *shortopts); -int mfx_getopt_long(int argc, char **argv, const char *shortopts, - const struct mfx_option *longopts, int *longind); - -#ifdef __cplusplus -/* } */ -#endif - -#endif /* __MFX_GETOPT_H */ diff --git a/src/util.cpp b/src/util.cpp index 084bbc1a..c54246a4 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -37,6 +37,7 @@ #endif #define ACC_WANT_ACC_INCI_H 1 #include "miniacc.h" +#define ACC_WANT_ACCLIB_GETOPT 1 #define ACC_WANT_ACCLIB_HSREAD 1 #define ACC_WANT_ACCLIB_MISC 1 #define ACC_WANT_ACCLIB_UA 1