aboutsummaryrefslogtreecommitdiffstats
path: root/getopt.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2010-07-16 12:45:40 +0300
committerArnold D. Robbins <arnold@skeeve.com>2010-07-16 12:45:40 +0300
commit558ba97bdeac5a68bb9248a5c4cdf2feeb24e771 (patch)
tree5c03c98edb9c5488103a6ffdef047e590e0b35b9 /getopt.c
parent8c042f99cc7465c86351d21331a129111b75345d (diff)
downloadegawk-558ba97bdeac5a68bb9248a5c4cdf2feeb24e771.tar.gz
egawk-558ba97bdeac5a68bb9248a5c4cdf2feeb24e771.tar.bz2
egawk-558ba97bdeac5a68bb9248a5c4cdf2feeb24e771.zip
Move to gawk-3.0.1.
Diffstat (limited to 'getopt.c')
-rw-r--r--getopt.c129
1 files changed, 127 insertions, 2 deletions
diff --git a/getopt.c b/getopt.c
index 023281cd..7306888b 100644
--- a/getopt.c
+++ b/getopt.c
@@ -3,7 +3,7 @@
"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, 95
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@@ -19,6 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+*/
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
@@ -483,7 +484,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
- int indfound;
+ int indfound = 0;
int option_index;
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
@@ -625,6 +626,130 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optopt = c;
return '?';
}
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* 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)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr,
+ gettext ("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *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 (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if (nameend - 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 or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, gettext ("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ 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)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ gettext ("%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ gettext ("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
if (temp[1] == ':')
{
if (temp[2] == ':')