diff options
| author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-04-02 23:03:30 +0200 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-04-02 23:08:00 +0200 | 
| commit | d68a600d005d9c110145310dc249daaf73653436 (patch) | |
| tree | 2c3cc0dc394ac50430d11f45a074845c52b53f3d /lib | |
| parent | d76eb9dd46081279642d3353f51ebc09fe4bbe9f (diff) | |
Add a libcompat implementation for getopt_long
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/compat/Makemodule.am | 1 | ||||
| -rw-r--r-- | lib/compat/getopt_long.c | 72 | ||||
| -rw-r--r-- | lib/compat/libcompat.vcxproj | 1 | ||||
| -rw-r--r-- | lib/compat/libcompat.vcxproj.filters | 3 | 
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>  | 
