[PATCH] Move option parsing code to parse-options.[ch].

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Kristian Høgsberg <krh@xxxxxxxxxx>
---
 Makefile         |    2 +-
 builtin-commit.c |  117 ++++++++----------------------------------------------
 parse-options.c  |   74 ++++++++++++++++++++++++++++++++++
 parse-options.h  |   29 +++++++++++++
 4 files changed, 121 insertions(+), 101 deletions(-)
 create mode 100644 parse-options.c
 create mode 100644 parse-options.h

diff --git a/Makefile b/Makefile
index 69ebc7a..2612465 100644
--- a/Makefile
+++ b/Makefile
@@ -310,7 +310,7 @@ LIB_OBJS = \
 	alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
 	color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
 	convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o \
-	transport.o bundle.o
+	transport.o bundle.o parse-options.o
 
 BUILTIN_OBJS = \
 	builtin-add.o \
diff --git a/builtin-commit.c b/builtin-commit.c
index 3e826ca..90f23de 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -18,6 +18,7 @@
 #include "log-tree.h"
 #include "strbuf.h"
 #include "utf8.h"
+#include "parse-options.h"
 
 static const char builtin_commit_usage[] =
 	"[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]";
@@ -27,90 +28,6 @@ static char *use_message_buffer;
 static const char commit_editmsg[] = "COMMIT_EDITMSG";
 static struct lock_file lock_file;
 
-enum option_type {
-    OPTION_NONE,
-    OPTION_STRING,
-    OPTION_INTEGER,
-    OPTION_LAST,
-};
-
-struct option {
-    enum option_type type;
-    const char *long_name;
-    char short_name;
-    void *value;
-};
-
-static int scan_options(const char ***argv, struct option *options)
-{
-	const char *value, *eq;
-	int i;
-
-	if (**argv == NULL)
-		return 0;
-	if ((**argv)[0] != '-')
-		return 0;
-	if (!strcmp(**argv, "--"))
-		return 0;
-
-	value = NULL;
-	for (i = 0; options[i].type != OPTION_LAST; i++) {
-		if ((**argv)[1] == '-') {
-			if (!prefixcmp(options[i].long_name, **argv + 2)) {
-				if (options[i].type != OPTION_NONE)
-					value = *++(*argv);
-				goto match;
-			}
-
-			eq = strchr(**argv + 2, '=');
-			if (eq && options[i].type != OPTION_NONE &&
-			    !strncmp(**argv + 2,
-				     options[i].long_name, eq - **argv - 2)) {
-				value = eq + 1;
-				goto match;
-			}
-		}
-
-		if ((**argv)[1] == options[i].short_name) {
-			if ((**argv)[2] == '\0') {
-				if (options[i].type != OPTION_NONE)
-					value = *++(*argv);
-				goto match;
-			}
-
-			if (options[i].type != OPTION_NONE) {
-				value = **argv + 2;
-				goto match;
-			}
-		}
-	}
-
-	usage(builtin_commit_usage);
-
- match:
-	switch (options[i].type) {
-	case OPTION_NONE:
-		*(int *)options[i].value = 1;
-		break;
-	case OPTION_STRING:
-		if (value == NULL)
-			die("option %s requires a value.", (*argv)[-1]);
-		*(const char **)options[i].value = value;
-		break;
-	case OPTION_INTEGER:
-		if (value == NULL)
-			die("option %s requires a value.", (*argv)[-1]);
-		*(int *)options[i].value = atoi(value);
-		break;
-	default:
-		assert(0);
-	}
-
-	(*argv)++;
-
-	return 1;
-}
-
 static char *logfile, *force_author, *message, *template_file;
 static char *edit_message, *use_message;
 static int all, edit_flag, also, interactive, only, no_verify, amend, signoff;
@@ -120,24 +37,23 @@ static int no_edit, initial_commit, in_merge;
 const char *only_include_assumed;
 
 static struct option commit_options[] = {
-	{ OPTION_STRING, "file", 'F', (void *) &logfile },
-	{ OPTION_NONE, "all", 'a', &all },
-	{ OPTION_STRING, "author", 0, (void *) &force_author },
-	{ OPTION_NONE, "edit", 'e', &edit_flag },
-	{ OPTION_NONE, "include", 'i', &also },
-	{ OPTION_NONE, "interactive", 0, &interactive },
-	{ OPTION_NONE, "only", 'o', &only },
+	{ OPTION_STRING, "file", 'F', &logfile },
+	{ OPTION_BOOLEAN, "all", 'a', &all },
+	{ OPTION_STRING, "author", 0, &force_author },
+	{ OPTION_BOOLEAN, "edit", 'e', &edit_flag },
+	{ OPTION_BOOLEAN, "include", 'i', &also },
+	{ OPTION_BOOLEAN, "interactive", 0, &interactive },
+	{ OPTION_BOOLEAN, "only", 'o', &only },
 	{ OPTION_STRING, "message", 'm', &message },
-	{ OPTION_NONE, "no-verify", 'n', &no_verify },
-	{ OPTION_NONE, "amend", 0, &amend },
+	{ OPTION_BOOLEAN, "no-verify", 'n', &no_verify },
+	{ OPTION_BOOLEAN, "amend", 0, &amend },
 	{ OPTION_STRING, "reedit-message", 'c', &edit_message },
 	{ OPTION_STRING, "reuse-message", 'C', &use_message },
-	{ OPTION_NONE, "signoff", 's', &signoff },
-	{ OPTION_NONE, "quiet", 'q', &quiet },
-	{ OPTION_NONE, "verbose", 'v', &verbose },
-	{ OPTION_NONE, "untracked-files", 0, &untracked_files },
+	{ OPTION_BOOLEAN, "signoff", 's', &signoff },
+	{ OPTION_BOOLEAN, "quiet", 'q', &quiet },
+	{ OPTION_BOOLEAN, "verbose", 'v', &verbose },
+	{ OPTION_BOOLEAN, "untracked-files", 0, &untracked_files },
 	{ OPTION_STRING, "template", 't', &template_file },
-	{ OPTION_LAST },
 };
 
 /* FIXME: Taken from builtin-add, should be shared. */
@@ -432,8 +348,9 @@ static void parse_and_validate_options(const char ***argv)
 	int f = 0;
 
 	(*argv)++;
-	while (scan_options(argv, commit_options))
-		;
+	while (parse_options(argv, commit_options, ARRAY_SIZE(commit_options),
+			     builtin_commit_usage))
+	       ;
 
 	if (logfile || message || use_message)
 		no_edit = 1;
diff --git a/parse-options.c b/parse-options.c
new file mode 100644
index 0000000..2fb30cd
--- /dev/null
+++ b/parse-options.c
@@ -0,0 +1,74 @@
+#include "git-compat-util.h"
+#include "parse-options.h"
+
+int parse_options(const char ***argv,
+		  struct option *options, int count,
+		  const char *usage_string)
+{
+	const char *value, *eq;
+	int i;
+
+	if (**argv == NULL)
+		return 0;
+	if ((**argv)[0] != '-')
+		return 0;
+	if (!strcmp(**argv, "--"))
+		return 0;
+
+	value = NULL;
+	for (i = 0; i < count; i++) {
+		if ((**argv)[1] == '-') {
+			if (!prefixcmp(options[i].long_name, **argv + 2)) {
+				if (options[i].type != OPTION_BOOLEAN)
+					value = *++(*argv);
+				goto match;
+			}
+
+			eq = strchr(**argv + 2, '=');
+			if (eq && options[i].type != OPTION_BOOLEAN &&
+			    !strncmp(**argv + 2,
+				     options[i].long_name, eq - **argv - 2)) {
+				value = eq + 1;
+				goto match;
+			}
+		}
+
+		if ((**argv)[1] == options[i].short_name) {
+			if ((**argv)[2] == '\0') {
+				if (options[i].type != OPTION_BOOLEAN)
+					value = *++(*argv);
+				goto match;
+			}
+
+			if (options[i].type != OPTION_BOOLEAN) {
+				value = **argv + 2;
+				goto match;
+			}
+		}
+	}
+
+	usage(usage_string);
+
+ match:
+	switch (options[i].type) {
+	case OPTION_BOOLEAN:
+		*(int *)options[i].value = 1;
+		break;
+	case OPTION_STRING:
+		if (value == NULL)
+			die("option %s requires a value.", (*argv)[-1]);
+		*(const char **)options[i].value = value;
+		break;
+	case OPTION_INTEGER:
+		if (value == NULL)
+			die("option %s requires a value.", (*argv)[-1]);
+		*(int *)options[i].value = atoi(value);
+		break;
+	default:
+		assert(0);
+	}
+
+	(*argv)++;
+
+	return 1;
+}
diff --git a/parse-options.h b/parse-options.h
new file mode 100644
index 0000000..39399c3
--- /dev/null
+++ b/parse-options.h
@@ -0,0 +1,29 @@
+#ifndef PARSE_OPTIONS_H
+#define PARSE_OPTIONS_H
+
+enum option_type {
+    OPTION_BOOLEAN,
+    OPTION_STRING,
+    OPTION_INTEGER,
+    OPTION_LAST,
+};
+
+struct option {
+    enum option_type type;
+    const char *long_name;
+    char short_name;
+    void *value;
+};
+
+/* Parse the given options against the list of known options.  The
+ * order of the option structs matters, in that ambiguous
+ * abbreviations (eg, --in could be short for --include or
+ * --interactive) are matched by the first option that share the
+ * prefix.
+ */
+
+extern int parse_options(const char ***argv,
+			 struct option *options, int count,
+			 const char *usage_string);
+
+#endif
-- 
1.5.2.5

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux