| Index: fusl/src/misc/getopt_long.c
|
| diff --git a/fusl/src/misc/getopt_long.c b/fusl/src/misc/getopt_long.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..480c00139e08682fd15d5798d871be4c85111b76
|
| --- /dev/null
|
| +++ b/fusl/src/misc/getopt_long.c
|
| @@ -0,0 +1,131 @@
|
| +#define _GNU_SOURCE
|
| +#include <stddef.h>
|
| +#include <getopt.h>
|
| +#include <stdio.h>
|
| +#include <string.h>
|
| +
|
| +extern int __optpos, __optreset;
|
| +
|
| +static void permute(char *const *argv, int dest, int src)
|
| +{
|
| + char **av = (char **)argv;
|
| + char *tmp = av[src];
|
| + int i;
|
| + for (i=src; i>dest; i--)
|
| + av[i] = av[i-1];
|
| + av[dest] = tmp;
|
| +}
|
| +
|
| +void __getopt_msg(const char *, const char *, const char *, size_t);
|
| +
|
| +static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly);
|
| +
|
| +static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
|
| +{
|
| + int ret, skipped, resumed;
|
| + if (!optind || __optreset) {
|
| + __optreset = 0;
|
| + __optpos = 0;
|
| + optind = 1;
|
| + }
|
| + if (optind >= argc || !argv[optind]) return -1;
|
| + skipped = optind;
|
| + if (optstring[0] != '+' && optstring[0] != '-') {
|
| + int i;
|
| + for (i=optind; ; i++) {
|
| + if (i >= argc || !argv[i]) return -1;
|
| + if (argv[i][0] == '-' && argv[i][1]) break;
|
| + }
|
| + optind = i;
|
| + }
|
| + resumed = optind;
|
| + ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly);
|
| + if (resumed > skipped) {
|
| + int i, cnt = optind-resumed;
|
| + for (i=0; i<cnt; i++)
|
| + permute(argv, skipped, optind-1);
|
| + optind = skipped + cnt;
|
| + }
|
| + return ret;
|
| +}
|
| +
|
| +static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
|
| +{
|
| + optarg = 0;
|
| + if (longopts && argv[optind][0] == '-' &&
|
| + ((longonly && argv[optind][1]) ||
|
| + (argv[optind][1] == '-' && argv[optind][2])))
|
| + {
|
| + int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':';
|
| + int i, cnt, match;
|
| + char *opt;
|
| + for (cnt=i=0; longopts[i].name; i++) {
|
| + const char *name = longopts[i].name;
|
| + opt = argv[optind]+1;
|
| + if (*opt == '-') opt++;
|
| + for (; *name && *name == *opt; name++, opt++);
|
| + if (*opt && *opt != '=') continue;
|
| + match = i;
|
| + if (!*name) {
|
| + cnt = 1;
|
| + break;
|
| + }
|
| + cnt++;
|
| + }
|
| + if (cnt==1) {
|
| + i = match;
|
| + optind++;
|
| + optopt = longopts[i].val;
|
| + if (*opt == '=') {
|
| + if (!longopts[i].has_arg) {
|
| + if (colon || !opterr)
|
| + return '?';
|
| + __getopt_msg(argv[0],
|
| + ": option does not take an argument: ",
|
| + longopts[i].name,
|
| + strlen(longopts[i].name));
|
| + return '?';
|
| + }
|
| + optarg = opt+1;
|
| + } else if (longopts[i].has_arg == required_argument) {
|
| + if (!(optarg = argv[optind])) {
|
| + if (colon) return ':';
|
| + if (!opterr) return '?';
|
| + __getopt_msg(argv[0],
|
| + ": option requires an argument: ",
|
| + longopts[i].name,
|
| + strlen(longopts[i].name));
|
| + return '?';
|
| + }
|
| + optind++;
|
| + }
|
| + if (idx) *idx = i;
|
| + if (longopts[i].flag) {
|
| + *longopts[i].flag = longopts[i].val;
|
| + return 0;
|
| + }
|
| + return longopts[i].val;
|
| + }
|
| + if (argv[optind][1] == '-') {
|
| + if (!colon && opterr)
|
| + __getopt_msg(argv[0], cnt ?
|
| + ": option is ambiguous: " :
|
| + ": unrecognized option: ",
|
| + argv[optind]+2,
|
| + strlen(argv[optind]+2));
|
| + optind++;
|
| + return '?';
|
| + }
|
| + }
|
| + return getopt(argc, argv, optstring);
|
| +}
|
| +
|
| +int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
|
| +{
|
| + return __getopt_long(argc, argv, optstring, longopts, idx, 0);
|
| +}
|
| +
|
| +int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
|
| +{
|
| + return __getopt_long(argc, argv, optstring, longopts, idx, 1);
|
| +}
|
|
|