NeoMutt  2024-04-25-91-gb0e085
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 <limits.h>
39#include <stdbool.h>
40#include <stddef.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 /* Store empty address as NULL */
78 if (value && (value[0] == '\0'))
79 value = NULL;
80
81 struct Address *addr = NULL;
82
83 int rc = CSR_SUCCESS;
84
85 if (!value && (cdef->type & D_NOT_EMPTY))
86 {
87 buf_printf(err, _("Option %s may not be empty"), cdef->name);
89 }
90
91 if (var && value)
92 {
93 // TODO - config can only store one
94 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
95 mutt_addrlist_parse(&al, value);
96 addr = mutt_addr_copy(TAILQ_FIRST(&al));
98 }
99
100 if (var)
101 {
102 if (cdef->validator)
103 {
104 rc = cdef->validator(cs, cdef, (intptr_t) addr, err);
105
106 if (CSR_RESULT(rc) != CSR_SUCCESS)
107 {
108 address_destroy(cs, &addr, cdef);
109 return rc | CSR_INV_VALIDATOR;
110 }
111 }
112
113 /* ordinary variable setting */
114 address_destroy(cs, var, cdef);
115
116 *(struct Address **) var = addr;
117
118 if (!addr)
119 rc |= CSR_SUC_EMPTY;
120 }
121 else
122 {
123 /* set the default/initial value */
124 if (cdef->type & D_INTERNAL_INITIAL_SET)
125 FREE(&cdef->initial);
126
128 cdef->initial = (intptr_t) mutt_str_dup(value);
129 }
130
131 return rc;
132}
133
137static int address_string_get(const struct ConfigSet *cs, void *var,
138 const struct ConfigDef *cdef, struct Buffer *result)
139{
140 if (var)
141 {
142 struct Address *a = *(struct Address **) var;
143 if (a)
144 {
145 mutt_addr_write(result, a, false);
146 }
147 }
148 else
149 {
150 buf_addstr(result, (char *) cdef->initial);
151 }
152
153 if (buf_is_empty(result))
154 return CSR_SUCCESS | CSR_SUC_EMPTY; /* empty string */
155
156 return CSR_SUCCESS;
157}
158
164static struct Address *address_dup(struct Address *addr)
165{
166 if (!addr)
167 return NULL; /* LCOV_EXCL_LINE */
168
169 struct Address *a = mutt_mem_calloc(1, sizeof(*a));
170 a->personal = buf_dup(addr->personal);
171 a->mailbox = buf_dup(addr->mailbox);
172 return a;
173}
174
178static int address_native_set(const struct ConfigSet *cs, void *var,
179 const struct ConfigDef *cdef, intptr_t value,
180 struct Buffer *err)
181{
182 int rc;
183
184 if (cdef->validator)
185 {
186 rc = cdef->validator(cs, cdef, value, err);
187
188 if (CSR_RESULT(rc) != CSR_SUCCESS)
189 return rc | CSR_INV_VALIDATOR;
190 }
191
192 mutt_addr_free(var);
193
194 struct Address *addr = address_dup((struct Address *) value);
195
196 rc = CSR_SUCCESS;
197 if (!addr)
198 rc |= CSR_SUC_EMPTY;
199
200 *(struct Address **) var = addr;
201 return rc;
202}
203
207static intptr_t address_native_get(const struct ConfigSet *cs, void *var,
208 const struct ConfigDef *cdef, struct Buffer *err)
209{
210 struct Address *addr = *(struct Address **) var;
211
212 return (intptr_t) addr;
213}
214
218static int address_reset(const struct ConfigSet *cs, void *var,
219 const struct ConfigDef *cdef, struct Buffer *err)
220{
221 struct Address *a = NULL;
222 const char *initial = (const char *) cdef->initial;
223
224 if (initial)
225 a = address_new(initial);
226
227 int rc = CSR_SUCCESS;
228
229 if (cdef->validator)
230 {
231 rc = cdef->validator(cs, cdef, (intptr_t) a, err);
232
233 if (CSR_RESULT(rc) != CSR_SUCCESS)
234 {
235 address_destroy(cs, &a, cdef);
236 return rc | CSR_INV_VALIDATOR;
237 }
238 }
239
240 if (!a)
241 rc |= CSR_SUC_EMPTY;
242
243 address_destroy(cs, var, cdef);
244
245 *(struct Address **) var = a;
246 return rc;
247}
248
252const struct ConfigSetType CstAddress = {
254 "address",
259 NULL, // string_plus_equals
260 NULL, // string_minus_equals
263};
264
272const struct Address *cs_subset_address(const struct ConfigSubset *sub, const char *name)
273{
274 ASSERT(sub && name);
275
276 struct HashElem *he = cs_subset_create_inheritance(sub, name);
277 ASSERT(he);
278
279#ifndef NDEBUG
280 struct HashElem *he_base = cs_get_base(he);
281 ASSERT(DTYPE(he_base->type) == DT_ADDRESS);
282#endif
283
284 intptr_t value = cs_subset_he_native_get(sub, he, NULL);
285 ASSERT(value != INT_MIN);
286
287 return (const struct Address *) value;
288}
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:52
const struct ConfigSetType CstAddress
Config type representing an Email Address.
Definition: config_type.c:252
static struct Address * address_dup(struct Address *addr)
Create a copy of an Address object.
Definition: config_type.c:164
const struct Address * cs_subset_address(const struct ConfigSubset *sub, const char *name)
Get an Address config item by name.
Definition: config_type.c:272
Representation of an email address.
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
struct Buffer * buf_new(const char *str)
Allocate a new Buffer.
Definition: buffer.c:304
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
struct Buffer * buf_dup(const struct Buffer *buf)
Copy a Buffer into a new allocated buffer.
Definition: buffer.c:586
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: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:207
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:178
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:218
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:137
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:51
#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
#define ASSERT(COND)
Definition: signal2.h:58
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