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/compat/getopt_long.c | |
parent | d76eb9dd46081279642d3353f51ebc09fe4bbe9f (diff) |
Add a libcompat implementation for getopt_long
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/compat/getopt_long.c')
-rw-r--r-- | lib/compat/getopt_long.c | 72 |
1 files changed, 72 insertions, 0 deletions
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 |