/src/neomutt/config/long.c
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * @file |
3 | | * Type representing a long |
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_long Type: Long |
25 | | * |
26 | | * Config type representing a long. |
27 | | * |
28 | | * - Backed by `long` |
29 | | * - Validator is passed `long` |
30 | | * - Implementation: #CstLong |
31 | | */ |
32 | | |
33 | | #include "config.h" |
34 | | #include <stddef.h> |
35 | | #include <stdint.h> |
36 | | #include "mutt/lib.h" |
37 | | #include "set.h" |
38 | | #include "types.h" |
39 | | |
40 | | /** |
41 | | * long_string_set - Set a Long by string - Implements ConfigSetType::string_set() - @ingroup cfg_type_string_set |
42 | | */ |
43 | | static int long_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, |
44 | | const char *value, struct Buffer *err) |
45 | 0 | { |
46 | 0 | if (!value || (value[0] == '\0')) |
47 | 0 | { |
48 | 0 | buf_printf(err, _("Option %s may not be empty"), cdef->name); |
49 | 0 | return CSR_ERR_INVALID | CSR_INV_TYPE; |
50 | 0 | } |
51 | | |
52 | 0 | long num = 0; |
53 | 0 | if (!mutt_str_atol_full(value, &num)) |
54 | 0 | { |
55 | 0 | buf_printf(err, _("Invalid long: %s"), value); |
56 | 0 | return CSR_ERR_INVALID | CSR_INV_TYPE; |
57 | 0 | } |
58 | | |
59 | 0 | if ((num < 0) && (cdef->type & DT_NOT_NEGATIVE)) |
60 | 0 | { |
61 | 0 | buf_printf(err, _("Option %s may not be negative"), cdef->name); |
62 | 0 | return CSR_ERR_INVALID | CSR_INV_VALIDATOR; |
63 | 0 | } |
64 | | |
65 | 0 | if (var) |
66 | 0 | { |
67 | 0 | if (num == (*(long *) var)) |
68 | 0 | return CSR_SUCCESS | CSR_SUC_NO_CHANGE; |
69 | | |
70 | 0 | if (cdef->validator) |
71 | 0 | { |
72 | 0 | int rc = cdef->validator(cs, cdef, (intptr_t) num, err); |
73 | |
|
74 | 0 | if (CSR_RESULT(rc) != CSR_SUCCESS) |
75 | 0 | return rc | CSR_INV_VALIDATOR; |
76 | 0 | } |
77 | | |
78 | 0 | *(long *) var = num; |
79 | 0 | } |
80 | 0 | else |
81 | 0 | { |
82 | 0 | cdef->initial = num; |
83 | 0 | } |
84 | | |
85 | 0 | return CSR_SUCCESS; |
86 | 0 | } |
87 | | |
88 | | /** |
89 | | * long_string_get - Get a Long as a string - Implements ConfigSetType::string_get() - @ingroup cfg_type_string_get |
90 | | */ |
91 | | static int long_string_get(const struct ConfigSet *cs, void *var, |
92 | | const struct ConfigDef *cdef, struct Buffer *result) |
93 | 0 | { |
94 | 0 | int value; |
95 | |
|
96 | 0 | if (var) |
97 | 0 | value = *(long *) var; |
98 | 0 | else |
99 | 0 | value = (int) cdef->initial; |
100 | |
|
101 | 0 | buf_printf(result, "%d", value); |
102 | 0 | return CSR_SUCCESS; |
103 | 0 | } |
104 | | |
105 | | /** |
106 | | * long_native_set - Set a Long config item by long - Implements ConfigSetType::native_set() - @ingroup cfg_type_native_set |
107 | | */ |
108 | | static int long_native_set(const struct ConfigSet *cs, void *var, |
109 | | const struct ConfigDef *cdef, intptr_t value, struct Buffer *err) |
110 | 0 | { |
111 | 0 | if ((value < 0) && (cdef->type & DT_NOT_NEGATIVE)) |
112 | 0 | { |
113 | 0 | buf_printf(err, _("Option %s may not be negative"), cdef->name); |
114 | 0 | return CSR_ERR_INVALID | CSR_INV_VALIDATOR; |
115 | 0 | } |
116 | | |
117 | 0 | if (value == (*(long *) var)) |
118 | 0 | return CSR_SUCCESS | CSR_SUC_NO_CHANGE; |
119 | | |
120 | 0 | if (cdef->validator) |
121 | 0 | { |
122 | 0 | int rc = cdef->validator(cs, cdef, value, err); |
123 | |
|
124 | 0 | if (CSR_RESULT(rc) != CSR_SUCCESS) |
125 | 0 | return rc | CSR_INV_VALIDATOR; |
126 | 0 | } |
127 | | |
128 | 0 | *(long *) var = value; |
129 | 0 | return CSR_SUCCESS; |
130 | 0 | } |
131 | | |
132 | | /** |
133 | | * long_native_get - Get a long from a Long config item - Implements ConfigSetType::native_get() - @ingroup cfg_type_native_get |
134 | | */ |
135 | | static intptr_t long_native_get(const struct ConfigSet *cs, void *var, |
136 | | const struct ConfigDef *cdef, struct Buffer *err) |
137 | 0 | { |
138 | 0 | return *(long *) var; |
139 | 0 | } |
140 | | |
141 | | /** |
142 | | * long_string_plus_equals - Add to a Long by string - Implements ConfigSetType::string_plus_equals() - @ingroup cfg_type_string_plus_equals |
143 | | */ |
144 | | static int long_string_plus_equals(const struct ConfigSet *cs, void *var, |
145 | | const struct ConfigDef *cdef, |
146 | | const char *value, struct Buffer *err) |
147 | 0 | { |
148 | 0 | long num = 0; |
149 | 0 | if (!mutt_str_atol_full(value, &num)) |
150 | 0 | { |
151 | 0 | buf_printf(err, _("Invalid long: %s"), NONULL(value)); |
152 | 0 | return CSR_ERR_INVALID | CSR_INV_TYPE; |
153 | 0 | } |
154 | | |
155 | 0 | long result = *((long *) var) + num; |
156 | 0 | if ((result < 0) && (cdef->type & DT_NOT_NEGATIVE)) |
157 | 0 | { |
158 | 0 | buf_printf(err, _("Option %s may not be negative"), cdef->name); |
159 | 0 | return CSR_ERR_INVALID | CSR_INV_VALIDATOR; |
160 | 0 | } |
161 | | |
162 | 0 | if (result == (*(long *) var)) |
163 | 0 | return CSR_SUCCESS | CSR_SUC_NO_CHANGE; |
164 | | |
165 | 0 | if (cdef->validator) |
166 | 0 | { |
167 | 0 | int rc = cdef->validator(cs, cdef, (intptr_t) result, err); |
168 | |
|
169 | 0 | if (CSR_RESULT(rc) != CSR_SUCCESS) |
170 | 0 | return rc | CSR_INV_VALIDATOR; |
171 | 0 | } |
172 | | |
173 | 0 | *(long *) var = result; |
174 | 0 | return CSR_SUCCESS; |
175 | 0 | } |
176 | | |
177 | | /** |
178 | | * long_string_minus_equals - Subtract from a Long by string - Implements ConfigSetType::string_minus_equals() - @ingroup cfg_type_string_minus_equals |
179 | | */ |
180 | | static int long_string_minus_equals(const struct ConfigSet *cs, void *var, |
181 | | const struct ConfigDef *cdef, |
182 | | const char *value, struct Buffer *err) |
183 | 0 | { |
184 | 0 | long num = 0; |
185 | 0 | if (!mutt_str_atol_full(value, &num)) |
186 | 0 | { |
187 | 0 | buf_printf(err, _("Invalid long: %s"), NONULL(value)); |
188 | 0 | return CSR_ERR_INVALID | CSR_INV_TYPE; |
189 | 0 | } |
190 | | |
191 | 0 | long result = *((long *) var) - num; |
192 | 0 | if ((result < 0) && (cdef->type & DT_NOT_NEGATIVE)) |
193 | 0 | { |
194 | 0 | buf_printf(err, _("Option %s may not be negative"), cdef->name); |
195 | 0 | return CSR_ERR_INVALID | CSR_INV_VALIDATOR; |
196 | 0 | } |
197 | | |
198 | 0 | if (result == (*(long *) var)) |
199 | 0 | return CSR_SUCCESS | CSR_SUC_NO_CHANGE; |
200 | | |
201 | 0 | if (cdef->validator) |
202 | 0 | { |
203 | 0 | int rc = cdef->validator(cs, cdef, (intptr_t) result, err); |
204 | |
|
205 | 0 | if (CSR_RESULT(rc) != CSR_SUCCESS) |
206 | 0 | return rc | CSR_INV_VALIDATOR; |
207 | 0 | } |
208 | | |
209 | 0 | *(long *) var = result; |
210 | 0 | return CSR_SUCCESS; |
211 | 0 | } |
212 | | |
213 | | /** |
214 | | * long_reset - Reset a Long to its initial value - Implements ConfigSetType::reset() - @ingroup cfg_type_reset |
215 | | */ |
216 | | static int long_reset(const struct ConfigSet *cs, void *var, |
217 | | const struct ConfigDef *cdef, struct Buffer *err) |
218 | 28.2k | { |
219 | 28.2k | if (cdef->initial == (*(long *) var)) |
220 | 28.2k | return CSR_SUCCESS | CSR_SUC_NO_CHANGE; |
221 | | |
222 | 2 | if (cdef->validator) |
223 | 0 | { |
224 | 0 | int rc = cdef->validator(cs, cdef, cdef->initial, err); |
225 | |
|
226 | 0 | if (CSR_RESULT(rc) != CSR_SUCCESS) |
227 | 0 | return rc | CSR_INV_VALIDATOR; |
228 | 0 | } |
229 | | |
230 | 2 | *(long *) var = cdef->initial; |
231 | 2 | return CSR_SUCCESS; |
232 | 2 | } |
233 | | |
234 | | /** |
235 | | * CstLong - Config type representing a long |
236 | | */ |
237 | | const struct ConfigSetType CstLong = { |
238 | | DT_LONG, |
239 | | "long", |
240 | | long_string_set, |
241 | | long_string_get, |
242 | | long_native_set, |
243 | | long_native_get, |
244 | | long_string_plus_equals, |
245 | | long_string_minus_equals, |
246 | | long_reset, |
247 | | NULL, // destroy |
248 | | }; |