[RFC PATCH 1/3] notmuch-opts.[ch]: new argument parsing framework for notmuch.
authorDavid Bremner <bremner@debian.org>
Thu, 1 Dec 2011 01:15:28 +0000 (17:15 +1600)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:40:31 +0000 (09:40 -0800)
d0/29c208fd6d646b01bd95f9ae53c0ea8eb29e20 [new file with mode: 0644]

diff --git a/d0/29c208fd6d646b01bd95f9ae53c0ea8eb29e20 b/d0/29c208fd6d646b01bd95f9ae53c0ea8eb29e20
new file mode 100644 (file)
index 0000000..d75c42f
--- /dev/null
@@ -0,0 +1,200 @@
+Return-Path: <bremner@unb.ca>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 11566431FD0\r
+       for <notmuch@notmuchmail.org>; Wed, 30 Nov 2011 17:15:55 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -2.3\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-2.3 tagged_above=-999 required=5\r
+       tests=[RCVD_IN_DNSWL_MED=-2.3] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id AABemqb8JyQ0 for <notmuch@notmuchmail.org>;\r
+       Wed, 30 Nov 2011 17:15:54 -0800 (PST)\r
+Received: from tempo.its.unb.ca (tempo.its.unb.ca [131.202.1.21])\r
+       (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\r
+       (No client certificate requested)\r
+       by olra.theworths.org (Postfix) with ESMTPS id B17C9429E26\r
+       for <notmuch@notmuchmail.org>; Wed, 30 Nov 2011 17:15:53 -0800 (PST)\r
+Received: from rocinante.cs.unb.ca (m3.kereda.com [207.194.238.3] (may be\r
+       forged)) (authenticated bits=0)\r
+       by tempo.its.unb.ca (8.13.8/8.13.8) with ESMTP id pB11FkF4008705\r
+       (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO);\r
+       Wed, 30 Nov 2011 21:15:48 -0400\r
+Received: from bremner by rocinante.cs.unb.ca with local (Exim 4.76)\r
+       (envelope-from <bremner@tesseract.cs.unb.ca>)\r
+       id 1RVvFZ-0006qC-Ra; Wed, 30 Nov 2011 17:15:45 -0800\r
+From: David Bremner <bremner@debian.org>\r
+To: notmuch@notmuchmail.org\r
+Subject: [RFC PATCH 1/3] notmuch-opts.[ch]: new argument parsing framework for\r
+       notmuch.\r
+Date: Wed, 30 Nov 2011 17:15:28 -0800\r
+Message-Id: <1322702130-26068-1-git-send-email-bremner@debian.org>\r
+X-Mailer: git-send-email 1.7.5.4\r
+In-Reply-To:\r
+ <7574621578db9bbfc88348c87e2f5431f4cb2296.1321223343.git.jani@nikula.org>\r
+References:\r
+ <7574621578db9bbfc88348c87e2f5431f4cb2296.1321223343.git.jani@nikula.org>\r
+Cc: David Bremner <bremner@debian.org>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Thu, 01 Dec 2011 01:15:55 -0000\r
+\r
+As we noticed when Jani kindly converted things to getopt_long, much\r
+of the work in argument parsing in notmuch is due to the the key-value\r
+style arguments like --format=(raw|json|text).  In this intitial\r
+attempt at factoring out some of the argument processing, we include\r
+support for this kind of arguments roughly in the style of getopt_long.\r
+---\r
+ Makefile.local |    1 +\r
+ notmuch-opts.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r
+ notmuch-opts.h |   34 ++++++++++++++++++++++++++\r
+ 3 files changed, 106 insertions(+), 0 deletions(-)\r
+ create mode 100644 notmuch-opts.c\r
+ create mode 100644 notmuch-opts.h\r
+\r
+diff --git a/Makefile.local b/Makefile.local\r
+index c94402b..6606be8 100644\r
+--- a/Makefile.local\r
++++ b/Makefile.local\r
+@@ -303,6 +303,7 @@ notmuch_client_srcs =              \\r
+       notmuch-count.c         \\r
+       notmuch-dump.c          \\r
+       notmuch-new.c           \\r
++      notmuch-opts.c          \\r
+       notmuch-reply.c         \\r
+       notmuch-restore.c       \\r
+       notmuch-search.c        \\r
+diff --git a/notmuch-opts.c b/notmuch-opts.c\r
+new file mode 100644\r
+index 0000000..6aac94c\r
+--- /dev/null\r
++++ b/notmuch-opts.c\r
+@@ -0,0 +1,71 @@\r
++#include <assert.h>\r
++#include <string.h>\r
++#include <stdio.h>\r
++#include "notmuch-opts.h"\r
++\r
++notmuch_bool_t\r
++parse_argument(const char *name,\r
++             const char *arg,\r
++             const notmuch_opt_desc_t *options,\r
++             notmuch_opt_t *state){\r
++\r
++    assert(arg);\r
++    assert(name);\r
++    assert(options);\r
++    assert(state);\r
++\r
++    state->arg_id = 0;\r
++    state->keyword_id = 0;\r
++\r
++    if (strncmp (arg,"--",2) != 0) {\r
++      state->arg_id = '*';\r
++      state->string = arg;\r
++      return TRUE;\r
++    }\r
++\r
++    if (strlen (arg) == 2) {\r
++      state->arg_id = '-';\r
++      return FALSE;\r
++    }\r
++\r
++    arg += 2;\r
++\r
++    const notmuch_opt_desc_t *try = options;\r
++    while (try->name) {\r
++      if (strncmp (arg, try->name, strlen(try->name) ) == 0) {\r
++          state->arg_id = try->arg_id;\r
++          if (try->opt_type == NOTMUCH_OPT_KEYWORD) {\r
++              notmuch_keyword_t *try_arg = try->keywords;\r
++              const char *arg_str=arg + strlen(try->name);\r
++\r
++              if (arg_str[0] != ':' && arg_str[0] != '=') {\r
++                  fprintf (stderr, "%s %s: syntax error\n", name, arg);\r
++                  return FALSE;\r
++              }\r
++\r
++              /* skip delimiter */\r
++              arg_str++;\r
++\r
++              while (try_arg->name && state->keyword_id == 0) {\r
++                  if (strcmp (arg_str, try_arg->name) == 0) {\r
++                      state->keyword_id = try_arg->keyword_id;\r
++                  }\r
++                  try_arg++;\r
++              }\r
++              if (state->keyword_id == 0) {\r
++                  fprintf (stderr, "%s %s: missing keyword\n", name, arg);\r
++                  return FALSE;\r
++              }\r
++\r
++\r
++          }\r
++      }\r
++      try++;\r
++    }\r
++    if (state->arg_id == 0) {\r
++      fprintf (stderr, "%s %s: unknown argument\n", name, arg);\r
++      return FALSE;\r
++    }\r
++\r
++    return TRUE;\r
++}\r
+diff --git a/notmuch-opts.h b/notmuch-opts.h\r
+new file mode 100644\r
+index 0000000..c442e3f\r
+--- /dev/null\r
++++ b/notmuch-opts.h\r
+@@ -0,0 +1,34 @@\r
++#ifndef NOTMUCH_OPTS_H\r
++#define NOTMUCH_OPTS_H\r
++\r
++#include "notmuch.h"\r
++\r
++enum notmuch_opt_type {\r
++    NOTMUCH_OPT_NULL = 0,\r
++    NOTMUCH_OPT_NO_ARG,\r
++    NOTMUCH_OPT_KEYWORD\r
++};\r
++\r
++typedef struct notmuch_keyword {\r
++    const char *name;\r
++    int keyword_id;\r
++} notmuch_keyword_t;\r
++\r
++typedef struct notmuch_opt_desc {\r
++    const char *name;\r
++    int  arg_id;\r
++    enum notmuch_opt_type opt_type;\r
++    struct notmuch_keyword *keywords;\r
++} notmuch_opt_desc_t;\r
++\r
++typedef struct notmuch_opt {\r
++    int arg_id;\r
++    int keyword_id;\r
++    const char *string;\r
++} notmuch_opt_t;\r
++\r
++notmuch_bool_t\r
++parse_argument (const char* name, const char *arg, const notmuch_opt_desc_t *options,\r
++              notmuch_opt_t *result);\r
++\r
++#endif\r
+-- \r
+1.7.5.4\r
+\r