source: messagelist.c @ 95c7f0c

release-1.10release-1.8release-1.9
Last change on this file since 95c7f0c was 901cee9, checked in by Jason Gross <jgross@mit.edu>, 13 years ago
Don't segfault when you expunge all messages from the messagelist When we used owl_list, trying to get an element from an empty list would return NULL. When we moved to GPtrArray, we dropped this checking, without dropping the assumption that, e.g., owl_view_get_element(v, owl_global_get_curmsg(&g)); works everywhere. This commit adds the logic back in to deal with this case. Additionally, don't segfault on things like :unpunt -1.
  • Property mode set to 100644
File size: 2.5 KB
RevLine 
[7d4fbcd]1#include "owl.h"
2#include <stdlib.h>
3#include <string.h>
4
[fc8a87a]5void owl_messagelist_create(owl_messagelist *ml)
[bd3f232]6{
[fc8a87a]7  ml->list = g_ptr_array_new();
8}
9
10void owl_messagelist_cleanup(owl_messagelist *ml, bool free_messages)
11{
12  if (free_messages)
13    g_ptr_array_foreach(ml->list, (GFunc)owl_message_delete, NULL);
14  g_ptr_array_free(ml->list, true);
[7d4fbcd]15}
16
[3eb599d]17int owl_messagelist_get_size(const owl_messagelist *ml)
[bd3f232]18{
[fc8a87a]19  return ml->list->len;
[7d4fbcd]20}
21
[3eb599d]22void *owl_messagelist_get_element(const owl_messagelist *ml, int n)
[bd3f232]23{
[901cee9]24  /* we assume things like owl_view_get_element(v, owl_global_get_curmsg(&g))
25   * work even when there are no messages in the message list.  So don't
26   * segfault if someone asks for the zeroth element of an empty list.
27   */
28  if (n >= ml->list->len) return NULL;
[fc8a87a]29  return ml->list->pdata[n];
[7d4fbcd]30}
31
[3eb599d]32owl_message *owl_messagelist_get_by_id(const owl_messagelist *ml, int target_id)
[bd3f232]33{
[7d4fbcd]34  /* return the message with id == 'id'.  If it doesn't exist return NULL. */
[0c8ab5e]35  int first, last, mid, msg_id;
[7d4fbcd]36  owl_message *m;
37
[0c8ab5e]38  first = 0;
[fc8a87a]39  last = ml->list->len - 1;
[0c8ab5e]40  while (first <= last) {
41    mid = (first + last) / 2;
[fc8a87a]42    m = ml->list->pdata[mid];
[0c8ab5e]43    msg_id = owl_message_get_id(m);
44    if (msg_id == target_id) {
45      return(m);
46    } else if (msg_id < target_id) {
47      first = mid + 1;
48    } else {
49      last = mid - 1;
50    }
[7d4fbcd]51  }
52  return(NULL);
53}
54
[d427f08]55void owl_messagelist_append_element(owl_messagelist *ml, void *element)
[bd3f232]56{
[fc8a87a]57  g_ptr_array_add(ml->list, element);
[7d4fbcd]58}
59
60/* do we really still want this? */
[bd3f232]61int owl_messagelist_delete_element(owl_messagelist *ml, int n)
62{
[7d4fbcd]63  /* mark a message as deleted */
[fc8a87a]64  owl_message_mark_delete(ml->list->pdata[n]);
[7d4fbcd]65  return(0);
66}
67
[bd3f232]68int owl_messagelist_undelete_element(owl_messagelist *ml, int n)
69{
[7d4fbcd]70  /* mark a message as deleted */
[fc8a87a]71  owl_message_unmark_delete(ml->list->pdata[n]);
[7d4fbcd]72  return(0);
73}
74
[bd3f232]75int owl_messagelist_expunge(owl_messagelist *ml)
76{
[7d4fbcd]77  /* expunge deleted messages */
[fc8a87a]78  int i;
79  GPtrArray *newlist;
[7d4fbcd]80  owl_message *m;
81
[fc8a87a]82  newlist = g_ptr_array_new();
[7d4fbcd]83  /*create a new list without messages marked as deleted */
[fc8a87a]84  for (i = 0; i < ml->list->len; i++) {
85    m = ml->list->pdata[i];
[7d4fbcd]86    if (owl_message_is_delete(m)) {
[91634ec]87      owl_message_delete(m);
[7d4fbcd]88    } else {
[fc8a87a]89      g_ptr_array_add(newlist, m);
[7d4fbcd]90    }
91  }
92
93  /* free the old list */
[fc8a87a]94  g_ptr_array_free(ml->list, true);
[7d4fbcd]95
96  /* copy the new list to the old list */
[66a8cd6]97  ml->list = newlist;
[7d4fbcd]98
99  return(0);
100}
[bd3f232]101
[3eb599d]102void owl_messagelist_invalidate_formats(const owl_messagelist *ml)
[bd3f232]103{
[fc8a87a]104  int i;
[bd3f232]105  owl_message *m;
106
[fc8a87a]107  for (i = 0; i < ml->list->len; i++) {
108    m = ml->list->pdata[i];
[bd3f232]109    owl_message_invalidate_format(m);
110  }
111}
Note: See TracBrowser for help on using the repository browser.