NeoMutt  2025-12-11-596-g7cc1dd
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
set.c
Go to the documentation of this file.
1
26
32
33#include "config.h"
34#include <limits.h>
35#include <stdio.h>
36#include "mutt/lib.h"
37#include "set.h"
38#include "inheritance.h"
39#include "types.h"
40
47static void cs_hashelem_free(int type, void *obj, intptr_t data)
48{
49 if (data == 0)
50 return; /* LCOV_EXCL_LINE */
51
52 struct ConfigSet *cs = (struct ConfigSet *) data;
53
54 const struct ConfigSetType *cst = NULL;
55
57 {
58 struct Inheritance *i = obj;
59
60 struct HashElem *he_base = cs_get_base(i->parent);
61 struct ConfigDef *cdef = he_base->data;
62
63 if (!cdef)
64 return; // LCOV_EXCL_LINE
65
66 cst = cs_get_type_def(cs, he_base->type);
67 if (cst && cst->destroy)
68 cst->destroy((void **) &i->var, cdef);
69
70 FREE(&i->name);
71 FREE(&i);
72 }
73 else
74 {
75 struct ConfigDef *cdef = obj;
76
77 cst = cs_get_type_def(cs, type);
78 if (cst && cst->destroy)
79 cst->destroy(&cdef->var, cdef);
80
81 /* If we allocated the initial value, clean it up */
82 if (cdef->type & D_INTERNAL_INITIAL_SET)
83 FREE(&cdef->initial);
85 {
86 FREE(&cdef->name);
87 FREE(&cdef->docs);
88 FREE(&cdef);
89 }
90 }
91}
92
100static struct HashElem *create_synonym(const struct ConfigSet *cs,
101 struct ConfigDef *cdef, struct Buffer *err)
102{
103 if (!cs || !cdef)
104 return NULL; /* LCOV_EXCL_LINE */
105
106 const char *name = (const char *) cdef->initial;
107 struct HashElem *he_parent = cs_get_elem(cs, name);
108 if (!he_parent)
109 {
110 buf_printf(err, _("Unknown option %s"), name);
111 return NULL;
112 }
113
114 struct HashElem *he_child = mutt_hash_typed_insert(cs->hash, cdef->name,
115 cdef->type, (void *) cdef);
116 if (!he_child)
117 return NULL; /* LCOV_EXCL_LINE */
118
119 cdef->var = (intptr_t) he_parent;
120 return he_child;
121}
122
128struct ConfigSet *cs_new(size_t size)
129{
130 struct ConfigSet *cs = MUTT_MEM_CALLOC(1, struct ConfigSet);
131
134
135 return cs;
136}
137
142void cs_free(struct ConfigSet **ptr)
143{
144 if (!ptr || !*ptr)
145 return;
146
147 struct ConfigSet *cs = *ptr;
148
149 mutt_hash_free(&cs->hash);
150 FREE(ptr);
151}
152
161struct HashElem *cs_get_base(struct HashElem *he)
162{
163 if (!(he->type & D_INTERNAL_INHERITED))
164 return he;
165
166 struct Inheritance *i = he->data;
167 return cs_get_base(i->parent);
168}
169
176struct HashElem *cs_get_elem(const struct ConfigSet *cs, const char *name)
177{
178 if (!cs || !name)
179 return NULL;
180
181 struct HashElem *he = mutt_hash_find_elem(cs->hash, name);
182 if (!he)
183 return NULL;
184
185 if (CONFIG_TYPE(he->type) != DT_SYNONYM)
186 return he;
187
188 const struct ConfigDef *cdef = he->data;
189
190 return (struct HashElem *) cdef->var;
191}
192
199const struct ConfigSetType *cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
200{
201 if (!cs)
202 return NULL;
203
205 if (type >= countof(cs->types))
206 return NULL; // LCOV_EXCL_LINE
207
208 if (!cs->types[type].name)
209 return NULL;
210
211 return &cs->types[type];
212}
213
220bool cs_register_type(struct ConfigSet *cs, const struct ConfigSetType *cst)
221{
222 if (!cs || !cst)
223 return false;
224
225 if (!cst->name || !cst->string_set || !cst->string_get || !cst->reset ||
226 !cst->native_set || !cst->native_get)
227 {
228 return false;
229 }
230
231 if (cst->type >= countof(cs->types))
232 return false;
233
234 if (cs->types[cst->type].name)
235 return false; /* already registered */
236
237 cs->types[cst->type] = *cst;
238 return true;
239}
240
250struct HashElem *cs_register_variable(const struct ConfigSet *cs,
251 struct ConfigDef *cdef, struct Buffer *err)
252{
253 if (!cs || !cdef)
254 return NULL; /* LCOV_EXCL_LINE */
255
256 if (CONFIG_TYPE(cdef->type) == DT_SYNONYM)
257 return create_synonym(cs, cdef, err);
258
259 const struct ConfigSetType *cst = cs_get_type_def(cs, cdef->type);
260 if (!cst)
261 {
262 buf_printf(err, _("Option %s has an invalid type %d"), cdef->name, cdef->type);
263 return NULL;
264 }
265
266 struct HashElem *he = mutt_hash_typed_insert(cs->hash, cdef->name, cdef->type, cdef);
267 if (!he)
268 return NULL; /* LCOV_EXCL_LINE */
269
270 // Temporarily disable the validator
271 // (trust that the hard-coded initial values are sane)
272 int (*validator)(const struct ConfigDef *cdef, intptr_t value,
273 struct Buffer *err) = cdef->validator;
274 cdef->validator = NULL;
275
276 if (cst->reset)
277 cst->reset(&cdef->var, cdef, err);
278
279 cdef->validator = validator;
280
281 return he;
282}
283
290bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[])
291{
292 if (!cs || !vars)
293 return false;
294
295 struct Buffer *err = buf_pool_get();
296
297 bool rc = true;
298
299 for (size_t i = 0; vars[i].name; i++)
300 {
301 if (!cs_register_variable(cs, &vars[i], err))
302 {
303 mutt_debug(LL_DEBUG1, "%s\n", buf_string(err));
304 rc = false;
305 }
306 }
307
308 buf_pool_release(&err);
309 return rc;
310}
311
327struct HashElem *cs_create_variable(const struct ConfigSet *cs,
328 struct ConfigDef *cdef, struct Buffer *err)
329{
330 struct ConfigDef *cdef_copy = MUTT_MEM_CALLOC(1, struct ConfigDef);
331 cdef_copy->name = mutt_str_dup(cdef->name);
332 cdef_copy->type = cdef->type | D_INTERNAL_FREE_CONFIGDEF;
333 cdef_copy->initial = cdef->initial;
334 cdef_copy->data = cdef->data;
335 cdef_copy->validator = cdef->validator;
336 cdef_copy->docs = mutt_str_dup(cdef->name);
337 cdef_copy->var = cdef->var;
338
339 struct HashElem *he = cs_register_variable(cs, cdef_copy, err);
340 if (!he)
341 {
342 FREE(&cdef_copy->name);
343 FREE(&cdef_copy->docs);
344 FREE(&cdef_copy);
345 }
346 return he;
347}
348
356struct HashElem *cs_inherit_variable(const struct ConfigSet *cs,
357 struct HashElem *he_parent, const char *name)
358{
359 if (!cs || !he_parent)
360 return NULL;
361
362 /* MyVars cannot be inherited, as they might get deleted */
363 if (CONFIG_TYPE(he_parent->type) == DT_MYVAR)
364 return NULL;
365
366 struct Inheritance *i = MUTT_MEM_CALLOC(1, struct Inheritance);
367 i->parent = he_parent;
368 i->name = mutt_str_dup(name);
369
371 if (!he)
372 {
373 FREE(&i->name);
374 FREE(&i);
375 }
376
377 return he;
378}
379
385void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
386{
387 if (!cs || !name)
388 return;
389
390 mutt_hash_delete(cs->hash, name, NULL);
391}
392
400int cs_he_reset(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
401{
402 if (!cs || !he)
403 return CSR_ERR_CODE;
404
405 /* An inherited var that's already pointing to its parent.
406 * Return 'success', but don't send a notification. */
407 if ((he->type & D_INTERNAL_INHERITED) && (CONFIG_TYPE(he->type) == 0))
408 return CSR_SUCCESS;
409
410 int rc = CSR_SUCCESS;
411
412 if (he->type & D_INTERNAL_INHERITED)
413 {
414 struct Inheritance *i = he->data;
415 struct HashElem *he_base = cs_get_base(he);
416 struct ConfigDef *cdef = he_base->data;
417 if (!cdef)
418 return CSR_ERR_CODE; // LCOV_EXCL_LINE
419
420 const struct ConfigSetType *cst = cs_get_type_def(cs, he_base->type);
421 if (cst && cst->destroy)
422 cst->destroy((void **) &i->var, cdef);
423
425 }
426 else
427 {
428 struct ConfigDef *cdef = he->data;
429 if (!cdef)
430 return CSR_ERR_CODE; // LCOV_EXCL_LINE
431
432 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
433 if (cst)
434 rc = cst->reset(&cdef->var, cdef, err);
435 }
436
437 return rc;
438}
439
447int cs_str_reset(const struct ConfigSet *cs, const char *name, struct Buffer *err)
448{
449 if (!cs || !name)
450 return CSR_ERR_CODE;
451
452 struct HashElem *he = cs_get_elem(cs, name);
453 if (!he)
454 {
455 buf_printf(err, _("Unknown option %s"), name);
456 return CSR_ERR_UNKNOWN;
457 }
458
459 return cs_he_reset(cs, he, err);
460}
461
469bool cs_he_has_been_set(const struct ConfigSet *cs, struct HashElem *he)
470{
471 if (!cs || !he)
472 return false;
473
474 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
475 if (!cst)
476 return false; // LCOV_EXCL_LINE
477
478 if (!cst->has_been_set) // Probably a my_var
479 return true;
480
481 struct ConfigDef *cdef = he->data;
482 void *var = &cdef->var;
483
484 return cst->has_been_set(var, cdef);
485}
486
494bool cs_str_has_been_set(const struct ConfigSet *cs, const char *name)
495{
496 if (!cs || !name)
497 return false;
498
499 struct HashElem *he = cs_get_elem(cs, name);
500 if (!he)
501 return false;
502
503 return cs_he_has_been_set(cs, he);
504}
505
514int cs_he_initial_set(const struct ConfigSet *cs, struct HashElem *he,
515 const char *value, struct Buffer *err)
516{
517 if (!cs || !he)
518 return CSR_ERR_CODE;
519
520 struct ConfigDef *cdef = NULL;
521
522 if (he->type & D_INTERNAL_INHERITED)
523 {
524 struct HashElem *he_base = cs_get_base(he);
525 cdef = he_base->data;
526 mutt_debug(LL_DEBUG1, "Variable '%s' is inherited type\n", cdef->name);
527 return CSR_ERR_CODE;
528 }
529
530 cdef = he->data;
531 if (!cdef)
532 return CSR_ERR_CODE; // LCOV_EXCL_LINE
533
534 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
535 if (!cst)
536 {
537 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
538 return CSR_ERR_CODE;
539 }
540
541 int rc = cst->string_set(NULL, cdef, value, err);
542 if (CSR_RESULT(rc) != CSR_SUCCESS)
543 return rc;
544
545 return CSR_SUCCESS;
546}
547
558int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
559{
560 if (!cs || !he || !result)
561 return CSR_ERR_CODE;
562
563 const struct ConfigDef *cdef = NULL;
564 const struct ConfigSetType *cst = NULL;
565
566 if (he->type & D_INTERNAL_INHERITED)
567 {
568 struct HashElem *he_base = cs_get_base(he);
569 cdef = he_base->data;
570 cst = cs_get_type_def(cs, he_base->type);
571 }
572 else
573 {
574 cdef = he->data;
575 cst = cs_get_type_def(cs, he->type);
576 }
577
578 if (!cst)
579 return CSR_ERR_CODE; // LCOV_EXCL_LINE
580
581 return cst->string_get(NULL, cdef, result);
582}
583
594int cs_str_initial_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
595{
596 if (!cs || !name)
597 return CSR_ERR_CODE;
598
599 struct HashElem *he = cs_get_elem(cs, name);
600 if (!he)
601 {
602 buf_printf(result, _("Unknown option %s"), name);
603 return CSR_ERR_UNKNOWN;
604 }
605
606 return cs_he_initial_get(cs, he, result);
607}
608
617int cs_he_string_set(const struct ConfigSet *cs, struct HashElem *he,
618 const char *value, struct Buffer *err)
619{
620 if (!cs || !he)
621 return CSR_ERR_CODE;
622
623 struct ConfigDef *cdef = NULL;
624 const struct ConfigSetType *cst = NULL;
625 void *var = NULL;
626
627 if (he->type & D_INTERNAL_INHERITED)
628 {
629 struct Inheritance *i = he->data;
630 struct HashElem *he_base = cs_get_base(he);
631 cdef = he_base->data;
632 cst = cs_get_type_def(cs, he_base->type);
633 var = &i->var;
634 }
635 else
636 {
637 cdef = he->data;
638 cst = cs_get_type_def(cs, he->type);
639 var = &cdef->var;
640 }
641
642 if (!cdef)
643 return CSR_ERR_CODE; // LCOV_EXCL_LINE
644
645 if (!cst)
646 {
647 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
648 return CSR_ERR_CODE;
649 }
650
651 int rc = cst->string_set(var, cdef, value, err);
652 if (CSR_RESULT(rc) != CSR_SUCCESS)
653 return rc;
654
655 if (he->type & D_INTERNAL_INHERITED)
656 he->type = cdef->type | D_INTERNAL_INHERITED;
657
658 return rc;
659}
660
669int cs_str_string_set(const struct ConfigSet *cs, const char *name,
670 const char *value, struct Buffer *err)
671{
672 if (!cs || !name)
673 return CSR_ERR_CODE;
674
675 struct HashElem *he = cs_get_elem(cs, name);
676 if (!he)
677 {
678 buf_printf(err, _("Unknown option %s"), name);
679 return CSR_ERR_UNKNOWN;
680 }
681
682 return cs_he_string_set(cs, he, value, err);
683}
684
692int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
693{
694 if (!cs || !he || !result)
695 return CSR_ERR_CODE;
696
697 struct ConfigDef *cdef = NULL;
698 const struct ConfigSetType *cst = NULL;
699 void *var = NULL;
700
701 if (he->type & D_INTERNAL_INHERITED)
702 {
703 struct Inheritance *i = he->data;
704
705 // inherited, value not set
706 if (CONFIG_TYPE(he->type) == 0)
707 return cs_he_string_get(cs, i->parent, result);
708
709 // inherited, value set
710 struct HashElem *he_base = cs_get_base(he);
711 cdef = he_base->data;
712 cst = cs_get_type_def(cs, he_base->type);
713 var = &i->var;
714 }
715 else
716 {
717 // not inherited
718 cdef = he->data;
719 cst = cs_get_type_def(cs, he->type);
720 var = &cdef->var;
721 }
722
723 if (!cdef || !cst)
724 return CSR_ERR_CODE; // LCOV_EXCL_LINE
725
726 return cst->string_get(var, cdef, result);
727}
728
737int cs_he_native_set(const struct ConfigSet *cs, struct HashElem *he,
738 intptr_t value, struct Buffer *err)
739{
740 if (!cs || !he)
741 return CSR_ERR_CODE;
742
743 struct ConfigDef *cdef = NULL;
744 const struct ConfigSetType *cst = NULL;
745 void *var = NULL;
746
747 if (he->type & D_INTERNAL_INHERITED)
748 {
749 struct Inheritance *i = he->data;
750 struct HashElem *he_base = cs_get_base(he);
751 cdef = he_base->data;
752 cst = cs_get_type_def(cs, he_base->type);
753 var = &i->var;
754 }
755 else
756 {
757 cdef = he->data;
758 cst = cs_get_type_def(cs, he->type);
759 var = &cdef->var;
760 }
761
762 if (!cst)
763 {
764 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
765 return CSR_ERR_CODE;
766 }
767
768 if (!var || !cdef)
769 return CSR_ERR_CODE; // LCOV_EXCL_LINE
770
771 int rc = cst->native_set(var, cdef, value, err);
772 if (CSR_RESULT(rc) != CSR_SUCCESS)
773 return rc;
774
775 if (he->type & D_INTERNAL_INHERITED)
776 he->type = cdef->type | D_INTERNAL_INHERITED;
777
778 return rc;
779}
780
789int cs_str_native_set(const struct ConfigSet *cs, const char *name,
790 intptr_t value, struct Buffer *err)
791{
792 if (!cs || !name)
793 return CSR_ERR_CODE;
794
795 struct HashElem *he = cs_get_elem(cs, name);
796 if (!he)
797 {
798 buf_printf(err, _("Unknown option %s"), name);
799 return CSR_ERR_UNKNOWN;
800 }
801
802 struct ConfigDef *cdef = NULL;
803 const struct ConfigSetType *cst = NULL;
804 void *var = NULL;
805
806 if (he->type & D_INTERNAL_INHERITED)
807 {
808 struct Inheritance *i = he->data;
809 struct HashElem *he_base = cs_get_base(he);
810 cdef = he_base->data;
811 cst = cs_get_type_def(cs, he_base->type);
812 var = &i->var;
813 }
814 else
815 {
816 cdef = he->data;
817 cst = cs_get_type_def(cs, he->type);
818 var = &cdef->var;
819 }
820
821 if (!cst || !var || !cdef)
822 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
823
824 int rc = cst->native_set(var, cdef, value, err);
825 if (CSR_RESULT(rc) != CSR_SUCCESS)
826 return rc;
827
828 if (he->type & D_INTERNAL_INHERITED)
829 he->type = cdef->type | D_INTERNAL_INHERITED;
830
831 return rc;
832}
833
842intptr_t cs_he_native_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
843{
844 if (!cs || !he)
845 return INT_MIN;
846
847 struct ConfigDef *cdef = NULL;
848 const struct ConfigSetType *cst = NULL;
849 void *var = NULL;
850
851 if (he->type & D_INTERNAL_INHERITED)
852 {
853 struct Inheritance *i = he->data;
854
855 // inherited, value not set
856 if (CONFIG_TYPE(he->type) == 0)
857 return cs_he_native_get(cs, i->parent, err);
858
859 // inherited, value set
860 struct HashElem *he_base = cs_get_base(he);
861 cdef = he_base->data;
862 cst = cs_get_type_def(cs, he_base->type);
863 var = &i->var;
864 }
865 else
866 {
867 // not inherited
868 cdef = he->data;
869 cst = cs_get_type_def(cs, he->type);
870 var = &cdef->var;
871 }
872
873 if (!var || !cdef)
874 return INT_MIN; // LCOV_EXCL_LINE
875
876 if (!cst)
877 {
878 buf_printf(err, _("Option %s has an invalid type %d"), cdef->name, he->type);
879 return INT_MIN;
880 }
881
882 return cst->native_get(var, cdef, err);
883}
884
893int cs_he_string_plus_equals(const struct ConfigSet *cs, struct HashElem *he,
894 const char *value, struct Buffer *err)
895{
896 if (!cs || !he)
897 return CSR_ERR_CODE;
898
899 struct ConfigDef *cdef = NULL;
900 const struct ConfigSetType *cst = NULL;
901 void *var = NULL;
902
903 if (he->type & D_INTERNAL_INHERITED)
904 {
905 struct Inheritance *i = he->data;
906 struct HashElem *he_base = cs_get_base(he);
907 cdef = he_base->data;
908 cst = cs_get_type_def(cs, he_base->type);
909 var = &i->var;
910 }
911 else
912 {
913 cdef = he->data;
914 cst = cs_get_type_def(cs, he->type);
915 var = &cdef->var;
916 }
917
918 if (!var || !cdef)
919 return CSR_ERR_CODE; // LCOV_EXCL_LINE
920
921 if (!cst)
922 {
923 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
924 return CSR_ERR_CODE;
925 }
926
927 if (!cst->string_plus_equals)
928 {
929 // L10N: e.g. Type 'boolean' doesn't support operation '+='
930 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "+=");
932 }
933
934 int rc = cst->string_plus_equals(var, cdef, value, err);
935 if (CSR_RESULT(rc) != CSR_SUCCESS)
936 return rc;
937
938 if (he->type & D_INTERNAL_INHERITED)
939 he->type = cdef->type | D_INTERNAL_INHERITED;
940
941 return rc;
942}
943
952int cs_he_string_minus_equals(const struct ConfigSet *cs, struct HashElem *he,
953 const char *value, struct Buffer *err)
954{
955 if (!cs || !he)
956 return CSR_ERR_CODE;
957
958 struct ConfigDef *cdef = NULL;
959 const struct ConfigSetType *cst = NULL;
960 void *var = NULL;
961
962 if (he->type & D_INTERNAL_INHERITED)
963 {
964 struct Inheritance *i = he->data;
965 struct HashElem *he_base = cs_get_base(he);
966 cdef = he_base->data;
967 cst = cs_get_type_def(cs, he_base->type);
968 var = &i->var;
969 }
970 else
971 {
972 cdef = he->data;
973 cst = cs_get_type_def(cs, he->type);
974 var = &cdef->var;
975 }
976
977 if (!var || !cdef)
978 return CSR_ERR_CODE; // LCOV_EXCL_LINE
979
980 if (!cst)
981 {
982 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
983 return CSR_ERR_CODE;
984 }
985
986 if (!cst->string_minus_equals)
987 {
988 // L10N: e.g. Type 'boolean' doesn't support operation '+='
989 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "-=");
991 }
992
993 int rc = cst->string_minus_equals(var, cdef, value, err);
994 if (CSR_RESULT(rc) != CSR_SUCCESS)
995 return rc;
996
997 if (he->type & D_INTERNAL_INHERITED)
998 he->type = cdef->type | D_INTERNAL_INHERITED;
999
1000 return rc;
1001}
1002
1010int cs_he_delete(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
1011{
1012 if (!cs || !he)
1013 return CSR_ERR_CODE;
1014
1015 mutt_hash_delete(cs->hash, he->key.strkey, he->data);
1016 return CSR_SUCCESS;
1017}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
int cs_str_initial_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
Get the initial, or parent, value of a config item.
Definition set.c:594
struct HashElem * cs_get_elem(const struct ConfigSet *cs, const char *name)
Get the HashElem representing a config item.
Definition set.c:176
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:893
void cs_free(struct ConfigSet **ptr)
Free a Config Set.
Definition set.c:142
int cs_str_reset(const struct ConfigSet *cs, const char *name, struct Buffer *err)
Reset a config item to its initial value.
Definition set.c:447
struct ConfigSet * cs_new(size_t size)
Create a new Config Set.
Definition set.c:128
struct HashElem * cs_create_variable(const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err)
Create and register one config item.
Definition set.c:327
bool cs_str_has_been_set(const struct ConfigSet *cs, const char *name)
Is the config value different to its initial value?
Definition set.c:494
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:400
const struct ConfigSetType * cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
Get the definition for a type.
Definition set.c:199
int cs_he_delete(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
Delete config item from a config set.
Definition set.c:1010
int cs_str_string_set(const struct ConfigSet *cs, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition set.c:669
static struct HashElem * create_synonym(const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err)
Create an alternative name for a config item.
Definition set.c:100
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:617
int cs_str_native_set(const struct ConfigSet *cs, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition set.c:789
struct HashElem * cs_get_base(struct HashElem *he)
Find the root Config Item.
Definition set.c:161
bool cs_he_has_been_set(const struct ConfigSet *cs, struct HashElem *he)
Is the config value different to its initial value?
Definition set.c:469
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:737
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:842
struct HashElem * cs_inherit_variable(const struct ConfigSet *cs, struct HashElem *he_parent, const char *name)
Create in inherited config item.
Definition set.c:356
bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[])
Register a set of config items.
Definition set.c:290
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:692
struct HashElem * cs_register_variable(const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err)
Register one config item.
Definition set.c:250
int cs_he_initial_set(const struct ConfigSet *cs, struct HashElem *he, const char *value, struct Buffer *err)
Set the initial value of a config item.
Definition set.c:514
int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
Get the initial, or parent, value of a config item.
Definition set.c:558
bool cs_register_type(struct ConfigSet *cs, const struct ConfigSetType *cst)
Register a type of config item.
Definition set.c:220
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:952
void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
Remove an inherited config item.
Definition set.c:385
A collection of config items.
#define CSR_ERR_INVALID
Value hasn't been set.
Definition set.h:36
#define CSV_INV_NOT_IMPL
Operation not permitted for the type.
Definition set.h:47
#define CSR_ERR_UNKNOWN
Unrecognised config item.
Definition set.h:35
#define CSR_ERR_CODE
Problem with the code.
Definition set.h:34
#define CSR_RESULT(x)
Extract the result code from CSR_* flags.
Definition set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition set.h:33
static void cs_hashelem_free(int type, void *obj, intptr_t data)
Free our hash table data - Implements hash_hdata_free_t -.
Definition set.c:47
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition hash.c:429
struct HashElem * mutt_hash_typed_insert(struct HashTable *table, const char *strkey, int type, void *data)
Insert a string with type info into a Hash Table.
Definition hash.c:319
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition hash.c:261
struct HashElem * mutt_hash_find_elem(const struct HashTable *table, const char *strkey)
Find the HashElem in a Hash Table element using a key.
Definition hash.c:379
void mutt_hash_set_destructor(struct HashTable *table, hash_hdata_free_t fn, intptr_t fn_data)
Set the destructor for a Hash Table.
Definition hash.c:303
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition hash.c:459
#define MUTT_HASH_NO_FLAGS
No flags are set.
Definition hash.h:111
An inherited config item.
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
#define countof(x)
Definition memory.h:49
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
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:257
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
String manipulation buffer.
Definition buffer.h:36
const char * name
User-visible name.
Definition set.h:65
intptr_t var
Storage for the variable.
Definition set.h:84
int(* validator)(const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition set.h:81
intptr_t data
Extra variable data.
Definition set.h:68
intptr_t initial
Initial value.
Definition set.h:67
uint32_t type
Variable type, e.g. DT_STRING.
Definition set.h:66
const char * docs
One-liner description.
Definition set.h:83
int(* string_set)(void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition set.h:114
int(* native_set)(void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition set.h:147
intptr_t(* native_get)(void *var, const struct ConfigDef *cdef, struct Buffer *err)
Definition set.h:163
int(* string_plus_equals)(void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition set.h:179
int type
Data type, e.g. DT_STRING.
Definition set.h:96
bool(* has_been_set)(void *var, const struct ConfigDef *cdef)
Definition set.h:210
int(* reset)(void *var, const struct ConfigDef *cdef, struct Buffer *err)
Definition set.h:225
int(* string_get)(void *var, const struct ConfigDef *cdef, struct Buffer *result)
Definition set.h:131
void(* destroy)(void *var, const struct ConfigDef *cdef)
Definition set.h:238
int(* string_minus_equals)(void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition set.h:195
const char * name
Name of the type, e.g. "String".
Definition set.h:97
Container for lots of config items.
Definition set.h:250
struct ConfigSetType types[18]
All the defined config types.
Definition set.h:252
struct HashTable * hash
Hash Table: "$name" -> ConfigDef.
Definition set.h:251
The item stored in a Hash Table.
Definition hash.h:44
union HashKey key
Key representing the data.
Definition hash.h:46
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition hash.h:45
void * data
User-supplied data.
Definition hash.h:47
An inherited config item.
Definition inheritance.h:32
struct HashElem * parent
HashElem of parent config item.
Definition inheritance.h:33
const char * name
Name of this config item.
Definition inheritance.h:34
intptr_t var
(Pointer to) value, of config item
Definition inheritance.h:35
Constants for all the config types.
#define CONFIG_TYPE(t)
Extract the type from the flags.
Definition types.h:50
#define D_INTERNAL_INHERITED
Config item is inherited.
Definition types.h:89
#define D_INTERNAL_FREE_CONFIGDEF
Config item must have its ConfigDef freed.
Definition types.h:87
#define D_INTERNAL_INITIAL_SET
Config item must have its initial value freed.
Definition types.h:90
@ DT_SYNONYM
synonym for another variable
Definition types.h:45
@ DT_MYVAR
a user-defined variable (my_foo)
Definition types.h:37
const char * strkey
String key.
Definition hash.h:36