This is necessary so that programs can take infix syntax queries from
a user and use the sexp query syntax to construct e.g. a refinement of
that query.
---
 lib/parse-sexp.cc         | 32 ++++++++++++++++++++++++++++++++
 test/T081-sexpr-search.sh | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc
index df3629af..502b1be0 100644
--- a/lib/parse-sexp.cc
+++ b/lib/parse-sexp.cc
@@ -56,6 +56,7 @@ static _sexp_field_t fields[] =
     { "from",         Xapian::Query::OP_PHRASE,       SEXP_FLAG_REGEXP },
     { "folder",       Xapian::Query::OP_OR,           SEXP_FLAG_REGEXP },
     { "id",           Xapian::Query::OP_OR,           SEXP_FLAG_REGEXP },
+    { "infix",        Xapian::Query::OP_INVALID,      SEXP_FLAG_NONE },
     { "is",           Xapian::Query::OP_AND,          SEXP_FLAG_WILDCARD | 
SEXP_FLAG_REGEXP },
     { "mid",          Xapian::Query::OP_OR,           SEXP_FLAG_REGEXP },
     { "mimetype",     Xapian::Query::OP_PHRASE,       SEXP_FLAG_NONE },
@@ -236,6 +237,34 @@ _sexp_parse_keywords (notmuch_database_t *notmuch, const 
char *prefix, const sex
     return NOTMUCH_STATUS_SUCCESS;
 }
 
+static notmuch_status_t
+_sexp_parse_infix (notmuch_database_t *notmuch, const sexp_t *sx, 
Xapian::Query &output)
+{
+
+    if (sx->ty != SEXP_VALUE) {
+       _notmuch_database_log (notmuch, "infix argument must be value, not 
list\n");
+       return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
+    }
+    try {
+       output = notmuch->query_parser->parse_query (sx->val, 
NOTMUCH_QUERY_PARSER_FLAGS);
+    } catch (const Xapian::QueryParserError &error) {
+       _notmuch_database_log (notmuch, "Syntax error in infix query: %s\n", 
sx->val);
+       return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
+    } catch (const Xapian::Error &error) {
+       if (! notmuch->exception_reported) {
+           _notmuch_database_log (notmuch,
+                                  "A Xapian exception occurred parsing query: 
%s\n",
+                                  error.get_msg ().c_str ());
+           _notmuch_database_log_append (notmuch,
+                                         "Query string was: %s\n",
+                                         sx->val);
+           notmuch->exception_reported = true;
+           return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+       }
+    }
+    return NOTMUCH_STATUS_SUCCESS;
+}
+
 /* Here we expect the s-expression to be a proper list, with first
  * element defining and operation, or as a special case the empty
  * list */
@@ -296,6 +325,9 @@ _notmuch_sexp_to_xapian_query (notmuch_database_t *notmuch, 
const sexp_t *sx, Xa
                    return _notmuch_query_name_to_query (notmuch, 
sx->list->next->val, output);
                }
            }
+           if (strcasecmp (field->name, "infix") == 0) {
+               return _sexp_parse_infix (notmuch, rest, output);
+           }
 
            term_prefix = _find_prefix (field->name);
 
diff --git a/test/T081-sexpr-search.sh b/test/T081-sexpr-search.sh
index f0a7efb0..45568ba5 100755
--- a/test/T081-sexpr-search.sh
+++ b/test/T081-sexpr-search.sh
@@ -471,4 +471,39 @@ missing subquery
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "infix query"
+notmuch search to:searchbyto | notmuch_search_sanitize > EXPECTED
+notmuch search --query-syntax=sexp '(infix "to:searchbyto")' |  
notmuch_search_sanitize > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "bad infix query 1"
+notmuch search --query-syntax=sexp '(infix "from:/unbalanced")' 2>&1|  
notmuch_search_sanitize > OUTPUT
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+Syntax error in infix query: from:/unbalanced
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "bad infix query 2"
+notmuch search --query-syntax=sexp '(infix "thread:{unbalanced")' 2>&1|  
notmuch_search_sanitize > OUTPUT
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+Syntax error in infix query: thread:{unbalanced
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "infix query that matches no messages"
+notmuch search --query-syntax=sexp '(and (infix "from:keithp") (infix 
"to:keithp"))' > OUTPUT
+test_expect_equal_file /dev/null OUTPUT
+
+test_begin_subtest "compound infix query"
+notmuch search date:2009-11-18..2009-11-18 and tag:unread > EXPECTED
+notmuch search --query-syntax=sexp  '(infix "date:2009-11-18..2009-11-18 and 
tag:unread")' > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "compound infix query 2"
+notmuch search date:2009-11-18..2009-11-18 and tag:unread > EXPECTED
+notmuch search --query-syntax=sexp  '(and (infix 
"date:2009-11-18..2009-11-18") (infix "tag:unread"))' > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
 test_done
-- 
2.30.2
_______________________________________________
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org

Reply via email to