From 311da16439ef69fc2054af3f4377fd4acd29a0e3 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Wed, 10 Sep 2014 17:21:50 +0200
Subject: [PATCH] Add support for optional_argument to our own getopt_long()
 implementation.

07c8651dd91d5a currently causes compilation errors on mscv (and
probably some other) compilers because our getopt_long()
implementation doesn't have support for optional_argument.

Thus implement optional_argument in our fallback implemenation. It's
quite possibly also useful in other cases.

Arguably this needs a configure check for optional_argument, but it
has existed pretty much since getopt_long() was introduced and thus
doesn't seem worth the configure runtime.

Normally I'd would not push a patch this fast, but this allows msvc to
build again and has low risk as only optional_argument behaviour has
changed.

Author: Michael Paquier and Andres Freund

Discussion: CAB7nPqS5VeedSCxrK=QouokbawgGKLpyc1Q++RRFCa_sjcSVrg@mail.gmail.com
---
 src/include/getopt_long.h |  1 +
 src/port/getopt_long.c    | 16 ++++++++++++----
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/include/getopt_long.h b/src/include/getopt_long.h
index e23c21f333..71a884c49c 100644
--- a/src/include/getopt_long.h
+++ b/src/include/getopt_long.h
@@ -23,6 +23,7 @@ struct option
 
 #define no_argument 0
 #define required_argument 1
+#define optional_argument 2
 #endif
 
 #ifndef HAVE_GETOPT_LONG
diff --git a/src/port/getopt_long.c b/src/port/getopt_long.c
index b099091a76..aa5b7319fd 100644
--- a/src/port/getopt_long.c
+++ b/src/port/getopt_long.c
@@ -100,11 +100,14 @@ getopt_long(int argc, char *const argv[],
 				if (strlen(longopts[i].name) == namelen
 					&& strncmp(place, longopts[i].name, namelen) == 0)
 				{
-					if (longopts[i].has_arg)
+					int			has_arg = longopts[i].has_arg;
+
+					if (has_arg != no_argument)
 					{
 						if (place[namelen] == '=')
 							optarg = place + namelen + 1;
-						else if (optind < argc - 1)
+						else if (optind < argc - 1 &&
+								 has_arg == required_argument)
 						{
 							optind++;
 							optarg = argv[optind];
@@ -113,13 +116,18 @@ getopt_long(int argc, char *const argv[],
 						{
 							if (optstring[0] == ':')
 								return BADARG;
-							if (opterr)
+
+							if (opterr && has_arg == required_argument)
 								fprintf(stderr,
 								   "%s: option requires an argument -- %s\n",
 										argv[0], place);
+
 							place = EMSG;
 							optind++;
-							return BADCH;
+
+							if (has_arg == required_argument)
+								return BADCH;
+							optarg = NULL;
 						}
 					}
 					else
-- 
2.40.0