Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id C608D6DE0231 for ; Sun, 22 May 2016 07:29:19 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at cworth.org X-Spam-Flag: NO X-Spam-Score: -0.012 X-Spam-Level: X-Spam-Status: No, score=-0.012 tagged_above=-999 required=5 tests=[AWL=-0.001, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01] autolearn=disabled Received: from arlo.cworth.org ([127.0.0.1]) by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id XVd3_frxp_4y for ; Sun, 22 May 2016 07:29:11 -0700 (PDT) Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197]) by arlo.cworth.org (Postfix) with ESMTPS id 652246DE0222 for ; Sun, 22 May 2016 07:29:10 -0700 (PDT) Received: from remotemail by fethera.tethera.net with local (Exim 4.84) (envelope-from ) id 1b4UNK-00051Q-Ct; Sun, 22 May 2016 10:29:02 -0400 Received: (nullmailer pid 5517 invoked by uid 1000); Sun, 22 May 2016 14:29:09 -0000 From: David Bremner To: notmuch@notmuchmail.org Subject: [RFC patch 1/2] lib: refactor _notmuch_message_has_term Date: Sun, 22 May 2016 11:28:58 -0300 Message-Id: <1463927339-5441-2-git-send-email-david@tethera.net> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1463927339-5441-1-git-send-email-david@tethera.net> References: <1463927339-5441-1-git-send-email-david@tethera.net> X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 May 2016 14:29:19 -0000 With essentially the same code path, we can provide a key/value lookup facility, for future use. --- lib/message.cc | 68 ++++++++++++++++++++++++++++++++++++++++----------- lib/notmuch-private.h | 6 +++++ 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/lib/message.cc b/lib/message.cc index 6839305..90c2bb2 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -1263,36 +1263,76 @@ _notmuch_message_remove_term (notmuch_message_t *message, return NOTMUCH_PRIVATE_STATUS_SUCCESS; } +/* + * look for a term with given prefix. If value != NULL, return the + * suffix of the first such term. If suffix == NULL, consider any + * non-empty suffix a mismatch +*/ +notmuch_private_status_t +_notmuch_message_get_prefixed_term (notmuch_message_t *message, + const char *prefix, + const char **value) +{ + notmuch_private_status_t status = NOTMUCH_PRIVATE_STATUS_SUCCESS; + + if (strlen (prefix) > NOTMUCH_TERM_MAX) + return NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG; + + try { + /* Look for prefixed term */ + Xapian::TermIterator i = message->doc.termlist_begin (); + i.skip_to (prefix); + if ((i == message->doc.termlist_end ()) || + (strncmp (prefix, (*i).c_str (), strlen(prefix)) != 0)) { + status = NOTMUCH_PRIVATE_STATUS_NO_TERM_FOUND; + } else { + std::string suffix = (*i).substr (strlen (prefix)); + if (value) { + *value = talloc_strdup (message, suffix.c_str ()); + } else { + /* non-exact match considered failure */ + if (suffix.length () > 0) + status = NOTMUCH_PRIVATE_STATUS_NO_TERM_FOUND; + } + } + } catch (Xapian::Error &error) { + status = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION; + } + + return status; +} + notmuch_private_status_t _notmuch_message_has_term (notmuch_message_t *message, const char *prefix_name, const char *value, notmuch_bool_t *result) { + notmuch_bool_t out = TRUE; + notmuch_private_status_t status; char *term; - notmuch_bool_t out = FALSE; - notmuch_private_status_t status = NOTMUCH_PRIVATE_STATUS_SUCCESS; if (value == NULL) return NOTMUCH_PRIVATE_STATUS_NULL_POINTER; + term = talloc_asprintf (message, "%s%s", _find_prefix (prefix_name), value); - if (strlen (term) > NOTMUCH_TERM_MAX) - return NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG; + if (term == NULL) { + status = NOTMUCH_PRIVATE_STATUS_OUT_OF_MEMORY; + goto DONE; + } - try { - /* Look for the exact term */ - Xapian::TermIterator i = message->doc.termlist_begin (); - i.skip_to (term); - if (i != message->doc.termlist_end () && - !strcmp ((*i).c_str (), term)) - out = TRUE; - } catch (Xapian::Error &error) { - status = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION; + status = _notmuch_message_get_prefixed_term (message, term, NULL); + if (status == NOTMUCH_PRIVATE_STATUS_NO_TERM_FOUND) { + status = NOTMUCH_PRIVATE_STATUS_SUCCESS; + out = FALSE; } - talloc_free (term); + + DONE: + if (term) + talloc_free (term); *result = out; return status; diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index 9280797..f7eba4a 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -141,6 +141,7 @@ typedef enum _notmuch_private_status { /* Then add our own private values. */ NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG = NOTMUCH_STATUS_LAST_STATUS, NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND, + NOTMUCH_PRIVATE_STATUS_NO_TERM_FOUND, NOTMUCH_PRIVATE_STATUS_LAST_STATUS } notmuch_private_status_t; @@ -333,6 +334,11 @@ _notmuch_message_initialize_ghost (notmuch_message_t *message, void _notmuch_message_close (notmuch_message_t *message); +notmuch_private_status_t +_notmuch_message_get_prefixed_term (notmuch_message_t *message, + const char *prefix, + const char **suffix); + /* Get a copy of the data in this message document. * * Caller should talloc_free the result when done. -- 2.8.1