unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH 0/6] cli getoptification
@ 2011-11-13 22:47 Jani Nikula
  2011-11-13 22:47 ` [PATCH 1/6] cli: notmuch new: use getopt_long for parsing command line options Jani Nikula
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Jani Nikula @ 2011-11-13 22:47 UTC (permalink / raw)
  To: notmuch, david

Hi, this set switches to getopt_long for parsing command line options where
applicable, and hopefully makes David happy. ;)

This is on top of id:"cover.1321217854.git.jani@nikula.org".

This was a fairly quick exercise, so watch out for bugs. getopt_long does have
subtle differences from the original. All the tests pass after patch 6/6.

BR,
Jani.


Jani Nikula (6):
  cli: notmuch new: use getopt_long for parsing command line options
  cli: notmuch search: use getopt_long for parsing command line options
  cli: notmuch show: use getopt_long for parsing command line options
  cli: notmuch count: use getopt_long for parsing command line options
  cli: notmuch reply: use getopt_long for parsing command line options
  test: emacs-large-search-buffer: expected results according to
    getopt_long

 notmuch-client.h               |    1 +
 notmuch-count.c                |   33 ++++++++-------
 notmuch-new.c                  |   20 +++++++--
 notmuch-reply.c                |   40 ++++++++++--------
 notmuch-search.c               |   90 +++++++++++++++++++++------------------
 notmuch-show.c                 |   61 +++++++++++++++-----------
 test/emacs-large-search-buffer |    2 +-
 7 files changed, 141 insertions(+), 106 deletions(-)

-- 
1.7.5.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/6] cli: notmuch new: use getopt_long for parsing command line options
  2011-11-13 22:47 [PATCH 0/6] cli getoptification Jani Nikula
@ 2011-11-13 22:47 ` Jani Nikula
  2011-11-13 22:47 ` [PATCH 2/6] cli: notmuch search: " Jani Nikula
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2011-11-13 22:47 UTC (permalink / raw)
  To: notmuch, david

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-client.h |    1 +
 notmuch-new.c    |   20 +++++++++++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index b50cb38..eb16f0d 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -43,6 +43,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <unistd.h>
+#include <getopt.h>
 #include <dirent.h>
 #include <errno.h>
 #include <signal.h>
diff --git a/notmuch-new.c b/notmuch-new.c
index 81a9350..145aa64 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -815,16 +815,26 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
     add_files_state.verbose = 0;
     add_files_state.output_is_a_tty = isatty (fileno (stdout));
 
-    argc--; argv++; /* skip subcommand argument */
+    while (1) {
+	int opt;
+	static struct option options[] = {
+	    { "verbose", no_argument, NULL, 0 },
+	    { NULL, 0, NULL, 0 },
+	};
+
+	opt = getopt_long (argc, argv, "", options, NULL);
+	if (opt == -1)
+	    break;
 
-    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
-	if (STRNCMP_LITERAL (argv[i], "--verbose") == 0) {
+	switch (opt) {
+	case 0:
 	    add_files_state.verbose = 1;
-	} else {
-	    fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
+	    break;
+	case '?':
 	    return 1;
 	}
     }
+
     config = notmuch_config_open (ctx, NULL, NULL);
     if (config == NULL)
 	return 1;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/6] cli: notmuch search: use getopt_long for parsing command line options
  2011-11-13 22:47 [PATCH 0/6] cli getoptification Jani Nikula
  2011-11-13 22:47 ` [PATCH 1/6] cli: notmuch new: use getopt_long for parsing command line options Jani Nikula
@ 2011-11-13 22:47 ` Jani Nikula
  2011-11-13 22:47 ` [PATCH 3/6] cli: notmuch show: " Jani Nikula
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2011-11-13 22:47 UTC (permalink / raw)
  To: notmuch, david

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-search.c |   90 ++++++++++++++++++++++++++++-------------------------
 1 files changed, 48 insertions(+), 42 deletions(-)

diff --git a/notmuch-search.c b/notmuch-search.c
index c62a594..4f7384a 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -417,81 +417,87 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
     notmuch_database_t *notmuch;
     notmuch_query_t *query;
     char *query_str;
-    char *opt;
     notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
     const search_format_t *format = &format_text;
-    int i, ret;
+    int ret;
     output_t output = OUTPUT_SUMMARY;
     int maxitems = -1; /* unlimited */
     int first = 0;
 
-    argc--; argv++; /* skip subcommand argument */
-
-    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
-	if (strcmp (argv[i], "--") == 0) {
-	    i++;
+    while (1) {
+	char *p;
+	int opt;
+	static struct option options[] = {
+	    { "sort", required_argument, NULL, 0 },
+	    { "first", required_argument, NULL, 1 },
+	    { "maxitems", required_argument, NULL, 2 },
+	    { "format", required_argument, NULL, 3 },
+	    { "output", required_argument, NULL, 4 },
+	    { NULL, 0, NULL, 0 },
+	};
+
+	opt = getopt_long (argc, argv, "", options, NULL);
+	if (opt == -1)
 	    break;
-	}
-        if (STRNCMP_LITERAL (argv[i], "--sort=") == 0) {
-	    opt = argv[i] + sizeof ("--sort=") - 1;
-	    if (strcmp (opt, "oldest-first") == 0) {
+
+	switch (opt) {
+	case 0:
+	    if (strcmp (optarg, "oldest-first") == 0) {
 		sort = NOTMUCH_SORT_OLDEST_FIRST;
-	    } else if (strcmp (opt, "newest-first") == 0) {
+	    } else if (strcmp (optarg, "newest-first") == 0) {
 		sort = NOTMUCH_SORT_NEWEST_FIRST;
 	    } else {
-		fprintf (stderr, "Invalid value for --sort: %s\n", opt);
+		fprintf (stderr, "Invalid value for --sort: %s\n", optarg);
 		return 1;
 	    }
-	} else if (STRNCMP_LITERAL (argv[i], "--first=") == 0) {
-	    char *p;
-	    opt = argv[i] + sizeof ("--first=") - 1;
-	    first = strtol (opt, &p, 10);
-	    if (*opt == '\0' || p == opt || *p != '\0') {
-		fprintf (stderr, "Invalid value for --first: %s\n", opt);
+	    break;
+	case 1:
+	    first = strtol (optarg, &p, 10);
+	    if (*optarg == '\0' || p == optarg || *p != '\0') {
+		fprintf (stderr, "Invalid value for --first: %s\n", optarg);
 		return 1;
 	    }
-	} else if (STRNCMP_LITERAL (argv[i], "--maxitems=") == 0) {
-	    char *p;
-	    opt = argv[i] + sizeof ("--maxitems=") - 1;
-	    maxitems = strtoul (opt, &p, 10);
-	    if (*opt == '\0' || p == opt || *p != '\0') {
-		fprintf (stderr, "Invalid value for --maxitems: %s\n", opt);
+	    break;
+	case 2:
+	    maxitems = strtoul (optarg, &p, 10);
+	    if (*optarg == '\0' || p == optarg || *p != '\0') {
+		fprintf (stderr, "Invalid value for --maxitems: %s\n", optarg);
 		return 1;
 	    }
-	} else if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
-	    opt = argv[i] + sizeof ("--format=") - 1;
-	    if (strcmp (opt, "text") == 0) {
+	    break;
+	case 3:
+	    if (strcmp (optarg, "text") == 0) {
 		format = &format_text;
-	    } else if (strcmp (opt, "json") == 0) {
+	    } else if (strcmp (optarg, "json") == 0) {
 		format = &format_json;
 	    } else {
-		fprintf (stderr, "Invalid value for --format: %s\n", opt);
+		fprintf (stderr, "Invalid value for --format: %s\n", optarg);
 		return 1;
 	    }
-	} else if (STRNCMP_LITERAL (argv[i], "--output=") == 0) {
-	    opt = argv[i] + sizeof ("--output=") - 1;
-	    if (strcmp (opt, "summary") == 0) {
+	    break;
+	case 4:
+	    if (strcmp (optarg, "summary") == 0) {
 		output = OUTPUT_SUMMARY;
-	    } else if (strcmp (opt, "threads") == 0) {
+	    } else if (strcmp (optarg, "threads") == 0) {
 		output = OUTPUT_THREADS;
-	    } else if (strcmp (opt, "messages") == 0) {
+	    } else if (strcmp (optarg, "messages") == 0) {
 		output = OUTPUT_MESSAGES;
-	    } else if (strcmp (opt, "files") == 0) {
+	    } else if (strcmp (optarg, "files") == 0) {
 		output = OUTPUT_FILES;
-	    } else if (strcmp (opt, "tags") == 0) {
+	    } else if (strcmp (optarg, "tags") == 0) {
 		output = OUTPUT_TAGS;
 	    } else {
-		fprintf (stderr, "Invalid value for --output: %s\n", opt);
+		fprintf (stderr, "Invalid value for --output: %s\n", optarg);
 		return 1;
 	    }
-	} else {
-	    fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
+	    break;
+	case '?':
 	    return 1;
 	}
     }
 
-    argc -= i;
-    argv += i;
+    argc -= optind;
+    argv += optind;
 
     config = notmuch_config_open (ctx, NULL, NULL);
     if (config == NULL)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/6] cli: notmuch show: use getopt_long for parsing command line options
  2011-11-13 22:47 [PATCH 0/6] cli getoptification Jani Nikula
  2011-11-13 22:47 ` [PATCH 1/6] cli: notmuch new: use getopt_long for parsing command line options Jani Nikula
  2011-11-13 22:47 ` [PATCH 2/6] cli: notmuch search: " Jani Nikula
@ 2011-11-13 22:47 ` Jani Nikula
  2011-11-13 22:47 ` [PATCH 4/6] cli: notmuch count: " Jani Nikula
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2011-11-13 22:47 UTC (permalink / raw)
  To: notmuch, david

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-show.c |   61 ++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 603992a..73b4557 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -923,12 +923,10 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
     notmuch_database_t *notmuch;
     notmuch_query_t *query;
     char *query_string;
-    char *opt;
     const notmuch_show_format_t *format = &format_text;
     notmuch_show_params_t params;
     int mbox = 0;
     int format_specified = 0;
-    int i;
 
     params.entire_thread = 0;
     params.raw = 0;
@@ -936,37 +934,50 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
     params.cryptoctx = NULL;
     params.decrypt = 0;
 
-    argc--; argv++; /* skip subcommand argument */
-
-    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
-	if (strcmp (argv[i], "--") == 0) {
-	    i++;
+    while (1) {
+	int opt;
+	static struct option options[] = {
+	    { "format", required_argument, NULL, 0 },
+	    { "part", required_argument, NULL, 1 },
+	    { "entire-thread", no_argument, NULL, 2 },
+	    { "decrypt", no_argument, NULL, 3 },
+	    { "verify", no_argument, NULL, 4 },
+	    { NULL, 0, NULL, 0 },
+	};
+
+	opt = getopt_long (argc, argv, "", options, NULL);
+	if (opt == -1)
 	    break;
-	}
-	if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
-	    opt = argv[i] + sizeof ("--format=") - 1;
-	    if (strcmp (opt, "text") == 0) {
+
+	switch (opt) {
+	case 0:
+	    if (strcmp (optarg, "text") == 0) {
 		format = &format_text;
-	    } else if (strcmp (opt, "json") == 0) {
+	    } else if (strcmp (optarg, "json") == 0) {
 		format = &format_json;
 		params.entire_thread = 1;
-	    } else if (strcmp (opt, "mbox") == 0) {
+	    } else if (strcmp (optarg, "mbox") == 0) {
 		format = &format_mbox;
 		mbox = 1;
-	    } else if (strcmp (opt, "raw") == 0) {
+	    } else if (strcmp (optarg, "raw") == 0) {
 		format = &format_raw;
 		params.raw = 1;
 	    } else {
-		fprintf (stderr, "Invalid value for --format: %s\n", opt);
+		fprintf (stderr, "Invalid value for --format: %s\n", optarg);
 		return 1;
 	    }
 	    format_specified = 1;
-	} else if (STRNCMP_LITERAL (argv[i], "--part=") == 0) {
-	    params.part = atoi(argv[i] + sizeof ("--part=") - 1);
-	} else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
+	    break;
+	case 1:
+	    params.part = atoi(optarg);
+	    break;
+	case 2:
 	    params.entire_thread = 1;
-	} else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
-		   (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
+	    break;
+	case 3:
+	    params.decrypt = 1;
+	    /* fallthrough */
+	case 4:
 	    if (params.cryptoctx == NULL) {
 		GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL);
 		if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg")))
@@ -976,16 +987,14 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
 		g_object_unref (session);
 		session = NULL;
 	    }
-	    if (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)
-		params.decrypt = 1;
-	} else {
-	    fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
+	    break;
+	case '?':
 	    return 1;
 	}
     }
 
-    argc -= i;
-    argv += i;
+    argc -= optind;
+    argv += optind;
 
     config = notmuch_config_open (ctx, NULL, NULL);
     if (config == NULL)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/6] cli: notmuch count: use getopt_long for parsing command line options
  2011-11-13 22:47 [PATCH 0/6] cli getoptification Jani Nikula
                   ` (2 preceding siblings ...)
  2011-11-13 22:47 ` [PATCH 3/6] cli: notmuch show: " Jani Nikula
@ 2011-11-13 22:47 ` Jani Nikula
  2011-11-13 22:47 ` [PATCH 5/6] cli: notmuch reply: " Jani Nikula
  2011-11-13 22:47 ` [PATCH 6/6] test: emacs-large-search-buffer: expected results according to getopt_long Jani Nikula
  5 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2011-11-13 22:47 UTC (permalink / raw)
  To: notmuch, david

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-count.c |   33 ++++++++++++++++++---------------
 1 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 20ce334..4987ca8 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -28,34 +28,37 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
     notmuch_database_t *notmuch;
     notmuch_query_t *query;
     char *query_str;
-    int i;
     notmuch_bool_t output_messages = TRUE;
 
-    argc--; argv++; /* skip subcommand argument */
+    while (1) {
+	int opt;
+	static struct option options[] = {
+	    { "output", required_argument, NULL, 0 },
+	    { NULL, 0, NULL, 0 },
+	};
 
-    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
-	if (strcmp (argv[i], "--") == 0) {
-	    i++;
+	opt = getopt_long (argc, argv, "", options, NULL);
+	if (opt == -1)
 	    break;
-	}
-	if (STRNCMP_LITERAL (argv[i], "--output=") == 0) {
-	    const char *opt = argv[i] + sizeof ("--output=") - 1;
-	    if (strcmp (opt, "threads") == 0) {
+
+	switch (opt) {
+	case 0:
+	    if (strcmp (optarg, "threads") == 0) {
 		output_messages = FALSE;
-	    } else if (strcmp (opt, "messages") == 0) {
+	    } else if (strcmp (optarg, "messages") == 0) {
 		output_messages = TRUE;
 	    } else {
-		fprintf (stderr, "Invalid value for --output: %s\n", opt);
+		fprintf (stderr, "Invalid value for --output: %s\n", optarg);
 		return 1;
 	    }
-	} else {
-	    fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
+	    break;
+	case '?':
 	    return 1;
 	}
     }
 
-    argc -= i;
-    argv += i;
+    argc -= optind;
+    argv += optind;
 
     config = notmuch_config_open (ctx, NULL, NULL);
     if (config == NULL)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/6] cli: notmuch reply: use getopt_long for parsing command line options
  2011-11-13 22:47 [PATCH 0/6] cli getoptification Jani Nikula
                   ` (3 preceding siblings ...)
  2011-11-13 22:47 ` [PATCH 4/6] cli: notmuch count: " Jani Nikula
@ 2011-11-13 22:47 ` Jani Nikula
  2011-11-13 22:47 ` [PATCH 6/6] test: emacs-large-search-buffer: expected results according to getopt_long Jani Nikula
  5 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2011-11-13 22:47 UTC (permalink / raw)
  To: notmuch, david

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 notmuch-reply.c |   40 +++++++++++++++++++++++-----------------
 1 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 7ac879f..45b9fe9 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -619,8 +619,8 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     notmuch_config_t *config;
     notmuch_database_t *notmuch;
     notmuch_query_t *query;
-    char *opt, *query_string;
-    int i, ret = 0;
+    char *query_string;
+    int ret = 0;
     int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);
     notmuch_show_params_t params;
 
@@ -628,24 +628,30 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     params.part = -1;
     params.cryptoctx = NULL;
 
-    argc--; argv++; /* skip subcommand argument */
+    while (1) {
+	int opt;
+	static struct option options[] = {
+	    { "format", required_argument, NULL, 0 },
+	    { "decrypt", no_argument, NULL, 1 },
+	    { NULL, 0, NULL, 0 },
+	};
 
-    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
-	if (strcmp (argv[i], "--") == 0) {
-	    i++;
+	opt = getopt_long (argc, argv, "", options, NULL);
+	if (opt == -1)
 	    break;
-	}
-        if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
-	    opt = argv[i] + sizeof ("--format=") - 1;
-	    if (strcmp (opt, "default") == 0) {
+
+	switch (opt) {
+	case 0:
+	    if (strcmp (optarg, "default") == 0) {
 		reply_format_func = notmuch_reply_format_default;
-	    } else if (strcmp (opt, "headers-only") == 0) {
+	    } else if (strcmp (optarg, "headers-only") == 0) {
 		reply_format_func = notmuch_reply_format_headers_only;
 	    } else {
-		fprintf (stderr, "Invalid value for --format: %s\n", opt);
+		fprintf (stderr, "Invalid value for --format: %s\n", optarg);
 		return 1;
 	    }
-	} else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
+	    break;
+	case 1:
 	    if (params.cryptoctx == NULL) {
 		GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL);
 		if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg")))
@@ -655,14 +661,14 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 		g_object_unref (session);
 		session = NULL;
 	    }
-	} else {
-	    fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
+	    break;
+	case '?':
 	    return 1;
 	}
     }
 
-    argc -= i;
-    argv += i;
+    argc -= optind;
+    argv += optind;
 
     config = notmuch_config_open (ctx, NULL, NULL);
     if (config == NULL)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/6] test: emacs-large-search-buffer: expected results according to getopt_long
  2011-11-13 22:47 [PATCH 0/6] cli getoptification Jani Nikula
                   ` (4 preceding siblings ...)
  2011-11-13 22:47 ` [PATCH 5/6] cli: notmuch reply: " Jani Nikula
@ 2011-11-13 22:47 ` Jani Nikula
  2011-12-01  1:15   ` [RFC PATCH 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch David Bremner
  5 siblings, 1 reply; 13+ messages in thread
From: Jani Nikula @ 2011-11-13 22:47 UTC (permalink / raw)
  To: notmuch, david

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 test/emacs-large-search-buffer |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/test/emacs-large-search-buffer b/test/emacs-large-search-buffer
index 6095e9d..1bdffac 100755
--- a/test/emacs-large-search-buffer
+++ b/test/emacs-large-search-buffer
@@ -35,7 +35,7 @@ test_emacs '(notmuch-search "--this-option-does-not-exist")
 	    (test-output)'
 cat <<EOF >EXPEXTED
 Error: Unexpected output from notmuch search:
-Unrecognized option: --this-option-does-not-exist
+search: unrecognized option '--this-option-does-not-exist'
 End of search results. (process returned 1)
 EOF
 test_expect_equal_file OUTPUT EXPEXTED
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC PATCH 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch.
  2011-11-13 22:47 ` [PATCH 6/6] test: emacs-large-search-buffer: expected results according to getopt_long Jani Nikula
@ 2011-12-01  1:15   ` David Bremner
  2011-12-01  1:15     ` [PATCH 2/3] notmuch-dump: convert to notmuch-opts option-parsing David Bremner
  2011-12-01  1:15     ` [PATCH 3/3] notmuch-dump.c: add a format option David Bremner
  0 siblings, 2 replies; 13+ messages in thread
From: David Bremner @ 2011-12-01  1:15 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/3] notmuch-dump: convert to notmuch-opts option-parsing.
  2011-12-01  1:15   ` [RFC PATCH 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch David Bremner
@ 2011-12-01  1:15     ` David Bremner
  2011-12-01  1:15     ` [PATCH 3/3] notmuch-dump.c: add a format option David Bremner
  1 sibling, 0 replies; 13+ messages in thread
From: David Bremner @ 2011-12-01  1:15 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This is actually a bit of a tricky case because of the treating of the
first non-option as a filename. On the other hand, we don't do any
"normal" argument parsing yet.
---
 notmuch-dump.c |   46 +++++++++++++++++++++++++++++++---------------
 1 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/notmuch-dump.c b/notmuch-dump.c
index 0475eb9..8a8d6ec 100644
--- a/notmuch-dump.c
+++ b/notmuch-dump.c
@@ -19,6 +19,7 @@
  */
 
 #include "notmuch-client.h"
+#include "notmuch-opts.h"
 
 int
 notmuch_dump_command (unused (void *ctx), int argc, char *argv[])
@@ -41,27 +42,42 @@ notmuch_dump_command (unused (void *ctx), int argc, char *argv[])
     if (notmuch == NULL)
 	return 1;
 
-    argc--; argv++; /* skip subcommand argument */
+    notmuch_opt_desc_t options[] = {
+	{ 0, 0, 0, 0 }
+    };
 
-    if (argc && strcmp (argv[0], "--") != 0) {
-	fprintf (stderr, "Warning: the output file argument of dump is deprecated.\n");
-	output = fopen (argv[0], "w");
-	if (output == NULL) {
-	    fprintf (stderr, "Error opening %s for writing: %s\n",
-		     argv[0], strerror (errno));
+    notmuch_opt_t result;
+    int opt_index;
+    notmuch_bool_t more_args=TRUE;
+
+    for (opt_index = 1; more_args && opt_index < argc; opt_index++) {
+
+	more_args=parse_argument (argv[0], argv[opt_index], options, &result);
+
+	switch (result.arg_id) {
+	case '?':
 	    return 1;
+	    break;
+	case '*':
+	    fprintf (stderr, "Warning: the output file argument of dump is deprecated.\n");
+	    output = fopen (result.string, "w");
+	    if (output == NULL) {
+		fprintf (stderr, "Error opening %s for writing: %s\n",
+			 result.string, strerror (errno));
+		return 1;
+	    }
+	case '-':
+	    /* fall through */
+	    more_args=FALSE;
+	    break;
 	}
-	argc--;
-	argv++;
     }
 
-    if (argc && strcmp (argv[0], "--") == 0){
-	argc--;
-	argv++;
-    }
+    if (opt_index < argc && strcmp(argv[opt_index],"--") == 0)
+	opt_index++;
 
-    if (argc) {
-	query_str = query_string_from_args (notmuch, argc, argv);
+    if (opt_index < argc) {
+	query_str = query_string_from_args (notmuch, argc-opt_index, argv+opt_index);
 	if (query_str == NULL) {
 	    fprintf (stderr, "Out of memory.\n");
 	    return 1;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/3] notmuch-dump.c: add a format option
  2011-12-01  1:15   ` [RFC PATCH 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch David Bremner
  2011-12-01  1:15     ` [PATCH 2/3] notmuch-dump: convert to notmuch-opts option-parsing David Bremner
@ 2011-12-01  1:15     ` David Bremner
  2011-12-02  6:41       ` [RFC Patch v2 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch David Bremner
  1 sibling, 1 reply; 13+ messages in thread
From: David Bremner @ 2011-12-01  1:15 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Note that the option does not do anything yet.
---
 notmuch-dump.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/notmuch-dump.c b/notmuch-dump.c
index 8a8d6ec..2a6daef 100644
--- a/notmuch-dump.c
+++ b/notmuch-dump.c
@@ -43,10 +43,13 @@ notmuch_dump_command (unused (void *ctx), int argc, char *argv[])
 	return 1;
 
     notmuch_opt_desc_t options[] = {
+	{ "format", 'f', NOTMUCH_OPT_KEYWORD,
+	  (notmuch_keyword_t []){ { "sup", 's' }, { "path", 'p' }, {0, 0} } },
 	{ 0, 0, 0, 0 }
     };
 
     notmuch_opt_t result;
+    int output_format='s';
     int opt_index;
     notmuch_bool_t more_args=TRUE;
 
@@ -55,6 +58,9 @@ notmuch_dump_command (unused (void *ctx), int argc, char *argv[])
 	more_args=parse_argument (argv[0], argv[opt_index], options, &result);
 
 	switch (result.arg_id) {
+	case 'f':
+	    output_format=result.keyword_id;
+	    break;
 	case '?':
 	    return 1;
 	    break;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC Patch v2 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch.
  2011-12-01  1:15     ` [PATCH 3/3] notmuch-dump.c: add a format option David Bremner
@ 2011-12-02  6:41       ` David Bremner
  2011-12-02  6:41         ` [RFC Patch v2 2/3] notmuch-dump: convert to notmuch-opts argument handling David Bremner
  2011-12-02  6:41         ` [RFC Patch v2 3/3] notmuch-dump: add --format option David Bremner
  0 siblings, 2 replies; 13+ messages in thread
From: David Bremner @ 2011-12-02  6:41 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

From: David Bremner <bremner@debian.org>

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 version I implement Austin Clements' suggestion of basing the
main API on taking pointers to output variables.
---
 Makefile.local |    1 +
 notmuch-opts.c |  120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 notmuch-opts.h |   50 +++++++++++++++++++++++
 3 files changed, 171 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..a8c5223
--- /dev/null
+++ b/notmuch-opts.c
@@ -0,0 +1,120 @@
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include "error_util.h"
+#include "notmuch-opts.h"
+
+/*
+  Search the list of keywords for a given argument, assigning the
+  output variable to the corresponding value.  Return FALSE if nothing
+  matches.
+*/
+
+static notmuch_bool_t
+_process_keyword_arg (const notmuch_opt_desc_t *arg_desc, const char *arg_str) {
+
+    if (arg_str[0] != ':' && arg_str[0] != '=') {
+	return FALSE;
+    }
+
+    /* skip delimiter */
+    arg_str++;
+
+    notmuch_keyword_t *keywords = arg_desc->keywords;
+
+    while (keywords->name) {
+	if (strcmp (arg_str, keywords->name) == 0) {
+	    if (arg_desc->output_var) {
+		*((int *)arg_desc->output_var) = keywords->value;
+	    }
+	    return TRUE;
+	}
+	keywords++;
+    }
+    return FALSE;
+}
+
+/*
+   Search for the {pos_arg_index}th position argument, return FALSE if
+   that does not exist.
+*/
+
+notmuch_bool_t
+parse_position_arg (const char *arg_str, int pos_arg_index, const notmuch_opt_desc_t *arg_desc) {
+
+    int pos_arg_counter = 0;
+    while (arg_desc->name){
+	if (arg_desc->opt_type == NOTMUCH_OPT_POSITION) {
+	    if (pos_arg_counter == pos_arg_index) {
+		if (arg_desc->output_var) {
+		    *((const char **)arg_desc->output_var) = arg_str;
+		}
+		return TRUE;
+	    }
+	    pos_arg_counter++;
+	}
+	arg_desc++;
+    }
+    return FALSE;
+}
+
+notmuch_opt_result_t
+parse_option (const char *arg,
+	      const notmuch_opt_desc_t *options){
+
+    assert(arg);
+    assert(options);
+
+    arg += 2;
+
+    const notmuch_opt_desc_t *try = options;
+    while (try->name) {
+	if (strncmp (arg, try->name, strlen(try->name)) == 0) {
+
+	    switch (try->opt_type) {
+	    case NOTMUCH_OPT_KEYWORD:
+		return  _process_keyword_arg (try, arg+strlen(try->name));
+		break;
+	    case NOTMUCH_OPT_BOOLEAN:
+		return TRUE;
+		break;
+	    case NOTMUCH_OPT_POSITION:
+	    case NOTMUCH_OPT_NULL:
+	    default:
+		INTERNAL_ERROR ("unknown or unhandled option type %d", try->opt_type);
+		/*UNREACHED*/
+	    }
+	}
+	try++;
+    }
+    return FALSE;
+}
+
+int
+notmuch_parse_args (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_index){
+
+    int pos_arg_index = 0;
+    notmuch_bool_t more_args = TRUE;
+
+    while (more_args && opt_index < argc) {
+	if (strncmp (argv[opt_index],"--",2) != 0) {
+
+	    more_args = parse_position_arg (argv[opt_index], pos_arg_index, options);
+
+	    if (more_args) {
+		pos_arg_index++;
+		opt_index++;
+	    }
+
+	} else {
+
+	    if (strlen (argv[opt_index]) == 2)
+		return opt_index+1;
+
+	    more_args = parse_option (argv[opt_index], options);
+	    opt_index++;
+	}
+    }
+
+    return opt_index;
+}
diff --git a/notmuch-opts.h b/notmuch-opts.h
new file mode 100644
index 0000000..75d65cb
--- /dev/null
+++ b/notmuch-opts.h
@@ -0,0 +1,50 @@
+#ifndef NOTMUCH_OPTS_H
+#define NOTMUCH_OPTS_H
+
+#include "notmuch.h"
+
+enum notmuch_opt_type {
+    NOTMUCH_OPT_NULL = 0,
+    NOTMUCH_OPT_BOOLEAN,
+    NOTMUCH_OPT_KEYWORD,
+    NOTMUCH_OPT_POSITION
+};
+
+typedef enum notmuch_opt_result {
+    NOTMUCH_OPT_ERROR = -2,
+    NOTMUCH_OPT_GOT_POS = -1,
+    NOTMUCH_OPT_STOP = 0,
+    NOTMUCH_OPT_SUCCESS = 1
+} notmuch_opt_result_t;
+
+typedef struct notmuch_keyword {
+    const char *name;
+    int value;
+} notmuch_keyword_t;
+
+typedef struct notmuch_opt_desc {
+    const char *name;
+    int  arg_id;
+    enum notmuch_opt_type opt_type;
+    struct notmuch_keyword *keywords;
+    void *output_var;
+} notmuch_opt_desc_t;
+
+typedef struct notmuch_opt {
+    int arg_id;
+    int keyword_id;
+    const char *string;
+} notmuch_opt_t;
+
+notmuch_bool_t
+parse_option (const char *arg, const notmuch_opt_desc_t* options);
+
+notmuch_bool_t
+parse_position_arg (const char *arg,
+		    int position_arg_index,
+		    const notmuch_opt_desc_t* options);
+
+int
+notmuch_parse_args(int argc, char **argv, const notmuch_opt_desc_t *options, int opt_index);
+
+#endif
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC Patch v2 2/3] notmuch-dump: convert to notmuch-opts argument handling.
  2011-12-02  6:41       ` [RFC Patch v2 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch David Bremner
@ 2011-12-02  6:41         ` David Bremner
  2011-12-02  6:41         ` [RFC Patch v2 3/3] notmuch-dump: add --format option David Bremner
  1 sibling, 0 replies; 13+ messages in thread
From: David Bremner @ 2011-12-02  6:41 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

From: David Bremner <bremner@debian.org>

The output file is handled via positional arguments. There are
currently no "normal" options.
---
 notmuch-dump.c |   27 +++++++++++++++------------
 1 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/notmuch-dump.c b/notmuch-dump.c
index 0475eb9..9e0c91d 100644
--- a/notmuch-dump.c
+++ b/notmuch-dump.c
@@ -19,6 +19,7 @@
  */
 
 #include "notmuch-client.h"
+#include "notmuch-opts.h"
 
 int
 notmuch_dump_command (unused (void *ctx), int argc, char *argv[])
@@ -41,27 +42,29 @@ notmuch_dump_command (unused (void *ctx), int argc, char *argv[])
     if (notmuch == NULL)
 	return 1;
 
-    argc--; argv++; /* skip subcommand argument */
+    char *output_file_name = NULL;
+    int opt_index;
 
-    if (argc && strcmp (argv[0], "--") != 0) {
+    notmuch_opt_desc_t options[] = {
+	{ "out-file", 'o', NOTMUCH_OPT_POSITION, 0, &output_file_name },
+	{ 0, 0, 0, 0, 0 }
+    };
+
+    opt_index = notmuch_parse_args (argc, argv, options, 1);
+
+    if (output_file_name) {
 	fprintf (stderr, "Warning: the output file argument of dump is deprecated.\n");
-	output = fopen (argv[0], "w");
+	output = fopen (output_file_name, "w");
 	if (output == NULL) {
 	    fprintf (stderr, "Error opening %s for writing: %s\n",
-		     argv[0], strerror (errno));
+		     output_file_name, strerror (errno));
 	    return 1;
 	}
-	argc--;
-	argv++;
     }
 
-    if (argc && strcmp (argv[0], "--") == 0){
-	argc--;
-	argv++;
-    }
 
-    if (argc) {
-	query_str = query_string_from_args (notmuch, argc, argv);
+    if (opt_index < argc) {
+	query_str = query_string_from_args (notmuch, argc-opt_index, argv+opt_index);
 	if (query_str == NULL) {
 	    fprintf (stderr, "Out of memory.\n");
 	    return 1;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC Patch v2 3/3] notmuch-dump: add --format option
  2011-12-02  6:41       ` [RFC Patch v2 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch David Bremner
  2011-12-02  6:41         ` [RFC Patch v2 2/3] notmuch-dump: convert to notmuch-opts argument handling David Bremner
@ 2011-12-02  6:41         ` David Bremner
  1 sibling, 0 replies; 13+ messages in thread
From: David Bremner @ 2011-12-02  6:41 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

From: David Bremner <bremner@debian.org>

Note that the new option does not control anything at the moment.
---
 notmuch-dump.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/notmuch-dump.c b/notmuch-dump.c
index 9e0c91d..d0ab360 100644
--- a/notmuch-dump.c
+++ b/notmuch-dump.c
@@ -42,10 +42,14 @@ notmuch_dump_command (unused (void *ctx), int argc, char *argv[])
     if (notmuch == NULL)
 	return 1;
 
+    int output_format = 's';
     char *output_file_name = NULL;
     int opt_index;
 
     notmuch_opt_desc_t options[] = {
+	{ "format", 'f', NOTMUCH_OPT_KEYWORD,
+	  (notmuch_keyword_t []){ { "sup", 's' }, { "path", 'p' }, {0, 0} },
+	  &output_format },
 	{ "out-file", 'o', NOTMUCH_OPT_POSITION, 0, &output_file_name },
 	{ 0, 0, 0, 0, 0 }
     };
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2011-12-02  6:42 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-13 22:47 [PATCH 0/6] cli getoptification Jani Nikula
2011-11-13 22:47 ` [PATCH 1/6] cli: notmuch new: use getopt_long for parsing command line options Jani Nikula
2011-11-13 22:47 ` [PATCH 2/6] cli: notmuch search: " Jani Nikula
2011-11-13 22:47 ` [PATCH 3/6] cli: notmuch show: " Jani Nikula
2011-11-13 22:47 ` [PATCH 4/6] cli: notmuch count: " Jani Nikula
2011-11-13 22:47 ` [PATCH 5/6] cli: notmuch reply: " Jani Nikula
2011-11-13 22:47 ` [PATCH 6/6] test: emacs-large-search-buffer: expected results according to getopt_long Jani Nikula
2011-12-01  1:15   ` [RFC PATCH 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch David Bremner
2011-12-01  1:15     ` [PATCH 2/3] notmuch-dump: convert to notmuch-opts option-parsing David Bremner
2011-12-01  1:15     ` [PATCH 3/3] notmuch-dump.c: add a format option David Bremner
2011-12-02  6:41       ` [RFC Patch v2 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch David Bremner
2011-12-02  6:41         ` [RFC Patch v2 2/3] notmuch-dump: convert to notmuch-opts argument handling David Bremner
2011-12-02  6:41         ` [RFC Patch v2 3/3] notmuch-dump: add --format option David Bremner

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

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 read-only IMAP folder(s) and NNTP newsgroup(s).