#include "gmime-filter-reply.h"
#include "sprinter.h"
-static notmuch_status_t
-format_part_text (const void *ctx, sprinter_t *sp, mime_node_t *node,
- int indent, const notmuch_show_params_t *params);
-
-static const notmuch_show_format_t format_text = {
- .new_sprinter = sprinter_text_create,
- .part = format_part_text,
-};
-
-static notmuch_status_t
-format_part_sprinter_entry (const void *ctx, sprinter_t *sp, mime_node_t *node,
- int indent, const notmuch_show_params_t *params);
-
-static const notmuch_show_format_t format_json = {
- .new_sprinter = sprinter_json_create,
- .part = format_part_sprinter_entry,
-};
-
-static const notmuch_show_format_t format_sexp = {
- .new_sprinter = sprinter_sexp_create,
- .part = format_part_sprinter_entry,
-};
-
-static notmuch_status_t
-format_part_mbox (const void *ctx, sprinter_t *sp, mime_node_t *node,
- int indent, const notmuch_show_params_t *params);
-
-static const notmuch_show_format_t format_mbox = {
- .new_sprinter = sprinter_text_create,
- .part = format_part_mbox,
-};
-
-static notmuch_status_t
-format_part_raw (unused (const void *ctx), sprinter_t *sp, mime_node_t *node,
- unused (int indent),
- unused (const notmuch_show_params_t *params));
-
-static const notmuch_show_format_t format_raw = {
- .new_sprinter = sprinter_text_create,
- .part = format_part_raw,
-};
-
static const char *
_get_tags_as_string (const void *ctx, notmuch_message_t *message)
{
* reflected in the file devel/schemata. */
InternetAddressList *recipients;
- const char *recipients_string;
+ char *recipients_string;
const char *reply_to_string;
+ char *date_string;
sp->begin_map (sp);
if (recipients_string) {
sp->map_key (sp, "To");
sp->string (sp, recipients_string);
+ g_free (recipients_string);
}
recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_CC);
if (recipients_string) {
sp->map_key (sp, "Cc");
sp->string (sp, recipients_string);
+ g_free (recipients_string);
}
recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_BCC);
if (recipients_string) {
sp->map_key (sp, "Bcc");
sp->string (sp, recipients_string);
+ g_free (recipients_string);
}
reply_to_string = g_mime_message_get_reply_to (message);
sp->string (sp, g_mime_object_get_header (GMIME_OBJECT (message), "References"));
} else {
sp->map_key (sp, "Date");
- sp->string (sp, g_mime_message_get_date_as_string (message));
+ date_string = g_mime_message_get_date_as_string (message);
+ sp->string (sp, date_string);
+ g_free (date_string);
}
sp->end (sp);
{
GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));
GMimeStream *stream_filter = NULL;
+ GMimeFilter *crlf_filter = NULL;
GMimeDataWrapper *wrapper;
const char *charset;
return;
stream_filter = g_mime_stream_filter_new (stream_out);
+ crlf_filter = g_mime_filter_crlf_new (FALSE, FALSE);
g_mime_stream_filter_add(GMIME_STREAM_FILTER (stream_filter),
- g_mime_filter_crlf_new (FALSE, FALSE));
+ crlf_filter);
+ g_object_unref (crlf_filter);
charset = g_mime_object_get_content_type_parameter (part, "charset");
if (charset) {
notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 1 : 0,
notmuch_message_get_filename (message));
} else {
+ char *content_string;
const char *disposition = _get_disposition (meta);
const char *cid = g_mime_object_get_content_id (meta);
const char *filename = leaf ?
printf (", Filename: %s", filename);
if (cid)
printf (", Content-id: %s", cid);
- printf (", Content-type: %s\n", g_mime_content_type_to_string (content_type));
+
+ content_string = g_mime_content_type_to_string (content_type);
+ printf (", Content-type: %s\n", content_string);
+ g_free (content_string);
}
if (GMIME_IS_MESSAGE (node->part)) {
GMimeMessage *message = GMIME_MESSAGE (node->part);
InternetAddressList *recipients;
- const char *recipients_string;
+ char *recipients_string;
+ char *date_string;
printf ("\fheader{\n");
if (node->envelope_file)
recipients_string = internet_address_list_to_string (recipients, 0);
if (recipients_string)
printf ("To: %s\n", recipients_string);
+ g_free (recipients_string);
recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_CC);
recipients_string = internet_address_list_to_string (recipients, 0);
if (recipients_string)
printf ("Cc: %s\n", recipients_string);
- printf ("Date: %s\n", g_mime_message_get_date_as_string (message));
+ g_free (recipients_string);
+ date_string = g_mime_message_get_date_as_string (message);
+ printf ("Date: %s\n", date_string);
+ g_free (date_string);
printf ("\fheader}\n");
printf ("\fbody{\n");
show_text_part_content (node->part, stream_stdout, 0);
g_object_unref(stream_stdout);
} else {
- printf ("Non-text part: %s\n",
- g_mime_content_type_to_string (content_type));
+ char *content_string = g_mime_content_type_to_string (content_type);
+ printf ("Non-text part: %s\n", content_string);
+ g_free (content_string);
}
}
GMimeObject *meta = node->envelope_part ?
GMIME_OBJECT (node->envelope_part) : node->part;
GMimeContentType *content_type = g_mime_object_get_content_type (meta);
+ char *content_string;
const char *disposition = _get_disposition (meta);
const char *cid = g_mime_object_get_content_id (meta);
const char *filename = GMIME_IS_PART (node->part) ?
}
sp->map_key (sp, "content-type");
- sp->string (sp, g_mime_content_type_to_string (content_type));
+ content_string = g_mime_content_type_to_string (content_type);
+ sp->string (sp, content_string);
+ g_free (content_string);
if (disposition) {
sp->map_key (sp, "content-disposition");
notmuch_status_t status;
unsigned int count;
- status = notmuch_query_count_messages_st (query, &count);
+ status = notmuch_query_count_messages (query, &count);
if (print_status_query ("notmuch show", query, status))
return 1;
return 1;
}
- status = notmuch_query_search_messages_st (query, &messages);
+ status = notmuch_query_search_messages (query, &messages);
if (print_status_query ("notmuch show", query, status))
return 1;
notmuch_messages_t *messages;
notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS;
- status= notmuch_query_search_threads_st (query, &threads);
+ status= notmuch_query_search_threads (query, &threads);
if (print_status_query ("notmuch show", query, status))
return 1;
NOTMUCH_FORMAT_RAW
};
+static const notmuch_show_format_t format_json = {
+ .new_sprinter = sprinter_json_create,
+ .part = format_part_sprinter_entry,
+};
+
+static const notmuch_show_format_t format_sexp = {
+ .new_sprinter = sprinter_sexp_create,
+ .part = format_part_sprinter_entry,
+};
+
+static const notmuch_show_format_t format_text = {
+ .new_sprinter = sprinter_text_create,
+ .part = format_part_text,
+};
+
+static const notmuch_show_format_t format_mbox = {
+ .new_sprinter = sprinter_text_create,
+ .part = format_part_mbox,
+};
+
+static const notmuch_show_format_t format_raw = {
+ .new_sprinter = sprinter_text_create,
+ .part = format_part_raw,
+};
+
+static const notmuch_show_format_t *formatters[] = {
+ [NOTMUCH_FORMAT_JSON] = &format_json,
+ [NOTMUCH_FORMAT_SEXP] = &format_sexp,
+ [NOTMUCH_FORMAT_TEXT] = &format_text,
+ [NOTMUCH_FORMAT_MBOX] = &format_mbox,
+ [NOTMUCH_FORMAT_RAW] = &format_raw,
+};
+
enum {
- ENTIRE_THREAD_DEFAULT,
- ENTIRE_THREAD_TRUE,
- ENTIRE_THREAD_FALSE,
+ ENTIRE_THREAD_DEFAULT = -1,
+ ENTIRE_THREAD_FALSE = FALSE,
+ ENTIRE_THREAD_TRUE = TRUE,
};
/* The following is to allow future options to be added more easily */
notmuch_query_t *query;
char *query_string;
int opt_index, ret;
- const notmuch_show_format_t *format = &format_text;
+ const notmuch_show_format_t *formatter;
sprinter_t *sprinter;
notmuch_show_params_t params = {
.part = -1,
.omit_excluded = TRUE,
.output_body = TRUE,
- .crypto = {
- .verify = FALSE,
- .decrypt = FALSE,
- .gpgpath = NULL
- },
- .include_html = FALSE
};
- int format_sel = NOTMUCH_FORMAT_NOT_SPECIFIED;
+ int format = NOTMUCH_FORMAT_NOT_SPECIFIED;
int exclude = EXCLUDE_TRUE;
int entire_thread = ENTIRE_THREAD_DEFAULT;
notmuch_bool_t single_message;
notmuch_opt_desc_t options[] = {
- { NOTMUCH_OPT_KEYWORD, &format_sel, "format", 'f',
+ { NOTMUCH_OPT_KEYWORD, &format, "format", 'f',
(notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON },
{ "text", NOTMUCH_FORMAT_TEXT },
{ "sexp", NOTMUCH_FORMAT_SEXP },
/* specifying a part implies single message display */
single_message = params.part >= 0;
- if (format_sel == NOTMUCH_FORMAT_NOT_SPECIFIED) {
+ if (format == NOTMUCH_FORMAT_NOT_SPECIFIED) {
/* if part was requested and format was not specified, use format=raw */
if (params.part >= 0)
- format_sel = NOTMUCH_FORMAT_RAW;
+ format = NOTMUCH_FORMAT_RAW;
else
- format_sel = NOTMUCH_FORMAT_TEXT;
+ format = NOTMUCH_FORMAT_TEXT;
}
- switch (format_sel) {
- case NOTMUCH_FORMAT_JSON:
- format = &format_json;
- break;
- case NOTMUCH_FORMAT_TEXT:
- format = &format_text;
- break;
- case NOTMUCH_FORMAT_SEXP:
- format = &format_sexp;
- break;
- case NOTMUCH_FORMAT_MBOX:
+ if (format == NOTMUCH_FORMAT_MBOX) {
if (params.part > 0) {
fprintf (stderr, "Error: specifying parts is incompatible with mbox output format.\n");
return EXIT_FAILURE;
}
-
- format = &format_mbox;
- break;
- case NOTMUCH_FORMAT_RAW:
- format = &format_raw;
+ } else if (format == NOTMUCH_FORMAT_RAW) {
/* raw format only supports single message display */
single_message = TRUE;
- break;
}
notmuch_exit_if_unsupported_format ();
/* Default is entire-thread = FALSE except for format=json and
* format=sexp. */
if (entire_thread == ENTIRE_THREAD_DEFAULT) {
- if (format_sel == NOTMUCH_FORMAT_JSON ||
- format_sel == NOTMUCH_FORMAT_SEXP)
- entire_thread = ENTIRE_THREAD_TRUE;
+ if (format == NOTMUCH_FORMAT_JSON || format == NOTMUCH_FORMAT_SEXP)
+ params.entire_thread = TRUE;
else
- entire_thread = ENTIRE_THREAD_FALSE;
+ params.entire_thread = FALSE;
+ } else {
+ params.entire_thread = entire_thread;
}
if (!params.output_body) {
fprintf (stderr, "Warning: --body=false is incompatible with --part > 0. Disabling.\n");
params.output_body = TRUE;
} else {
- if (format_sel != NOTMUCH_FORMAT_JSON &&
- format_sel != NOTMUCH_FORMAT_SEXP)
+ if (format != NOTMUCH_FORMAT_JSON && format != NOTMUCH_FORMAT_SEXP)
fprintf (stderr,
"Warning: --body=false only implemented for format=json and format=sexp\n");
}
}
if (params.include_html &&
- (format_sel != NOTMUCH_FORMAT_JSON && format_sel != NOTMUCH_FORMAT_SEXP)) {
+ (format != NOTMUCH_FORMAT_JSON && format != NOTMUCH_FORMAT_SEXP)) {
fprintf (stderr, "Warning: --include-html only implemented for format=json and format=sexp\n");
}
- if (entire_thread == ENTIRE_THREAD_TRUE)
- params.entire_thread = TRUE;
- else
- params.entire_thread = FALSE;
-
query_string = query_string_from_args (config, argc-opt_index, argv+opt_index);
if (query_string == NULL) {
fprintf (stderr, "Out of memory\n");
}
/* Create structure printer. */
- sprinter = format->new_sprinter(config, stdout);
+ formatter = formatters[format];
+ sprinter = formatter->new_sprinter(config, stdout);
/* If a single message is requested we do not use search_excludes. */
if (single_message) {
- ret = do_show_single (config, query, format, sprinter, ¶ms);
+ ret = do_show_single (config, query, formatter, sprinter, ¶ms);
} else {
/* We always apply set the exclude flag. The
* exclude=true|false option controls whether or not we return
const char **search_exclude_tags;
size_t search_exclude_tags_length;
unsigned int i;
+ notmuch_status_t status;
search_exclude_tags = notmuch_config_get_search_exclude_tags
(config, &search_exclude_tags_length);
- for (i = 0; i < search_exclude_tags_length; i++)
- notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+
+ for (i = 0; i < search_exclude_tags_length; i++) {
+ status = notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+ if (status && status != NOTMUCH_STATUS_IGNORED) {
+ print_status_query ("notmuch show", query, status);
+ ret = -1;
+ goto DONE;
+ }
+ }
if (exclude == EXCLUDE_FALSE) {
notmuch_query_set_omit_excluded (query, FALSE);
params.omit_excluded = FALSE;
}
- ret = do_show (config, query, format, sprinter, ¶ms);
+ ret = do_show (config, query, formatter, sprinter, ¶ms);
}
+ DONE:
notmuch_crypto_cleanup (¶ms.crypto);
notmuch_query_destroy (query);
notmuch_database_destroy (notmuch);