NeoMutt  2024-12-12-14-g7b49f7
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
sort.c
Go to the documentation of this file.
1
31#include "config.h"
32#include <stdbool.h>
33#include <stddef.h>
34#include "mutt/lib.h"
35#include "address/lib.h"
36#include "config/lib.h"
37#include "sort.h"
38#include "alias.h"
39#include "gui.h"
40
46static int alias_sort_alias(const void *a, const void *b, void *sdata)
47{
48 const struct AliasView *av_a = a;
49 const struct AliasView *av_b = b;
50 const bool sort_reverse = *(bool *) sdata;
51
52 if (av_a->is_visible != av_b->is_visible)
53 return av_a->is_visible ? -1 : 1;
54
55 if (!av_a->is_visible)
56 return 0;
57
58 int rc = mutt_str_coll(av_a->alias->name, av_b->alias->name);
59 return sort_reverse ? -rc : rc;
60}
61
67static int alias_sort_email(const void *a, const void *b, void *sdata)
68{
69 const struct AliasView *av_a = a;
70 const struct AliasView *av_b = b;
71 const bool sort_reverse = *(bool *) sdata;
72
73 const struct AddressList *al_a = &av_a->alias->addr;
74 const struct AddressList *al_b = &av_b->alias->addr;
75
76 if (av_a->is_visible != av_b->is_visible)
77 return av_a->is_visible ? -1 : 1;
78
79 if (!av_a->is_visible)
80 return 0;
81
82 int rc;
83 if (al_a == al_b)
84 {
85 rc = 0;
86 }
87 else if (!al_a)
88 {
89 rc = -1;
90 }
91 else if (!al_b)
92 {
93 rc = 1;
94 }
95 else
96 {
97 const struct Address *addr_a = TAILQ_FIRST(al_a);
98 const struct Address *addr_b = TAILQ_FIRST(al_b);
99 if (addr_a && addr_a->mailbox)
100 {
101 if (addr_b && addr_b->mailbox)
102 rc = buf_coll(addr_a->mailbox, addr_b->mailbox);
103 else
104 rc = 1;
105 }
106 else if (addr_b && addr_b->mailbox)
107 {
108 rc = -1;
109 }
110 else if (addr_a && addr_b)
111 {
112 rc = buf_coll(addr_a->personal, addr_b->personal);
113 }
114 else
115 {
116 rc = 0;
117 }
118 }
119
120 return sort_reverse ? -rc : rc;
121}
122
128static int alias_sort_name(const void *a, const void *b, void *sdata)
129{
130 const struct AliasView *av_a = a;
131 const struct AliasView *av_b = b;
132 const bool sort_reverse = *(bool *) sdata;
133
134 const struct AddressList *al_a = &av_a->alias->addr;
135 const struct AddressList *al_b = &av_b->alias->addr;
136
137 if (av_a->is_visible != av_b->is_visible)
138 return av_a->is_visible ? -1 : 1;
139
140 if (!av_a->is_visible)
141 return 0;
142
143 int rc;
144 if (al_a == al_b)
145 {
146 rc = 0;
147 }
148 else if (!al_a)
149 {
150 rc = -1;
151 }
152 else if (!al_b)
153 {
154 rc = 1;
155 }
156 else
157 {
158 const struct Address *addr_a = TAILQ_FIRST(al_a);
159 const struct Address *addr_b = TAILQ_FIRST(al_b);
160 if (addr_a && addr_a->personal)
161 {
162 if (addr_b && addr_b->personal)
163 rc = buf_coll(addr_a->personal, addr_b->personal);
164 else
165 rc = 1;
166 }
167 else if (addr_b && addr_b->personal)
168 {
169 rc = -1;
170 }
171 else if (addr_a && addr_b)
172 {
173 rc = buf_coll(addr_a->mailbox, addr_b->mailbox);
174 }
175 else
176 {
177 rc = 0;
178 }
179 }
180
181 return sort_reverse ? -rc : rc;
182}
183
189static int alias_sort_unsorted(const void *a, const void *b, void *sdata)
190{
191 const struct AliasView *av_a = a;
192 const struct AliasView *av_b = b;
193 const bool sort_reverse = *(bool *) sdata;
194
195 if (av_a->is_visible != av_b->is_visible)
196 return av_a->is_visible ? -1 : 1;
197
198 if (!av_a->is_visible)
199 return 0;
200
201 int rc = mutt_numeric_cmp(av_a->orig_seq, av_b->orig_seq);
202 return sort_reverse ? -rc : rc;
203}
204
210{
211 switch ((sort & SORT_MASK))
212 {
213 case ALIAS_SORT_ALIAS:
214 return alias_sort_alias;
215
216 case ALIAS_SORT_EMAIL:
217 return alias_sort_email;
218
219 case ALIAS_SORT_NAME:
220 return alias_sort_name;
221
223 return alias_sort_unsorted;
224
225 default:
226 return alias_sort_alias;
227 }
228}
229
235void alias_array_sort(struct AliasViewArray *ava, const struct ConfigSubset *sub)
236{
237 if (!ava || ARRAY_EMPTY(ava))
238 return;
239
240 short c_sort_alias = cs_subset_sort(sub, "alias_sort");
241 if (c_sort_alias == ALIAS_SORT_ALIAS)
242 {
243 struct AliasView *av = ARRAY_GET(ava, 0);
244 struct Alias *a = av->alias;
245
246 if (!a->name) // We've got a Query
247 c_sort_alias = ALIAS_SORT_NAME;
248 }
249
250 bool sort_reverse = (c_sort_alias & SORT_REVERSE);
251 ARRAY_SORT(ava, alias_get_sort_function(c_sort_alias), &sort_reverse);
252
253 struct AliasView *avp = NULL;
254 ARRAY_FOREACH(avp, ava)
255 {
256 avp->num = ARRAY_FOREACH_IDX;
257 }
258}
Email Address Handling.
void alias_array_sort(struct AliasViewArray *ava, const struct ConfigSubset *sub)
Sort and reindex an AliasViewArray.
Definition: sort.c:235
static sort_t alias_get_sort_function(short sort)
Sorting function decision logic.
Definition: sort.c:209
@ ALIAS_SORT_UNSORTED
Sort by the order the Aliases were configured.
Definition: sort.h:34
@ ALIAS_SORT_NAME
Sort by Real Name.
Definition: sort.h:33
@ ALIAS_SORT_EMAIL
Sort by Email Address.
Definition: sort.h:32
@ ALIAS_SORT_ALIAS
Sort by Alias short name.
Definition: sort.h:31
Representation of a single alias to an email address.
#define ARRAY_SORT(head, fn, sdata)
Sort an array.
Definition: array.h:279
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:212
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:74
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:109
int buf_coll(const struct Buffer *a, const struct Buffer *b)
Collate two strings (compare using locale)
Definition: buffer.c:725
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:266
Convenience wrapper for the config headers.
#define SORT_MASK
Mask for the sort id.
Definition: sort.h:38
#define mutt_numeric_cmp(a, b)
Definition: sort.h:26
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort.h:39
static int alias_sort_unsorted(const void *a, const void *b, void *sdata)
Compare two Aliases by their original configuration position - Implements sort_t -.
Definition: sort.c:189
static int alias_sort_email(const void *a, const void *b, void *sdata)
Compare two Aliases by their Email Addresses - Implements sort_t -.
Definition: sort.c:67
static int alias_sort_alias(const void *a, const void *b, void *sdata)
Compare two Aliases by their short names - Implements sort_t -.
Definition: sort.c:46
static int alias_sort_name(const void *a, const void *b, void *sdata)
Compare two Aliases by their Names - Implements sort_t -.
Definition: sort.c:128
Shared code for the Alias and Query Dialogs.
Convenience wrapper for the library headers.
int mutt_str_coll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:509
int(* sort_t)(const void *a, const void *b, void *sdata)
Definition: qsort_r.h:41
#define TAILQ_FIRST(head)
Definition: queue.h:741
Sidebar sorting functions.
An email address.
Definition: address.h:36
struct Buffer * personal
Real name of address.
Definition: address.h:37
struct Buffer * mailbox
Mailbox and host address.
Definition: address.h:38
GUI data wrapping an Alias.
Definition: gui.h:38
bool is_visible
Is visible?
Definition: gui.h:45
struct Alias * alias
Alias.
Definition: gui.h:46
int num
Index number in list.
Definition: gui.h:39
int orig_seq
Sequence in alias config file.
Definition: gui.h:40
A shortcut for an email address or addresses.
Definition: alias.h:35
char * name
Short name.
Definition: alias.h:36
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:37
A set of inherited config items.
Definition: subset.h:47