Line data Source code
1 : /**
2 : * @file
3 : * Type representing a sort option
4 : *
5 : * @authors
6 : * Copyright (C) 2017-2018 Richard Russon <rich@flatcap.org>
7 : *
8 : * @copyright
9 : * This program is free software: you can redistribute it and/or modify it under
10 : * the terms of the GNU General Public License as published by the Free Software
11 : * Foundation, either version 2 of the License, or (at your option) any later
12 : * version.
13 : *
14 : * This program is distributed in the hope that it will be useful, but WITHOUT
15 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 : * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 : * details.
18 : *
19 : * You should have received a copy of the GNU General Public License along with
20 : * this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : /**
24 : * @page config_sort Type: Sorting
25 : *
26 : * Config type representing a sort option.
27 : *
28 : * - Backed by `short`
29 : * - Validator is passed `short`
30 : */
31 :
32 : #include "config.h"
33 : #include <limits.h>
34 : #include <stdint.h>
35 : #include <string.h>
36 : #include "mutt/lib.h"
37 : #include "set.h"
38 : #include "sort2.h"
39 : #include "types.h"
40 :
41 : #define PREFIX_REVERSE "reverse-"
42 : #define PREFIX_LAST "last-"
43 :
44 : /**
45 : * sort_string_set - Set a Sort by string - Implements ConfigSetType::string_set()
46 : */
47 220 : static int sort_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef,
48 : const char *value, struct Buffer *err)
49 : {
50 220 : intptr_t id = -1;
51 220 : int flags = 0;
52 :
53 220 : if (!value || (value[0] == '\0'))
54 : {
55 12 : mutt_buffer_printf(err, _("Option %s may not be empty"), cdef->name);
56 12 : return CSR_ERR_INVALID | CSR_INV_TYPE;
57 : }
58 :
59 208 : size_t plen = 0;
60 :
61 : if (cdef->type | DT_SORT_REVERSE)
62 : {
63 208 : plen = mutt_str_startswith(value, PREFIX_REVERSE);
64 208 : if (plen != 0)
65 : {
66 2 : flags |= SORT_REVERSE;
67 2 : value += plen;
68 : }
69 : }
70 :
71 : if (cdef->type | DT_SORT_LAST)
72 : {
73 208 : plen = mutt_str_startswith(value, PREFIX_LAST);
74 208 : if (plen != 0)
75 : {
76 3 : flags |= SORT_LAST;
77 3 : value += plen;
78 : }
79 : }
80 :
81 208 : id = mutt_map_get_value(value, (struct Mapping *) cdef->data);
82 :
83 208 : if (id < 0)
84 : {
85 38 : mutt_buffer_printf(err, _("Invalid sort name: %s"), value);
86 38 : return CSR_ERR_INVALID | CSR_INV_TYPE;
87 : }
88 :
89 170 : id |= flags;
90 :
91 170 : if (var)
92 : {
93 168 : if (id == (*(short *) var))
94 14 : return CSR_SUCCESS | CSR_SUC_NO_CHANGE;
95 :
96 154 : if (cdef->validator)
97 : {
98 9 : int rc = cdef->validator(cs, cdef, (intptr_t) id, err);
99 :
100 9 : if (CSR_RESULT(rc) != CSR_SUCCESS)
101 2 : return rc | CSR_INV_VALIDATOR;
102 : }
103 :
104 152 : *(short *) var = id;
105 : }
106 : else
107 : {
108 2 : cdef->initial = id;
109 : }
110 :
111 154 : return CSR_SUCCESS;
112 : }
113 :
114 : /**
115 : * sort_string_get - Get a Sort as a string - Implements ConfigSetType::string_get()
116 : */
117 66 : static int sort_string_get(const struct ConfigSet *cs, void *var,
118 : const struct ConfigDef *cdef, struct Buffer *result)
119 : {
120 : int sort;
121 :
122 66 : if (var)
123 56 : sort = *(short *) var;
124 : else
125 10 : sort = (int) cdef->initial;
126 :
127 66 : if (sort & SORT_REVERSE)
128 2 : mutt_buffer_addstr(result, PREFIX_REVERSE);
129 66 : if (sort & SORT_LAST)
130 3 : mutt_buffer_addstr(result, PREFIX_LAST);
131 :
132 66 : sort &= SORT_MASK;
133 :
134 66 : const char *str = NULL;
135 :
136 66 : str = mutt_map_get_name(sort, (struct Mapping *) cdef->data);
137 :
138 66 : if (!str)
139 : {
140 8 : mutt_debug(LL_DEBUG1, "Variable has an invalid value: %d/%d\n",
141 : cdef->type & DT_SUBTYPE_MASK, sort);
142 8 : return CSR_ERR_INVALID | CSR_INV_TYPE;
143 : }
144 :
145 58 : mutt_buffer_addstr(result, str);
146 58 : return CSR_SUCCESS;
147 : }
148 :
149 : /**
150 : * sort_native_set - Set a Sort config item by int - Implements ConfigSetType::native_set()
151 : */
152 162 : static int sort_native_set(const struct ConfigSet *cs, void *var,
153 : const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
154 : {
155 162 : const char *str = NULL;
156 :
157 162 : str = mutt_map_get_name((value & SORT_MASK), (struct Mapping *) cdef->data);
158 :
159 162 : if (!str)
160 : {
161 6 : mutt_buffer_printf(err, _("Invalid sort type: %ld"), value);
162 6 : return CSR_ERR_INVALID | CSR_INV_TYPE;
163 : }
164 :
165 156 : if (value == (*(short *) var))
166 12 : return CSR_SUCCESS | CSR_SUC_NO_CHANGE;
167 :
168 144 : if (cdef->validator)
169 : {
170 6 : int rc = cdef->validator(cs, cdef, value, err);
171 :
172 6 : if (CSR_RESULT(rc) != CSR_SUCCESS)
173 2 : return rc | CSR_INV_VALIDATOR;
174 : }
175 :
176 142 : *(short *) var = value;
177 142 : return CSR_SUCCESS;
178 : }
179 :
180 : /**
181 : * sort_native_get - Get an int from a Sort config item - Implements ConfigSetType::native_get()
182 : */
183 20 : static intptr_t sort_native_get(const struct ConfigSet *cs, void *var,
184 : const struct ConfigDef *cdef, struct Buffer *err)
185 : {
186 20 : return *(short *) var;
187 : }
188 :
189 : /**
190 : * sort_reset - Reset a Sort to its initial value - Implements ConfigSetType::reset()
191 : */
192 60 : static int sort_reset(const struct ConfigSet *cs, void *var,
193 : const struct ConfigDef *cdef, struct Buffer *err)
194 : {
195 60 : if (cdef->initial == (*(short *) var))
196 6 : return CSR_SUCCESS | CSR_SUC_NO_CHANGE;
197 :
198 54 : if (cdef->validator)
199 : {
200 11 : int rc = cdef->validator(cs, cdef, cdef->initial, err);
201 :
202 11 : if (CSR_RESULT(rc) != CSR_SUCCESS)
203 2 : return rc | CSR_INV_VALIDATOR;
204 : }
205 :
206 52 : *(short *) var = cdef->initial;
207 52 : return CSR_SUCCESS;
208 : }
209 :
210 : /**
211 : * cst_sort - Config type representing a sort option
212 : */
213 : const struct ConfigSetType cst_sort = {
214 : DT_SORT,
215 : "sort",
216 : sort_string_set,
217 : sort_string_get,
218 : sort_native_set,
219 : sort_native_get,
220 : NULL, // string_plus_equals
221 : NULL, // string_minus_equals
222 : sort_reset,
223 : NULL, // destroy
224 : };
|