From: "Kristian Høgsberg" <krh@redhat.com>
To: git@vger.kernel.org
Cc: "Kristian Høgsberg" <krh@redhat.com>
Subject: [PATCH] Move option parsing code to parse-options.[ch].
Date: Fri, 21 Sep 2007 15:01:17 -0400 [thread overview]
Message-ID: <1190401278-2869-1-git-send-email-krh@redhat.com> (raw)
Signed-off-by: Kristian Høgsberg <krh@redhat.com>
---
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
next reply other threads:[~2007-09-21 19:01 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-21 19:01 Kristian Høgsberg [this message]
2007-09-21 19:01 ` [PATCH] Share add_files_to_cache() with builtin-add.c Kristian Høgsberg
2007-09-21 19:44 ` [PATCH] Move option parsing code to parse-options.[ch] Junio C Hamano
2007-09-24 18:41 ` Kristian Høgsberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1190401278-2869-1-git-send-email-krh@redhat.com \
--to=krh@redhat.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).