From 0a3dc05c277707e5ca1a547fa010dab446db8083 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 21 Jan 2012 16:27:51 +0100 Subject: [PATCH] Fix custom getopt_long for certain arguments. getopt_long() treats this as equivalent: {"-c", "foo"}, {"-cfoo"}. This is fixed. --- getopt.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/getopt.c b/getopt.c index 7c4e7241a9..87cf91520b 100644 --- a/getopt.c +++ b/getopt.c @@ -71,18 +71,29 @@ static int parse_short(const char *optstring, char * const *argv) if (!opt) return '?'; - bool multiple_opt = argv[0][2]; + bool extra_opt = argv[0][2]; bool takes_arg = opt[1] == ':'; - if (multiple_opt && takes_arg) // Makes little sense to allow. - return '?'; + + // If we take an argument, and we see additional characters, + // this is in fact the argument (i.e. -cfoo is same as -c foo). + bool embedded_arg = extra_opt && takes_arg; if (takes_arg) { - optarg = argv[1]; - optind += 2; + if (embedded_arg) + { + optarg = argv[0] + 2; + optind++; + } + else + { + optarg = argv[1]; + optind += 2; + } + return optarg ? opt[0] : '?'; } - else if (multiple_opt) + else if (embedded_arg) // If we see additional characters, and they don't take arguments, this means we have multiple flags in one. { memmove(&argv[0][1], &argv[0][2], strlen(&argv[0][2]) + 1); return opt[0];