home: hub: minipeg

Download patch

ref: aee77b97a7506d7cd3f02f80a713f1e6b5d1271e
parent: bf7a16e59b193714cece221765b046845acb1696
author: Gregory Pakosz <gregory.pakosz@gmail.com>
date: Mon Jul 22 06:41:05 CDT 2013

imported peg-0.1.12

--- a/README.md
+++ b/README.md
@@ -26,6 +26,9 @@
 
 ## Version history
 
+* **0.1.12** ([zip](../../archive/0.1.12.zip), [tar.gz](../../archive/0.1.12.tar.gz)) &mdash; 2013-07-20  
+Use BSD-licensed `getopt()` in Windows build.  
+Verbose mode handles Variable nodes.  
 * **0.1.11** ([zip](../../archive/0.1.11.zip), [tar.gz](../../archive/0.1.11.tar.gz)) &mdash; 2013-06-03  
 Add error actions via `"~"` operator.  
 Support declaration of local variables at the top level of semantic actions.  
--- a/src/leg.c
+++ b/src/leg.c
@@ -1,4 +1,4 @@
-/* A recursive-descent parser generated by peg 0.1.11 */
+/* A recursive-descent parser generated by peg 0.1.12 */
 
 #include <stdio.h>
 #include <stdlib.h>
--- a/src/peg.peg-c
+++ b/src/peg.peg-c
@@ -1,4 +1,4 @@
-/* A recursive-descent parser generated by peg 0.1.11 */
+/* A recursive-descent parser generated by peg 0.1.12 */
 
 #include <stdio.h>
 #include <stdlib.h>
--- a/src/tree.c
+++ b/src/tree.c
@@ -13,7 +13,7 @@
  * 
  * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
  * 
- * Last edited: 2012-05-15 23:29:12 by piumarta on emilia
+ * Last edited: 2013-07-20 12:47:35 by piumarta on margaux1
  */
 
 #include <stdio.h>
@@ -310,6 +310,7 @@
   switch (node->type)
     {
     case Rule:		fprintf(stream, " %s", node->rule.name);				break;
+    case Variable:	fprintf(stream, " %s:", node->variable.name);				break;
     case Name:		fprintf(stream, " %s", node->name.rule->rule.name);			break;
     case Dot:		fprintf(stream, " .");							break;
     case Character:	fprintf(stream, " '%s'", node->character.value);			break;
--- a/src/version.h
+++ b/src/version.h
@@ -1,3 +1,3 @@
 #define PEG_MAJOR	0
 #define PEG_MINOR	1
-#define PEG_LEVEL	11
+#define PEG_LEVEL	12
--- a/win/getopt.c
+++ b/win/getopt.c
@@ -1,230 +1,562 @@
+/*	$OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl Exp $	*/
+/*	$NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $	*/
+
 /*
- *  pgetopt.c - Portable implementation of getopt() command line args parser, 
- *              originally made available by IBM and the authors listed below.
- *     
- *  Created on 8/8/08.
- *  Portions of this document are Copyright (C) 2008, PlexFX, 
- *											               All Rights Reserved.
+ * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
  *
- *  History: 
- *  Original Date Unknown
- *              This code is quite old, but it was originally called GETOPT.C 
- *              in the comments, along with a GETOPT.H thin header, and used the 
- *              same namespace as the getopt() implementation on my UNIX variant 
- *              platforms.  The original date has been lost.  It may date back 
- *              to even pre-ANSI C.  The development team at PlexFX has been 
- *              using it (primarily for Windows command line tools, but also on
- *              other platforms for many years.  A search for historical dates
- *              via web search engines found it widely used, but no date stamps
- *              on its original form seem to have been preserved.
- *              It can be found in various forms in open source packages, such 
- *              as using a search engine on one or both of the author strings 
- *              shown in the original comment block below.  For example, as of 
- *              the creation date on this file, a slightly modified verion of 
- *              it was used in library code found in the CVS tree for 
- *              OpenSolaris.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
  *
- *              It was also included on at least some of the MSDN Library discs
- *              Around the early 2001-2003 time frame.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- *  2008-08-08  This version is a modified version of the original IBM code, but
- *              the filename and namespace used has been altered along with some
- *              calling convention changes.  As such, it can be used as a drop-
- *              in replacement for getopt() even on UNIX or Linux systems that 
- *              have their own getopt() implementations in libc without naming
- *              collisions.  This means it can be used portably on any OS with
- *              a conforming C compiler.  It does *not* attempt to implement the
- *              more long-winded getopt_long() interface.  Naming of APIs, 
- *              headers and the optarg/optind externs have been prefixed with
- *              'p' to accomplish this.  Examples: pgetopt(), poptarg, poptind,
- *              pgetopt.c, pgetopt.h.
- *              Note: This interface keeps external state (to match original
- *                    calling conventions).  As such, it is not thread safe,
- *                    and should be called in only one thread (use from main()
- *							 before additional threads are started).  As the command
- *                    line should never change, this should not be an issue.
- *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
  */
-
-/* Original IBM "AS IS" license follows */
-
-/*****************************************************************************
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
  *
- *  MODULE NAME : GETOPT.C
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
  *
- *  COPYRIGHTS:
- *             This module contains code made available by IBM
- *             Corporation on an AS IS basis.  Any one receiving the
- *             module is considered to be licensed under IBM copyrights
- *             to use the IBM-provided source code in any way he or she
- *             deems fit, including copying it, compiling it, modifying
- *             it, and redistributing it, with or without
- *             modifications.  No license under any IBM patents or
- *             patent applications is to be implied from this copyright
- *             license.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
  *
- *             A user of the module should understand that IBM cannot
- *             provide technical support for the module and will not be
- *             responsible for any consequences of use of the program.
- *
- *             Any notices, including this one, are not to be removed
- *             from the module without the prior written consent of
- *             IBM.
- *
- *  AUTHOR:   Original author:
- *                 G. R. Blair (BOBBLAIR at AUSVM1)
- *                 Internet: bobblair@bobblair.austin.ibm.com
- *
- *            Extensively revised by:
- *                 John Q. Walker II, Ph.D. (JOHHQ at RALVM6)
- *                 Internet: johnq@ralvm6.vnet.ibm.com
- *
- *****************************************************************************/
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
 
-/******************************************************************************
- * pgetopt()
- *
- * The pgetopt() function is a command line parser.  It returns the next
- * option character in argv that matches an option character in optstring.
- *
- * The argv argument points to an array of argc+1 elements containing argc
- * pointers to character strings followed by a null pointer.
- *
- * The optstring argument points to a string of option characters; if an
- * option character is followed by a colon, the option is expected to have
- * an argument that may or may not be separated from it by white space.
- * The external variable poptarg is set to point to the start of the option
- * argument on return from pgetopt().
- *
- * The pgetopt() function places in poptind the argv index of the next argument
- * to be processed.  The system initializes the external variable poptind to
- * 1 before the first call to pgetopt().
- *
- * When all options have been processed (that is, up to the first nonoption
- * argument), pgetopt() returns EOF.  The special option "--" may be used to
- * delimit the end of the options; EOF will be returned, and "--" will be
- * skipped.
- *
- * The pgetopt() function returns a question mark (?) when it encounters an
- * option character not included in optstring.  This error message can be
- * disabled by setting popterr to zero.  Otherwise, it returns the option
- * character that was detected.
- *
- * If the special option "--" is detected, or all options have been
- * processed, EOF is returned.
- *
- * Options are marked by either a minus sign (-) or a slash (/).
- *
- * No other errors are defined.
- *****************************************************************************/
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <windows.h>
 
-#include <stdio.h>                  /* for EOF */
-#include <string.h>                 /* for strchr() */
-#include "getopt.h"						/* getopt() interface and example code */
+#define	REPLACE_GETOPT		/* use this getopt as the system getopt(3) */
 
-/* global variables that are specified as exported by getopt() */
-char *optarg = NULL;    /* pointer to the start of the option argument  */
-int   optind = 1;       /* number of the next argv[] to be evaluated    */
-int   opterr = 1;       /* non-zero if a question mark should be returned
-                          * when a non-valid option character is detected */
+#ifdef REPLACE_GETOPT
+int	opterr = 1;		/* if error message should be printed */
+int	optind = 1;		/* index into parent argv vector */
+int	optopt = '?';		/* character checked for validity */
+#undef	optreset		/* see getopt.h */
+#define	optreset		__mingw_optreset
+int	optreset;		/* reset getopt */
+char    *optarg;		/* argument associated with option */
+#endif
 
-/* handle possible future character set concerns by putting this in a macro */
-#define _next_char(string)  (char)(*(string+1))
+#define PRINT_ERROR	((opterr) && (*options != ':'))
 
-int 
-getopt(int argc, char *argv[], char *optstring)
+#define FLAG_PERMUTE	0x01	/* permute non-options to the end of argv */
+#define FLAG_ALLARGS	0x02	/* treat non-options as args to option "-1" */
+#define FLAG_LONGONLY	0x04	/* operate as getopt_long_only */
+
+/* return values */
+#define	BADCH		(int)'?'
+#define	BADARG		((*options == ':') ? (int)':' : (int)'?')
+#define	INORDER 	(int)1
+
+#ifndef __CYGWIN__
+#define __progname __argv[0]
+#else
+extern char __declspec(dllimport) *__progname;
+#endif
+
+#ifdef __CYGWIN__
+static char EMSG[] = "";
+#else
+#define	EMSG		""
+#endif
+
+static int getopt_internal(int, char * const *, const char *,
+			   const struct option *, int *, int);
+static int parse_long_options(char * const *, const char *,
+			      const struct option *, int *, int);
+static int gcd(int, int);
+static void permute_args(int, int, int, char * const *);
+
+static char *place = EMSG; /* option letter processing */
+
+/* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1;   /* first option after non options (for permute) */
+
+/* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptchar[] = "unknown option -- %c";
+static const char illoptstring[] = "unknown option -- %s";
+
+static void
+_vwarnx(const char *fmt,va_list ap)
 {
-	static char *IndexPosition = NULL; /* place inside current argv string */
-	char *ArgString = NULL;        /* where to start from next */
-	char *OptString;               /* the string in our program */
-	
-	
-   if (IndexPosition != NULL) {
-		/* we last left off inside an argv string */
-		if (*(++IndexPosition)) {
-			/* there is more to come in the most recent argv */
-			ArgString = IndexPosition;
+  (void)fprintf(stderr,"%s: ",__progname);
+  if (fmt != NULL)
+    (void)vfprintf(stderr,fmt,ap);
+  (void)fprintf(stderr,"\n");
+}
+
+static void
+warnx(const char *fmt,...)
+{
+  va_list ap;
+  va_start(ap,fmt);
+  _vwarnx(fmt,ap);
+  va_end(ap);
+}
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+gcd(int a, int b)
+{
+	int c;
+
+	c = a % b;
+	while (c != 0) {
+		a = b;
+		b = c;
+		c = a % b;
+	}
+
+	return (b);
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+permute_args(int panonopt_start, int panonopt_end, int opt_end,
+	char * const *nargv)
+{
+	int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+	char *swap;
+
+	/*
+	 * compute lengths of blocks and number and size of cycles
+	 */
+	nnonopts = panonopt_end - panonopt_start;
+	nopts = opt_end - panonopt_end;
+	ncycle = gcd(nnonopts, nopts);
+	cyclelen = (opt_end - panonopt_start) / ncycle;
+
+	for (i = 0; i < ncycle; i++) {
+		cstart = panonopt_end+i;
+		pos = cstart;
+		for (j = 0; j < cyclelen; j++) {
+			if (pos >= panonopt_end)
+				pos -= nnonopts;
+			else
+				pos += nopts;
+			swap = nargv[pos];
+			/* LINTED const cast */
+			((char **) nargv)[pos] = nargv[cstart];
+			/* LINTED const cast */
+			((char **)nargv)[cstart] = swap;
 		}
 	}
-	
-	if (ArgString == NULL) {
-		/* we didn't leave off in the middle of an argv string */
-		if (optind >= argc) {
-			/* more command-line arguments than the argument count */
-			IndexPosition = NULL;  /* not in the middle of anything */
-			return EOF;             /* used up all command-line arguments */
+}
+
+/*
+ * parse_long_options --
+ *	Parse long options in argc/argv argument vector.
+ * Returns -1 if short_too is set and the option does not match long_options.
+ */
+static int
+parse_long_options(char * const *nargv, const char *options,
+	const struct option *long_options, int *idx, int short_too)
+{
+	char *current_argv, *has_equal;
+	size_t current_argv_len;
+	int i, ambiguous, match;
+
+#define IDENTICAL_INTERPRETATION(_x, _y)                                \
+	(long_options[(_x)].has_arg == long_options[(_y)].has_arg &&    \
+	 long_options[(_x)].flag == long_options[(_y)].flag &&          \
+	 long_options[(_x)].val == long_options[(_y)].val)
+
+	current_argv = place;
+	match = -1;
+	ambiguous = 0;
+
+	optind++;
+
+	if ((has_equal = strchr(current_argv, '=')) != NULL) {
+		/* argument found (--option=arg) */
+		current_argv_len = has_equal - current_argv;
+		has_equal++;
+	} else
+		current_argv_len = strlen(current_argv);
+
+	for (i = 0; long_options[i].name; i++) {
+		/* find matching long option */
+		if (strncmp(current_argv, long_options[i].name,
+		    current_argv_len))
+			continue;
+
+		if (strlen(long_options[i].name) == current_argv_len) {
+			/* exact match */
+			match = i;
+			ambiguous = 0;
+			break;
 		}
-		
-		/*---------------------------------------------------------------------
-		 * If the next argv[] is not an option, there can be no more options.
-		 *-------------------------------------------------------------------*/
-		ArgString = argv[optind++]; /* set this to the next argument ptr */
-		
-		if (('/' != *ArgString) && /* doesn't start with a slash or a dash? */
-			 ('-' != *ArgString)) {
-			--optind;               /* point to current arg once we're done */
-			optarg = NULL;          /* no argument follows the option */
-			IndexPosition = NULL;  /* not in the middle of anything */
-			return EOF;             /* used up all the command-line flags */
+		/*
+		 * If this is a known short option, don't allow
+		 * a partial match of a single character.
+		 */
+		if (short_too && current_argv_len == 1)
+			continue;
+
+		if (match == -1)	/* partial match */
+			match = i;
+		else if (!IDENTICAL_INTERPRETATION(i, match))
+			ambiguous = 1;
+	}
+	if (ambiguous) {
+		/* ambiguous abbreviation */
+		if (PRINT_ERROR)
+			warnx(ambig, (int)current_argv_len,
+			     current_argv);
+		optopt = 0;
+		return (BADCH);
+	}
+	if (match != -1) {		/* option found */
+		if (long_options[match].has_arg == no_argument
+		    && has_equal) {
+			if (PRINT_ERROR)
+				warnx(noarg, (int)current_argv_len,
+				     current_argv);
+			/*
+			 * XXX: GNU sets optopt to val regardless of flag
+			 */
+			if (long_options[match].flag == NULL)
+				optopt = long_options[match].val;
+			else
+				optopt = 0;
+			return (BADARG);
 		}
-		
-		/* check for special end-of-flags markers */
-		if ((strcmp(ArgString, "-") == 0) ||
-			 (strcmp(ArgString, "--") == 0)) {
-			optarg = NULL;          /* no argument follows the option */
-			IndexPosition = NULL;  /* not in the middle of anything */
-			return EOF;             /* encountered the special flag */
+		if (long_options[match].has_arg == required_argument ||
+		    long_options[match].has_arg == optional_argument) {
+			if (has_equal)
+				optarg = has_equal;
+			else if (long_options[match].has_arg ==
+			    required_argument) {
+				/*
+				 * optional argument doesn't use next nargv
+				 */
+				optarg = nargv[optind++];
+			}
 		}
-		
-		ArgString++;               /* look past the / or - */
+		if ((long_options[match].has_arg == required_argument)
+		    && (optarg == NULL)) {
+			/*
+			 * Missing argument; leading ':' indicates no error
+			 * should be generated.
+			 */
+			if (PRINT_ERROR)
+				warnx(recargstring,
+				    current_argv);
+			/*
+			 * XXX: GNU sets optopt to val regardless of flag
+			 */
+			if (long_options[match].flag == NULL)
+				optopt = long_options[match].val;
+			else
+				optopt = 0;
+			--optind;
+			return (BADARG);
+		}
+	} else {			/* unknown option */
+		if (short_too) {
+			--optind;
+			return (-1);
+		}
+		if (PRINT_ERROR)
+			warnx(illoptstring, current_argv);
+		optopt = 0;
+		return (BADCH);
 	}
-	
-	if (':' == *ArgString) {       /* is it a colon? */
-		/*---------------------------------------------------------------------
-		 * Rare case: if opterr is non-zero, return a question mark;
-		 * otherwise, just return the colon we're on.
-		 *-------------------------------------------------------------------*/
-		return (opterr ? (int)'?' : (int)':');
-	}
-	else if ((OptString = strchr(optstring, *ArgString)) == 0) {
-		/*---------------------------------------------------------------------
-		 * The letter on the command-line wasn't any good.
-		 *-------------------------------------------------------------------*/
-		optarg = NULL;              /* no argument follows the option */
-		IndexPosition = NULL;      /* not in the middle of anything */
-		return (opterr ? (int)'?' : (int)*ArgString);
-	}
-	else {
-		/*---------------------------------------------------------------------
-		 * The letter on the command-line matches one we expect to see
-		 *-------------------------------------------------------------------*/
-		if (':' == _next_char(OptString)) { /* is the next letter a colon? */
-			/* It is a colon.  Look for an argument string. */
-			if ('\0' != _next_char(ArgString)) {  /* argument in this argv? */
-				optarg = &ArgString[1];   /* Yes, it is */
+	if (idx)
+		*idx = match;
+	if (long_options[match].flag) {
+		*long_options[match].flag = long_options[match].val;
+		return (0);
+	} else
+		return (long_options[match].val);
+#undef IDENTICAL_INTERPRETATION
+}
+
+/*
+ * getopt_internal --
+ *	Parse argc/argv argument vector.  Called by user level routines.
+ */
+static int
+getopt_internal(int nargc, char * const *nargv, const char *options,
+	const struct option *long_options, int *idx, int flags)
+{
+	char *oli;				/* option letter list index */
+	int optchar, short_too;
+	static int posixly_correct = -1;
+
+	if (options == NULL)
+		return (-1);
+
+	/*
+	 * XXX Some GNU programs (like cvs) set optind to 0 instead of
+	 * XXX using optreset.  Work around this braindamage.
+	 */
+	if (optind == 0)
+		optind = optreset = 1;
+
+	/*
+	 * Disable GNU extensions if POSIXLY_CORRECT is set or options
+	 * string begins with a '+'.
+	 *
+	 * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or
+	 *                 optreset != 0 for GNU compatibility.
+	 */
+	if (posixly_correct == -1 || optreset != 0)
+		posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+	if (*options == '-')
+		flags |= FLAG_ALLARGS;
+	else if (posixly_correct || *options == '+')
+		flags &= ~FLAG_PERMUTE;
+	if (*options == '+' || *options == '-')
+		options++;
+
+	optarg = NULL;
+	if (optreset)
+		nonopt_start = nonopt_end = -1;
+start:
+	if (optreset || !*place) {		/* update scanning pointer */
+		optreset = 0;
+		if (optind >= nargc) {          /* end of argument vector */
+			place = EMSG;
+			if (nonopt_end != -1) {
+				/* do permutation, if we have to */
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				optind -= nonopt_end - nonopt_start;
 			}
-			else {
-				/*-------------------------------------------------------------
-				 * The argument string must be in the next argv.
-				 * But, what if there is none (bad input from the user)?
-				 * In that case, return the letter, and optarg as NULL.
-				 *-----------------------------------------------------------*/
-				if (optind < argc)
-					optarg = argv[optind++];
-				else {
-					optarg = NULL;
-					return (opterr ? (int)'?' : (int)*ArgString);
-				}
+			else if (nonopt_start != -1) {
+				/*
+				 * If we skipped non-options, set optind
+				 * to the first of them.
+				 */
+				optind = nonopt_start;
 			}
-			IndexPosition = NULL;  /* not in the middle of anything */
+			nonopt_start = nonopt_end = -1;
+			return (-1);
 		}
-		else {
-			/* it's not a colon, so just return the letter */
-			optarg = NULL;          /* no argument follows the option */
-			IndexPosition = ArgString;    /* point to the letter we're on */
+		if (*(place = nargv[optind]) != '-' ||
+		    (place[1] == '\0' && strchr(options, '-') == NULL)) {
+			place = EMSG;		/* found non-option */
+			if (flags & FLAG_ALLARGS) {
+				/*
+				 * GNU extension:
+				 * return non-option as argument to option 1
+				 */
+				optarg = nargv[optind++];
+				return (INORDER);
+			}
+			if (!(flags & FLAG_PERMUTE)) {
+				/*
+				 * If no permutation wanted, stop parsing
+				 * at first non-option.
+				 */
+				return (-1);
+			}
+			/* do permutation */
+			if (nonopt_start == -1)
+				nonopt_start = optind;
+			else if (nonopt_end != -1) {
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				nonopt_start = optind -
+				    (nonopt_end - nonopt_start);
+				nonopt_end = -1;
+			}
+			optind++;
+			/* process next argument */
+			goto start;
 		}
-		return (int)*ArgString;    /* return the letter that matched */
+		if (nonopt_start != -1 && nonopt_end == -1)
+			nonopt_end = optind;
+
+		/*
+		 * If we have "-" do nothing, if "--" we are done.
+		 */
+		if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
+			optind++;
+			place = EMSG;
+			/*
+			 * We found an option (--), so if we skipped
+			 * non-options, we have to permute.
+			 */
+			if (nonopt_end != -1) {
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				optind -= nonopt_end - nonopt_start;
+			}
+			nonopt_start = nonopt_end = -1;
+			return (-1);
+		}
 	}
+
+	/*
+	 * Check long options if:
+	 *  1) we were passed some
+	 *  2) the arg is not just "-"
+	 *  3) either the arg starts with -- we are getopt_long_only()
+	 */
+	if (long_options != NULL && place != nargv[optind] &&
+	    (*place == '-' || (flags & FLAG_LONGONLY))) {
+		short_too = 0;
+		if (*place == '-')
+			place++;		/* --foo long option */
+		else if (*place != ':' && strchr(options, *place) != NULL)
+			short_too = 1;		/* could be short option too */
+
+		optchar = parse_long_options(nargv, options, long_options,
+		    idx, short_too);
+		if (optchar != -1) {
+			place = EMSG;
+			return (optchar);
+		}
+	}
+
+	if ((optchar = (int)*place++) == (int)':' ||
+	    (optchar == (int)'-' && *place != '\0') ||
+	    (oli = strchr(options, optchar)) == NULL) {
+		/*
+		 * If the user specified "-" and  '-' isn't listed in
+		 * options, return -1 (non-option) as per POSIX.
+		 * Otherwise, it is an unknown option character (or ':').
+		 */
+		if (optchar == (int)'-' && *place == '\0')
+			return (-1);
+		if (!*place)
+			++optind;
+		if (PRINT_ERROR)
+			warnx(illoptchar, optchar);
+		optopt = optchar;
+		return (BADCH);
+	}
+	if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
+		/* -W long-option */
+		if (*place)			/* no space */
+			/* NOTHING */;
+		else if (++optind >= nargc) {	/* no arg */
+			place = EMSG;
+			if (PRINT_ERROR)
+				warnx(recargchar, optchar);
+			optopt = optchar;
+			return (BADARG);
+		} else				/* white space */
+			place = nargv[optind];
+		optchar = parse_long_options(nargv, options, long_options,
+		    idx, 0);
+		place = EMSG;
+		return (optchar);
+	}
+	if (*++oli != ':') {			/* doesn't take argument */
+		if (!*place)
+			++optind;
+	} else {				/* takes (optional) argument */
+		optarg = NULL;
+		if (*place)			/* no white space */
+			optarg = place;
+		else if (oli[1] != ':') {	/* arg not optional */
+			if (++optind >= nargc) {	/* no arg */
+				place = EMSG;
+				if (PRINT_ERROR)
+					warnx(recargchar, optchar);
+				optopt = optchar;
+				return (BADARG);
+			} else
+				optarg = nargv[optind];
+		}
+		place = EMSG;
+		++optind;
+	}
+	/* dump back option letter */
+	return (optchar);
 }
 
+#ifdef REPLACE_GETOPT
+/*
+ * getopt --
+ *	Parse argc/argv argument vector.
+ *
+ * [eventually this will replace the BSD getopt]
+ */
+int
+getopt(int nargc, char * const *nargv, const char *options)
+{
 
+	/*
+	 * We don't pass FLAG_PERMUTE to getopt_internal() since
+	 * the BSD getopt(3) (unlike GNU) has never done this.
+	 *
+	 * Furthermore, since many privileged programs call getopt()
+	 * before dropping privileges it makes sense to keep things
+	 * as simple (and bug-free) as possible.
+	 */
+	return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
+}
+#endif /* REPLACE_GETOPT */
+
+/*
+ * getopt_long --
+ *	Parse argc/argv argument vector.
+ */
+int
+getopt_long(int nargc, char * const *nargv, const char *options,
+    const struct option *long_options, int *idx)
+{
+
+	return (getopt_internal(nargc, nargv, options, long_options, idx,
+	    FLAG_PERMUTE));
+}
+
+/*
+ * getopt_long_only --
+ *	Parse argc/argv argument vector.
+ */
+int
+getopt_long_only(int nargc, char * const *nargv, const char *options,
+    const struct option *long_options, int *idx)
+{
+
+	return (getopt_internal(nargc, nargv, options, long_options, idx,
+	    FLAG_PERMUTE|FLAG_LONGONLY));
+}
--- a/win/getopt.h
+++ b/win/getopt.h
@@ -1,134 +1,95 @@
-/*
- *  pgetopt.h - Portable implementation of getopt() command line args parser, 
- *              originally made available by IBM and the authors listed below.
- *     
- *  Created on 8/8/08.
- *  Portions of this document are Copyright (C) 2008, PlexFX, 
- *											               All Rights Reserved.
+#ifndef __GETOPT_H__
+/**
+ * DISCLAIMER
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the w64 mingw-runtime package.
  *
- *  History: 
- *  Original Date Unknown
- *              This code is quite old, but it was originally called GETOPT.H 
- *              in the comments, along with a GETOPT.C source file, and used the 
- *              same namespace as the getopt() implementation on my UNIX variant 
- *              platforms.  The original date has been lost.  It may date back 
- *              to even pre-ANSI C.  The development team at PlexFX has been 
- *              using it (primarily for Windows command line tools, but also on
- *              other platforms for many years.  A search for historical dates
- *              via web search engines found it widely used, but no date stamps
- *              on its original form seem to have been preserved.
- *              It can be found in various forms in open source packages, such 
- *              as using a search engine on one or both of the author strings 
- *              shown in the original comment block below.  For example, as of 
- *              the creation date on this file, a slightly modified verion of 
- *              it was used in library code found in the CVS tree for 
- *              OpenSolaris.
- *
- *              It was also included on at least some of the MSDN Library discs
- *              Around the early 2001-2003 time frame.
- *
- *  2008-08-08  This version is a modified version of the original IBM code, but
- *              the filename and namespace used has been altered along with some
- *              calling convention changes.  As such, it can be used as a drop-
- *              in replacement for getopt() even on UNIX or Linux systems that 
- *              have their own getopt() implementations in libc without naming
- *              collisions.  This means it can be used portably on any OS with
- *              a conforming C compiler.  It does *not* attempt to implement the
- *              more long-winded getopt_long() interface.  Naming of APIs, 
- *              headers and the optarg/optind externs have been prefixed with
- *              'p' to accomplish this.  Examples: pgetopt(), poptarg, poptind,
- *              pgetopt.c, pgetopt.h.  Also added some comments to clarify usage
- *              for the popterr extern.
- *              Note: This interface keeps external state (to match original
- *                    calling conventions).  As such, it is not thread safe,
- *                    and should be called in only one thread (use from main()
- *							 before additional threads are started).  As the command
- *                    line should never change, this should not be an issue.
- *
+ * The w64 mingw-runtime package and its code is distributed in the hope that it 
+ * will be useful but WITHOUT ANY WARRANTY.  ALL WARRANTIES, EXPRESSED OR 
+ * IMPLIED ARE HEREBY DISCLAIMED.  This includes but is not limited to 
+ * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-/* Original IBM "AS IS" license follows */
+#define __GETOPT_H__
 
-/*****************************************************************************
- *
- *  MODULE NAME : GETOPT.H
- *
- *  COPYRIGHTS:
- *             This module contains code made available by IBM
- *             Corporation on an AS IS basis.  Any one receiving the
- *             module is considered to be licensed under IBM copyrights
- *             to use the IBM-provided source code in any way he or she
- *             deems fit, including copying it, compiling it, modifying
- *             it, and redistributing it, with or without
- *             modifications.  No license under any IBM patents or
- *             patent applications is to be implied from this copyright
- *             license.
- *
- *             A user of the module should understand that IBM cannot
- *             provide technical support for the module and will not be
- *             responsible for any consequences of use of the program.
- *
- *             Any notices, including this one, are not to be removed
- *             from the module without the prior written consent of
- *             IBM.
- *
- *  AUTHOR:   Original author:
- *                 G. R. Blair (BOBBLAIR at AUSVM1)
- *                 Internet: bobblair@bobblair.austin.ibm.com
- *
- *            Extensively revised by:
- *                 John Q. Walker II, Ph.D. (JOHHQ at RALVM6)
- *                 Internet: johnq@ralvm6.vnet.ibm.com
- *
- *****************************************************************************/
+/* All the headers include this file. */
+#include <crtdefs.h>
 
-#ifndef H_GETOPT
-#define H_GETOPT 1
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-extern char * optarg;  /* carries the optional argument when a command line
-                         * arg is specified with a ':' after it in the optstring
-                         * and is usually handled by the caller in a switch()
-                         * block. */
-extern int    optind;	/* The caller should not need to adjust this normally */
-extern int    opterr;  /* The getopt() function returns a question mark (?) 
-                         * when it encounters an option character not included in 
-								 * optstring.  This error message can be disabled by 
-                         * setting opterr to zero.  Otherwise, it returns the 
-                         * option character that was detected. */
+extern int optind;		/* index of first non-option in argv      */
+extern int optopt;		/* single option character, as parsed     */
+extern int opterr;		/* flag to enable built-in diagnostics... */
+				/* (user may set to zero, to suppress)    */
 
-int getopt(int argc, char *argv[], char *optstring);
+extern char *optarg;		/* pointer to argument of current option  */
 
-/* Example code by PlexFX to demonstrate calling of and parsing optional extra
- * args.  This is a sample code fragment, untested, minimal or non-existent 
- * error handling, and some headers variable declarations are omitted.
+extern int getopt(int nargc, char * const *nargv, const char *options);
+
+#ifdef _BSD_SOURCE
+/*
+ * BSD adds the non-standard `optreset' feature, for reinitialisation
+ * of `getopt' parsing.  We support this feature, for applications which
+ * proclaim their BSD heritage, before including this header; however,
+ * to maintain portability, developers are advised to avoid it.
  */
+# define optreset  __mingw_optreset
+extern int optreset;
+#endif
+#ifdef __cplusplus
+}
+#endif
+/*
+ * POSIX requires the `getopt' API to be specified in `unistd.h';
+ * thus, `unistd.h' includes this header.  However, we do not want
+ * to expose the `getopt_long' or `getopt_long_only' APIs, when
+ * included in this manner.  Thus, close the standard __GETOPT_H__
+ * declarations block, and open an additional __GETOPT_LONG_H__
+ * specific block, only when *not* __UNISTD_H_SOURCED__, in which
+ * to declare the extended API.
+ */
+#endif /* !defined(__GETOPT_H__) */
 
-#if 0 /* remove, for example purposes only */
+#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
+#define __GETOPT_LONG_H__
 
-/* Note the ':' shown below in the pattern string, to specify additional arg */
-char opt_pattern[] = "s:V?";
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-while ((c = getopt(argc, argv, opt_pattern)) != -1) 
+struct option		/* specification for a long form option...	*/
 {
-	switch(c) 
-	{
-      case 's':      /* specify a /s option with a numeric size parameter 
-							 * which is provided in optarg, a char *
-		                * Example: $ someprogram /s 100
-		                */
-			
-			some_size = atoi(optarg);   /* should use strtol() in new code */
-         break;
-		case 'V':		/* specify a /V version option, with no parameter */
-			puts("someprogram: Version 1.0");
-			break;
-		case '?':		/* explicit allows of -? or /? */
-		default:			/* and give usage any time invalid arguments are given */
-			PrintUsage();						/* call some function to show usage */
-			break;
-	}
-}
-#endif /* 0 */
+  const char *name;		/* option name, without leading hyphens */
+  int         has_arg;		/* does it take an argument?		*/
+  int        *flag;		/* where to save its status, or NULL	*/
+  int         val;		/* its associated status value		*/
+};
 
-#endif /* ! H_GETOPT */
+enum    		/* permitted values for its `has_arg' field...	*/
+{
+  no_argument = 0,      	/* option never takes an argument	*/
+  required_argument,		/* option always requires an argument	*/
+  optional_argument		/* option may take an argument		*/
+};
 
+extern int getopt_long(int nargc, char * const *nargv, const char *options,
+    const struct option *long_options, int *idx);
+extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
+    const struct option *long_options, int *idx);
+/*
+ * Previous MinGW implementation had...
+ */
+#ifndef HAVE_DECL_GETOPT
+/*
+ * ...for the long form API only; keep this for compatibility.
+ */
+# define HAVE_DECL_GETOPT	1
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */