NeoMutt  2025-12-11-911-gd8d604
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
132 cs->hash = mutt_hash_new(size, MUTT_HASH_NONE);
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 if (he->type & D_INTERNAL_INHERITED)
475 {
476 if (CONFIG_TYPE(he->type) == 0)
477 return false;
478
479 struct Inheritance *i = he->data;
480 struct Buffer value = { 0 };
481 struct Buffer parent = { 0 };
482
483 buf_init(&value);
484 buf_init(&parent);
485
486 bool rc = false;
487 if ((CSR_RESULT(cs_he_string_get(cs, he, &value)) == CSR_SUCCESS) &&
488 (CSR_RESULT(cs_he_string_get(cs, i->parent, &parent)) == CSR_SUCCESS))
489 {
490 rc = !mutt_str_equal(buf_string(&value), buf_string(&parent));
491 }
492
493 buf_dealloc(&parent);
494 buf_dealloc(&value);
495 return rc;
496 }
497
498 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
499 if (!cst)
500 return false; // LCOV_EXCL_LINE
501
502 if (!cst->has_been_set) // Probably a my_var
503 return true;
504
505 struct ConfigDef *cdef = he->data;
506 void *var = &cdef->var;
507
508 return cst->has_been_set(var, cdef);
509}
510
518bool cs_str_has_been_set(const struct ConfigSet *cs, const char *name)
519{
520 if (!cs || !name)
521 return false;
522
523 struct HashElem *he = cs_get_elem(cs, name);
524 if (!he)
525 return false;
526
527 return cs_he_has_been_set(cs, he);
528}
529
538int cs_he_initial_set(const struct ConfigSet *cs, struct HashElem *he,
539 const char *value, struct Buffer *err)
540{
541 if (!cs || !he)
542 return CSR_ERR_CODE;
543
544 struct ConfigDef *cdef = NULL;
545
546 if (he->type & D_INTERNAL_INHERITED)
547 {
548 struct HashElem *he_base = cs_get_base(he);
549 cdef = he_base->data;
550 mutt_debug(LL_DEBUG1, "Variable '%s' is inherited type\n", cdef->name);
551 return CSR_ERR_CODE;
552 }
553
554 cdef = he->data;
555 if (!cdef)
556 return CSR_ERR_CODE; // LCOV_EXCL_LINE
557
558 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
559 if (!cst)
560 {
561 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
562 return CSR_ERR_CODE;
563 }
564
565 int rc = cst->string_set(NULL, cdef, value, err);
566 if (CSR_RESULT(rc) != CSR_SUCCESS)
567 return rc;
568
569 return CSR_SUCCESS;
570}
571
582int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
583{
584 if (!cs || !he || !result)
585 return CSR_ERR_CODE;
586
587 const struct ConfigDef *cdef = NULL;
588 const struct ConfigSetType *cst = NULL;
589
590 if (he->type & D_INTERNAL_INHERITED)
591 {
592 struct HashElem *he_base = cs_get_base(he);
593 cdef = he_base->data;
594 cst = cs_get_type_def(cs, he_base->type);
595 }
596 else
597 {
598 cdef = he->data;
599 cst = cs_get_type_def(cs, he->type);
600 }
601
602 if (!cst)
603 return CSR_ERR_CODE; // LCOV_EXCL_LINE
604
605 return cst->string_get(NULL, cdef, result);
606}
607
618int cs_str_initial_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
619{
620 if (!cs || !name)
621 return CSR_ERR_CODE;
622
623 struct HashElem *he = cs_get_elem(cs, name);
624 if (!he)
625 {
626 buf_printf(result, _("Unknown option %s"), name);
627 return CSR_ERR_UNKNOWN;
628 }
629
630 return cs_he_initial_get(cs, he, result);
631}
632
641int cs_he_string_set(const struct ConfigSet *cs, struct HashElem *he,
642 const char *value, struct Buffer *err)
643{
644 if (!cs || !he)
645 return CSR_ERR_CODE;
646
647 struct ConfigDef *cdef = NULL;
648 const struct ConfigSetType *cst = NULL;
649 void *var = NULL;
650
651 if (he->type & D_INTERNAL_INHERITED)
652 {
653 struct Inheritance *i = he->data;
654 struct HashElem *he_base = cs_get_base(he);
655 cdef = he_base->data;
656 cst = cs_get_type_def(cs, he_base->type);
657 var = &i->var;
658 }
659 else
660 {
661 cdef = he->data;
662 cst = cs_get_type_def(cs, he->type);
663 var = &cdef->var;
664 }
665
666 if (!cdef)
667 return CSR_ERR_CODE; // LCOV_EXCL_LINE
668
669 if (!cst)
670 {
671 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
672 return CSR_ERR_CODE;
673 }
674
675 int rc = cst->string_set(var, cdef, value, err);
676 if (CSR_RESULT(rc) != CSR_SUCCESS)
677 return rc;
678
679 if (he->type & D_INTERNAL_INHERITED)
680 he->type = cdef->type | D_INTERNAL_INHERITED;
681
682 return rc;
683}
684
693int cs_str_string_set(const struct ConfigSet *cs, const char *name,
694 const char *value, struct Buffer *err)
695{
696 if (!cs || !name)
697 return CSR_ERR_CODE;
698
699 struct HashElem *he = cs_get_elem(cs, name);
700 if (!he)
701 {
702 buf_printf(err, _("Unknown option %s"), name);
703 return CSR_ERR_UNKNOWN;
704 }
705
706 return cs_he_string_set(cs, he, value, err);
707}
708
716int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
717{
718 if (!cs || !he || !result)
719 return CSR_ERR_CODE;
720
721 struct ConfigDef *cdef = NULL;
722 const struct ConfigSetType *cst = NULL;
723 void *var = NULL;
724
725 if (he->type & D_INTERNAL_INHERITED)
726 {
727 struct Inheritance *i = he->data;
728
729 // inherited, value not set
730 if (CONFIG_TYPE(he->type) == 0)
731 return cs_he_string_get(cs, i->parent, result);
732
733 // inherited, value set
734 struct HashElem *he_base = cs_get_base(he);
735 cdef = he_base->data;
736 cst = cs_get_type_def(cs, he_base->type);
737 var = &i->var;
738 }
739 else
740 {
741 // not inherited
742 cdef = he->data;
743 cst = cs_get_type_def(cs, he->type);
744 var = &cdef->var;
745 }
746
747 if (!cdef || !cst)
748 return CSR_ERR_CODE; // LCOV_EXCL_LINE
749
750 return cst->string_get(var, cdef, result);
751}
752
761int cs_he_native_set(const struct ConfigSet *cs, struct HashElem *he,
762 intptr_t value, struct Buffer *err)
763{
764 if (!cs || !he)
765 return CSR_ERR_CODE;
766
767 struct ConfigDef *cdef = NULL;
768 const struct ConfigSetType *cst = NULL;
769 void *var = NULL;
770
771 if (he->type & D_INTERNAL_INHERITED)
772 {
773 struct Inheritance *i = he->data;
774 struct HashElem *he_base = cs_get_base(he);
775 cdef = he_base->data;
776 cst = cs_get_type_def(cs, he_base->type);
777 var = &i->var;
778 }
779 else
780 {
781 cdef = he->data;
782 cst = cs_get_type_def(cs, he->type);
783 var = &cdef->var;
784 }
785
786 if (!cst)
787 {
788 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
789 return CSR_ERR_CODE;
790 }
791
792 if (!var || !cdef)
793 return CSR_ERR_CODE; // LCOV_EXCL_LINE
794
795 int rc = cst->native_set(var, cdef, value, err);
796 if (CSR_RESULT(rc) != CSR_SUCCESS)
797 return rc;
798
799 if (he->type & D_INTERNAL_INHERITED)
800 he->type = cdef->type | D_INTERNAL_INHERITED;
801
802 return rc;
803}
804
813int cs_str_native_set(const struct ConfigSet *cs, const char *name,
814 intptr_t value, struct Buffer *err)
815{
816 if (!cs || !name)
817 return CSR_ERR_CODE;
818
819 struct HashElem *he = cs_get_elem(cs, name);
820 if (!he)
821 {
822 buf_printf(err, _("Unknown option %s"), name);
823 return CSR_ERR_UNKNOWN;
824 }
825
826 struct ConfigDef *cdef = NULL;
827 const struct ConfigSetType *cst = NULL;
828 void *var = NULL;
829
830 if (he->type & D_INTERNAL_INHERITED)
831 {
832 struct Inheritance *i = he->data;
833 struct HashElem *he_base = cs_get_base(he);
834 cdef = he_base->data;
835 cst = cs_get_type_def(cs, he_base->type);
836 var = &i->var;
837 }
838 else
839 {
840 cdef = he->data;
841 cst = cs_get_type_def(cs, he->type);
842 var = &cdef->var;
843 }
844
845 if (!cst || !var || !cdef)
846 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
847
848 int rc = cst->native_set(var, cdef, value, err);
849 if (CSR_RESULT(rc) != CSR_SUCCESS)
850 return rc;
851
852 if (he->type & D_INTERNAL_INHERITED)
853 he->type = cdef->type | D_INTERNAL_INHERITED;
854
855 return rc;
856}
857
866intptr_t cs_he_native_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
867{
868 if (!cs || !he)
869 return INT_MIN;
870
871 struct ConfigDef *cdef = NULL;
872 const struct ConfigSetType *cst = NULL;
873 void *var = NULL;
874
875 if (he->type & D_INTERNAL_INHERITED)
876 {
877 struct Inheritance *i = he->data;
878
879 // inherited, value not set
880 if (CONFIG_TYPE(he->type) == 0)
881 return cs_he_native_get(cs, i->parent, err);
882
883 // inherited, value set
884 struct HashElem *he_base = cs_get_base(he);
885 cdef = he_base->data;
886 cst = cs_get_type_def(cs, he_base->type);
887 var = &i->var;
888 }
889 else
890 {
891 // not inherited
892 cdef = he->data;
893 cst = cs_get_type_def(cs, he->type);
894 var = &cdef->var;
895 }
896
897 if (!var || !cdef)
898 return INT_MIN; // LCOV_EXCL_LINE
899
900 if (!cst)
901 {
902 buf_printf(err, _("Option %s has an invalid type %d"), cdef->name, he->type);
903 return INT_MIN;
904 }
905
906 return cst->native_get(var, cdef, err);
907}
908
917int cs_he_string_plus_equals(const struct ConfigSet *cs, struct HashElem *he,
918 const char *value, struct Buffer *err)
919{
920 if (!cs || !he)
921 return CSR_ERR_CODE;
922
923 struct ConfigDef *cdef = NULL;
924 const struct ConfigSetType *cst = NULL;
925 void *var = NULL;
926
927 if (he->type & D_INTERNAL_INHERITED)
928 {
929 struct Inheritance *i = he->data;
930 struct HashElem *he_base = cs_get_base(he);
931 cdef = he_base->data;
932 cst = cs_get_type_def(cs, he_base->type);
933 var = &i->var;
934 }
935 else
936 {
937 cdef = he->data;
938 cst = cs_get_type_def(cs, he->type);
939 var = &cdef->var;
940 }
941
942 if (!var || !cdef)
943 return CSR_ERR_CODE; // LCOV_EXCL_LINE
944
945 if (!cst)
946 {
947 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
948 return CSR_ERR_CODE;
949 }
950
951 if (!cst->string_plus_equals)
952 {
953 // L10N: e.g. Type 'boolean' doesn't support operation '+='
954 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "+=");
956 }
957
958 int rc = cst->string_plus_equals(var, cdef, value, err);
959 if (CSR_RESULT(rc) != CSR_SUCCESS)
960 return rc;
961
962 if (he->type & D_INTERNAL_INHERITED)
963 he->type = cdef->type | D_INTERNAL_INHERITED;
964
965 return rc;
966}
967
976int cs_he_string_minus_equals(const struct ConfigSet *cs, struct HashElem *he,
977 const char *value, struct Buffer *err)
978{
979 if (!cs || !he)
980 return CSR_ERR_CODE;
981
982 struct ConfigDef *cdef = NULL;
983 const struct ConfigSetType *cst = NULL;
984 void *var = NULL;
985
986 if (he->type & D_INTERNAL_INHERITED)
987 {
988 struct Inheritance *i = he->data;
989 struct HashElem *he_base = cs_get_base(he);
990 cdef = he_base->data;
991 cst = cs_get_type_def(cs, he_base->type);
992 var = &i->var;
993 }
994 else
995 {
996 cdef = he->data;
997 cst = cs_get_type_def(cs, he->type);
998 var = &cdef->var;
999 }
1000
1001 if (!var || !cdef)
1002 return CSR_ERR_CODE; // LCOV_EXCL_LINE
1003
1004 if (!cst)
1005 {
1006 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
1007 return CSR_ERR_CODE;
1008 }
1009
1010 if (!cst->string_minus_equals)
1011 {
1012 // L10N: e.g. Type 'boolean' doesn't support operation '+='
1013 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "-=");
1015 }
1016
1017 int rc = cst->string_minus_equals(var, cdef, value, err);
1018 if (CSR_RESULT(rc) != CSR_SUCCESS)
1019 return rc;
1020
1021 if (he->type & D_INTERNAL_INHERITED)
1022 he->type = cdef->type | D_INTERNAL_INHERITED;
1023
1024 return rc;
1025}
1026
1034int cs_he_delete(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
1035{
1036 if (!cs || !he)
1037 return CSR_ERR_CODE;
1038
1039 mutt_hash_delete(cs->hash, he->key.strkey, he->data);
1040 return CSR_SUCCESS;
1041}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
void buf_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition buffer.c:377
struct Buffer * buf_init(struct Buffer *buf)
Initialise a new Buffer.
Definition buffer.c:61
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:618
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:917
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:518
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:1034
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:693
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:641
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:813
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:761
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:866
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:716
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:538
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:582
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:976
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:53
#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
@ MUTT_HASH_NONE
No flags are set.
Definition hash.h:115
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
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
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:66
intptr_t var
Storage for the variable.
Definition set.h:85
int(* validator)(const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition set.h:82
intptr_t data
Extra variable data.
Definition set.h:69
intptr_t initial
Initial value.
Definition set.h:68
uint32_t type
Variable type, e.g. DT_STRING.
Definition set.h:67
const char * docs
One-liner description.
Definition set.h:84
int(* string_set)(void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition set.h:115
int(* native_set)(void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition set.h:148
intptr_t(* native_get)(void *var, const struct ConfigDef *cdef, struct Buffer *err)
Definition set.h:164
int(* string_plus_equals)(void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition set.h:180
int type
Data type, e.g. DT_STRING.
Definition set.h:97
bool(* has_been_set)(void *var, const struct ConfigDef *cdef)
Definition set.h:211
int(* reset)(void *var, const struct ConfigDef *cdef, struct Buffer *err)
Definition set.h:226
int(* string_get)(void *var, const struct ConfigDef *cdef, struct Buffer *result)
Definition set.h:132
void(* destroy)(void *var, const struct ConfigDef *cdef)
Definition set.h:239
int(* string_minus_equals)(void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition set.h:196
const char * name
Name of the type, e.g. "String".
Definition set.h:98
Container for lots of config items.
Definition set.h:251
struct ConfigSetType types[18]
All the defined config types.
Definition set.h:253
struct HashTable * hash
Hash Table: "$name" -> ConfigDef.
Definition set.h:252
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