aboutsummaryrefslogtreecommitdiffhomepage
path: root/notmuch-tag.c
diff options
context:
space:
mode:
authorGravatar Austin Clements <amdragon@MIT.EDU>2013-01-06 15:22:38 -0500
committerGravatar David Bremner <bremner@debian.org>2013-01-06 22:39:36 -0400
commit25cf5f5dc45cac42f15643f6df09b46d51d7b5ec (patch)
tree20f76784471c8203620b9c74973632ff76d6be62 /notmuch-tag.c
parentbaca1219af0ef1f81985759e868a68e9dd78e0d1 (diff)
util: Factor out boolean term quoting routine
This is now a generic boolean term quoting function. It performs minimal quoting to produce user-friendly queries. This could live in tag-util as well, but it is really nothing specific to tags (although the conventions are specific to Xapian). The API is changed from "caller-allocates" to "readline-like". The scan for max tag length is pushed down into the quoting routine. Furthermore, this now combines the term prefix with the quoted term; arguably this is just as easy to do in the caller, but this will nicely parallel the boolean term parsing function to be introduced shortly. This is an amalgamation of code written by David Bremner and myself.
Diffstat (limited to 'notmuch-tag.c')
-rw-r--r--notmuch-tag.c48
1 files changed, 14 insertions, 34 deletions
diff --git a/notmuch-tag.c b/notmuch-tag.c
index 88d559be..fc9d43a7 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -19,6 +19,7 @@
*/
#include "notmuch-client.h"
+#include "string-util.h"
static volatile sig_atomic_t interrupted;
@@ -35,25 +36,6 @@ handle_sigint (unused (int sig))
interrupted = 1;
}
-static char *
-_escape_tag (char *buf, const char *tag)
-{
- const char *in = tag;
- char *out = buf;
-
- /* Boolean terms surrounded by double quotes can contain any
- * character. Double quotes are quoted by doubling them. */
- *out++ = '"';
- while (*in) {
- if (*in == '"')
- *out++ = '"';
- *out++ = *in++;
- }
- *out++ = '"';
- *out = 0;
- return buf;
-}
-
typedef struct {
const char *tag;
notmuch_bool_t remove;
@@ -71,25 +53,16 @@ _optimize_tag_query (void *ctx, const char *orig_query_string,
* parenthesize and the exclusion part of the query must not use
* the '-' operator (though the NOT operator is fine). */
- char *escaped, *query_string;
+ char *escaped = NULL;
+ size_t escaped_len = 0;
+ char *query_string;
const char *join = "";
- int i;
- unsigned int max_tag_len = 0;
+ size_t i;
/* Don't optimize if there are no tag changes. */
if (tag_ops[0].tag == NULL)
return talloc_strdup (ctx, orig_query_string);
- /* Allocate a buffer for escaping tags. This is large enough to
- * hold a fully escaped tag with every character doubled plus
- * enclosing quotes and a NUL. */
- for (i = 0; tag_ops[i].tag; i++)
- if (strlen (tag_ops[i].tag) > max_tag_len)
- max_tag_len = strlen (tag_ops[i].tag);
- escaped = talloc_array (ctx, char, max_tag_len * 2 + 3);
- if (! escaped)
- return NULL;
-
/* Build the new query string */
if (strcmp (orig_query_string, "*") == 0)
query_string = talloc_strdup (ctx, "(");
@@ -97,10 +70,17 @@ _optimize_tag_query (void *ctx, const char *orig_query_string,
query_string = talloc_asprintf (ctx, "( %s ) and (", orig_query_string);
for (i = 0; tag_ops[i].tag && query_string; i++) {
+ /* XXX in case of OOM, query_string will be deallocated when
+ * ctx is, which might be at shutdown */
+ if (make_boolean_term (ctx,
+ "tag", tag_ops[i].tag,
+ &escaped, &escaped_len))
+ return NULL;
+
query_string = talloc_asprintf_append_buffer (
- query_string, "%s%stag:%s", join,
+ query_string, "%s%s%s", join,
tag_ops[i].remove ? "" : "not ",
- _escape_tag (escaped, tag_ops[i].tag));
+ escaped);
join = " or ";
}