[RFC PATCH 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch.
David Bremner
bremner at debian.org
Wed Nov 30 17:15:28 PST 2011
As we noticed when Jani kindly converted things to getopt_long, much
of the work in argument parsing in notmuch is due to the the key-value
style arguments like --format=(raw|json|text). In this intitial
attempt at factoring out some of the argument processing, we include
support for this kind of arguments roughly in the style of getopt_long.
---
Makefile.local | 1 +
notmuch-opts.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
notmuch-opts.h | 34 ++++++++++++++++++++++++++
3 files changed, 106 insertions(+), 0 deletions(-)
create mode 100644 notmuch-opts.c
create mode 100644 notmuch-opts.h
diff --git a/Makefile.local b/Makefile.local
index c94402b..6606be8 100644
--- a/Makefile.local
+++ b/Makefile.local
@@ -303,6 +303,7 @@ notmuch_client_srcs = \
notmuch-count.c \
notmuch-dump.c \
notmuch-new.c \
+ notmuch-opts.c \
notmuch-reply.c \
notmuch-restore.c \
notmuch-search.c \
diff --git a/notmuch-opts.c b/notmuch-opts.c
new file mode 100644
index 0000000..6aac94c
--- /dev/null
+++ b/notmuch-opts.c
@@ -0,0 +1,71 @@
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include "notmuch-opts.h"
+
+notmuch_bool_t
+parse_argument(const char *name,
+ const char *arg,
+ const notmuch_opt_desc_t *options,
+ notmuch_opt_t *state){
+
+ assert(arg);
+ assert(name);
+ assert(options);
+ assert(state);
+
+ state->arg_id = 0;
+ state->keyword_id = 0;
+
+ if (strncmp (arg,"--",2) != 0) {
+ state->arg_id = '*';
+ state->string = arg;
+ return TRUE;
+ }
+
+ if (strlen (arg) == 2) {
+ state->arg_id = '-';
+ return FALSE;
+ }
+
+ arg += 2;
+
+ const notmuch_opt_desc_t *try = options;
+ while (try->name) {
+ if (strncmp (arg, try->name, strlen(try->name) ) == 0) {
+ state->arg_id = try->arg_id;
+ if (try->opt_type == NOTMUCH_OPT_KEYWORD) {
+ notmuch_keyword_t *try_arg = try->keywords;
+ const char *arg_str=arg + strlen(try->name);
+
+ if (arg_str[0] != ':' && arg_str[0] != '=') {
+ fprintf (stderr, "%s %s: syntax error\n", name, arg);
+ return FALSE;
+ }
+
+ /* skip delimiter */
+ arg_str++;
+
+ while (try_arg->name && state->keyword_id == 0) {
+ if (strcmp (arg_str, try_arg->name) == 0) {
+ state->keyword_id = try_arg->keyword_id;
+ }
+ try_arg++;
+ }
+ if (state->keyword_id == 0) {
+ fprintf (stderr, "%s %s: missing keyword\n", name, arg);
+ return FALSE;
+ }
+
+
+ }
+ }
+ try++;
+ }
+ if (state->arg_id == 0) {
+ fprintf (stderr, "%s %s: unknown argument\n", name, arg);
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/notmuch-opts.h b/notmuch-opts.h
new file mode 100644
index 0000000..c442e3f
--- /dev/null
+++ b/notmuch-opts.h
@@ -0,0 +1,34 @@
+#ifndef NOTMUCH_OPTS_H
+#define NOTMUCH_OPTS_H
+
+#include "notmuch.h"
+
+enum notmuch_opt_type {
+ NOTMUCH_OPT_NULL = 0,
+ NOTMUCH_OPT_NO_ARG,
+ NOTMUCH_OPT_KEYWORD
+};
+
+typedef struct notmuch_keyword {
+ const char *name;
+ int keyword_id;
+} notmuch_keyword_t;
+
+typedef struct notmuch_opt_desc {
+ const char *name;
+ int arg_id;
+ enum notmuch_opt_type opt_type;
+ struct notmuch_keyword *keywords;
+} notmuch_opt_desc_t;
+
+typedef struct notmuch_opt {
+ int arg_id;
+ int keyword_id;
+ const char *string;
+} notmuch_opt_t;
+
+notmuch_bool_t
+parse_argument (const char* name, const char *arg, const notmuch_opt_desc_t *options,
+ notmuch_opt_t *result);
+
+#endif
--
1.7.5.4
More information about the notmuch
mailing list