NeoMutt  2025-01-09-81-g753ae0
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
set.c
Go to the documentation of this file.
1
32#include "config.h"
33#include <limits.h>
34#include <stdio.h>
35#include "mutt/lib.h"
36#include "set.h"
37#include "inheritance.h"
38#include "types.h"
39
46static void cs_hashelem_free(int type, void *obj, intptr_t data)
47{
48 if (data == 0)
49 return; /* LCOV_EXCL_LINE */
50
51 struct ConfigSet *cs = (struct ConfigSet *) data;
52
53 const struct ConfigSetType *cst = NULL;
54
56 {
57 struct Inheritance *i = obj;
58
59 struct HashElem *he_base = cs_get_base(i->parent);
60 struct ConfigDef *cdef = he_base->data;
61
62 if (!cdef)
63 return; // LCOV_EXCL_LINE
64
65 cst = cs_get_type_def(cs, he_base->type);
66 if (cst && cst->destroy)
67 cst->destroy((void **) &i->var, cdef);
68
69 FREE(&i->name);
70 FREE(&i);
71 }
72 else
73 {
74 struct ConfigDef *cdef = obj;
75
76 cst = cs_get_type_def(cs, type);
77 if (cst && cst->destroy)
78 cst->destroy(&cdef->var, cdef);
79
80 /* If we allocated the initial value, clean it up */
81 if (cdef->type & D_INTERNAL_INITIAL_SET)
82 FREE(&cdef->initial);
84 {
85 FREE(&cdef->name);
86 FREE(&cdef->docs);
87 FREE(&cdef);
88 }
89 }
90}
91
99static struct HashElem *create_synonym(const struct ConfigSet *cs,
100 struct ConfigDef *cdef, struct Buffer *err)
101{
102 if (!cs || !cdef)
103 return NULL; /* LCOV_EXCL_LINE */
104
105 const char *name = (const char *) cdef->initial;
106 struct HashElem *he_parent = cs_get_elem(cs, name);
107 if (!he_parent)
108 {
109 buf_printf(err, _("Unknown option %s"), name);
110 return NULL;
111 }
112
113 struct HashElem *he_child = mutt_hash_typed_insert(cs->hash, cdef->name,
114 cdef->type, (void *) cdef);
115 if (!he_child)
116 return NULL; /* LCOV_EXCL_LINE */
117
118 cdef->var = (intptr_t) he_parent;
119 return he_child;
120}
121
127struct ConfigSet *cs_new(size_t size)
128{
129 struct ConfigSet *cs = MUTT_MEM_CALLOC(1, struct ConfigSet);
130
133
134 return cs;
135}
136
141void cs_free(struct ConfigSet **ptr)
142{
143 if (!ptr || !*ptr)
144 return;
145
146 struct ConfigSet *cs = *ptr;
147
148 mutt_hash_free(&cs->hash);
149 FREE(ptr);
150}
151
160struct HashElem *cs_get_base(struct HashElem *he)
161{
162 if (!(he->type & D_INTERNAL_INHERITED))
163 return he;
164
165 struct Inheritance *i = he->data;
166 return cs_get_base(i->parent);
167}
168
175struct HashElem *cs_get_elem(const struct ConfigSet *cs, const char *name)
176{
177 if (!cs || !name)
178 return NULL;
179
180 struct HashElem *he = mutt_hash_find_elem(cs->hash, name);
181 if (!he)
182 return NULL;
183
184 if (CONFIG_TYPE(he->type) != DT_SYNONYM)
185 return he;
186
187 const struct ConfigDef *cdef = he->data;
188
189 return (struct HashElem *) cdef->var;
190}
191
198const struct ConfigSetType *cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
199{
200 if (!cs)
201 return NULL;
202
204 if (type >= mutt_array_size(cs->types))
205 return NULL; // LCOV_EXCL_LINE
206
207 if (!cs->types[type].name)
208 return NULL;
209
210 return &cs->types[type];
211}
212
219bool cs_register_type(struct ConfigSet *cs, const struct ConfigSetType *cst)
220{
221 if (!cs || !cst)
222 return false;
223
224 if (!cst->name || !cst->string_set || !cst->string_get || !cst->reset ||
225 !cst->native_set || !cst->native_get)
226 {
227 return false;
228 }
229
230 if (cst->type >= mutt_array_size(cs->types))
231 return false;
232
233 if (cs->types[cst->type].name)
234 return false; /* already registered */
235
236 cs->types[cst->type] = *cst;
237 return true;
238}
239
249struct HashElem *cs_register_variable(const struct ConfigSet *cs,
250 struct ConfigDef *cdef, struct Buffer *err)
251{
252 if (!cs || !cdef)
253 return NULL; /* LCOV_EXCL_LINE */
254
255 if (CONFIG_TYPE(cdef->type) == DT_SYNONYM)
256 return create_synonym(cs, cdef, err);
257
258 const struct ConfigSetType *cst = cs_get_type_def(cs, cdef->type);
259 if (!cst)
260 {
261 buf_printf(err, _("Option %s has an invalid type %d"), cdef->name, cdef->type);
262 return NULL;
263 }
264
265 struct HashElem *he = mutt_hash_typed_insert(cs->hash, cdef->name, cdef->type, cdef);
266 if (!he)
267 return NULL; /* LCOV_EXCL_LINE */
268
269 // Temporarily disable the validator
270 // (trust that the hard-coded initial values are sane)
271 int (*validator)(const struct ConfigDef *cdef, intptr_t value,
272 struct Buffer *err) = cdef->validator;
273 cdef->validator = NULL;
274
275 if (cst->reset)
276 cst->reset(&cdef->var, cdef, err);
277
278 cdef->validator = validator;
279
280 return he;
281}
282
289bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[])
290{
291 if (!cs || !vars)
292 return false;
293
294 struct Buffer *err = buf_pool_get();
295
296 bool rc = true;
297
298 for (size_t i = 0; vars[i].name; i++)
299 {
300 if (!cs_register_variable(cs, &vars[i], err))
301 {
302 mutt_debug(LL_DEBUG1, "%s\n", buf_string(err));
303 rc = false;
304 }
305 }
306
307 buf_pool_release(&err);
308 return rc;
309}
310
326struct HashElem *cs_create_variable(const struct ConfigSet *cs,
327 struct ConfigDef *cdef, struct Buffer *err)
328{
329 struct ConfigDef *cdef_copy = MUTT_MEM_CALLOC(1, struct ConfigDef);
330 cdef_copy->name = mutt_str_dup(cdef->name);
331 cdef_copy->type = cdef->type | D_INTERNAL_FREE_CONFIGDEF;
332 cdef_copy->initial = cdef->initial;
333 cdef_copy->data = cdef->data;
334 cdef_copy->validator = cdef->validator;
335 cdef_copy->docs = mutt_str_dup(cdef->name);
336 cdef_copy->var = cdef->var;
337
338 struct HashElem *he = cs_register_variable(cs, cdef_copy, err);
339 if (!he)
340 {
341 FREE(&cdef_copy->name);
342 FREE(&cdef_copy->docs);
343 FREE(&cdef_copy);
344 }
345 return he;
346}
347
355struct HashElem *cs_inherit_variable(const struct ConfigSet *cs,
356 struct HashElem *he_parent, const char *name)
357{
358 if (!cs || !he_parent)
359 return NULL;
360
361 /* MyVars cannot be inherited, as they might get deleted */
362 if (CONFIG_TYPE(he_parent->type) == DT_MYVAR)
363 return NULL;
364
365 struct Inheritance *i = MUTT_MEM_CALLOC(1, struct Inheritance);
366 i->parent = he_parent;
367 i->name = mutt_str_dup(name);
368
370 if (!he)
371 {
372 FREE(&i->name);
373 FREE(&i);
374 }
375
376 return he;
377}
378
384void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
385{
386 if (!cs || !name)
387 return;
388
389 mutt_hash_delete(cs->hash, name, NULL);
390}
391
399int cs_he_reset(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
400{
401 if (!cs || !he)
402 return CSR_ERR_CODE;
403
404 /* An inherited var that's already pointing to its parent.
405 * Return 'success', but don't send a notification. */
406 if ((he->type & D_INTERNAL_INHERITED) && (CONFIG_TYPE(he->type) == 0))
407 return CSR_SUCCESS;
408
409 int rc = CSR_SUCCESS;
410
411 if (he->type & D_INTERNAL_INHERITED)
412 {
413 struct Inheritance *i = he->data;
414 struct HashElem *he_base = cs_get_base(he);
415 struct ConfigDef *cdef = he_base->data;
416 if (!cdef)
417 return CSR_ERR_CODE; // LCOV_EXCL_LINE
418
419 const struct ConfigSetType *cst = cs_get_type_def(cs, he_base->type);
420 if (cst && cst->destroy)
421 cst->destroy((void **) &i->var, cdef);
422
424 }
425 else
426 {
427 struct ConfigDef *cdef = he->data;
428 if (!cdef)
429 return CSR_ERR_CODE; // LCOV_EXCL_LINE
430
431 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
432 if (cst)
433 rc = cst->reset(&cdef->var, cdef, err);
434 }
435
436 return rc;
437}
438
446int cs_str_reset(const struct ConfigSet *cs, const char *name, struct Buffer *err)
447{
448 if (!cs || !name)
449 return CSR_ERR_CODE;
450
451 struct HashElem *he = cs_get_elem(cs, name);
452 if (!he)
453 {
454 buf_printf(err, _("Unknown option %s"), name);
455 return CSR_ERR_UNKNOWN;
456 }
457
458 return cs_he_reset(cs, he, err);
459}
460
468bool cs_he_has_been_set(const struct ConfigSet *cs, struct HashElem *he)
469{
470 if (!cs || !he)
471 return false;
472
473 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
474 if (!cst)
475 return false; // LCOV_EXCL_LINE
476
477 if (!cst->has_been_set) // Probably a my_var
478 return true;
479
480 struct ConfigDef *cdef = he->data;
481 void *var = &cdef->var;
482
483 return cst->has_been_set(var, cdef);
484}
485
493bool cs_str_has_been_set(const struct ConfigSet *cs, const char *name)
494{
495 if (!cs || !name)
496 return false;
497
498 struct HashElem *he = cs_get_elem(cs, name);
499 if (!he)
500 return false;
501
502 return cs_he_has_been_set(cs, he);
503}
504
513int cs_he_initial_set(const struct ConfigSet *cs, struct HashElem *he,
514 const char *value, struct Buffer *err)
515{
516 if (!cs || !he)
517 return CSR_ERR_CODE;
518
519 struct ConfigDef *cdef = NULL;
520
521 if (he->type & D_INTERNAL_INHERITED)
522 {
523 struct HashElem *he_base = cs_get_base(he);
524 cdef = he_base->data;
525 mutt_debug(LL_DEBUG1, "Variable '%s' is inherited type\n", cdef->name);
526 return CSR_ERR_CODE;
527 }
528
529 cdef = he->data;
530 if (!cdef)
531 return CSR_ERR_CODE; // LCOV_EXCL_LINE
532
533 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
534 if (!cst)
535 {
536 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
537 return CSR_ERR_CODE;
538 }
539
540 int rc = cst->string_set(NULL, cdef, value, err);
541 if (CSR_RESULT(rc) != CSR_SUCCESS)
542 return rc;
543
544 return CSR_SUCCESS;
545}
546
555int cs_str_initial_set(const struct ConfigSet *cs, const char *name,
556 const char *value, struct Buffer *err)
557{
558 if (!cs || !name)
559 return CSR_ERR_CODE;
560
561 struct HashElem *he = cs_get_elem(cs, name);
562 if (!he)
563 {
564 buf_printf(err, _("Unknown option %s"), name);
565 return CSR_ERR_UNKNOWN;
566 }
567
568 return cs_he_initial_set(cs, he, value, err);
569}
570
581int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
582{
583 if (!cs || !he || !result)
584 return CSR_ERR_CODE;
585
586 const struct ConfigDef *cdef = NULL;
587 const struct ConfigSetType *cst = NULL;
588
589 if (he->type & D_INTERNAL_INHERITED)
590 {
591 struct HashElem *he_base = cs_get_base(he);
592 cdef = he_base->data;
593 cst = cs_get_type_def(cs, he_base->type);
594 }
595 else
596 {
597 cdef = he->data;
598 cst = cs_get_type_def(cs, he->type);
599 }
600
601 if (!cst)
602 return CSR_ERR_CODE; // LCOV_EXCL_LINE
603
604 return cst->string_get(NULL, cdef, result);
605}
606
617int cs_str_initial_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
618{
619 if (!cs || !name)
620 return CSR_ERR_CODE;
621
622 struct HashElem *he = cs_get_elem(cs, name);
623 if (!he)
624 {
625 buf_printf(result, _("Unknown option %s"), name);
626 return CSR_ERR_UNKNOWN;
627 }
628
629 return cs_he_initial_get(cs, he, result);
630}
631
640int cs_he_string_set(const struct ConfigSet *cs, struct HashElem *he,
641 const char *value, struct Buffer *err)
642{
643 if (!cs || !he)
644 return CSR_ERR_CODE;
645
646 struct ConfigDef *cdef = NULL;
647 const struct ConfigSetType *cst = NULL;
648 void *var = NULL;
649
650 if (he->type & D_INTERNAL_INHERITED)
651 {
652 struct Inheritance *i = he->data;
653 struct HashElem *he_base = cs_get_base(he);
654 cdef = he_base->data;
655 cst = cs_get_type_def(cs, he_base->type);
656 var = &i->var;
657 }
658 else
659 {
660 cdef = he->data;
661 cst = cs_get_type_def(cs, he->type);
662 var = &cdef->var;
663 }
664
665 if (!cdef)
666 return CSR_ERR_CODE; // LCOV_EXCL_LINE
667
668 if (!cst)
669 {
670 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
671 return CSR_ERR_CODE;
672 }
673
674 int rc = cst->string_set(var, cdef, value, err);
675 if (CSR_RESULT(rc) != CSR_SUCCESS)
676 return rc;
677
678 if (he->type & D_INTERNAL_INHERITED)
679 he->type = cdef->type | D_INTERNAL_INHERITED;
680
681 return rc;
682}
683
692int cs_str_string_set(const struct ConfigSet *cs, const char *name,
693 const char *value, struct Buffer *err)
694{
695 if (!cs || !name)
696 return CSR_ERR_CODE;
697
698 struct HashElem *he = cs_get_elem(cs, name);
699 if (!he)
700 {
701 buf_printf(err, _("Unknown option %s"), name);
702 return CSR_ERR_UNKNOWN;
703 }
704
705 return cs_he_string_set(cs, he, value, err);
706}
707
715int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
716{
717 if (!cs || !he || !result)
718 return CSR_ERR_CODE;
719
720 struct ConfigDef *cdef = NULL;
721 const struct ConfigSetType *cst = NULL;
722 void *var = NULL;
723
724 if (he->type & D_INTERNAL_INHERITED)
725 {
726 struct Inheritance *i = he->data;
727
728 // inherited, value not set
729 if (CONFIG_TYPE(he->type) == 0)
730 return cs_he_string_get(cs, i->parent, result);
731
732 // inherited, value set
733 struct HashElem *he_base = cs_get_base(he);
734 cdef = he_base->data;
735 cst = cs_get_type_def(cs, he_base->type);
736 var = &i->var;
737 }
738 else
739 {
740 // not inherited
741 cdef = he->data;
742 cst = cs_get_type_def(cs, he->type);
743 var = &cdef->var;
744 }
745
746 if (!cdef || !cst)
747 return CSR_ERR_CODE; // LCOV_EXCL_LINE
748
749 return cst->string_get(var, cdef, result);
750}
751
760int cs_he_native_set(const struct ConfigSet *cs, struct HashElem *he,
761 intptr_t value, struct Buffer *err)
762{
763 if (!cs || !he)
764 return CSR_ERR_CODE;
765
766 struct ConfigDef *cdef = NULL;
767 const struct ConfigSetType *cst = NULL;
768 void *var = NULL;
769
770 if (he->type & D_INTERNAL_INHERITED)
771 {
772 struct Inheritance *i = he->data;
773 struct HashElem *he_base = cs_get_base(he);
774 cdef = he_base->data;
775 cst = cs_get_type_def(cs, he_base->type);
776 var = &i->var;
777 }
778 else
779 {
780 cdef = he->data;
781 cst = cs_get_type_def(cs, he->type);
782 var = &cdef->var;
783 }
784
785 if (!cst)
786 {
787 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
788 return CSR_ERR_CODE;
789 }
790
791 if (!var || !cdef)
792 return CSR_ERR_CODE; // LCOV_EXCL_LINE
793
794 int rc = cst->native_set(var, cdef, value, err);
795 if (CSR_RESULT(rc) != CSR_SUCCESS)
796 return rc;
797
798 if (he->type & D_INTERNAL_INHERITED)
799 he->type = cdef->type | D_INTERNAL_INHERITED;
800
801 return rc;
802}
803
812int cs_str_native_set(const struct ConfigSet *cs, const char *name,
813 intptr_t value, struct Buffer *err)
814{
815 if (!cs || !name)
816 return CSR_ERR_CODE;
817
818 struct HashElem *he = cs_get_elem(cs, name);
819 if (!he)
820 {
821 buf_printf(err, _("Unknown option %s"), name);
822 return CSR_ERR_UNKNOWN;
823 }
824
825 struct ConfigDef *cdef = NULL;
826 const struct ConfigSetType *cst = NULL;
827 void *var = NULL;
828
829 if (he->type & D_INTERNAL_INHERITED)
830 {
831 struct Inheritance *i = he->data;
832 struct HashElem *he_base = cs_get_base(he);
833 cdef = he_base->data;
834 cst = cs_get_type_def(cs, he_base->type);
835 var = &i->var;
836 }
837 else
838 {
839 cdef = he->data;
840 cst = cs_get_type_def(cs, he->type);
841 var = &cdef->var;
842 }
843
844 if (!cst || !var || !cdef)
845 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
846
847 int rc = cst->native_set(var, cdef, value, err);
848 if (CSR_RESULT(rc) != CSR_SUCCESS)
849 return rc;
850
851 if (he->type & D_INTERNAL_INHERITED)
852 he->type = cdef->type | D_INTERNAL_INHERITED;
853
854 return rc;
855}
856
865intptr_t cs_he_native_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
866{
867 if (!cs || !he)
868 return INT_MIN;
869
870 struct ConfigDef *cdef = NULL;
871 const struct ConfigSetType *cst = NULL;
872 void *var = NULL;
873
874 if (he->type & D_INTERNAL_INHERITED)
875 {
876 struct Inheritance *i = he->data;
877
878 // inherited, value not set
879 if (CONFIG_TYPE(he->type) == 0)
880 return cs_he_native_get(cs, i->parent, err);
881
882 // inherited, value set
883 struct HashElem *he_base = cs_get_base(he);
884 cdef = he_base->data;
885 cst = cs_get_type_def(cs, he_base->type);
886 var = &i->var;
887 }
888 else
889 {
890 // not inherited
891 cdef = he->data;
892 cst = cs_get_type_def(cs, he->type);
893 var = &cdef->var;
894 }
895
896 if (!var || !cdef)
897 return INT_MIN; // LCOV_EXCL_LINE
898
899 if (!cst)
900 {
901 buf_printf(err, _("Option %s has an invalid type %d"), cdef->name, he->type);
902 return INT_MIN;
903 }
904
905 return cst->native_get(var, cdef, err);
906}
907
916int cs_he_string_plus_equals(const struct ConfigSet *cs, struct HashElem *he,
917 const char *value, struct Buffer *err)
918{
919 if (!cs || !he)
920 return CSR_ERR_CODE;
921
922 struct ConfigDef *cdef = NULL;
923 const struct ConfigSetType *cst = NULL;
924 void *var = NULL;
925
926 if (he->type & D_INTERNAL_INHERITED)
927 {
928 struct Inheritance *i = he->data;
929 struct HashElem *he_base = cs_get_base(he);
930 cdef = he_base->data;
931 cst = cs_get_type_def(cs, he_base->type);
932 var = &i->var;
933 }
934 else
935 {
936 cdef = he->data;
937 cst = cs_get_type_def(cs, he->type);
938 var = &cdef->var;
939 }
940
941 if (!var || !cdef)
942 return INT_MIN; // LCOV_EXCL_LINE
943
944 if (!cst)
945 {
946 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
947 return CSR_ERR_CODE;
948 }
949
950 if (!cst->string_plus_equals)
951 {
952 // L10N: e.g. Type 'boolean' doesn't support operation '+='
953 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "+=");
955 }
956
957 int rc = cst->string_plus_equals(var, cdef, value, err);
958 if (CSR_RESULT(rc) != CSR_SUCCESS)
959 return rc;
960
961 if (he->type & D_INTERNAL_INHERITED)
962 he->type = cdef->type | D_INTERNAL_INHERITED;
963
964 return rc;
965}
966
975int cs_he_string_minus_equals(const struct ConfigSet *cs, struct HashElem *he,
976 const char *value, struct Buffer *err)
977{
978 if (!cs || !he)
979 return CSR_ERR_CODE;
980
981 struct ConfigDef *cdef = NULL;
982 const struct ConfigSetType *cst = NULL;
983 void *var = NULL;
984
985 if (he->type & D_INTERNAL_INHERITED)
986 {
987 struct Inheritance *i = he->data;
988 struct HashElem *he_base = cs_get_base(he);
989 cdef = he_base->data;
990 cst = cs_get_type_def(cs, he_base->type);
991 var = &i->var;
992 }
993 else
994 {
995 cdef = he->data;
996 cst = cs_get_type_def(cs, he->type);
997 var = &cdef->var;
998 }
999
1000 if (!var || !cdef)
1001 return INT_MIN; // LCOV_EXCL_LINE
1002
1003 if (!cst)
1004 {
1005 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
1006 return CSR_ERR_CODE;
1007 }
1008
1009 if (!cst->string_minus_equals)
1010 {
1011 // L10N: e.g. Type 'boolean' doesn't support operation '+='
1012 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "-=");
1014 }
1015
1016 int rc = cst->string_minus_equals(var, cdef, value, err);
1017 if (CSR_RESULT(rc) != CSR_SUCCESS)
1018 return rc;
1019
1020 if (he->type & D_INTERNAL_INHERITED)
1021 he->type = cdef->type | D_INTERNAL_INHERITED;
1022
1023 return rc;
1024}
1025
1033int cs_he_delete(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
1034{
1035 if (!cs || !he)
1036 return CSR_ERR_CODE;
1037
1038 mutt_hash_delete(cs->hash, he->key.strkey, he->data);
1039 return CSR_SUCCESS;
1040}
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:617
struct HashElem * cs_get_elem(const struct ConfigSet *cs, const char *name)
Get the HashElem representing a config item.
Definition: set.c:175
int cs_str_initial_set(const struct ConfigSet *cs, const char *name, const char *value, struct Buffer *err)
Set the initial value of a config item.
Definition: set.c:555
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:916
void cs_free(struct ConfigSet **ptr)
Free a Config Set.
Definition: set.c:141
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:446
struct ConfigSet * cs_new(size_t size)
Create a new Config Set.
Definition: set.c:127
struct HashElem * cs_create_variable(const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err)
Create and register one config item.
Definition: set.c:326
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:493
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:399
const struct ConfigSetType * cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
Get the definition for a type.
Definition: set.c:198
int cs_he_delete(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
Delete config item from a config set.
Definition: set.c:1033
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:692
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:99
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:640
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:812
struct HashElem * cs_get_base(struct HashElem *he)
Find the root Config Item.
Definition: set.c:160
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:468
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:760
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:865
struct HashElem * cs_inherit_variable(const struct ConfigSet *cs, struct HashElem *he_parent, const char *name)
Create in inherited config item.
Definition: set.c:355
bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[])
Register a set of config items.
Definition: set.c:289
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:715
struct HashElem * cs_register_variable(const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err)
Register one config item.
Definition: set.c:249
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:513
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:581
bool cs_register_type(struct ConfigSet *cs, const struct ConfigSetType *cst)
Register a type of config item.
Definition: set.c:219
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:975
void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
Remove an inherited config item.
Definition: set.c:384
#define CSR_ERR_INVALID
Value hasn't been set.
Definition: set.h:38
#define CSV_INV_NOT_IMPL
Operation not permitted for the type.
Definition: set.h:49
#define CSR_ERR_UNKNOWN
Unrecognised config item.
Definition: set.h:37
#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
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:46
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:427
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:317
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:259
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:377
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:301
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
#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:43
#define FREE(x)
Definition: memory.h:55
#define MUTT_MEM_CALLOC(n, type)
Definition: memory.h:40
#define mutt_array_size(x)
Definition: memory.h:38
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:254
Parse the 'set' command.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
String manipulation buffer.
Definition: buffer.h:36
Definition: set.h:64
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)
Definition: types.h:49
#define D_INTERNAL_INHERITED
Config item is inherited.
Definition: types.h:88
#define D_INTERNAL_FREE_CONFIGDEF
Config item must have its ConfigDef freed.
Definition: types.h:86
#define D_INTERNAL_INITIAL_SET
Config item must have its initial value freed.
Definition: types.h:89
@ 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