NeoMutt  2025-12-11-694-ga89709
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
sort.c
Go to the documentation of this file.
1
24
34
35#include "config.h"
36#include <stdbool.h>
37#include <stdint.h>
38#include <string.h>
39#include "mutt/lib.h"
40#include "sort.h"
41#include "set.h"
42#include "types.h"
43
45#define PREFIX_REVERSE "reverse-"
47#define PREFIX_LAST "last-"
48
52static int sort_string_set(void *var, struct ConfigDef *cdef, const char *value,
53 struct Buffer *err)
54{
55 intptr_t id = -1;
56 uint16_t flags = 0;
57
58 if (!value || (value[0] == '\0'))
59 {
60 buf_printf(err, _("Option %s may not be empty"), cdef->name);
62 }
63
64 size_t plen = 0;
65
66 if (cdef->type & D_SORT_REVERSE)
67 {
69 if (plen != 0)
70 {
71 flags |= SORT_REVERSE;
72 value += plen;
73 }
74 }
75
76 if (cdef->type & D_SORT_LAST)
77 {
78 plen = mutt_str_startswith(value, PREFIX_LAST);
79 if (plen != 0)
80 {
81 flags |= SORT_LAST;
82 value += plen;
83 }
84 }
85
86 id = mutt_map_get_value(value, (struct Mapping *) cdef->data);
87
88 if (id < 0)
89 {
90 buf_printf(err, _("Invalid value for %s"), cdef->name);
91 const struct Mapping *map = (const struct Mapping *) cdef->data;
92 if (map)
93 {
94 buf_addch(err, '\n');
95 struct Buffer *list = buf_pool_get();
96 int count = 0;
97 for (int i = 0; map[i].name; i++)
98 {
99 // Skip compatibility aliases (duplicate values)
100 bool dominated = false;
101 for (int j = 0; j < i; j++)
102 {
103 if (map[j].value == map[i].value)
104 {
105 dominated = true;
106 break;
107 }
108 }
109 if (dominated)
110 continue;
111
112 if (count > 0)
113 buf_addstr(list, ", ");
114 buf_addstr(list, map[i].name);
115 count++;
116 }
117 buf_add_printf(err, _("Choose from: %s"), buf_string(list));
118 buf_pool_release(&list);
119 }
121 }
122
123 id |= flags;
124
125 if (var)
126 {
127 if (id == (*(short *) var))
129
130 if (startup_only(cdef, err))
132
133 if (cdef->validator)
134 {
135 int rc = cdef->validator(cdef, (intptr_t) id, err);
136
137 if (CSR_RESULT(rc) != CSR_SUCCESS)
138 return rc | CSR_INV_VALIDATOR;
139 }
140
141 *(short *) var = id;
142 }
143 else
144 {
145 cdef->initial = id;
146 }
147
148 return CSR_SUCCESS;
149}
150
154static int sort_string_get(void *var, const struct ConfigDef *cdef, struct Buffer *result)
155{
156 int sort;
157
158 if (var)
159 sort = *(short *) var;
160 else
161 sort = (int) cdef->initial;
162
163 if (sort & SORT_REVERSE)
164 buf_addstr(result, PREFIX_REVERSE);
165 if (sort & SORT_LAST)
166 buf_addstr(result, PREFIX_LAST);
167
168 sort &= SORT_MASK;
169
170 const char *str = NULL;
171
172 str = mutt_map_get_name(sort, (struct Mapping *) cdef->data);
173
174 if (!str)
175 {
176 mutt_debug(LL_DEBUG1, "Variable has an invalid value: %d/%d\n", cdef->type, sort);
178 }
179
180 buf_addstr(result, str);
181 return CSR_SUCCESS;
182}
183
187static int sort_native_set(void *var, const struct ConfigDef *cdef,
188 intptr_t value, struct Buffer *err)
189{
190 const char *str = NULL;
191
192 str = mutt_map_get_name((value & SORT_MASK), (struct Mapping *) cdef->data);
193
194 if (!str)
195 {
196 buf_printf(err, _("Invalid sort type: %ld"), (long) value);
198 }
199
200 if (value == (*(short *) var))
202
203 if (startup_only(cdef, err))
205
206 if (cdef->validator)
207 {
208 int rc = cdef->validator(cdef, value, err);
209
210 if (CSR_RESULT(rc) != CSR_SUCCESS)
211 return rc | CSR_INV_VALIDATOR;
212 }
213
214 *(short *) var = value;
215 return CSR_SUCCESS;
216}
217
221static intptr_t sort_native_get(void *var, const struct ConfigDef *cdef, struct Buffer *err)
222{
223 return *(short *) var;
224}
225
229static bool sort_has_been_set(void *var, const struct ConfigDef *cdef)
230{
231 return (cdef->initial != (*(short *) var));
232}
233
237static int sort_reset(void *var, const struct ConfigDef *cdef, struct Buffer *err)
238{
239 if (cdef->initial == (*(short *) var))
241
242 if (startup_only(cdef, err))
244
245 if (cdef->validator)
246 {
247 int rc = cdef->validator(cdef, cdef->initial, err);
248
249 if (CSR_RESULT(rc) != CSR_SUCCESS)
250 return rc | CSR_INV_VALIDATOR;
251 }
252
253 *(short *) var = cdef->initial;
254 return CSR_SUCCESS;
255}
256
260const struct ConfigSetType CstSort = {
261 DT_SORT,
262 "sort",
267 NULL, // string_plus_equals
268 NULL, // string_minus_equals
271 NULL, // destroy
272};
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition buffer.c:204
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:241
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:226
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
const struct ConfigSetType CstSort
Config type representing a sort option.
Definition sort.c:260
A collection of config items.
static bool startup_only(const struct ConfigDef *cdef, struct Buffer *err)
Validator function for D_ON_STARTUP.
Definition set.h:296
#define CSR_ERR_INVALID
Value hasn't been set.
Definition set.h:36
#define CSR_INV_TYPE
Value is not valid for the type.
Definition set.h:45
#define CSR_INV_VALIDATOR
Value was rejected by the validator.
Definition set.h:46
#define CSR_INV_WARNING
Report as a warning, not an error.
Definition set.h:48
#define CSR_SUC_NO_CHANGE
The value hasn't changed.
Definition set.h:42
#define CSR_RESULT(x)
Extract the result code from CSR_* flags.
Definition set.h:53
#define CSR_SUCCESS
Action completed successfully.
Definition set.h:33
#define PREFIX_REVERSE
Prefix for reverse sorting.
Definition sort.c:45
#define PREFIX_LAST
Prefix for last sorting (used in threading)
Definition sort.c:47
Type representing a sort option.
#define SORT_MASK
Mask for the sort id.
Definition sort.h:39
#define SORT_LAST
Sort thread by last-X, e.g. received date.
Definition sort.h:41
#define SORT_REVERSE
Reverse the order of the sort.
Definition sort.h:40
static bool sort_has_been_set(void *var, const struct ConfigDef *cdef)
Is the config value different to its initial value?
Definition sort.c:229
static intptr_t sort_native_get(void *var, const struct ConfigDef *cdef, struct Buffer *err)
Get an int from a Sort config item - Implements ConfigSetType::native_get() -.
Definition sort.c:221
static int sort_native_set(void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Set a Sort config item by int - Implements ConfigSetType::native_set() -.
Definition sort.c:187
static int sort_reset(void *var, const struct ConfigDef *cdef, struct Buffer *err)
Reset a Sort to its initial value - Implements ConfigSetType::reset() -.
Definition sort.c:237
static int sort_string_get(void *var, const struct ConfigDef *cdef, struct Buffer *result)
Get a Sort as a string - Implements ConfigSetType::string_get() -.
Definition sort.c:154
static int sort_string_set(void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Set a Sort by string - Implements ConfigSetType::string_set() -.
Definition sort.c:52
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition mapping.c:85
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition mapping.c:42
Convenience wrapper for the library headers.
#define _(a)
Definition message.h:28
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition string.c:234
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
String manipulation buffer.
Definition buffer.h:36
const char * name
User-visible name.
Definition set.h:66
int(* validator)(const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition set.h:82
intptr_t data
Extra variable data.
Definition set.h:69
intptr_t initial
Initial value.
Definition set.h:68
uint32_t type
Variable type, e.g. DT_STRING.
Definition set.h:67
Mapping between user-readable string and a constant.
Definition mapping.h:33
const char * name
String value.
Definition mapping.h:34
Constants for all the config types.
@ DT_SORT
sorting methods
Definition types.h:43
#define D_SORT_LAST
Sort flag for -last prefix.
Definition types.h:119
#define D_SORT_REVERSE
Sort flag for -reverse prefix.
Definition types.h:120