NeoMutt  2024-11-14-34-g5aaf0d
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_name(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_address(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->personal)
100 {
101 if (addr_b && addr_b->personal)
102 rc = buf_coll(addr_a->personal, addr_b->personal);
103 else
104 rc = 1;
105 }
106 else if (addr_b && addr_b->personal)
107 {
108 rc = -1;
109 }
110 else if (addr_a && addr_b)
111 {
112 rc = buf_coll(addr_a->mailbox, addr_b->mailbox);
113 }
114 else
115 {
116 rc = 0;
117 }
118 }
119
120 return sort_reverse ? -rc : rc;
121}
122
128static int alias_sort_unsort(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 if (av_a->is_visible != av_b->is_visible)
135 return av_a->is_visible ? -1 : 1;
136
137 if (!av_a->is_visible)
138 return 0;
139
140 int rc = mutt_numeric_cmp(av_a->orig_seq, av_b->orig_seq);
141 return sort_reverse ? -rc : rc;
142}
143
149{
150 switch ((sort & SORT_MASK))
151 {
152 case SORT_ALIAS:
153 return alias_sort_name;
154 case SORT_ADDRESS:
155 return alias_sort_address;
156 case SORT_ORDER:
157 return alias_sort_unsort;
158 default:
159 return alias_sort_name;
160 }
161}
162
168void alias_array_sort(struct AliasViewArray *ava, const struct ConfigSubset *sub)
169{
170 if (!ava || ARRAY_EMPTY(ava))
171 return;
172
173 const short c_sort_alias = cs_subset_sort(sub, "sort_alias");
174 bool sort_reverse = (c_sort_alias & SORT_REVERSE);
175 ARRAY_SORT(ava, alias_get_sort_function(c_sort_alias), &sort_reverse);
176
177 struct AliasView *avp = NULL;
178 ARRAY_FOREACH(avp, ava)
179 {
180 avp->num = ARRAY_FOREACH_IDX;
181 }
182}
Email Address Handling.
void alias_array_sort(struct AliasViewArray *ava, const struct ConfigSubset *sub)
Sort and reindex an AliasViewArray.
Definition: sort.c:168
static sort_t alias_get_sort_function(short sort)
Sorting function decision logic.
Definition: sort.c:148
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
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.
static int alias_sort_unsort(const void *a, const void *b, void *sdata)
Compare two Aliases by their original configuration position - Implements sort_t -.
Definition: sort.c:128
static int alias_sort_address(const void *a, const void *b, void *sdata)
Compare two Aliases by their Addresses - Implements sort_t -.
Definition: sort.c:67
static int alias_sort_name(const void *a, const void *b, void *sdata)
Compare two Aliases by their short names - Implements sort_t -.
Definition: sort.c:46
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:723
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:70
@ SORT_ORDER
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:40
@ SORT_ALIAS
Sort by email alias.
Definition: sort2.h:45
@ SORT_ADDRESS
Sort by email address.
Definition: sort2.h:46
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:71
Assorted sorting methods.
#define mutt_numeric_cmp(a, b)
Definition: sort.h:35
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
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