]> git.notmuchmail.org Git - notmuch/commitdiff
Merge branch 'release'
authorDavid Bremner <david@tethera.net>
Sun, 19 Mar 2017 00:02:42 +0000 (21:02 -0300)
committerDavid Bremner <david@tethera.net>
Sun, 19 Mar 2017 00:02:42 +0000 (21:02 -0300)
Merge in memory fixes

1  2 
lib/message.cc
notmuch-show.c

diff --combined lib/message.cc
index e08659e5d96a15b7564e280cc0716b3d83985516,36a07a8890b0dd52a092fc8c88434676cc4193be..cb313326270e6bc3b0ba5813a5491269e5a62ebb
@@@ -870,9 -870,9 +870,9 @@@ _notmuch_message_ensure_filename_list (
         *
         * It would be nice to do the upgrade of the document directly
         * here, but the database is likely open in read-only mode. */
-       const char *data;
  
-       data = message->doc.get_data ().c_str ();
+       std::string datastr = message->doc.get_data ();
+       const char *data = datastr.c_str ();
  
        if (data == NULL)
            INTERNAL_ERROR ("message with no filename");
@@@ -1034,16 -1034,10 +1034,16 @@@ _notmuch_message_set_header_values (not
  
      /* GMime really doesn't want to see a NULL date, so protect its
       * sensibilities. */
 -    if (date == NULL || *date == '\0')
 +    if (date == NULL || *date == '\0') {
        time_value = 0;
 -    else
 +    } else {
        time_value = g_mime_utils_header_decode_date (date, NULL);
 +      /*
 +       * Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=779923
 +       */
 +      if (time_value < 0)
 +          time_value = 0;
 +    }
  
      message->doc.add_value (NOTMUCH_VALUE_TIMESTAMP,
                            Xapian::sortable_serialise (time_value));
diff --combined notmuch-show.c
index aff93803734ff7b64fe61494687ddad6ba7ec7ce,1954096d9091d43c9cd5cf34a3d856aa635ed3d4..7451d5ab563cd03a33df05671d4efce5af7eb12c
  #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)
  {
@@@ -202,8 -244,9 +202,9 @@@ format_headers_sprinter (sprinter_t *sp
       * 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);
@@@ -270,6 -318,7 +276,7 @@@ show_text_part_content (GMimeObject *pa
  {
      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) {
@@@ -432,6 -483,7 +441,7 @@@ format_part_text (const void *ctx, spri
                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);
        }
      }
  
@@@ -553,6 -614,7 +572,7 @@@ format_part_sprinter (const void *ctx, 
      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");
@@@ -965,43 -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 */
@@@ -1017,20 -1048,25 +1039,20 @@@ notmuch_show_command (notmuch_config_t 
      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 },
      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 ();
      /* 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) {
            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");
      }
  
      /* 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 */
            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);