This is a bit messy, but throwing and catching
Xapian::QueryParserError exceptions outside of the Xapian query parser
seems worse.
---
 lib/parse-time-vrp.cc | 97 +++++++++++++++++++++++++++++++------------
 lib/parse-time-vrp.h  |  8 ++++
 2 files changed, 79 insertions(+), 26 deletions(-)

diff --git a/lib/parse-time-vrp.cc b/lib/parse-time-vrp.cc
index 22bf2ab5..75c67797 100644
--- a/lib/parse-time-vrp.cc
+++ b/lib/parse-time-vrp.cc
@@ -24,21 +24,26 @@
 #include "parse-time-vrp.h"
 #include "parse-time-string.h"
 
-Xapian::Query
-ParseTimeRangeProcessor::operator() (const std::string &begin, const 
std::string &end)
+notmuch_status_t
+_notmuch_time_range_to_query (Xapian::valueno slot, const std::string &begin, 
const std::string &end,
+                             std::string &msg, Xapian::Query &output)
 {
     double from = DBL_MIN, to = DBL_MAX;
     time_t parsed_time, now;
     std::string str;
 
     /* Use the same 'now' for begin and end. */
-    if (time (&now) == (time_t) -1)
-       throw Xapian::QueryParserError ("unable to get current time");
+    if (time (&now) == (time_t) -1) {
+       msg = "unable to get current time";
+       /* XXX Give a better status value */
+       return NOTMUCH_STATUS_ILLEGAL_ARGUMENT;
+    }
 
     if (! begin.empty ()) {
-       if (parse_time_string (begin.c_str (), &parsed_time, &now, 
PARSE_TIME_ROUND_DOWN))
-           throw Xapian::QueryParserError ("Didn't understand date 
specification '" + begin + "'");
-       else
+       if (parse_time_string (begin.c_str (), &parsed_time, &now, 
PARSE_TIME_ROUND_DOWN)) {
+           msg = "Didn't understand date specification '" + begin + "'";
+           return NOTMUCH_STATUS_ILLEGAL_ARGUMENT;
+       } else
            from = (double) parsed_time;
     }
 
@@ -48,39 +53,79 @@ ParseTimeRangeProcessor::operator() (const std::string 
&begin, const std::string
        else
            str = end;
 
-       if (parse_time_string (str.c_str (), &parsed_time, &now, 
PARSE_TIME_ROUND_UP_INCLUSIVE))
-           throw Xapian::QueryParserError ("Didn't understand date 
specification '" + str + "'");
-       else
+       if (parse_time_string (str.c_str (), &parsed_time, &now, 
PARSE_TIME_ROUND_UP_INCLUSIVE)) {
+           msg = "Didn't understand date specification '" + str + "'";
+           return NOTMUCH_STATUS_ILLEGAL_ARGUMENT;
+       } else
            to = (double) parsed_time;
     }
 
-    return Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot,
-                         Xapian::sortable_serialise (from),
-                         Xapian::sortable_serialise (to));
+    output = Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot,
+                           Xapian::sortable_serialise (from),
+                           Xapian::sortable_serialise (to));
+
+    return NOTMUCH_STATUS_SUCCESS;
 }
 
-/* XXX TODO: is throwing an exception the right thing to do here? */
 Xapian::Query
-DateFieldProcessor::operator() (const std::string & str)
+ParseTimeRangeProcessor::operator() (const std::string &begin, const 
std::string &end)
+{
+    Xapian::Query output;
+    notmuch_status_t status;
+    std::string msg;
+
+    status = _notmuch_time_range_to_query (slot, begin, end, msg, output);
+    if (status)
+       throw Xapian::QueryParserError (msg);
+
+    return output;
+}
+
+notmuch_status_t
+_notmuch_time_string_to_query (Xapian::valueno slot, const std::string &str,
+                              std::string &msg, Xapian::Query &output)
 {
     double from = DBL_MIN, to = DBL_MAX;
     time_t parsed_time, now;
 
     /* Use the same 'now' for begin and end. */
-    if (time (&now) == (time_t) -1)
-       throw Xapian::QueryParserError ("Unable to get current time");
+    if (time (&now) == (time_t) -1) {
+       msg = "Unable to get current time";
+       return NOTMUCH_STATUS_ILLEGAL_ARGUMENT;
+    }
 
-    if (parse_time_string (str.c_str (), &parsed_time, &now, 
PARSE_TIME_ROUND_DOWN))
-       throw Xapian::QueryParserError ("Didn't understand date specification 
'" + str + "'");
-    else
+    if (parse_time_string (str.c_str (), &parsed_time, &now, 
PARSE_TIME_ROUND_DOWN)) {
+       msg = "Didn't understand date specification '" + str + "'";
+       return NOTMUCH_STATUS_ILLEGAL_ARGUMENT;
+    } else
        from = (double) parsed_time;
 
-    if (parse_time_string (str.c_str (), &parsed_time, &now, 
PARSE_TIME_ROUND_UP_INCLUSIVE))
-       throw Xapian::QueryParserError ("Didn't understand date specification 
'" + str + "'");
-    else
+    if (parse_time_string (str.c_str (), &parsed_time, &now, 
PARSE_TIME_ROUND_UP_INCLUSIVE)) {
+       msg = "Didn't understand date specification '" + str + "'";
+       return NOTMUCH_STATUS_ILLEGAL_ARGUMENT;
+    } else
        to = (double) parsed_time;
 
-    return Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot,
-                         Xapian::sortable_serialise (from),
-                         Xapian::sortable_serialise (to));
+    output = Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot,
+                           Xapian::sortable_serialise (from),
+                           Xapian::sortable_serialise (to));
+
+    return NOTMUCH_STATUS_SUCCESS;
+
+}
+
+/* XXX TODO: is throwing an exception the right thing to do here? */
+Xapian::Query
+DateFieldProcessor::operator() (const std::string & str)
+{
+    Xapian::Query output;
+    notmuch_status_t status;
+    std::string msg;
+
+    status = _notmuch_time_string_to_query (slot, str, msg, output);
+    if (status)
+       throw Xapian::QueryParserError (msg);
+
+    return output;
+
 }
diff --git a/lib/parse-time-vrp.h b/lib/parse-time-vrp.h
index f495e716..76d16eb2 100644
--- a/lib/parse-time-vrp.h
+++ b/lib/parse-time-vrp.h
@@ -25,6 +25,14 @@
 
 #include <xapian.h>
 
+/* for use outside the Xapian query parser */
+notmuch_status_t
+_notmuch_time_range_to_query (Xapian::valueno slot, const std::string &begin, 
const std::string &end,
+                             std::string &msg, Xapian::Query &output);
+notmuch_status_t
+_notmuch_time_string_to_query (Xapian::valueno slot, const std::string &str,
+                              std::string &msg, Xapian::Query &output);
+
 /* see *ValueRangeProcessor in xapian-core/include/xapian/queryparser.h */
 class ParseTimeRangeProcessor : public Xapian::RangeProcessor {
 
-- 
2.30.2
_______________________________________________
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org

Reply via email to