Merge branch 'release'
[notmuch] / notmuch-show.c
index 1954096d9091d43c9cd5cf34a3d856aa635ed3d4..7451d5ab563cd03a33df05671d4efce5af7eb12c 100644 (file)
 #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)
 {
@@ -1029,10 +987,43 @@ enum {
     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 */
@@ -1048,25 +1039,20 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
     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 },
@@ -1102,40 +1088,25 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
     if (params.crypto.decrypt)
        params.crypto.verify = TRUE;
 
-    if (format_sel == NOTMUCH_FORMAT_NOT_SPECIFIED) {
+    /* specifying a part implies single message display */
+    single_message = params.part >= 0;
+
+    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;
-       /* If --format=raw specified without specifying part, we can only
-        * output single message, so set part=0 */
-       if (params.part < 0)
-           params.part = 0;
-       params.raw = TRUE;
-       break;
+    } else if (format == NOTMUCH_FORMAT_RAW) {
+       /* raw format only supports single message display */
+       single_message = TRUE;
     }
 
     notmuch_exit_if_unsupported_format ();
@@ -1143,10 +1114,12 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
     /* Default is entire-thread = FALSE except for format=json and
      * format=sexp. */
     if (entire_thread == ENTIRE_THREAD_DEFAULT) {
-       if (format == &format_json || format == &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) {
@@ -1154,22 +1127,17 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
            fprintf (stderr, "Warning: --body=false is incompatible with --part > 0. Disabling.\n");
            params.output_body = TRUE;
        } else {
-           if (format != &format_json && format != &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");
@@ -1196,12 +1164,13 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
     }
 
     /* 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 (params.part >= 0)
-       ret = do_show_single (config, query, format, sprinter, &params);
-    else {
+    if (single_message) {
+       ret = do_show_single (config, query, formatter, sprinter, &params);
+    else {
        /* We always apply set the exclude flag. The
         * exclude=true|false option controls whether or not we return
         * threads that only match in an excluded message */
@@ -1219,7 +1188,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
            params.omit_excluded = FALSE;
        }
 
-       ret = do_show (config, query, format, sprinter, &params);
+       ret = do_show (config, query, formatter, sprinter, &params);
     }
 
     notmuch_crypto_cleanup (&params.crypto);