#include "notmuch-client.h"
#include "sprinter.h"
+#include "string-util.h"
typedef enum {
OUTPUT_SUMMARY,
loop = out = talloc_strdup (ctx, str);
for (; *loop; loop++) {
- if ((unsigned char)(*loop) < 32)
+ if (*loop == '\t' || *loop == '\n')
+ *loop = ' ';
+ else if ((unsigned char)(*loop) < 32)
*loop = '?';
}
return out;
}
+/* Return two stable query strings that identify exactly the matched
+ * and unmatched messages currently in thread. If there are no
+ * matched or unmatched messages, the returned buffers will be
+ * NULL. */
+static int
+get_thread_query (notmuch_thread_t *thread,
+ char **matched_out, char **unmatched_out)
+{
+ notmuch_messages_t *messages;
+ char *escaped = NULL;
+ size_t escaped_len = 0;
+
+ *matched_out = *unmatched_out = NULL;
+
+ for (messages = notmuch_thread_get_messages (thread);
+ notmuch_messages_valid (messages);
+ notmuch_messages_move_to_next (messages))
+ {
+ notmuch_message_t *message = notmuch_messages_get (messages);
+ const char *mid = notmuch_message_get_message_id (message);
+ /* Determine which query buffer to extend */
+ char **buf = notmuch_message_get_flag (
+ message, NOTMUCH_MESSAGE_FLAG_MATCH) ? matched_out : unmatched_out;
+ /* Add this message's id: query. Since "id" is an exclusive
+ * prefix, it is implicitly 'or'd together, so we only need to
+ * join queries with a space. */
+ if (make_boolean_term (thread, "id", mid, &escaped, &escaped_len) < 0)
+ return -1;
+ if (*buf)
+ *buf = talloc_asprintf_append_buffer (*buf, " %s", escaped);
+ else
+ *buf = talloc_strdup (thread, escaped);
+ if (!*buf)
+ return -1;
+ }
+ talloc_free (escaped);
+ return 0;
+}
+
static int
do_search_threads (sprinter_t *format,
notmuch_query_t *query,
format->string (format, authors);
format->map_key (format, "subject");
format->string (format, subject);
+ if (notmuch_format_version >= 2) {
+ char *matched_query, *unmatched_query;
+ if (get_thread_query (thread, &matched_query,
+ &unmatched_query) < 0) {
+ fprintf (stderr, "Out of memory\n");
+ return 1;
+ }
+ format->map_key (format, "query");
+ format->begin_list (format);
+ if (matched_query)
+ format->string (format, matched_query);
+ else
+ format->null (format);
+ if (unmatched_query)
+ format->string (format, unmatched_query);
+ else
+ format->null (format);
+ format->end (format);
+ }
}
talloc_free (ctx_quote);
};
opt_index = parse_arguments (argc, argv, options, 1);
-
- if (opt_index < 0) {
- return 1;
- }
+ if (opt_index < 0)
+ return EXIT_FAILURE;
switch (format_sel) {
case NOTMUCH_FORMAT_TEXT:
case NOTMUCH_FORMAT_TEXT0:
if (output == OUTPUT_SUMMARY) {
fprintf (stderr, "Error: --format=text0 is not compatible with --output=summary.\n");
- return 1;
+ return EXIT_FAILURE;
}
format = sprinter_text0_create (config, stdout);
break;
if (notmuch_database_open (notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much))
- return 1;
+ return EXIT_FAILURE;
query_str = query_string_from_args (notmuch, argc-opt_index, argv+opt_index);
if (query_str == NULL) {
fprintf (stderr, "Out of memory.\n");
- return 1;
+ return EXIT_FAILURE;
}
if (*query_str == '\0') {
fprintf (stderr, "Error: notmuch search requires at least one search term.\n");
- return 1;
+ return EXIT_FAILURE;
}
query = notmuch_query_create (notmuch, query_str);
if (query == NULL) {
fprintf (stderr, "Out of memory\n");
- return 1;
+ return EXIT_FAILURE;
}
notmuch_query_set_sort (query, sort);
talloc_free (format);
- return ret;
+ return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}