NeoMutt  2022-04-29-145-g9b6a0e
Teaching an old dog new tricks
DOXYGEN
enum.c
Go to the documentation of this file.
1 
33 #include "config.h"
34 #include <stddef.h>
35 #include <limits.h>
36 #include <stdint.h>
37 #include "mutt/lib.h"
38 #include "enum.h"
39 #include "set.h"
40 #include "types.h"
41 
45 static int enum_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef,
46  const char *value, struct Buffer *err)
47 {
48  if (!cs || !cdef || !value)
49  return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
50 
51  struct EnumDef *ed = (struct EnumDef *) cdef->data;
52  if (!ed || !ed->lookup)
53  return CSR_ERR_CODE;
54 
55  int num = mutt_map_get_value(value, ed->lookup);
56  if (num < 0)
57  {
58  mutt_buffer_printf(err, _("Invalid enum value: %s"), value);
59  return (CSR_ERR_INVALID | CSR_INV_TYPE);
60  }
61 
62  if (var)
63  {
64  if (num == (*(unsigned char *) var))
65  return (CSR_SUCCESS | CSR_SUC_NO_CHANGE);
66 
67  if (cdef->validator)
68  {
69  int rc = cdef->validator(cs, cdef, (intptr_t) num, err);
70 
71  if (CSR_RESULT(rc) != CSR_SUCCESS)
72  return (rc | CSR_INV_VALIDATOR);
73  }
74 
75  *(unsigned char *) var = num;
76  }
77  else
78  {
79  cdef->initial = num;
80  }
81 
82  return CSR_SUCCESS;
83 }
84 
88 static int enum_string_get(const struct ConfigSet *cs, void *var,
89  const struct ConfigDef *cdef, struct Buffer *result)
90 {
91  if (!cs || !cdef)
92  return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
93 
94  unsigned int value;
95 
96  if (var)
97  value = *(unsigned char *) var;
98  else
99  value = (int) cdef->initial;
100 
101  struct EnumDef *ed = (struct EnumDef *) cdef->data;
102  if (!ed || !ed->lookup)
103  return CSR_ERR_CODE;
104 
105  const char *name = mutt_map_get_name(value, ed->lookup);
106  if (!name)
107  {
108  mutt_debug(LL_DEBUG1, "Variable has an invalid value: %d\n", value);
109  return (CSR_ERR_INVALID | CSR_INV_TYPE);
110  }
111 
112  mutt_buffer_addstr(result, name);
113  return CSR_SUCCESS;
114 }
115 
119 static int enum_native_set(const struct ConfigSet *cs, void *var,
120  const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
121 {
122  if (!cs || !var || !cdef)
123  return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
124 
125  struct EnumDef *ed = (struct EnumDef *) cdef->data;
126  if (!ed || !ed->lookup)
127  return CSR_ERR_CODE;
128 
129  const char *name = mutt_map_get_name(value, ed->lookup);
130  if (!name)
131  {
132  mutt_buffer_printf(err, _("Invalid enum value: %ld"), value);
133  return (CSR_ERR_INVALID | CSR_INV_TYPE);
134  }
135 
136  if (value == (*(unsigned char *) var))
137  return (CSR_SUCCESS | CSR_SUC_NO_CHANGE);
138 
139  if (cdef->validator)
140  {
141  int rc = cdef->validator(cs, cdef, value, err);
142 
143  if (CSR_RESULT(rc) != CSR_SUCCESS)
144  return (rc | CSR_INV_VALIDATOR);
145  }
146 
147  *(unsigned char *) var = value;
148  return CSR_SUCCESS;
149 }
150 
154 static intptr_t enum_native_get(const struct ConfigSet *cs, void *var,
155  const struct ConfigDef *cdef, struct Buffer *err)
156 {
157  if (!cs || !var || !cdef)
158  return INT_MIN; /* LCOV_EXCL_LINE */
159 
160  return *(unsigned char *) var;
161 }
162 
166 static int enum_reset(const struct ConfigSet *cs, void *var,
167  const struct ConfigDef *cdef, struct Buffer *err)
168 {
169  if (!cs || !var || !cdef)
170  return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
171 
172  if (cdef->initial == (*(unsigned char *) var))
173  return (CSR_SUCCESS | CSR_SUC_NO_CHANGE);
174 
175  if (cdef->validator)
176  {
177  int rc = cdef->validator(cs, cdef, cdef->initial, err);
178 
179  if (CSR_RESULT(rc) != CSR_SUCCESS)
180  return (rc | CSR_INV_VALIDATOR);
181  }
182 
183  *(unsigned char *) var = cdef->initial;
184  return CSR_SUCCESS;
185 }
186 
190 const struct ConfigSetType CstEnum = {
191  DT_ENUM,
192  "enum",
197  NULL, // string_plus_equals
198  NULL, // string_minus_equals
199  enum_reset,
200  NULL, // destroy
201 };
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:223
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:158
const struct ConfigSetType CstEnum
Config type representing an enumeration.
Definition: enum.c:190
Type representing an enumeration.
static intptr_t enum_native_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Get an int object from an Enumeration config item - Implements ConfigSetType::native_get() -.
Definition: enum.c:154
static int enum_native_set(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Set an Enumeration config item by int - Implements ConfigSetType::native_set() -.
Definition: enum.c:119
static int enum_reset(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Reset an Enumeration to its initial value - Implements ConfigSetType::reset() -.
Definition: enum.c:166
static int enum_string_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *result)
Get an Enumeration as a string - Implements ConfigSetType::string_get() -.
Definition: enum.c:88
static int enum_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Set an Enumeration by string - Implements ConfigSetType::string_set() -.
Definition: enum.c:45
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
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
A collection of config items.
#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_ERR_CODE
Problem with the code.
Definition: set.h:36
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
String manipulation buffer.
Definition: buffer.h:34
Definition: set.h:64
int(* validator)(const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition: set.h:82
intptr_t data
Extra variable data.
Definition: set.h:68
intptr_t initial
Initial value.
Definition: set.h:67
Container for lots of config items.
Definition: set.h:260
An enumeration.
Definition: enum.h:30
const char * name
Config variable.
Definition: enum.h:31
struct Mapping * lookup
Lookup table.
Definition: enum.h:33
Constants for all the config types.
#define DT_ENUM
an enumeration
Definition: types.h:31