NeoMutt  2024-03-23-23-gec7045
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
number.c
Go to the documentation of this file.
1
36#include "config.h"
37#include <stddef.h>
38#include <limits.h>
39#include <stdint.h>
40#include "mutt/lib.h"
41#include "set.h"
42#include "types.h"
43
47static int number_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef,
48 const char *value, struct Buffer *err)
49{
50 if (!value || (value[0] == '\0'))
51 {
52 buf_printf(err, _("Option %s may not be empty"), cdef->name);
54 }
55
56 int num = 0;
57 if (!mutt_str_atoi_full(value, &num))
58 {
59 buf_printf(err, _("Invalid number: %s"), value);
61 }
62
63 if ((num < SHRT_MIN) || (num > SHRT_MAX))
64 {
65 buf_printf(err, _("Number is too big: %s"), value);
67 }
68
69 if ((num < 0) && (cdef->type & D_INTEGER_NOT_NEGATIVE))
70 {
71 buf_printf(err, _("Option %s may not be negative"), cdef->name);
73 }
74
75 if (var)
76 {
77 if (num == (*(short *) var))
79
80 if (cdef->validator)
81 {
82 int rc = cdef->validator(cs, cdef, (intptr_t) num, err);
83
84 if (CSR_RESULT(rc) != CSR_SUCCESS)
85 return rc | CSR_INV_VALIDATOR;
86 }
87
88 if (startup_only(cdef, err))
90
91 *(short *) var = num;
92 }
93 else
94 {
95 cdef->initial = num;
96 }
97
98 return CSR_SUCCESS;
99}
100
104static int number_string_get(const struct ConfigSet *cs, void *var,
105 const struct ConfigDef *cdef, struct Buffer *result)
106{
107 int value;
108
109 if (var)
110 value = *(short *) var;
111 else
112 value = (int) cdef->initial;
113
114 buf_printf(result, "%d", value);
115 return CSR_SUCCESS;
116}
117
121static int number_native_set(const struct ConfigSet *cs, void *var,
122 const struct ConfigDef *cdef, intptr_t value,
123 struct Buffer *err)
124{
125 if ((value < SHRT_MIN) || (value > SHRT_MAX))
126 {
127 buf_printf(err, _("Invalid number: %ld"), (long) value);
129 }
130
131 if ((value < 0) && (cdef->type & D_INTEGER_NOT_NEGATIVE))
132 {
133 buf_printf(err, _("Option %s may not be negative"), cdef->name);
135 }
136
137 if (value == (*(short *) var))
139
140 if (cdef->validator)
141 {
142 int rc = cdef->validator(cs, cdef, value, err);
143
144 if (CSR_RESULT(rc) != CSR_SUCCESS)
145 return rc | CSR_INV_VALIDATOR;
146 }
147
148 if (startup_only(cdef, err))
150
151 *(short *) var = value;
152 return CSR_SUCCESS;
153}
154
158static intptr_t number_native_get(const struct ConfigSet *cs, void *var,
159 const struct ConfigDef *cdef, struct Buffer *err)
160{
161 return *(short *) var;
162}
163
167static int number_string_plus_equals(const struct ConfigSet *cs, void *var,
168 const struct ConfigDef *cdef,
169 const char *value, struct Buffer *err)
170{
171 int num = 0;
172 if (!mutt_str_atoi_full(value, &num))
173 {
174 buf_printf(err, _("Invalid number: %s"), NONULL(value));
176 }
177
178 int result = *((short *) var) + num;
179 if ((result < SHRT_MIN) || (result > SHRT_MAX))
180 {
181 buf_printf(err, _("Number is too big: %s"), value);
183 }
184
185 if ((result < 0) && (cdef->type & D_INTEGER_NOT_NEGATIVE))
186 {
187 buf_printf(err, _("Option %s may not be negative"), cdef->name);
189 }
190
191 if (cdef->validator)
192 {
193 int rc = cdef->validator(cs, cdef, (intptr_t) result, err);
194
195 if (CSR_RESULT(rc) != CSR_SUCCESS)
196 return rc | CSR_INV_VALIDATOR;
197 }
198
199 if (startup_only(cdef, err))
201
202 *(short *) var = result;
203 return CSR_SUCCESS;
204}
205
209static int number_string_minus_equals(const struct ConfigSet *cs, void *var,
210 const struct ConfigDef *cdef,
211 const char *value, struct Buffer *err)
212{
213 int num = 0;
214 if (!mutt_str_atoi(value, &num))
215 {
216 buf_printf(err, _("Invalid number: %s"), NONULL(value));
218 }
219
220 int result = *((short *) var) - num;
221 if ((result < SHRT_MIN) || (result > SHRT_MAX))
222 {
223 buf_printf(err, _("Number is too big: %s"), value);
225 }
226
227 if ((result < 0) && (cdef->type & D_INTEGER_NOT_NEGATIVE))
228 {
229 buf_printf(err, _("Option %s may not be negative"), cdef->name);
231 }
232
233 if (cdef->validator)
234 {
235 int rc = cdef->validator(cs, cdef, (intptr_t) result, err);
236
237 if (CSR_RESULT(rc) != CSR_SUCCESS)
238 return rc | CSR_INV_VALIDATOR;
239 }
240
241 if (startup_only(cdef, err))
243
244 *(short *) var = result;
245 return CSR_SUCCESS;
246}
247
251static int number_reset(const struct ConfigSet *cs, void *var,
252 const struct ConfigDef *cdef, struct Buffer *err)
253{
254 if (cdef->initial == (*(short *) var))
256
257 if (cdef->validator)
258 {
259 int rc = cdef->validator(cs, cdef, cdef->initial, err);
260
261 if (CSR_RESULT(rc) != CSR_SUCCESS)
262 return rc | CSR_INV_VALIDATOR;
263 }
264
265 if (startup_only(cdef, err))
267
268 *(short *) var = cdef->initial;
269 return CSR_SUCCESS;
270}
271
275const struct ConfigSetType CstNumber = {
276 DT_NUMBER,
277 "number",
285 NULL, // destroy
286};
const char * mutt_str_atoi(const char *str, int *dst)
Convert ASCII string to an integer.
Definition: atoi.c:188
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:178
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:38
#define CSR_INV_TYPE
Value is not valid for the type.
Definition: set.h:47
#define CSR_INV_VALIDATOR
Value was rejected by the validator.
Definition: set.h:48
#define CSR_SUC_NO_CHANGE
The value hasn't changed.
Definition: set.h:44
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
static intptr_t number_native_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Get an int from a Number config item - Implements ConfigSetType::native_get() -.
Definition: number.c:158
static int number_native_set(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Set a Number config item by int - Implements ConfigSetType::native_set() -.
Definition: number.c:121
static int number_reset(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Reset a Number to its initial value - Implements ConfigSetType::reset() -.
Definition: number.c:251
static int number_string_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *result)
Get a Number as a string - Implements ConfigSetType::string_get() -.
Definition: number.c:104
static int number_string_minus_equals(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Subtract from a Number by string - Implements ConfigSetType::string_minus_equals() -.
Definition: number.c:209
static int number_string_plus_equals(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Add to a Number by string - Implements ConfigSetType::string_plus_equals() -.
Definition: number.c:167
static int number_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Set a Number by string - Implements ConfigSetType::string_set() -.
Definition: number.c:47
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
const struct ConfigSetType CstNumber
Config type representing a number.
Definition: number.c:275
Parse the 'set' command.
#define NONULL(x)
Definition: string2.h:37
String manipulation buffer.
Definition: buffer.h:36
Definition: set.h:64
const char * name
User-visible name.
Definition: set.h:65
int(* validator)(const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition: set.h:82
intptr_t initial
Initial value.
Definition: set.h:67
uint32_t type
Variable type, e.g. DT_STRING.
Definition: set.h:66
Container for lots of config items.
Definition: set.h:252
Constants for all the config types.
@ DT_NUMBER
a number
Definition: types.h:39
#define D_INTEGER_NOT_NEGATIVE
Negative numbers are not allowed.
Definition: types.h:99