NeoMutt  2024-11-14-138-ge5ca67
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
subset.c File Reference

Subset of config items. More...

#include "config.h"
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include "mutt/lib.h"
#include "subset.h"
#include "set.h"
+ Include dependency graph for subset.c:

Go to the source code of this file.

Functions

int elem_list_sort (const void *a, const void *b, void *sdata)
 Compare two HashElem pointers to config - Implements sort_t -.
 
struct HashElem ** get_elem_list (struct ConfigSet *cs)
 Create a sorted list of all config items.
 
void cs_subset_free (struct ConfigSubset **ptr)
 Free a Config Subset.
 
struct ConfigSubsetcs_subset_new (const char *name, struct ConfigSubset *sub_parent, struct Notify *not_parent)
 Create a new Config Subset.
 
struct HashElemcs_subset_lookup (const struct ConfigSubset *sub, const char *name)
 Find an inherited config item.
 
struct HashElemcs_subset_create_inheritance (const struct ConfigSubset *sub, const char *name)
 Create a Subset config item (inherited)
 
void cs_subset_notify_observers (const struct ConfigSubset *sub, struct HashElem *he, enum NotifyConfig ev)
 Notify all observers of an event.
 
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.
 
int cs_subset_he_native_set (const struct ConfigSubset *sub, struct HashElem *he, intptr_t value, struct Buffer *err)
 Natively set the value of a HashElem config item.
 
int cs_subset_str_native_set (const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
 Natively set the value of a string config item.
 
int cs_subset_he_reset (const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
 Reset a config item to its initial value.
 
int cs_subset_he_string_get (const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *result)
 Get a config item as a string.
 
int cs_subset_str_string_get (const struct ConfigSubset *sub, const char *name, struct Buffer *result)
 Get a config item as a string.
 
int cs_subset_he_string_set (const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
 Set a config item by string.
 
int cs_subset_str_string_set (const struct ConfigSubset *sub, const char *name, const char *value, struct Buffer *err)
 Set a config item by string.
 
int cs_subset_he_string_plus_equals (const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
 Add to a config item by string.
 
int cs_subset_he_string_minus_equals (const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
 Remove from a config item by string.
 
int cs_subset_he_delete (const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
 Delete config item from a config.
 

Variables

static const struct Mapping ConfigEventNames []
 Names for logging.
 

Detailed Description

Subset of config items.

Authors
  • Richard Russon
  • Pietro Cerutti
  • Rayford Shireman

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file subset.c.

Function Documentation

◆ get_elem_list()

struct HashElem ** get_elem_list ( struct ConfigSet cs)

Create a sorted list of all config items.

Parameters
csConfigSet to read
Return values
ptrNull-terminated array of HashElem

Definition at line 79 of file subset.c.

80{
81 if (!cs)
82 return NULL;
83
84 struct HashElem **he_list = MUTT_MEM_CALLOC(1024, struct HashElem *);
85 size_t index = 0;
86
87 struct HashWalkState walk = { 0 };
88 struct HashElem *he = NULL;
89
90 while ((he = mutt_hash_walk(cs->hash, &walk)))
91 {
92 he_list[index++] = he;
93 if (index == 1022)
94 break; /* LCOV_EXCL_LINE */
95 }
96
97 mutt_qsort_r(he_list, index, sizeof(struct HashElem *), elem_list_sort, NULL);
98
99 return he_list;
100}
int elem_list_sort(const void *a, const void *b, void *sdata)
Compare two HashElem pointers to config - Implements sort_t -.
Definition: subset.c:63
struct HashElem * mutt_hash_walk(const struct HashTable *table, struct HashWalkState *state)
Iterate through all the HashElem's in a Hash Table.
Definition: hash.c:489
#define MUTT_MEM_CALLOC(n, type)
Definition: memory.h:40
void mutt_qsort_r(void *base, size_t nmemb, size_t size, sort_t compar, void *sdata)
Sort an array, where the comparator has access to opaque data rather than requiring global variables.
Definition: qsort_r.c:67
struct HashTable * hash
Hash Table: "$name" -> ConfigDef.
Definition: set.h:253
The item stored in a Hash Table.
Definition: hash.h:43
Cursor to iterate through a Hash Table.
Definition: hash.h:132
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_free()

void cs_subset_free ( struct ConfigSubset **  ptr)

Free a Config Subset.

Parameters
ptrSubset to free
Note
Config items matching this Subset will be freed

Definition at line 108 of file subset.c.

109{
110 if (!ptr || !*ptr)
111 return;
112
113 struct ConfigSubset *sub = *ptr;
114
115 struct EventConfig ev_c = { sub, NULL, NULL };
116 mutt_debug(LL_NOTIFY, "NT_CONFIG_DELETED: ALL\n");
118
119 if (sub->cs && sub->name)
120 {
121 char scope[256] = { 0 };
122 snprintf(scope, sizeof(scope), "%s:", sub->name);
123
124 // We don't know if any config items have been set,
125 // so search for anything with a matching scope.
126 struct HashElem **he_list = get_elem_list(sub->cs);
127 for (size_t i = 0; he_list[i]; i++)
128 {
129 const char *item = he_list[i]->key.strkey;
130 if (mutt_str_startswith(item, scope) != 0)
131 {
132 cs_uninherit_variable(sub->cs, item);
133 }
134 }
135 FREE(&he_list);
136 }
137
138 notify_free(&sub->notify);
139 FREE(&sub->name);
140 FREE(ptr);
141}
void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
Remove an inherited config item.
Definition: set.c:376
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
@ LL_NOTIFY
Log of notifications.
Definition: logging2.h:48
#define FREE(x)
Definition: memory.h:55
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:173
void notify_free(struct Notify **ptr)
Free a notification handler.
Definition: notify.c:75
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:230
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:43
A set of inherited config items.
Definition: subset.h:47
struct Notify * notify
Notifications: NotifyConfig, EventConfig.
Definition: subset.h:52
const char * name
Scope name of Subset.
Definition: subset.h:48
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:51
A config-change event.
Definition: subset.h:71
const struct ConfigSubset * sub
Config Subset.
Definition: subset.h:72
union HashKey key
Key representing the data.
Definition: hash.h:45
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:79
@ NT_CONFIG_DELETED
Config item has been deleted.
Definition: subset.h:64
const char * strkey
String key.
Definition: hash.h:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_new()

struct ConfigSubset * cs_subset_new ( const char *  name,
struct ConfigSubset sub_parent,
struct Notify not_parent 
)

Create a new Config Subset.

Parameters
nameName for this Subset
sub_parentParent Subset
not_parentParent Notification
Return values
ptrNew Subset
Note
The name will be combined with the parents' names

Definition at line 152 of file subset.c.

154{
155 struct ConfigSubset *sub = MUTT_MEM_CALLOC(1, struct ConfigSubset);
156
157 if (sub_parent)
158 {
159 sub->parent = sub_parent;
160 sub->cs = sub_parent->cs;
161 }
162
163 if (name)
164 {
165 char scope[256] = { 0 };
166
167 if (sub_parent && sub_parent->name)
168 snprintf(scope, sizeof(scope), "%s:%s", sub_parent->name, name);
169 else
170 mutt_str_copy(scope, name, sizeof(scope));
171
172 sub->name = mutt_str_dup(scope);
173 }
174
175 sub->notify = notify_new();
176 notify_set_parent(sub->notify, not_parent);
177
178 return sub;
179}
struct Notify * notify_new(void)
Create a new notifications handler.
Definition: notify.c:62
void notify_set_parent(struct Notify *notify, struct Notify *parent)
Set the parent notification handler.
Definition: notify.c:95
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:581
struct ConfigSubset * parent
Parent Subset.
Definition: subset.h:50
enum ConfigScope scope
Scope of Subset, e.g. SET_SCOPE_ACCOUNT.
Definition: subset.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_lookup()

struct HashElem * cs_subset_lookup ( const struct ConfigSubset sub,
const char *  name 
)

Find an inherited config item.

Parameters
subSubset to search
nameName of Config item to find
Return values
ptrHashElem of the config item

Definition at line 187 of file subset.c.

188{
189 if (!sub || !name)
190 return NULL;
191
192 char scope[256] = { 0 };
193 if (sub->name)
194 snprintf(scope, sizeof(scope), "%s:%s", sub->name, name);
195 else
196 mutt_str_copy(scope, name, sizeof(scope));
197
198 return cs_get_elem(sub->cs, scope);
199}
struct HashElem * cs_get_elem(const struct ConfigSet *cs, const char *name)
Get the HashElem representing a config item.
Definition: set.c:175
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_create_inheritance()

struct HashElem * cs_subset_create_inheritance ( const struct ConfigSubset sub,
const char *  name 
)

Create a Subset config item (inherited)

Parameters
subConfig Subset
nameName of config item
Return values
ptrHashElem of the config item
NULLError

Definition at line 208 of file subset.c.

209{
210 if (!sub)
211 return NULL;
212
213 struct HashElem *he = cs_subset_lookup(sub, name);
214 if (he)
215 return he;
216
217 if (sub->parent)
218 {
219 // Create parent before creating name
220 he = cs_subset_create_inheritance(sub->parent, name);
221 }
222
223 if (!he)
224 return NULL;
225
226 char scope[256] = { 0 };
227 snprintf(scope, sizeof(scope), "%s:%s", sub->name, name);
228 return cs_inherit_variable(sub->cs, he, scope);
229}
struct HashElem * cs_inherit_variable(const struct ConfigSet *cs, struct HashElem *he_parent, const char *name)
Create in inherited config item.
Definition: set.c:347
struct HashElem * cs_subset_create_inheritance(const struct ConfigSubset *sub, const char *name)
Create a Subset config item (inherited)
Definition: subset.c:208
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:187
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_notify_observers()

void cs_subset_notify_observers ( const struct ConfigSubset sub,
struct HashElem he,
enum NotifyConfig  ev 
)

Notify all observers of an event.

Parameters
subConfig Subset
heHashElem representing config item
evType of event

Definition at line 237 of file subset.c.

239{
240 if (!sub || !he)
241 return;
242
243 struct HashElem *he_base = cs_get_base(he);
244 struct EventConfig ev_c = { sub, he_base->key.strkey, he };
245 mutt_debug(LL_NOTIFY, "%s: %s\n",
247 notify_send(sub->notify, NT_CONFIG, ev, &ev_c);
248}
struct HashElem * cs_get_base(struct HashElem *he)
Find the root Config Item.
Definition: set.c:160
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
#define NONULL(x)
Definition: string2.h:37
struct HashElem * he
Config item that changed.
Definition: subset.h:74
static const struct Mapping ConfigEventNames[]
Names for logging.
Definition: subset.c:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_he_native_get()

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.

Parameters
subConfig Subset
heHashElem representing config item
errBuffer for error messages
Return values
intptr_tNative pointer/value
INT_MINError

Definition at line 258 of file subset.c.

260{
261 if (!sub)
262 return INT_MIN;
263
264 return cs_he_native_get(sub->cs, he, err);
265}
intptr_t cs_he_native_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
Natively get the value of a HashElem config item.
Definition: set.c:813
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_he_native_set()

int cs_subset_he_native_set ( const struct ConfigSubset sub,
struct HashElem he,
intptr_t  value,
struct Buffer err 
)

Natively set the value of a HashElem config item.

Parameters
subConfig Subset
heHashElem representing config item
valueNative pointer/value to set
errBuffer for error messages
Return values
numResult, e.g. CSR_SUCCESS

Definition at line 275 of file subset.c.

277{
278 if (!sub)
279 return CSR_ERR_CODE;
280
281 int rc = cs_he_native_set(sub->cs, he, value, err);
282
283 if ((CSR_RESULT(rc) == CSR_SUCCESS) && !(rc & CSR_SUC_NO_CHANGE))
285
286 return rc;
287}
int cs_he_native_set(const struct ConfigSet *cs, struct HashElem *he, intptr_t value, struct Buffer *err)
Natively set the value of a HashElem config item.
Definition: set.c:708
#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
void cs_subset_notify_observers(const struct ConfigSubset *sub, struct HashElem *he, enum NotifyConfig ev)
Notify all observers of an event.
Definition: subset.c:237
@ NT_CONFIG_SET
Config item has been set.
Definition: subset.h:62
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_str_native_set()

int cs_subset_str_native_set ( const struct ConfigSubset sub,
const char *  name,
intptr_t  value,
struct Buffer err 
)

Natively set the value of a string config item.

Parameters
subConfig Subset
nameName of config item
valueNative pointer/value to set
errBuffer for error messages
Return values
numResult, e.g. CSR_SUCCESS

Definition at line 297 of file subset.c.

299{
300 struct HashElem *he = cs_subset_create_inheritance(sub, name);
301
302 return cs_subset_he_native_set(sub, he, value, err);
303}
int cs_subset_he_native_set(const struct ConfigSubset *sub, struct HashElem *he, intptr_t value, struct Buffer *err)
Natively set the value of a HashElem config item.
Definition: subset.c:275
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_he_reset()

int cs_subset_he_reset ( const struct ConfigSubset sub,
struct HashElem he,
struct Buffer err 
)

Reset a config item to its initial value.

Parameters
subConfig Subset
heHashElem representing config item
errBuffer for error messages
Return values
numResult, e.g. CSR_SUCCESS

Definition at line 312 of file subset.c.

313{
314 if (!sub)
315 return CSR_ERR_CODE;
316
317 int rc = cs_he_reset(sub->cs, he, err);
318
319 if ((CSR_RESULT(rc) == CSR_SUCCESS) && !(rc & CSR_SUC_NO_CHANGE))
321
322 return rc;
323}
int cs_he_reset(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
Reset a config item to its initial value.
Definition: set.c:391
@ NT_CONFIG_RESET
Config item has been reset to initial, or parent, value.
Definition: subset.h:63
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_he_string_get()

int cs_subset_he_string_get ( const struct ConfigSubset sub,
struct HashElem he,
struct Buffer result 
)

Get a config item as a string.

Parameters
subConfig Subset
heHashElem representing config item
resultBuffer for results or error messages
Return values
numResult, e.g. CSR_SUCCESS

Definition at line 332 of file subset.c.

334{
335 if (!sub)
336 return CSR_ERR_CODE;
337
338 return cs_he_string_get(sub->cs, he, result);
339}
int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
Get a config item as a string.
Definition: set.c:663
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_str_string_get()

int cs_subset_str_string_get ( const struct ConfigSubset sub,
const char *  name,
struct Buffer result 
)

Get a config item as a string.

Parameters
subConfig Subset
nameName of config item
resultBuffer for results or error messages
Return values
numResult, e.g. CSR_SUCCESS

Definition at line 348 of file subset.c.

350{
351 struct HashElem *he = cs_subset_create_inheritance(sub, name);
352
353 return cs_subset_he_string_get(sub, he, result);
354}
int cs_subset_he_string_get(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *result)
Get a config item as a string.
Definition: subset.c:332
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_he_string_set()

int cs_subset_he_string_set ( const struct ConfigSubset sub,
struct HashElem he,
const char *  value,
struct Buffer err 
)

Set a config item by string.

Parameters
subConfig Subset
heHashElem representing config item
valueValue to set
errBuffer for error messages
Return values
numResult, e.g. CSR_SUCCESS

Definition at line 364 of file subset.c.

366{
367 if (!sub)
368 return CSR_ERR_CODE;
369
370 int rc = cs_he_string_set(sub->cs, he, value, err);
371
372 if ((CSR_RESULT(rc) == CSR_SUCCESS) && !(rc & CSR_SUC_NO_CHANGE))
374
375 return rc;
376}
int cs_he_string_set(const struct ConfigSet *cs, struct HashElem *he, const char *value, struct Buffer *err)
Set a config item by string.
Definition: set.c:588
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_str_string_set()

int cs_subset_str_string_set ( const struct ConfigSubset sub,
const char *  name,
const char *  value,
struct Buffer err 
)

Set a config item by string.

Parameters
subConfig Subset
nameName of config item
valueValue to set
errBuffer for error messages
Return values
numResult, e.g. CSR_SUCCESS

Definition at line 386 of file subset.c.

388{
389 struct HashElem *he = cs_subset_create_inheritance(sub, name);
390
391 return cs_subset_he_string_set(sub, he, value, err);
392}
int cs_subset_he_string_set(const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
Set a config item by string.
Definition: subset.c:364
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_he_string_plus_equals()

int cs_subset_he_string_plus_equals ( const struct ConfigSubset sub,
struct HashElem he,
const char *  value,
struct Buffer err 
)

Add to a config item by string.

Parameters
subConfig Subset
heHashElem representing config item
valueValue to set
errBuffer for error messages
Return values
numResult, e.g. CSR_SUCCESS

Definition at line 402 of file subset.c.

404{
405 if (!sub)
406 return CSR_ERR_CODE;
407
408 int rc = cs_he_string_plus_equals(sub->cs, he, value, err);
409
410 if ((CSR_RESULT(rc) == CSR_SUCCESS) && !(rc & CSR_SUC_NO_CHANGE))
412
413 return rc;
414}
int cs_he_string_plus_equals(const struct ConfigSet *cs, struct HashElem *he, const char *value, struct Buffer *err)
Add to a config item by string.
Definition: set.c:864
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_he_string_minus_equals()

int cs_subset_he_string_minus_equals ( const struct ConfigSubset sub,
struct HashElem he,
const char *  value,
struct Buffer err 
)

Remove from a config item by string.

Parameters
subConfig Subset
heHashElem representing config item
valueValue to set
errBuffer for error messages
Return values
numResult, e.g. CSR_SUCCESS

Definition at line 424 of file subset.c.

426{
427 if (!sub)
428 return CSR_ERR_CODE;
429
430 int rc = cs_he_string_minus_equals(sub->cs, he, value, err);
431
432 if ((CSR_RESULT(rc) == CSR_SUCCESS) && !(rc & CSR_SUC_NO_CHANGE))
434
435 return rc;
436}
int cs_he_string_minus_equals(const struct ConfigSet *cs, struct HashElem *he, const char *value, struct Buffer *err)
Remove from a config item by string.
Definition: set.c:923
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cs_subset_he_delete()

int cs_subset_he_delete ( const struct ConfigSubset sub,
struct HashElem he,
struct Buffer err 
)

Delete config item from a config.

Parameters
subConfig Subset
heHashElem representing config item
errBuffer for error messages
Return values
numResult, e.g. CSR_SUCCESS

Definition at line 445 of file subset.c.

446{
447 if (!sub)
448 return CSR_ERR_CODE;
449
450 const char *name = mutt_str_dup(he->key.strkey);
451 int rc = cs_he_delete(sub->cs, he, err);
452
453 if (CSR_RESULT(rc) == CSR_SUCCESS)
454 {
455 struct EventConfig ev_c = { sub, name, NULL };
456 mutt_debug(LL_NOTIFY, "NT_CONFIG_DELETED: %s\n", name);
458 }
459
460 FREE(&name);
461 return rc;
462}
int cs_he_delete(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
Delete config item from a config set.
Definition: set.c:981
const char * name
Name of config item that changed.
Definition: subset.h:73
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ ConfigEventNames

const struct Mapping ConfigEventNames[]
static
Initial value:
= {
{ "NT_CONFIG_SET", NT_CONFIG_SET },
{ "NT_CONFIG_RESET", NT_CONFIG_RESET },
{ "NT_CONFIG_DELETED", NT_CONFIG_DELETED },
{ NULL, 0 },
}

Names for logging.

Definition at line 51 of file subset.c.