From b4f53143b0e05fd3061cdf2e65e17a6a2904090b Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Fri, 24 Jul 2015 00:50:58 -0700 Subject: Migrate source files into src/ directory This change moves source files into a src/ directory, and puts object files into an obj/ directory. The Makefile and xcode project are updated accordingly. Fixes #1866 --- src/wgetopt.cpp | 715 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 715 insertions(+) create mode 100644 src/wgetopt.cpp (limited to 'src/wgetopt.cpp') diff --git a/src/wgetopt.cpp b/src/wgetopt.cpp new file mode 100644 index 00000000..2d2117f6 --- /dev/null +++ b/src/wgetopt.cpp @@ -0,0 +1,715 @@ +/** \file wgetopt.c + A version of the getopt library for use with wide character strings. + + This is simply the gnu getopt library, but converted for use with + wchar_t instead of char. This is not usually useful since the argv + array is always defined to be of type char**, but in fish, all + internal commands use wide characters and hence this library is + useful. + + If you want to use this version of getopt in your program, + download the fish sourcecode, available at the fish homepage. Extract + the sourcode, copy wgetopt.c and wgetopt.h into your program + directory, include wgetopt.h in your program, and use all the + regular getopt functions, prefixing every function, global + variable and structure with a 'w', and use only wide character + strings. There are no other functional changes in this version of + getopt besides using wide character strings. + + For examples of how to use wgetopt, see the fish builtin + functions, many of which are defined in builtin.c. + +*/ + + +/* 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, 93, 94 + Free Software Foundation, Inc. + + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in /gd/gnu/lib. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, write to the Free Software Foundation, Inc., 675 Mass Ave, + Cambridge, MA 02139, USA. */ + +#include "config.h" + +#if !defined (__STDC__) || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include +#include + +#include +#include +#include +#include + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +#include +#endif /* GNU C library. */ + +/* 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 "wgetopt.h" +#include "wutil.h" +#include "fallback.h" + + + +/* 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. */ + +wchar_t *woptarg = 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, `woptind' 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 woptind = 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 wchar_t *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int wopterr = 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. */ + +int woptopt = '?'; + +/* 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 `woptind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +/** + Use translation functions if available +*/ +#ifdef _ +#undef _ +#endif + +#ifdef HAVE_TRANSLATE_H +#ifdef USE_GETTEXT +#define _(string) wgettext(string) +#else +#define _(string) (string) +#endif +#else +#define _(wstr) wstr +#endif + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +#include +#define my_index wcschr +#else + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +char *getenv(); + +static wchar_t * +my_index(const wchar_t *str, int chr) +{ + while (*str) + { + if (*str == chr) + return (wchar_t *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +#if !defined (__STDC__) || !__STDC__ +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int wcslen(const wchar_t *); +#endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* 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,woptind), 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. */ + +static void +exchange(wchar_t **argv) +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = woptind; + wchar_t *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (woptind - last_nonopt); + last_nonopt = woptind; +} + +/* Initialize the internal data when the first call is made. */ + +static const wchar_t * +_wgetopt_initialize(const wchar_t *optstring) +{ + /* 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. */ + + first_nonopt = last_nonopt = woptind = 1; + + nextchar = NULL; + + posixly_correct = getenv("POSIXLY_CORRECT"); + + /* 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; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + + return optstring; +} + +/* 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 `woptind' 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 `woptind' 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 '?' after printing an error message. If you set `wopterr' to + zero, the error message is suppressed but we still return '?'. + + 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 `woptarg', otherwise `woptarg' 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. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + 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. */ + +int +_wgetopt_internal(int argc, wchar_t *const *argv, const wchar_t *optstring, const struct woption *longopts, int *longind, int long_only) +{ + woptarg = NULL; + + if (woptind == 0) + optstring = _wgetopt_initialize(optstring); + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + 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 != woptind) + exchange((wchar_t **) argv); + else if (last_nonopt != woptind) + first_nonopt = woptind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (woptind < argc + && (argv[woptind][0] != '-' || argv[woptind][1] == '\0')) + woptind++; + last_nonopt = woptind; + } + + /* The 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 (woptind != argc && !wcscmp(argv[woptind], L"--")) + { + woptind++; + + if (first_nonopt != last_nonopt && last_nonopt != woptind) + exchange((wchar_t **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = woptind; + last_nonopt = argc; + + woptind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (woptind == 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) + woptind = 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[woptind][0] != '-' || argv[woptind][1] == '\0')) + { + if (ordering == REQUIRE_ORDER) + return EOF; + woptarg = argv[woptind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[woptind] + 1 + + (longopts != NULL && argv[woptind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[woptind][1] == '-' + || (long_only && (argv[woptind][2] || !my_index(optstring, argv[woptind][1]))))) + { + wchar_t *nameend; + const struct woption *p; + const struct woption *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; /* set to zero by Anton */ + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!wcsncmp(p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int)(nameend - nextchar) == (unsigned int)wcslen(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 or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (wopterr) + fwprintf(stderr, _(L"%ls: Option '%ls' is ambiguous\n"), + argv[0], argv[woptind]); + nextchar += wcslen(nextchar); + woptind++; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + woptind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + woptarg = nameend + 1; + else + { + if (wopterr) + { + if (argv[woptind - 1][1] == '-') + /* --option */ + fwprintf(stderr, + _(L"%ls: Option '--%ls' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fwprintf(stderr, + _(L"%ls: Option '%lc%ls' doesn't allow an argument\n"), + argv[0], argv[woptind - 1][0], pfound->name); + } + nextchar += wcslen(nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (woptind < argc) + woptarg = argv[woptind++]; + else + { + if (wopterr) + fwprintf(stderr, _(L"%ls: Option '%ls' requires an argument\n"), + argv[0], argv[woptind - 1]); + nextchar += wcslen(nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += wcslen(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[woptind][1] == '-' + || my_index(optstring, *nextchar) == NULL) + { + if (wopterr) + { + if (argv[woptind][1] == '-') + /* --option */ + fwprintf(stderr, _(L"%ls: Unrecognized option '--%ls'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fwprintf(stderr, _(L"%ls: Unrecognized option '%lc%ls'\n"), + argv[0], argv[woptind][0], nextchar); + } + nextchar = (wchar_t *) L""; + woptind++; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + wchar_t c = *nextchar++; + wchar_t *temp = const_cast(my_index(optstring, c)); + + /* Increment `woptind' when we start to process its last character. */ + if (*nextchar == '\0') + ++woptind; + + if (temp == NULL || c == ':') + { + if (wopterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fwprintf(stderr, _(L"%ls: Illegal option -- %lc\n"), argv[0], c); + else + fwprintf(stderr, _(L"%ls: Invalid option -- %lc\n"), argv[0], c); + } + woptopt = c; + + if (*nextchar != '\0') + woptind++; + + return '?'; + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + woptarg = nextchar; + woptind++; + } + else + woptarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + woptarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + woptind++; + } + else if (woptind == argc) + { + if (wopterr) + { + /* 1003.2 specifies the format of this message. */ + fwprintf(stderr, _(L"%ls: Option requires an argument -- %lc\n"), + argv[0], c); + } + woptopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `woptind' once; + increment it again when taking next ARGV-elt as argument. */ + woptarg = argv[woptind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +wgetopt(int argc, wchar_t *const *argv, const wchar_t *optstring) +{ + return _wgetopt_internal(argc, argv, optstring, + (const struct woption *) 0, + (int *) 0, + 0); +} + +int +wgetopt_long(int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index) +{ + return _wgetopt_internal(argc, argv, options, long_options, opt_index, 0); +} + +int +wgetopt_long_only(int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index) +{ + return _wgetopt_internal(argc, argv, options, long_options, opt_index, 1); +} -- cgit v1.2.3 From f4d1657c22c81a7720a91026f915b80d2d6aa6e8 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 25 Jul 2015 18:16:00 -0700 Subject: Eliminate wgetopt global variables Replace them with a new struct wgetopter_t that uses instance variables instead. --- src/builtin.cpp | 316 +++++++++++++++++++++----------------------- src/builtin_commandline.cpp | 44 +++--- src/builtin_complete.cpp | 37 +++--- src/builtin_jobs.cpp | 19 +-- src/builtin_set.cpp | 31 ++--- src/builtin_set_color.cpp | 13 +- src/builtin_ulimit.cpp | 29 ++-- src/wgetopt.cpp | 122 ++--------------- src/wgetopt.h | 296 +++++++++++++++++++++-------------------- 9 files changed, 403 insertions(+), 504 deletions(-) (limited to 'src/wgetopt.cpp') diff --git a/src/builtin.cpp b/src/builtin.cpp index 59778862..3381996a 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -636,7 +636,7 @@ static int builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int u */ static int builtin_bind(parser_t &parser, wchar_t **argv) { - + wgetopter_t w; enum { BIND_INSERT, @@ -657,7 +657,7 @@ static int builtin_bind(parser_t &parser, wchar_t **argv) int use_terminfo = 0; - woptind=0; + w.woptind=0; static const struct woption long_options[] = { @@ -675,11 +675,11 @@ static int builtin_bind(parser_t &parser, wchar_t **argv) while (1) { int opt_index = 0; - int opt = wgetopt_long(argc, - argv, - L"aehkKfM:m:", - long_options, - &opt_index); + int opt = w.wgetopt_long(argc, + argv, + L"aehkKfM:m:", + long_options, + &opt_index); if (opt == -1) break; @@ -722,17 +722,17 @@ static int builtin_bind(parser_t &parser, wchar_t **argv) break; case 'M': - bind_mode = woptarg; + bind_mode = w.woptarg; bind_mode_given = true; break; case 'm': - sets_bind_mode = woptarg; + sets_bind_mode = w.woptarg; sets_bind_mode_given = true; break; case '?': - builtin_unknown_option(parser, argv[0], argv[woptind-1]); + builtin_unknown_option(parser, argv[0], argv[w.woptind-1]); return STATUS_BUILTIN_ERROR; @@ -752,7 +752,7 @@ static int builtin_bind(parser_t &parser, wchar_t **argv) case BIND_ERASE: { - if (builtin_bind_erase(&argv[woptind], all, bind_mode_given ? bind_mode : NULL, use_terminfo)) + if (builtin_bind_erase(&argv[w.woptind], all, bind_mode_given ? bind_mode : NULL, use_terminfo)) { res = STATUS_BUILTIN_ERROR; } @@ -761,7 +761,7 @@ static int builtin_bind(parser_t &parser, wchar_t **argv) case BIND_INSERT: { - switch (argc-woptind) + switch (argc-w.woptind) { case 0: { @@ -774,7 +774,7 @@ static int builtin_bind(parser_t &parser, wchar_t **argv) wcstring seq; if (use_terminfo) { - if (!get_terminfo_sequence(argv[woptind], &seq)) + if (!get_terminfo_sequence(argv[w.woptind], &seq)) { res = STATUS_BUILTIN_ERROR; // get_terminfo_sequence already printed the error @@ -783,12 +783,12 @@ static int builtin_bind(parser_t &parser, wchar_t **argv) } else { - seq = argv[woptind]; + seq = argv[w.woptind]; } if (!builtin_bind_list_one(seq, bind_mode)) { res = STATUS_BUILTIN_ERROR; - wcstring eseq = escape_string(argv[woptind], 0); + wcstring eseq = escape_string(argv[w.woptind], 0); if (use_terminfo) { append_format(stderr_buffer, _(L"%ls: No binding found for key '%ls'\n"), argv[0], eseq.c_str()); @@ -803,7 +803,7 @@ static int builtin_bind(parser_t &parser, wchar_t **argv) default: { - if (builtin_bind_add(argv[woptind], (const wchar_t **)argv + (woptind + 1), argc - (woptind + 1), bind_mode, sets_bind_mode, use_terminfo)) + if (builtin_bind_add(argv[w.woptind], (const wchar_t **)argv + (w.woptind + 1), argc - (w.woptind + 1), bind_mode, sets_bind_mode, use_terminfo)) { res = STATUS_BUILTIN_ERROR; } @@ -845,6 +845,7 @@ static int builtin_bind(parser_t &parser, wchar_t **argv) */ static int builtin_block(parser_t &parser, wchar_t **argv) { + wgetopter_t w; enum { UNSET, @@ -857,7 +858,7 @@ static int builtin_block(parser_t &parser, wchar_t **argv) int erase = 0; int argc=builtin_count_args(argv); - woptind=0; + w.woptind=0; static const struct woption long_options[] = @@ -888,11 +889,11 @@ static int builtin_block(parser_t &parser, wchar_t **argv) { int opt_index = 0; - int opt = wgetopt_long(argc, - argv, - L"elgh", - long_options, - &opt_index); + int opt = w.wgetopt_long(argc, + argv, + L"elgh", + long_options, + &opt_index); if (opt == -1) break; @@ -925,7 +926,7 @@ static int builtin_block(parser_t &parser, wchar_t **argv) break; case '?': - builtin_unknown_option(parser, argv[0], argv[woptind-1]); + builtin_unknown_option(parser, argv[0], argv[w.woptind-1]); return STATUS_BUILTIN_ERROR; } @@ -1003,8 +1004,7 @@ static int builtin_builtin(parser_t &parser, wchar_t **argv) { int argc=builtin_count_args(argv); int list=0; - - woptind=0; + wgetopter_t w; static const struct woption long_options[] = @@ -1027,11 +1027,11 @@ static int builtin_builtin(parser_t &parser, wchar_t **argv) { int opt_index = 0; - int opt = wgetopt_long(argc, - argv, - L"nh", - long_options, - &opt_index); + int opt = w.wgetopt_long(argc, + argv, + L"nh", + long_options, + &opt_index); if (opt == -1) break; @@ -1057,7 +1057,7 @@ static int builtin_builtin(parser_t &parser, wchar_t **argv) break; case '?': - builtin_unknown_option(parser, argv[0], argv[woptind-1]); + builtin_unknown_option(parser, argv[0], argv[w.woptind-1]); return STATUS_BUILTIN_ERROR; } @@ -1085,10 +1085,9 @@ static int builtin_builtin(parser_t &parser, wchar_t **argv) */ static int builtin_emit(parser_t &parser, wchar_t **argv) { + wgetopter_t w; int argc=builtin_count_args(argv); - woptind=0; - static const struct woption long_options[] = { @@ -1106,11 +1105,11 @@ static int builtin_emit(parser_t &parser, wchar_t **argv) { int opt_index = 0; - int opt = wgetopt_long(argc, - argv, - L"h", - long_options, - &opt_index); + int opt = w.wgetopt_long(argc, + argv, + L"h", + long_options, + &opt_index); if (opt == -1) break; @@ -1131,20 +1130,20 @@ static int builtin_emit(parser_t &parser, wchar_t **argv) return STATUS_BUILTIN_OK; case '?': - builtin_unknown_option(parser, argv[0], argv[woptind-1]); + builtin_unknown_option(parser, argv[0], argv[w.woptind-1]); return STATUS_BUILTIN_ERROR; } } - if (!argv[woptind]) + if (!argv[w.woptind]) { append_format(stderr_buffer, L"%ls: expected event name\n", argv[0]); return STATUS_BUILTIN_ERROR; } - const wchar_t *eventname = argv[woptind]; - wcstring_list_t args(argv + woptind + 1, argv + argc); + const wchar_t *eventname = argv[w.woptind]; + wcstring_list_t args(argv + w.woptind + 1, argv + argc); event_fire_generic(eventname, &args); return STATUS_BUILTIN_OK; @@ -1157,10 +1156,11 @@ static int builtin_emit(parser_t &parser, wchar_t **argv) */ static int builtin_command(parser_t &parser, wchar_t **argv) { + wgetopter_t w; int argc=builtin_count_args(argv); int print_path=0; - woptind=0; + w.woptind=0; static const struct woption long_options[] = @@ -1174,11 +1174,11 @@ static int builtin_command(parser_t &parser, wchar_t **argv) { int opt_index = 0; - int opt = wgetopt_long(argc, - argv, - L"svh", - long_options, - &opt_index); + int opt = w.wgetopt_long(argc, + argv, + L"svh", + long_options, + &opt_index); if (opt == -1) break; @@ -1204,7 +1204,7 @@ static int builtin_command(parser_t &parser, wchar_t **argv) break; case '?': - builtin_unknown_option(parser, argv[0], argv[woptind-1]); + builtin_unknown_option(parser, argv[0], argv[w.woptind-1]); return STATUS_BUILTIN_ERROR; } @@ -1219,7 +1219,7 @@ static int builtin_command(parser_t &parser, wchar_t **argv) int found=0; - for (int idx = woptind; argv[idx]; ++idx) + for (int idx = w.woptind; argv[idx]; ++idx) { const wchar_t *command_name = argv[idx]; wcstring path; @@ -1239,6 +1239,7 @@ static int builtin_command(parser_t &parser, wchar_t **argv) */ static int builtin_generic(parser_t &parser, wchar_t **argv) { + wgetopter_t w; int argc=builtin_count_args(argv); /* Hackish - if we have no arguments other than the command, we are a "naked invocation" and we just print help */ @@ -1248,8 +1249,6 @@ static int builtin_generic(parser_t &parser, wchar_t **argv) return STATUS_BUILTIN_ERROR; } - woptind=0; - static const struct woption long_options[] = { @@ -1261,11 +1260,11 @@ static int builtin_generic(parser_t &parser, wchar_t **argv) { int opt_index = 0; - int opt = wgetopt_long(argc, - argv, - L"h", - long_options, - &opt_index); + int opt = w.wgetopt_long(argc, + argv, + L"h", + long_options, + &opt_index); if (opt == -1) break; @@ -1286,7 +1285,7 @@ static int builtin_generic(parser_t &parser, wchar_t **argv) return STATUS_BUILTIN_OK; case '?': - builtin_unknown_option(parser, argv[0], argv[woptind-1]); + builtin_unknown_option(parser, argv[0], argv[w.woptind-1]); return STATUS_BUILTIN_ERROR; } @@ -1435,6 +1434,7 @@ static void functions_def(const wcstring &name, wcstring &out) */ static int builtin_functions(parser_t &parser, wchar_t **argv) { + wgetopter_t w; int i; int erase=0; wchar_t *desc=0; @@ -1446,8 +1446,6 @@ static int builtin_functions(parser_t &parser, wchar_t **argv) int query = 0; int copy = 0; - woptind=0; - static const struct woption long_options[] = { @@ -1489,11 +1487,11 @@ static int builtin_functions(parser_t &parser, wchar_t **argv) { int opt_index = 0; - int opt = wgetopt_long(argc, - argv, - L"ed:nahqc", - long_options, - &opt_index); + int opt = w.wgetopt_long(argc, + argv, + L"ed:nahqc", + long_options, + &opt_index); if (opt == -1) break; @@ -1516,7 +1514,7 @@ static int builtin_functions(parser_t &parser, wchar_t **argv) break; case 'd': - desc=woptarg; + desc=w.woptarg; break; case 'n': @@ -1540,7 +1538,7 @@ static int builtin_functions(parser_t &parser, wchar_t **argv) break; case '?': - builtin_unknown_option(parser, argv[0], argv[woptind-1]); + builtin_unknown_option(parser, argv[0], argv[w.woptind-1]); return STATUS_BUILTIN_ERROR; } @@ -1564,7 +1562,7 @@ static int builtin_functions(parser_t &parser, wchar_t **argv) if (erase) { int i; - for (i=woptind; i 1)) + if ((search_mode || line_mode || cursor_mode || paging_mode) && (argc-w.woptind > 1)) { append_format(stderr_buffer, @@ -513,7 +513,7 @@ static int builtin_commandline(parser_t &parser, wchar_t **argv) } - if ((tokenize || cut_at_cursor) && (argc-woptind)) + if ((tokenize || cut_at_cursor) && (argc-w.woptind)) { append_format(stderr_buffer, BUILTIN_ERR_COMBO2, @@ -525,7 +525,7 @@ static int builtin_commandline(parser_t &parser, wchar_t **argv) return 1; } - if (append_mode && !(argc-woptind)) + if (append_mode && !(argc-w.woptind)) { append_format(stderr_buffer, BUILTIN_ERR_COMBO2, @@ -551,19 +551,19 @@ static int builtin_commandline(parser_t &parser, wchar_t **argv) if (cursor_mode) { - if (argc-woptind) + if (argc-w.woptind) { wchar_t *endptr; long new_pos; errno = 0; - new_pos = wcstol(argv[woptind], &endptr, 10); + new_pos = wcstol(argv[w.woptind], &endptr, 10); if (*endptr || errno) { append_format(stderr_buffer, BUILTIN_ERR_NOT_NUMBER, argv[0], - argv[woptind]); + argv[w.woptind]); builtin_print_help(parser, argv[0], stderr_buffer); } @@ -639,7 +639,7 @@ static int builtin_commandline(parser_t &parser, wchar_t **argv) } - switch (argc-woptind) + switch (argc-w.woptind) { case 0: { @@ -649,16 +649,16 @@ static int builtin_commandline(parser_t &parser, wchar_t **argv) case 1: { - replace_part(begin, end, argv[woptind], append_mode); + replace_part(begin, end, argv[w.woptind], append_mode); break; } default: { - wcstring sb = argv[woptind]; + wcstring sb = argv[w.woptind]; int i; - for (i=woptind+1; i fgcolors; - for (; woptind < argc; woptind++) + for (; w.woptind < argc; w.woptind++) { - rgb_color_t fg = rgb_color_t(argv[woptind]); + rgb_color_t fg = rgb_color_t(argv[w.woptind]); if (fg.is_none() || fg.is_ignore()) { - append_format(stderr_buffer, _(L"%ls: Unknown color '%ls'\n"), argv[0], argv[woptind]); + append_format(stderr_buffer, _(L"%ls: Unknown color '%ls'\n"), argv[0], argv[w.woptind]); return STATUS_BUILTIN_ERROR; } fgcolors.push_back(fg); diff --git a/src/builtin_ulimit.cpp b/src/builtin_ulimit.cpp index 23524543..64b126b7 100644 --- a/src/builtin_ulimit.cpp +++ b/src/builtin_ulimit.cpp @@ -254,6 +254,7 @@ static int set(int resource, int hard, int soft, rlim_t value) */ static int builtin_ulimit(parser_t &parser, wchar_t ** argv) { + wgetopter_t w; int hard=0; int soft=0; @@ -262,7 +263,7 @@ static int builtin_ulimit(parser_t &parser, wchar_t ** argv) int argc = builtin_count_args(argv); - woptind=0; + w.woptind=0; while (1) { @@ -334,11 +335,11 @@ static int builtin_ulimit(parser_t &parser, wchar_t ** argv) int opt_index = 0; - int opt = wgetopt_long(argc, - argv, - L"aHScdflmnstuvh", - long_options, - &opt_index); + int opt = w.wgetopt_long(argc, + argv, + L"aHScdflmnstuvh", + long_options, + &opt_index); if (opt == -1) break; @@ -419,14 +420,14 @@ static int builtin_ulimit(parser_t &parser, wchar_t ** argv) return 0; case L'?': - builtin_unknown_option(parser, argv[0], argv[woptind-1]); + builtin_unknown_option(parser, argv[0], argv[w.woptind-1]); return 1; } } if (report_all) { - if (argc - woptind == 0) + if (argc - w.woptind == 0) { print_all(hard); } @@ -441,7 +442,7 @@ static int builtin_ulimit(parser_t &parser, wchar_t ** argv) return 0; } - switch (argc - woptind) + switch (argc - w.woptind) { case 0: { @@ -468,28 +469,28 @@ static int builtin_ulimit(parser_t &parser, wchar_t ** argv) hard=soft=1; } - if (wcscasecmp(argv[woptind], L"unlimited")==0) + if (wcscasecmp(argv[w.woptind], L"unlimited")==0) { new_limit = RLIM_INFINITY; } - else if (wcscasecmp(argv[woptind], L"hard")==0) + else if (wcscasecmp(argv[w.woptind], L"hard")==0) { new_limit = get(what, 1); } - else if (wcscasecmp(argv[woptind], L"soft")==0) + else if (wcscasecmp(argv[w.woptind], L"soft")==0) { new_limit = get(what, soft); } else { errno=0; - new_limit = wcstol(argv[woptind], &end, 10); + new_limit = wcstol(argv[w.woptind], &end, 10); if (errno || *end) { append_format(stderr_buffer, L"%ls: Invalid limit '%ls'\n", argv[0], - argv[woptind]); + argv[w.woptind]); builtin_print_help(parser, argv[0], stderr_buffer); return 1; } diff --git a/src/wgetopt.cpp b/src/wgetopt.cpp index 2d2117f6..b63fe74f 100644 --- a/src/wgetopt.cpp +++ b/src/wgetopt.cpp @@ -84,9 +84,6 @@ 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. */ @@ -95,87 +92,6 @@ #include "fallback.h" - -/* 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. */ - -wchar_t *woptarg = 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, `woptind' 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 woptind = 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 wchar_t *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int wopterr = 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. */ - -int woptopt = '?'; - -/* 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 `woptind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -/* Value of POSIXLY_CORRECT environment variable. */ -static char *posixly_correct; - /** Use translation functions if available */ @@ -233,14 +149,6 @@ extern int wcslen(const wchar_t *); #endif /* not __GNU_LIBRARY__ */ -/* 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) @@ -251,8 +159,7 @@ static int last_nonopt; `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ -static void -exchange(wchar_t **argv) +void wgetopter_t::exchange(wchar_t **argv) { int bottom = first_nonopt; int middle = last_nonopt; @@ -308,8 +215,7 @@ exchange(wchar_t **argv) /* Initialize the internal data when the first call is made. */ -static const wchar_t * -_wgetopt_initialize(const wchar_t *optstring) +const wchar_t * wgetopter_t::_wgetopt_initialize(const wchar_t *optstring) { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped @@ -319,8 +225,6 @@ _wgetopt_initialize(const wchar_t *optstring) nextchar = NULL; - posixly_correct = getenv("POSIXLY_CORRECT"); - /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') @@ -333,8 +237,6 @@ _wgetopt_initialize(const wchar_t *optstring) ordering = REQUIRE_ORDER; ++optstring; } - else if (posixly_correct != NULL) - ordering = REQUIRE_ORDER; else ordering = PERMUTE; @@ -368,7 +270,7 @@ _wgetopt_initialize(const wchar_t *optstring) 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 `woptarg', otherwise `woptarg' is set to zero. + it is returned in `w.woptarg', otherwise `w.woptarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. @@ -397,8 +299,7 @@ _wgetopt_initialize(const wchar_t *optstring) If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ -int -_wgetopt_internal(int argc, wchar_t *const *argv, const wchar_t *optstring, const struct woption *longopts, int *longind, int long_only) +int wgetopter_t::_wgetopt_internal(int argc, wchar_t *const *argv, const wchar_t *optstring, const struct woption *longopts, int *longind, int long_only) { woptarg = NULL; @@ -631,11 +532,7 @@ _wgetopt_internal(int argc, wchar_t *const *argv, const wchar_t *optstring, cons { if (wopterr) { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fwprintf(stderr, _(L"%ls: Illegal option -- %lc\n"), argv[0], c); - else - fwprintf(stderr, _(L"%ls: Invalid option -- %lc\n"), argv[0], c); + fwprintf(stderr, _(L"%ls: Invalid option -- %lc\n"), argv[0], c); } woptopt = c; @@ -693,8 +590,7 @@ _wgetopt_internal(int argc, wchar_t *const *argv, const wchar_t *optstring, cons } } -int -wgetopt(int argc, wchar_t *const *argv, const wchar_t *optstring) +int wgetopter_t::wgetopt(int argc, wchar_t *const *argv, const wchar_t *optstring) { return _wgetopt_internal(argc, argv, optstring, (const struct woption *) 0, @@ -702,14 +598,12 @@ wgetopt(int argc, wchar_t *const *argv, const wchar_t *optstring) 0); } -int -wgetopt_long(int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index) +int wgetopter_t::wgetopt_long(int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index) { return _wgetopt_internal(argc, argv, options, long_options, opt_index, 0); } -int -wgetopt_long_only(int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index) +int wgetopter_t::wgetopt_long_only(int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index) { return _wgetopt_internal(argc, argv, options, long_options, opt_index, 1); } diff --git a/src/wgetopt.h b/src/wgetopt.h index 5a03ba33..91d50489 100644 --- a/src/wgetopt.h +++ b/src/wgetopt.h @@ -49,162 +49,170 @@ Cambridge, MA 02139, USA. */ #include -#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 wchar_t *woptarg; - - /** 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, `woptind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - - extern int woptind; - - /** Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - - extern int wopterr; - - /** Set to an option character which was unrecognized. */ - - extern int woptopt; - - /** 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 woption +class wgetopter_t +{ +private: + void exchange(wchar_t **argv); + const wchar_t * _wgetopt_initialize(const wchar_t *optstring); + int _wgetopt_internal(int argc, wchar_t *const *argv, const wchar_t *optstring, const struct woption *longopts, int *longind, int long_only); + +public: + /* 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. */ + + wchar_t *woptarg; + + /* 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, `woptind' 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 woptind; + + + /* 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. */ + + wchar_t *nextchar; + + /* Callers store zero here to inhibit the error message + for unrecognized options. */ + + int wopterr; + + /* 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. */ + + int woptopt; + + /* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is PERMUTE. + + 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 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 `woptind' != ARGC. */ + + enum { - /** - long name for switch - */ -#if defined (__STDC__) && __STDC__ - const wchar_t *name; -#else - wchar_t *name; -#endif - /** - Must be one of no_argument, required_argument and - optional_argument. - - 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; - - /** - If non-null, the flag whose value should be set if this switch is encountered - */ - int *flag; - - /** - If \c flag is non-null, this is the value that flag will be set - to. Otherwise, this is the return-value of the function call. - */ - int val; - }; - - /* Names for the values of the `has_arg' field of `struct option'. */ - + 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. */ + + int first_nonopt; + int last_nonopt; + + + wgetopter_t() : woptarg(NULL), woptind(0), nextchar(0), wopterr(0), woptopt('?'), first_nonopt(0), last_nonopt(0) + { + } + + int wgetopt(int argc, wchar_t *const *argv, const wchar_t *optstring); + int wgetopt_long(int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index); + int wgetopt_long_only(int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index); +}; + +/** 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 woption +{ /** - Specifies that a switch does not accept an argument + long name for switch */ -#define no_argument 0 + const wchar_t *name; /** - Specifies that a switch requires an argument - */ -#define required_argument 1 - /** - Specifies that a switch accepts an optional argument - */ -#define optional_argument 2 + Must be one of no_argument, required_argument and + optional_argument. -#if defined (__STDC__) && __STDC__ -#ifdef __GNU_LIBRARY__ - /** - Get options from argument list. See the glibc manual for information on how to use this function. + has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ - extern int wgetopt(int argc, wchar_t *const *argv, const wchar_t *shortopts); -#else /* not __GNU_LIBRARY__ */ - - extern int wgetopt(); -#endif /* __GNU_LIBRARY__ */ - /** - Get options from argument list. See the glibc manual for information on how to use this function. - */ - extern int wgetopt_long(int argc, wchar_t *const *argv, const wchar_t *shortopts, - const struct woption *longopts, int *longind); - /** - Get options from argument list. See the glibc manual for information on how to use this function. - */ - extern int wgetopt_long_only(int argc, wchar_t *const *argv, - const wchar_t *shortopts, - const struct woption *longopts, int *longind); + int has_arg; /** - Internal only. Users should not call this directly. + If non-null, the flag whose value should be set if this switch is encountered */ - extern int _wgetopt_internal(int argc, wchar_t *const *argv, - const wchar_t *shortopts, - const struct woption *longopts, int *longind, - int long_only); -#else /* not __STDC__ */ - - /** - Get options from argument list. See the glibc manual for information on how to use this function. - */ - extern int wgetopt(); - - /** - Get options from argument list. See the glibc manual for information on how to use this function. - */ - extern int wgetopt_long(); - - /** - Get options from argument list. See the glibc manual for information on how to use this function. - */ - extern int wgetopt_long_only(); + int *flag; /** - Internal only. Users should not call this directly. + If \c flag is non-null, this is the value that flag will be set + to. Otherwise, this is the return-value of the function call. */ - extern int _wgetopt_internal(); -#endif /* __STDC__ */ + int val; +}; -#ifdef __cplusplus -} -#endif +/* Names for the values of the `has_arg' field of `struct option'. */ + +/** + Specifies that a switch does not accept an argument +*/ +#define no_argument 0 +/** + Specifies that a switch requires an argument +*/ +#define required_argument 1 +/** + Specifies that a switch accepts an optional argument +*/ +#define optional_argument 2 #endif /* FISH_WGETOPT_H */ -- cgit v1.2.3