NeoMutt  2024-04-16-36-g75b6fb
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
config_type.c
Go to the documentation of this file.
1
37#include "config.h"
38#include <stddef.h>
39#include <assert.h>
40#include <limits.h>
41#include <stdbool.h>
42#include <stdint.h>
43#include "mutt/lib.h"
44#include "config/lib.h"
45#include "config_type.h"
46#include "address.h"
47
53struct Address *address_new(const char *addr)
54{
55 struct Address *a = mutt_mem_calloc(1, sizeof(*a));
56 a->mailbox = buf_new(addr);
57 return a;
58}
59
63static void address_destroy(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
64{
65 struct Address **a = var;
66 if (!*a)
67 return;
68
70}
71
75static int address_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef,
76 const char *value, struct Buffer *err)
77{
78 /* Store empty address as NULL */
79 if (value && (value[0] == '\0'))
80 value = NULL;
81
82 struct Address *addr = NULL;
83
84 int rc = CSR_SUCCESS;
85
86 if (!value && (cdef->type & D_NOT_EMPTY))
87 {
88 buf_printf(err, _("Option %s may not be empty"), cdef->name);
90 }
91
92 if (var && value)
93 {
94 // TODO - config can only store one
95 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
96 mutt_addrlist_parse(&al, value);
97 addr = mutt_addr_copy(TAILQ_FIRST(&al));
99 }
100
101 if (var)
102 {
103 if (cdef->validator)
104 {
105 rc = cdef->validator(cs, cdef, (intptr_t) addr, err);
106
107 if (CSR_RESULT(rc) != CSR_SUCCESS)
108 {
109 address_destroy(cs, &addr, cdef);
110 return rc | CSR_INV_VALIDATOR;
111 }
112 }
113
114 /* ordinary variable setting */
115 address_destroy(cs, var, cdef);
116
117 *(struct Address **) var = addr;
118
119 if (!addr)
120 rc |= CSR_SUC_EMPTY;
121 }
122 else
123 {
124 /* set the default/initial value */
125 if (cdef->type & D_INTERNAL_INITIAL_SET)
126 FREE(&cdef->initial);
127
129 cdef->initial = (intptr_t) mutt_str_dup(value);
130 }
131
132 return rc;
133}
134
138static int address_string_get(const struct ConfigSet *cs, void *var,
139 const struct ConfigDef *cdef, struct Buffer *result)
140{
141 if (var)
142 {
143 struct Address *a = *(struct Address **) var;
144 if (a)
145 {
146 mutt_addr_write(result, a, false);
147 }
148 }
149 else
150 {
151 buf_addstr(result, (char *) cdef->initial);
152 }
153
154 if (buf_is_empty(result))
155 return CSR_SUCCESS | CSR_SUC_EMPTY; /* empty string */
156
157 return CSR_SUCCESS;
158}
159
165static struct Address *address_dup(struct Address *addr)
166{
167 if (!addr)
168 return NULL; /* LCOV_EXCL_LINE */
169
170 struct Address *a = mutt_mem_calloc(1, sizeof(*a));
171 a->personal = buf_dup(addr->personal);
172 a->mailbox = buf_dup(addr->mailbox);
173 return a;
174}
175
179static int address_native_set(const struct ConfigSet *cs, void *var,
180 const struct ConfigDef *cdef, intptr_t value,
181 struct Buffer *err)
182{
183 int rc;
184
185 if (cdef->validator)
186 {
187 rc = cdef->validator(cs, cdef, value, err);
188
189 if (CSR_RESULT(rc) != CSR_SUCCESS)
190 return rc | CSR_INV_VALIDATOR;
191 }
192
193 mutt_addr_free(var);
194
195 struct Address *addr = address_dup((struct Address *) value);
196
197 rc = CSR_SUCCESS;
198 if (!addr)
199 rc |= CSR_SUC_EMPTY;
200
201 *(struct Address **) var = addr;
202 return rc;
203}
204
208static intptr_t address_native_get(const struct ConfigSet *cs, void *var,
209 const struct ConfigDef *cdef, struct Buffer *err)
210{
211 struct Address *addr = *(struct Address **) var;
212
213 return (intptr_t) addr;
214}
215
219static int address_reset(const struct ConfigSet *cs, void *var,
220 const struct ConfigDef *cdef, struct Buffer *err)
221{
222 struct Address *a = NULL;
223 const char *initial = (const char *) cdef->initial;
224
225 if (initial)
226 a = address_new(initial);
227
228 int rc = CSR_SUCCESS;
229
230 if (cdef->validator)
231 {
232 rc = cdef->validator(cs, cdef, (intptr_t) a, err);
233
234 if (CSR_RESULT(rc) != CSR_SUCCESS)
235 {
236 address_destroy(cs, &a, cdef);
237 return rc | CSR_INV_VALIDATOR;
238 }
239 }
240
241 if (!a)
242 rc |= CSR_SUC_EMPTY;
243
244 address_destroy(cs, var, cdef);
245
246 *(struct Address **) var = a;
247 return rc;
248}
249
253const struct ConfigSetType CstAddress = {
255 "address",
260 NULL, // string_plus_equals
261 NULL, // string_minus_equals
264};
265
273const struct Address *cs_subset_address(const struct ConfigSubset *sub, const char *name)
274{
275 assert(sub && name);
276
277 struct HashElem *he = cs_subset_create_inheritance(sub, name);
278 assert(he);
279
280#ifndef NDEBUG
281 struct HashElem *he_base = cs_get_base(he);
282 assert(DTYPE(he_base->type) == DT_ADDRESS);
283#endif
284
285 intptr_t value = cs_subset_he_native_get(sub, he, NULL);
286 assert(value != INT_MIN);
287
288 return (const struct Address *) value;
289}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1460
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:462
size_t mutt_addr_write(struct Buffer *buf, struct Address *addr, bool display)
Write a single Address to a buffer.
Definition: address.c:1050
struct Address * mutt_addr_copy(const struct Address *addr)
Copy the real address.
Definition: address.c:745
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:480
struct Address * address_new(const char *addr)
Create an Address from a string.
Definition: config_type.c:53
const struct ConfigSetType CstAddress
Config type representing an Email Address.
Definition: config_type.c:253
static struct Address * address_dup(struct Address *addr)
Create a copy of an Address object.
Definition: config_type.c:165
const struct Address * cs_subset_address(const struct ConfigSubset *sub, const char *name)
Get an Address config item by name.
Definition: config_type.c:273
Representation of an email address.
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:290
struct Buffer * buf_new(const char *str)
Allocate a new Buffer.
Definition: buffer.c:303
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
struct Buffer * buf_dup(const struct Buffer *buf)
Copy a Buffer into a new allocated buffer.
Definition: buffer.c:585
Convenience wrapper for the config headers.
struct HashElem * cs_get_base(struct HashElem *he)
Find the root Config Item.
Definition: set.c:160
#define CSR_ERR_INVALID
Value hasn't been set.
Definition: set.h:38
#define CSR_INV_VALIDATOR
Value was rejected by the validator.
Definition: set.h:48
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUC_EMPTY
Value is empty/unset.
Definition: set.h:42
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
Config type representing an email address.
static void address_destroy(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
Destroy an Address object - Implements ConfigSetType::destroy() -.
Definition: config_type.c:63
static intptr_t address_native_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Get an Address object from an Address config item - Implements ConfigSetType::native_get() -.
Definition: config_type.c:208
static int address_native_set(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Set an Address config item by Address object - Implements ConfigSetType::native_set() -.
Definition: config_type.c:179
static int address_reset(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Reset an Address to its initial value - Implements ConfigSetType::reset() -.
Definition: config_type.c:219
static int address_string_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *result)
Get an Address as a string - Implements ConfigSetType::string_get() -.
Definition: config_type.c:138
static int address_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Set an Address by string - Implements ConfigSetType::string_set() -.
Definition: config_type.c:75
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define FREE(x)
Definition: memory.h:45
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
#define TAILQ_FIRST(head)
Definition: queue.h:723
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
An email address.
Definition: address.h:36
struct Buffer * personal
Real name of address.
Definition: address.h:37
struct Buffer * mailbox
Mailbox and host address.
Definition: address.h:38
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
A set of inherited config items.
Definition: subset.h:47
The item stored in a Hash Table.
Definition: hash.h:43
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:44
intptr_t cs_subset_he_native_get(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
Natively get the value of a HashElem config item.
Definition: subset.c:258
struct HashElem * cs_subset_create_inheritance(const struct ConfigSubset *sub, const char *name)
Create a Subset config item (inherited)
Definition: subset.c:208
#define DTYPE(t)
Definition: types.h:50
#define D_INTERNAL_INITIAL_SET
Config item must have its initial value freed.
Definition: types.h:90
@ DT_ADDRESS
e-mail address
Definition: types.h:31
#define D_NOT_EMPTY
Empty strings are not allowed.
Definition: types.h:80