aboutsummaryrefslogtreecommitdiff
path: root/lib/compat
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2020-04-02 23:03:30 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2020-04-02 23:08:00 +0200
commitd68a600d005d9c110145310dc249daaf73653436 (patch)
tree2c3cc0dc394ac50430d11f45a074845c52b53f3d /lib/compat
parentd76eb9dd46081279642d3353f51ebc09fe4bbe9f (diff)
Add a libcompat implementation for getopt_long
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/compat')
-rw-r--r--lib/compat/Makemodule.am1
-rw-r--r--lib/compat/getopt_long.c72
-rw-r--r--lib/compat/libcompat.vcxproj1
-rw-r--r--lib/compat/libcompat.vcxproj.filters3
4 files changed, 77 insertions, 0 deletions
diff --git a/lib/compat/Makemodule.am b/lib/compat/Makemodule.am
index f1bb2de..b7649ef 100644
--- a/lib/compat/Makemodule.am
+++ b/lib/compat/Makemodule.am
@@ -2,6 +2,7 @@ libcompat_a_SOURCES = lib/compat/getline.c lib/compat/getsubopt.c
libcompat_a_SOURCES += lib/compat/strndup.c lib/compat/mockups.c
libcompat_a_SOURCES += lib/compat/chdir.c include/compat.h
libcompat_a_SOURCES += lib/compat/path_to_windows.c lib/compat/getopt.c
+libcompat_a_SOURCES += lib/compat/getopt_long.c
noinst_LIBRARIES += libcompat.a
diff --git a/lib/compat/getopt_long.c b/lib/compat/getopt_long.c
new file mode 100644
index 0000000..24f5864
--- /dev/null
+++ b/lib/compat/getopt_long.c
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * getopt_long.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+#include "compat.h"
+
+#ifdef HAVE_GETOPT
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#ifndef HAVE_GETOPT_LONG
+int getopt_long(int argc, char *const argv[], const char *optstr,
+ const struct option *longopts, int *longindex)
+{
+ size_t i, len;
+ char *ptr;
+ (void)longindex;
+
+ if (optind >= argc || argv[optind][0] != '-' ||
+ argv[optind][1] != '-' || argv[optind][2] == '\0')
+ return getopt(argc, argv, optstr);
+
+ optarg = NULL;
+ ptr = argv[optind] + 2;
+
+ for (len = 0; ptr[len] != '\0' && ptr[len] != '='; ++len)
+ ;
+
+ for (i = 0; longopts[i].name != NULL; ++i) {
+ if (strncmp(longopts[i].name, ptr, len) != 0)
+ continue;
+
+ if (longopts[i].name[len] == '\0')
+ break;
+ }
+
+ if (longopts[i].name == NULL)
+ goto fail_unknown;
+
+ if (ptr[len] == '=') {
+ if (!longopts[i].has_arg)
+ goto fail_arg;
+
+ optarg = ptr + len + 1;
+ } else if (longopts[i].has_arg) {
+ if (++optind >= argc)
+ goto fail_no_arg;
+
+ optarg = argv[optind];
+ }
+
+ ++optind;
+ return longopts[i].val;
+fail_unknown:
+ fprintf(stderr, "%s: unknown option `--%s`\n", argv[0], ptr);
+ return '?';
+fail_arg:
+ fprintf(stderr, "%s: no argument expected for option `--%s`\n",
+ argv[0], ptr);
+ return '?';
+fail_no_arg:
+ fprintf(stderr, "%s: missing argument for option `--%s`\n",
+ argv[0], ptr);
+ return '?';
+}
+#endif
diff --git a/lib/compat/libcompat.vcxproj b/lib/compat/libcompat.vcxproj
index 307754e..0dada12 100644
--- a/lib/compat/libcompat.vcxproj
+++ b/lib/compat/libcompat.vcxproj
@@ -157,6 +157,7 @@
<ClCompile Include="chdir.c" />
<ClCompile Include="getline.c" />
<ClCompile Include="getopt.c" />
+ <ClCompile Include="getopt_long.c" />
<ClCompile Include="getsubopt.c" />
<ClCompile Include="mockups.c" />
<ClCompile Include="path_to_windows.c" />
diff --git a/lib/compat/libcompat.vcxproj.filters b/lib/compat/libcompat.vcxproj.filters
index f2851d1..2eb9cfb 100644
--- a/lib/compat/libcompat.vcxproj.filters
+++ b/lib/compat/libcompat.vcxproj.filters
@@ -17,6 +17,9 @@
<ClCompile Include="getopt.c">
<Filter>Source</Filter>
</ClCompile>
+ <ClCompile Include="getopt_long.c">
+ <Filter>Source</Filter>
+ </ClCompile>
<ClCompile Include="getsubopt.c">
<Filter>Source</Filter>
</ClCompile>