source: messagelist.c @ 530c51c

Last change on this file since 530c51c was 5c2ef5b, checked in by Jason Gross <jgross@mit.edu>, 11 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.3 KB
Line 
1#include "owl.h"
2#include <stdlib.h>
3#include <string.h>
4
5void owl_messagelist_create(owl_messagelist *ml)
6{
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);
15}
16
17int owl_messagelist_get_size(const owl_messagelist *ml)
18{
19  return ml->list->len;
20}
21
22void *owl_messagelist_get_element(const owl_messagelist *ml, int n)
23{
24  if (n >= ml->list->len) return NULL;
25  return ml->list->pdata[n];
26}
27
28owl_message *owl_messagelist_get_by_id(const owl_messagelist *ml, int target_id)
29{
30  /* return the message with id == 'id'.  If it doesn't exist return NULL. */
31  int first, last, mid, msg_id;
32  owl_message *m;
33
34  first = 0;
35  last = ml->list->len - 1;
36  while (first <= last) {
37    mid = (first + last) / 2;
38    m = ml->list->pdata[mid];
39    msg_id = owl_message_get_id(m);
40    if (msg_id == target_id) {
41      return(m);
42    } else if (msg_id < target_id) {
43      first = mid + 1;
44    } else {
45      last = mid - 1;
46    }
47  }
48  return(NULL);
49}
50
51void owl_messagelist_append_element(owl_messagelist *ml, void *element)
52{
53  g_ptr_array_add(ml->list, element);
54}
55
56/* do we really still want this? */
57int owl_messagelist_delete_element(owl_messagelist *ml, int n)
58{
59  /* mark a message as deleted */
60  owl_message_mark_delete(ml->list->pdata[n]);
61  return(0);
62}
63
64int owl_messagelist_undelete_element(owl_messagelist *ml, int n)
65{
66  /* mark a message as deleted */
67  owl_message_unmark_delete(ml->list->pdata[n]);
68  return(0);
69}
70
71int owl_messagelist_expunge(owl_messagelist *ml)
72{
73  /* expunge deleted messages */
74  int i;
75  GPtrArray *newlist;
76  owl_message *m;
77
78  newlist = g_ptr_array_new();
79  /*create a new list without messages marked as deleted */
80  for (i = 0; i < ml->list->len; i++) {
81    m = ml->list->pdata[i];
82    if (owl_message_is_delete(m)) {
83      owl_message_delete(m);
84    } else {
85      g_ptr_array_add(newlist, m);
86    }
87  }
88
89  /* free the old list */
90  g_ptr_array_free(ml->list, true);
91
92  /* copy the new list to the old list */
93  ml->list = newlist;
94
95  return(0);
96}
97
98void owl_messagelist_invalidate_formats(const owl_messagelist *ml)
99{
100  int i;
101  owl_message *m;
102
103  for (i = 0; i < ml->list->len; i++) {
104    m = ml->list->pdata[i];
105    owl_message_invalidate_format(m);
106  }
107}
Note: See TracBrowser for help on using the repository browser.