Coverage Report

Created: 2023-06-07 06:15

/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
};