cli: Implement "command" option parser

Add a new helper getopt_command() that works like a POSIX-compliant
(i.e. no `argv` permutating) getopt_long(),  except that it doesn't
search for options with a `--' prefix but those without.

Change-Id: I18b63ee4e5b523e2f4cfcd0c8764ea9353927236
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/268
diff --git a/cli_common.c b/cli_common.c
index 90c54b1..8257fcf 100644
--- a/cli_common.c
+++ b/cli_common.c
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <getopt.h>
 #include <sys/stat.h>
 
 #include "flash.h"
@@ -213,6 +214,22 @@
 	return 0;
 }
 
+/* Note: Changes global `optind` from <getopt.h>. */
+int getopt_command(const int argc, char *const argv[], const struct opt_command *const opts)
+{
+	if (optind >= argc || argv[optind][0] == '-')
+		return -1;
+
+	unsigned int i;
+	for (i = 0; opts[i].name; ++i) {
+		if (!strcmp(argv[optind], opts[i].name)) {
+			++optind;
+			return opts[i].val;
+		}
+	}
+	return -1;
+}
+
 void print_generic_options(void)
 {
 	fprintf(stderr, "\n"
diff --git a/include/cli.h b/include/cli.h
index 4347f9c..06cd517 100644
--- a/include/cli.h
+++ b/include/cli.h
@@ -70,6 +70,13 @@
 int close_logfile(void);
 void start_logging(void);
 
+/* generic helper, like getopt_long() but without `--' prefix, re-uses `optind` */
+struct opt_command {
+	const char *name;
+	int val;
+};
+int getopt_command(int argc, char *const argv[], const struct opt_command *);
+
 void print_generic_options(void);
 
 #endif