NeoMutt  2025-01-09-117-gace867
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
557int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
558{
559 if (!cs || !he || !result)
560 return CSR_ERR_CODE;
561
562 const struct ConfigDef *cdef = NULL;
563 const struct ConfigSetType *cst = NULL;
564
565 if (he->type & D_INTERNAL_INHERITED)
566 {
567 struct HashElem *he_base = cs_get_base(he);
568 cdef = he_base->data;
569 cst = cs_get_type_def(cs, he_base->type);
570 }
571 else
572 {
573 cdef = he->data;
574 cst = cs_get_type_def(cs, he->type);
575 }
576
577 if (!cst)
578 return CSR_ERR_CODE; // LCOV_EXCL_LINE
579
580 return cst->string_get(NULL, cdef, result);
581}
582
593int cs_str_initial_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
594{
595 if (!cs || !name)
596 return CSR_ERR_CODE;
597
598 struct HashElem *he = cs_get_elem(cs, name);
599 if (!he)
600 {
601 buf_printf(result, _("Unknown option %s"), name);
602 return CSR_ERR_UNKNOWN;
603 }
604
605 return cs_he_initial_get(cs, he, result);
606}
607
616int cs_he_string_set(const struct ConfigSet *cs, struct HashElem *he,
617 const char *value, struct Buffer *err)
618{
619 if (!cs || !he)
620 return CSR_ERR_CODE;
621
622 struct ConfigDef *cdef = NULL;
623 const struct ConfigSetType *cst = NULL;
624 void *var = NULL;
625
626 if (he->type & D_INTERNAL_INHERITED)
627 {
628 struct Inheritance *i = he->data;
629 struct HashElem *he_base = cs_get_base(he);
630 cdef = he_base->data;
631 cst = cs_get_type_def(cs, he_base->type);
632 var = &i->var;
633 }
634 else
635 {
636 cdef = he->data;
637 cst = cs_get_type_def(cs, he->type);
638 var = &cdef->var;
639 }
640
641 if (!cdef)
642 return CSR_ERR_CODE; // LCOV_EXCL_LINE
643
644 if (!cst)
645 {
646 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
647 return CSR_ERR_CODE;
648 }
649
650 int rc = cst->string_set(var, cdef, value, err);
651 if (CSR_RESULT(rc) != CSR_SUCCESS)
652 return rc;
653
654 if (he->type & D_INTERNAL_INHERITED)
655 he->type = cdef->type | D_INTERNAL_INHERITED;
656
657 return rc;
658}
659
668int cs_str_string_set(const struct ConfigSet *cs, const char *name,
669 const char *value, struct Buffer *err)
670{
671 if (!cs || !name)
672 return CSR_ERR_CODE;
673
674 struct HashElem *he = cs_get_elem(cs, name);
675 if (!he)
676 {
677 buf_printf(err, _("Unknown option %s"), name);
678 return CSR_ERR_UNKNOWN;
679 }
680
681 return cs_he_string_set(cs, he, value, err);
682}
683
691int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
692{
693 if (!cs || !he || !result)
694 return CSR_ERR_CODE;
695
696 struct ConfigDef *cdef = NULL;
697 const struct ConfigSetType *cst = NULL;
698 void *var = NULL;
699
700 if (he->type & D_INTERNAL_INHERITED)
701 {
702 struct Inheritance *i = he->data;
703
704 // inherited, value not set
705 if (CONFIG_TYPE(he->type) == 0)
706 return cs_he_string_get(cs, i->parent, result);
707
708 // inherited, value set
709 struct HashElem *he_base = cs_get_base(he);
710 cdef = he_base->data;
711 cst = cs_get_type_def(cs, he_base->type);
712 var = &i->var;
713 }
714 else
715 {
716 // not inherited
717 cdef = he->data;
718 cst = cs_get_type_def(cs, he->type);
719 var = &cdef->var;
720 }
721
722 if (!cdef || !cst)
723 return CSR_ERR_CODE; // LCOV_EXCL_LINE
724
725 return cst->string_get(var, cdef, result);
726}
727
736int cs_he_native_set(const struct ConfigSet *cs, struct HashElem *he,
737 intptr_t value, struct Buffer *err)
738{
739 if (!cs || !he)
740 return CSR_ERR_CODE;
741
742 struct ConfigDef *cdef = NULL;
743 const struct ConfigSetType *cst = NULL;
744 void *var = NULL;
745
746 if (he->type & D_INTERNAL_INHERITED)
747 {
748 struct Inheritance *i = he->data;
749 struct HashElem *he_base = cs_get_base(he);
750 cdef = he_base->data;
751 cst = cs_get_type_def(cs, he_base->type);
752 var = &i->var;
753 }
754 else
755 {
756 cdef = he->data;
757 cst = cs_get_type_def(cs, he->type);
758 var = &cdef->var;
759 }
760
761 if (!cst)
762 {
763 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
764 return CSR_ERR_CODE;
765 }
766
767 if (!var || !cdef)
768 return CSR_ERR_CODE; // LCOV_EXCL_LINE
769
770 int rc = cst->native_set(var, cdef, value, err);
771 if (CSR_RESULT(rc) != CSR_SUCCESS)
772 return rc;
773
774 if (he->type & D_INTERNAL_INHERITED)
775 he->type = cdef->type | D_INTERNAL_INHERITED;
776
777 return rc;
778}
779
788int cs_str_native_set(const struct ConfigSet *cs, const char *name,
789 intptr_t value, struct Buffer *err)
790{
791 if (!cs || !name)
792 return CSR_ERR_CODE;
793
794 struct HashElem *he = cs_get_elem(cs, name);
795 if (!he)
796 {
797 buf_printf(err, _("Unknown option %s"), name);
798 return CSR_ERR_UNKNOWN;
799 }
800
801 struct ConfigDef *cdef = NULL;
802 const struct ConfigSetType *cst = NULL;
803 void *var = NULL;
804
805 if (he->type & D_INTERNAL_INHERITED)
806 {
807 struct Inheritance *i = he->data;
808 struct HashElem *he_base = cs_get_base(he);
809 cdef = he_base->data;
810 cst = cs_get_type_def(cs, he_base->type);
811 var = &i->var;
812 }
813 else
814 {
815 cdef = he->data;
816 cst = cs_get_type_def(cs, he->type);
817 var = &cdef->var;
818 }
819
820 if (!cst || !var || !cdef)
821 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
822
823 int rc = cst->native_set(var, cdef, value, err);
824 if (CSR_RESULT(rc) != CSR_SUCCESS)
825 return rc;
826
827 if (he->type & D_INTERNAL_INHERITED)
828 he->type = cdef->type | D_INTERNAL_INHERITED;
829
830 return rc;
831}
832
841intptr_t cs_he_native_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
842{
843 if (!cs || !he)
844 return INT_MIN;
845
846 struct ConfigDef *cdef = NULL;
847 const struct ConfigSetType *cst = NULL;
848 void *var = NULL;
849
850 if (he->type & D_INTERNAL_INHERITED)
851 {
852 struct Inheritance *i = he->data;
853
854 // inherited, value not set
855 if (CONFIG_TYPE(he->type) == 0)
856 return cs_he_native_get(cs, i->parent, err);
857
858 // inherited, value set
859 struct HashElem *he_base = cs_get_base(he);
860 cdef = he_base->data;
861 cst = cs_get_type_def(cs, he_base->type);
862 var = &i->var;
863 }
864 else
865 {
866 // not inherited
867 cdef = he->data;
868 cst = cs_get_type_def(cs, he->type);
869 var = &cdef->var;
870 }
871
872 if (!var || !cdef)
873 return INT_MIN; // LCOV_EXCL_LINE
874
875 if (!cst)
876 {
877 buf_printf(err, _("Option %s has an invalid type %d"), cdef->name, he->type);
878 return INT_MIN;
879 }
880
881 return cst->native_get(var, cdef, err);
882}
883
892int cs_he_string_plus_equals(const struct ConfigSet *cs, struct HashElem *he,
893 const char *value, struct Buffer *err)
894{
895 if (!cs || !he)
896 return CSR_ERR_CODE;
897
898 struct ConfigDef *cdef = NULL;
899 const struct ConfigSetType *cst = NULL;
900 void *var = NULL;
901
902 if (he->type & D_INTERNAL_INHERITED)
903 {
904 struct Inheritance *i = he->data;
905 struct HashElem *he_base = cs_get_base(he);
906 cdef = he_base->data;
907 cst = cs_get_type_def(cs, he_base->type);
908 var = &i->var;
909 }
910 else
911 {
912 cdef = he->data;
913 cst = cs_get_type_def(cs, he->type);
914 var = &cdef->var;
915 }
916
917 if (!var || !cdef)
918 return INT_MIN; // LCOV_EXCL_LINE
919
920 if (!cst)
921 {
922 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
923 return CSR_ERR_CODE;
924 }
925
926 if (!cst->string_plus_equals)
927 {
928 // L10N: e.g. Type 'boolean' doesn't support operation '+='
929 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "+=");
931 }
932
933 int rc = cst->string_plus_equals(var, cdef, value, err);
934 if (CSR_RESULT(rc) != CSR_SUCCESS)
935 return rc;
936
937 if (he->type & D_INTERNAL_INHERITED)
938 he->type = cdef->type | D_INTERNAL_INHERITED;
939
940 return rc;
941}
942
951int cs_he_string_minus_equals(const struct ConfigSet *cs, struct HashElem *he,
952 const char *value, struct Buffer *err)
953{
954 if (!cs || !he)
955 return CSR_ERR_CODE;
956
957 struct ConfigDef *cdef = NULL;
958 const struct ConfigSetType *cst = NULL;
959 void *var = NULL;
960
961 if (he->type & D_INTERNAL_INHERITED)
962 {
963 struct Inheritance *i = he->data;
964 struct HashElem *he_base = cs_get_base(he);
965 cdef = he_base->data;
966 cst = cs_get_type_def(cs, he_base->type);
967 var = &i->var;
968 }
969 else
970 {
971 cdef = he->data;
972 cst = cs_get_type_def(cs, he->type);
973 var = &cdef->var;
974 }
975
976 if (!var || !cdef)
977 return INT_MIN; // LCOV_EXCL_LINE
978
979 if (!cst)
980 {
981 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
982 return CSR_ERR_CODE;
983 }
984
985 if (!cst->string_minus_equals)
986 {
987 // L10N: e.g. Type 'boolean' doesn't support operation '+='
988 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "-=");
990 }
991
992 int rc = cst->string_minus_equals(var, cdef, value, err);
993 if (CSR_RESULT(rc) != CSR_SUCCESS)
994 return rc;
995
996 if (he->type & D_INTERNAL_INHERITED)
997 he->type = cdef->type | D_INTERNAL_INHERITED;
998
999 return rc;
1000}
1001
1009int cs_he_delete(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
1010{
1011 if (!cs || !he)
1012 return CSR_ERR_CODE;
1013
1014 mutt_hash_delete(cs->hash, he->key.strkey, he->data);
1015 return CSR_SUCCESS;
1016}
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:593
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_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:892
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:1009
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:668
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:616
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:788
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:736
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:841
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:691
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:557
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:951
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: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)
Definition: set.h:50
#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:46
#define mutt_debug(LEVEL,...)
Definition: logging2.h:90
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:44
#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:62
const char * name
User-visible name.
Definition: set.h:63
intptr_t var
Storage for the variable.
Definition: set.h:82
int(* validator)(const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition: set.h:79
intptr_t data
Extra variable data.
Definition: set.h:66
intptr_t initial
Initial value.
Definition: set.h:65
uint32_t type
Variable type, e.g. DT_STRING.
Definition: set.h:64
const char * docs
One-liner description.
Definition: set.h:81
int(* string_set)(void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition: set.h:112
int(* native_set)(void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition: set.h:145
intptr_t(* native_get)(void *var, const struct ConfigDef *cdef, struct Buffer *err)
Definition: set.h:161
int(* string_plus_equals)(void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition: set.h:177
int type
Data type, e.g. DT_STRING.
Definition: set.h:94
bool(* has_been_set)(void *var, const struct ConfigDef *cdef)
Definition: set.h:208
int(* reset)(void *var, const struct ConfigDef *cdef, struct Buffer *err)
Definition: set.h:223
int(* string_get)(void *var, const struct ConfigDef *cdef, struct Buffer *result)
Definition: set.h:129
void(* destroy)(void *var, const struct ConfigDef *cdef)
Definition: set.h:236
int(* string_minus_equals)(void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition: set.h:193
const char * name
Name of the type, e.g. "String".
Definition: set.h:95
Container for lots of config items.
Definition: set.h:248
struct ConfigSetType types[18]
All the defined config types.
Definition: set.h:250
struct HashTable * hash
Hash Table: "$name" -> ConfigDef.
Definition: set.h:249
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