NeoMutt  2023-11-03-85-g512e01
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
config_type.c
Go to the documentation of this file.
1
36#include "config.h"
37#include <stddef.h>
38#include <assert.h>
39#include <limits.h>
40#include <stdbool.h>
41#include <stdint.h>
42#include "mutt/lib.h"
43#include "config/lib.h"
44#include "config_type.h"
45#include "address.h"
46
52struct Address *address_new(const char *addr)
53{
54 struct Address *a = mutt_mem_calloc(1, sizeof(*a));
55 a->mailbox = buf_new(addr);
56 return a;
57}
58
62static void address_destroy(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
63{
64 struct Address **a = var;
65 if (!*a)
66 return;
67
69}
70
74static int address_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef,
75 const char *value, struct Buffer *err)
76{
77 struct Address *addr = NULL;
78
79 /* An empty address "" will be stored as NULL */
80 if (var && value && (value[0] != '\0'))
81 {
82 // TODO - config can only store one
83 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
84 mutt_addrlist_parse(&al, value);
85 addr = mutt_addr_copy(TAILQ_FIRST(&al));
87 }
88
89 int rc = CSR_SUCCESS;
90
91 if (var)
92 {
93 if (cdef->validator)
94 {
95 rc = cdef->validator(cs, cdef, (intptr_t) addr, err);
96
97 if (CSR_RESULT(rc) != CSR_SUCCESS)
98 {
99 address_destroy(cs, &addr, cdef);
100 return rc | CSR_INV_VALIDATOR;
101 }
102 }
103
104 /* ordinary variable setting */
105 address_destroy(cs, var, cdef);
106
107 *(struct Address **) var = addr;
108
109 if (!addr)
110 rc |= CSR_SUC_EMPTY;
111 }
112 else
113 {
114 /* set the default/initial value */
115 if (cdef->type & DT_INITIAL_SET)
116 FREE(&cdef->initial);
117
118 cdef->type |= DT_INITIAL_SET;
119 cdef->initial = (intptr_t) mutt_str_dup(value);
120 }
121
122 return rc;
123}
124
128static int address_string_get(const struct ConfigSet *cs, void *var,
129 const struct ConfigDef *cdef, struct Buffer *result)
130{
131 if (var)
132 {
133 struct Address *a = *(struct Address **) var;
134 if (a)
135 {
136 mutt_addr_write(result, a, false);
137 }
138 }
139 else
140 {
141 buf_addstr(result, (char *) cdef->initial);
142 }
143
144 if (buf_is_empty(result))
145 return CSR_SUCCESS | CSR_SUC_EMPTY; /* empty string */
146
147 return CSR_SUCCESS;
148}
149
155static struct Address *address_dup(struct Address *addr)
156{
157 if (!addr)
158 return NULL; /* LCOV_EXCL_LINE */
159
160 struct Address *a = mutt_mem_calloc(1, sizeof(*a));
161 a->personal = buf_dup(addr->personal);
162 a->mailbox = buf_dup(addr->mailbox);
163 return a;
164}
165
169static int address_native_set(const struct ConfigSet *cs, void *var,
170 const struct ConfigDef *cdef, intptr_t value,
171 struct Buffer *err)
172{
173 int rc;
174
175 if (cdef->validator)
176 {
177 rc = cdef->validator(cs, cdef, value, err);
178
179 if (CSR_RESULT(rc) != CSR_SUCCESS)
180 return rc | CSR_INV_VALIDATOR;
181 }
182
183 mutt_addr_free(var);
184
185 struct Address *addr = address_dup((struct Address *) value);
186
187 rc = CSR_SUCCESS;
188 if (!addr)
189 rc |= CSR_SUC_EMPTY;
190
191 *(struct Address **) var = addr;
192 return rc;
193}
194
198static intptr_t address_native_get(const struct ConfigSet *cs, void *var,
199 const struct ConfigDef *cdef, struct Buffer *err)
200{
201 struct Address *addr = *(struct Address **) var;
202
203 return (intptr_t) addr;
204}
205
209static int address_reset(const struct ConfigSet *cs, void *var,
210 const struct ConfigDef *cdef, struct Buffer *err)
211{
212 struct Address *a = NULL;
213 const char *initial = (const char *) cdef->initial;
214
215 if (initial)
216 a = address_new(initial);
217
218 int rc = CSR_SUCCESS;
219
220 if (cdef->validator)
221 {
222 rc = cdef->validator(cs, cdef, (intptr_t) a, err);
223
224 if (CSR_RESULT(rc) != CSR_SUCCESS)
225 {
226 address_destroy(cs, &a, cdef);
227 return rc | CSR_INV_VALIDATOR;
228 }
229 }
230
231 if (!a)
232 rc |= CSR_SUC_EMPTY;
233
234 address_destroy(cs, var, cdef);
235
236 *(struct Address **) var = a;
237 return rc;
238}
239
243const struct ConfigSetType CstAddress = {
245 "address",
250 NULL, // string_plus_equals
251 NULL, // string_minus_equals
254};
255
263const struct Address *cs_subset_address(const struct ConfigSubset *sub, const char *name)
264{
265 assert(sub && name);
266
267 struct HashElem *he = cs_subset_create_inheritance(sub, name);
268 assert(he);
269
270#ifndef NDEBUG
271 struct HashElem *he_base = cs_get_base(he);
272 assert(DTYPE(he_base->type) == DT_ADDRESS);
273#endif
274
275 intptr_t value = cs_subset_he_native_get(sub, he, NULL);
276 assert(value != INT_MIN);
277
278 return (const struct Address *) value;
279}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1461
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:460
size_t mutt_addr_write(struct Buffer *buf, struct Address *addr, bool display)
Write a single Address to a buffer.
Definition: address.c:1047
struct Address * mutt_addr_copy(const struct Address *addr)
Copy the real address.
Definition: address.c:742
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:478
Representation of an email address.
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:303
struct Buffer * buf_new(const char *str)
Allocate a new Buffer.
Definition: buffer.c:316
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:238
struct Buffer * buf_dup(const struct Buffer *buf)
Copy a Buffer into a new allocated buffer.
Definition: buffer.c:557
Convenience wrapper for the config headers.
struct HashElem * cs_get_base(struct HashElem *he)
Find the root Config Item.
Definition: set.c:157
#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
struct Address * address_new(const char *addr)
Create an Address from a string.
Definition: config_type.c:52
const struct ConfigSetType CstAddress
Config type representing an Email Address.
Definition: config_type.c:243
static struct Address * address_dup(struct Address *addr)
Create a copy of an Address object.
Definition: config_type.c:155
const struct Address * cs_subset_address(const struct ConfigSubset *sub, const char *name)
Get an Address config item by name.
Definition: config_type.c:263
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:62
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:198
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:169
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:209
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:128
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:74
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.
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:251
#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: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 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:44
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:45
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:249
struct HashElem * cs_subset_create_inheritance(const struct ConfigSubset *sub, const char *name)
Create a Subset config item (inherited)
Definition: subset.c:199
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:45
#define DT_INITIAL_SET
Config item must have its initial value freed.
Definition: types.h:80
#define DT_ADDRESS
e-mail address
Definition: types.h:29