NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
sort.c
Go to the documentation of this file.
1 
29 #include "config.h"
30 #include <stddef.h>
31 #include "mutt/lib.h"
32 #include "address/lib.h"
33 #include "config/lib.h"
34 #include "alias/lib.h"
35 #include "sort.h"
36 #include "lib.h"
37 #include "alias.h"
38 #include "gui.h"
39 
40 #define RSORT(num) ((sort_alias & SORT_REVERSE) ? -num : num)
41 
42 static short sort_alias = 0;
43 
49 static int alias_sort_name(const void *a, const void *b)
50 {
51  const struct AliasView *av_a = a;
52  const struct AliasView *av_b = b;
53 
54  if (av_a->is_visible != av_b->is_visible)
55  return av_a->is_visible ? -1 : 1;
56 
57  if (!av_a->is_visible)
58  return 0;
59 
60  int r = mutt_str_coll(av_a->alias->name, av_b->alias->name);
61 
62  return RSORT(r);
63 }
64 
70 static int alias_sort_address(const void *a, const void *b)
71 {
72  const struct AliasView *av_a = a;
73  const struct AliasView *av_b = b;
74 
75  const struct AddressList *al_a = &av_a->alias->addr;
76  const struct AddressList *al_b = &av_b->alias->addr;
77 
78  if (av_a->is_visible != av_b->is_visible)
79  return av_a->is_visible ? -1 : 1;
80 
81  if (!av_a->is_visible)
82  return 0;
83 
84  int r;
85  if (al_a == al_b)
86  r = 0;
87  else if (!al_a)
88  r = -1;
89  else if (!al_b)
90  r = 1;
91  else
92  {
93  const struct Address *addr_a = TAILQ_FIRST(al_a);
94  const struct Address *addr_b = TAILQ_FIRST(al_b);
95  if (addr_a && addr_a->personal)
96  {
97  if (addr_b && addr_b->personal)
98  r = mutt_str_coll(addr_a->personal, addr_b->personal);
99  else
100  r = 1;
101  }
102  else if (addr_b && addr_b->personal)
103  r = -1;
104  else if (addr_a && addr_b)
105  r = mutt_str_coll(addr_a->mailbox, addr_b->mailbox);
106  else
107  r = 0;
108  }
109 
110  return RSORT(r);
111 }
112 
118 static int alias_sort_unsort(const void *a, const void *b)
119 {
120  const struct AliasView *av_a = a;
121  const struct AliasView *av_b = b;
122 
123  if (av_a->is_visible != av_b->is_visible)
124  return av_a->is_visible ? -1 : 1;
125 
126  if (!av_a->is_visible)
127  return 0;
128 
129  int r = (av_a->orig_seq - av_b->orig_seq);
130 
131  return RSORT(r);
132 }
133 
138 static sort_t alias_get_sort_function(short sort)
139 {
140  switch ((sort & SORT_MASK))
141  {
142  case SORT_ALIAS:
143  return alias_sort_name;
144  case SORT_ADDRESS:
145  return alias_sort_address;
146  case SORT_ORDER:
147  return alias_sort_unsort;
148  default:
149  return alias_sort_name;
150  }
151 }
152 
158 void alias_array_sort(struct AliasViewArray *ava, const struct ConfigSubset *sub)
159 {
160  if (!ava || ARRAY_EMPTY(ava))
161  return;
162 
163  sort_alias = cs_subset_sort(sub, "sort_alias");
165 
166  struct AliasView *avp = NULL;
167  ARRAY_FOREACH(avp, ava)
168  {
169  avp->num = ARRAY_FOREACH_IDX;
170  }
171 }
lib.h
Alias::addr
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
Address::personal
char * personal
Real name of address.
Definition: address.h:36
alias_sort_address
static int alias_sort_address(const void *a, const void *b)
Compare two Aliases by their Addresses - Implements sort_t.
Definition: sort.c:70
sort_alias
static short sort_alias
Definition: sort.c:42
SORT_ALIAS
@ SORT_ALIAS
Sort by email alias.
Definition: sort2.h:55
mutt_str_coll
int mutt_str_coll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:644
AliasView::is_visible
bool is_visible
Is visible?
Definition: gui.h:44
ARRAY_SORT
#define ARRAY_SORT(head, fn)
Sort an array.
Definition: array.h:271
AliasView::alias
struct Alias * alias
Alias.
Definition: gui.h:45
AliasView::num
int num
Index number in list.
Definition: gui.h:38
SORT_MASK
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:80
sort_t
int(* sort_t)(const void *a, const void *b)
Prototype for a function to compare two emails.
Definition: sort.h:50
AliasView
GUI data wrapping an Alias.
Definition: gui.h:36
alias.h
lib.h
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:716
ARRAY_FOREACH
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
lib.h
alias_sort_name
static int alias_sort_name(const void *a, const void *b)
Compare two Aliases by their short names - Implements sort_t.
Definition: sort.c:49
lib.h
alias_get_sort_function
static sort_t alias_get_sort_function(short sort)
Sorting function decision logic.
Definition: sort.c:138
SORT_ORDER
@ SORT_ORDER
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:50
SORT_ADDRESS
@ SORT_ADDRESS
Sort by email address.
Definition: sort2.h:56
cs_subset_sort
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:219
Address::mailbox
char * mailbox
Mailbox and host address.
Definition: address.h:37
Alias::name
char * name
Short name.
Definition: alias.h:35
ARRAY_EMPTY
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:70
alias_array_sort
void alias_array_sort(struct AliasViewArray *ava, const struct ConfigSubset *sub)
Sort and reindex an AliasViewArray.
Definition: sort.c:158
sort.h
AliasView::orig_seq
int orig_seq
Sequence in alias config file.
Definition: gui.h:39
alias_sort_unsort
static int alias_sort_unsort(const void *a, const void *b)
Compare two Aliases by their original configuration position - Implements sort_t.
Definition: sort.c:118
gui.h
ConfigSubset
A set of inherited config items.
Definition: subset.h:46
RSORT
#define RSORT(num)
Definition: sort.c:40
Address
An email address.
Definition: address.h:34