NeoMutt  2024-10-02-37-gfa9146
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(cs, (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(cs, &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, sizeof(*cs));
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 (DTYPE(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
203 type = DTYPE(type);
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 (DTYPE(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 if (cst->reset)
270 cst->reset(cs, &cdef->var, cdef, err);
271
272 return he;
273}
274
281bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[])
282{
283 if (!cs || !vars)
284 return false;
285
286 struct Buffer *err = buf_pool_get();
287
288 bool rc = true;
289
290 for (size_t i = 0; vars[i].name; i++)
291 {
292 if (!cs_register_variable(cs, &vars[i], err))
293 {
294 mutt_debug(LL_DEBUG1, "%s\n", buf_string(err));
295 rc = false;
296 }
297 }
298
299 buf_pool_release(&err);
300 return rc;
301}
302
318struct HashElem *cs_create_variable(const struct ConfigSet *cs,
319 struct ConfigDef *cdef, struct Buffer *err)
320{
321 struct ConfigDef *cdef_copy = mutt_mem_calloc(1, sizeof(struct ConfigDef));
322 cdef_copy->name = mutt_str_dup(cdef->name);
323 cdef_copy->type = cdef->type | D_INTERNAL_FREE_CONFIGDEF;
324 cdef_copy->initial = cdef->initial;
325 cdef_copy->data = cdef->data;
326 cdef_copy->validator = cdef->validator;
327 cdef_copy->docs = mutt_str_dup(cdef->name);
328 cdef_copy->var = cdef->var;
329
330 struct HashElem *he = cs_register_variable(cs, cdef_copy, err);
331 if (!he)
332 {
333 FREE(&cdef_copy->name);
334 FREE(&cdef_copy->docs);
335 FREE(&cdef_copy);
336 }
337 return he;
338}
339
347struct HashElem *cs_inherit_variable(const struct ConfigSet *cs,
348 struct HashElem *he_parent, const char *name)
349{
350 if (!cs || !he_parent)
351 return NULL;
352
353 /* MyVars cannot be inherited, as they might get deleted */
354 if (DTYPE(he_parent->type) == DT_MYVAR)
355 return NULL;
356
357 struct Inheritance *i = mutt_mem_calloc(1, sizeof(*i));
358 i->parent = he_parent;
359 i->name = mutt_str_dup(name);
360
362 if (!he)
363 {
364 FREE(&i->name);
365 FREE(&i);
366 }
367
368 return he;
369}
370
376void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
377{
378 if (!cs || !name)
379 return;
380
381 mutt_hash_delete(cs->hash, name, NULL);
382}
383
391int cs_he_reset(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
392{
393 if (!cs || !he)
394 return CSR_ERR_CODE;
395
396 /* An inherited var that's already pointing to its parent.
397 * Return 'success', but don't send a notification. */
398 if ((he->type & D_INTERNAL_INHERITED) && (DTYPE(he->type) == 0))
399 return CSR_SUCCESS;
400
401 int rc = CSR_SUCCESS;
402
403 if (he->type & D_INTERNAL_INHERITED)
404 {
405 struct Inheritance *i = he->data;
406 struct HashElem *he_base = cs_get_base(he);
407 struct ConfigDef *cdef = he_base->data;
408 if (!cdef)
409 return CSR_ERR_CODE; // LCOV_EXCL_LINE
410
411 const struct ConfigSetType *cst = cs_get_type_def(cs, he_base->type);
412 if (cst && cst->destroy)
413 cst->destroy(cs, (void **) &i->var, cdef);
414
416 }
417 else
418 {
419 struct ConfigDef *cdef = he->data;
420 if (!cdef)
421 return CSR_ERR_CODE; // LCOV_EXCL_LINE
422
423 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
424 if (cst)
425 rc = cst->reset(cs, &cdef->var, cdef, err);
426 }
427
428 return rc;
429}
430
438int cs_str_reset(const struct ConfigSet *cs, const char *name, struct Buffer *err)
439{
440 if (!cs || !name)
441 return CSR_ERR_CODE;
442
443 struct HashElem *he = cs_get_elem(cs, name);
444 if (!he)
445 {
446 buf_printf(err, _("Unknown option %s"), name);
447 return CSR_ERR_UNKNOWN;
448 }
449
450 return cs_he_reset(cs, he, err);
451}
452
461int cs_he_initial_set(const struct ConfigSet *cs, struct HashElem *he,
462 const char *value, struct Buffer *err)
463{
464 if (!cs || !he)
465 return CSR_ERR_CODE;
466
467 struct ConfigDef *cdef = NULL;
468
469 if (he->type & D_INTERNAL_INHERITED)
470 {
471 struct HashElem *he_base = cs_get_base(he);
472 cdef = he_base->data;
473 mutt_debug(LL_DEBUG1, "Variable '%s' is inherited type\n", cdef->name);
474 return CSR_ERR_CODE;
475 }
476
477 cdef = he->data;
478 if (!cdef)
479 return CSR_ERR_CODE; // LCOV_EXCL_LINE
480
481 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
482 if (!cst)
483 {
484 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
485 return CSR_ERR_CODE;
486 }
487
488 int rc = cst->string_set(cs, NULL, cdef, value, err);
489 if (CSR_RESULT(rc) != CSR_SUCCESS)
490 return rc;
491
492 return CSR_SUCCESS;
493}
494
503int cs_str_initial_set(const struct ConfigSet *cs, const char *name,
504 const char *value, struct Buffer *err)
505{
506 if (!cs || !name)
507 return CSR_ERR_CODE;
508
509 struct HashElem *he = cs_get_elem(cs, name);
510 if (!he)
511 {
512 buf_printf(err, _("Unknown option %s"), name);
513 return CSR_ERR_UNKNOWN;
514 }
515
516 return cs_he_initial_set(cs, he, value, err);
517}
518
529int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
530{
531 if (!cs || !he || !result)
532 return CSR_ERR_CODE;
533
534 const struct ConfigDef *cdef = NULL;
535 const struct ConfigSetType *cst = NULL;
536
537 if (he->type & D_INTERNAL_INHERITED)
538 {
539 struct HashElem *he_base = cs_get_base(he);
540 cdef = he_base->data;
541 cst = cs_get_type_def(cs, he_base->type);
542 }
543 else
544 {
545 cdef = he->data;
546 cst = cs_get_type_def(cs, he->type);
547 }
548
549 if (!cst)
550 return CSR_ERR_CODE; // LCOV_EXCL_LINE
551
552 return cst->string_get(cs, NULL, cdef, result);
553}
554
565int cs_str_initial_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
566{
567 if (!cs || !name)
568 return CSR_ERR_CODE;
569
570 struct HashElem *he = cs_get_elem(cs, name);
571 if (!he)
572 {
573 buf_printf(result, _("Unknown option %s"), name);
574 return CSR_ERR_UNKNOWN;
575 }
576
577 return cs_he_initial_get(cs, he, result);
578}
579
588int cs_he_string_set(const struct ConfigSet *cs, struct HashElem *he,
589 const char *value, struct Buffer *err)
590{
591 if (!cs || !he)
592 return CSR_ERR_CODE;
593
594 struct ConfigDef *cdef = NULL;
595 const struct ConfigSetType *cst = NULL;
596 void *var = NULL;
597
598 if (he->type & D_INTERNAL_INHERITED)
599 {
600 struct Inheritance *i = he->data;
601 struct HashElem *he_base = cs_get_base(he);
602 cdef = he_base->data;
603 cst = cs_get_type_def(cs, he_base->type);
604 var = &i->var;
605 }
606 else
607 {
608 cdef = he->data;
609 cst = cs_get_type_def(cs, he->type);
610 var = &cdef->var;
611 }
612
613 if (!cdef)
614 return CSR_ERR_CODE; // LCOV_EXCL_LINE
615
616 if (!cst)
617 {
618 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
619 return CSR_ERR_CODE;
620 }
621
622 int rc = cst->string_set(cs, var, cdef, value, err);
623 if (CSR_RESULT(rc) != CSR_SUCCESS)
624 return rc;
625
626 if (he->type & D_INTERNAL_INHERITED)
627 he->type = cdef->type | D_INTERNAL_INHERITED;
628
629 return rc;
630}
631
640int cs_str_string_set(const struct ConfigSet *cs, const char *name,
641 const char *value, struct Buffer *err)
642{
643 if (!cs || !name)
644 return CSR_ERR_CODE;
645
646 struct HashElem *he = cs_get_elem(cs, name);
647 if (!he)
648 {
649 buf_printf(err, _("Unknown option %s"), name);
650 return CSR_ERR_UNKNOWN;
651 }
652
653 return cs_he_string_set(cs, he, value, err);
654}
655
663int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
664{
665 if (!cs || !he || !result)
666 return CSR_ERR_CODE;
667
668 struct ConfigDef *cdef = NULL;
669 const struct ConfigSetType *cst = NULL;
670 void *var = NULL;
671
672 if (he->type & D_INTERNAL_INHERITED)
673 {
674 struct Inheritance *i = he->data;
675
676 // inherited, value not set
677 if (DTYPE(he->type) == 0)
678 return cs_he_string_get(cs, i->parent, result);
679
680 // inherited, value set
681 struct HashElem *he_base = cs_get_base(he);
682 cdef = he_base->data;
683 cst = cs_get_type_def(cs, he_base->type);
684 var = &i->var;
685 }
686 else
687 {
688 // not inherited
689 cdef = he->data;
690 cst = cs_get_type_def(cs, he->type);
691 var = &cdef->var;
692 }
693
694 if (!cdef || !cst)
695 return CSR_ERR_CODE; // LCOV_EXCL_LINE
696
697 return cst->string_get(cs, var, cdef, result);
698}
699
708int cs_he_native_set(const struct ConfigSet *cs, struct HashElem *he,
709 intptr_t value, struct Buffer *err)
710{
711 if (!cs || !he)
712 return CSR_ERR_CODE;
713
714 struct ConfigDef *cdef = NULL;
715 const struct ConfigSetType *cst = NULL;
716 void *var = NULL;
717
718 if (he->type & D_INTERNAL_INHERITED)
719 {
720 struct Inheritance *i = he->data;
721 struct HashElem *he_base = cs_get_base(he);
722 cdef = he_base->data;
723 cst = cs_get_type_def(cs, he_base->type);
724 var = &i->var;
725 }
726 else
727 {
728 cdef = he->data;
729 cst = cs_get_type_def(cs, he->type);
730 var = &cdef->var;
731 }
732
733 if (!cst)
734 {
735 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
736 return CSR_ERR_CODE;
737 }
738
739 if (!var || !cdef)
740 return CSR_ERR_CODE; // LCOV_EXCL_LINE
741
742 int rc = cst->native_set(cs, var, cdef, value, err);
743 if (CSR_RESULT(rc) != CSR_SUCCESS)
744 return rc;
745
746 if (he->type & D_INTERNAL_INHERITED)
747 he->type = cdef->type | D_INTERNAL_INHERITED;
748
749 return rc;
750}
751
760int cs_str_native_set(const struct ConfigSet *cs, const char *name,
761 intptr_t value, struct Buffer *err)
762{
763 if (!cs || !name)
764 return CSR_ERR_CODE;
765
766 struct HashElem *he = cs_get_elem(cs, name);
767 if (!he)
768 {
769 buf_printf(err, _("Unknown option %s"), name);
770 return CSR_ERR_UNKNOWN;
771 }
772
773 struct ConfigDef *cdef = NULL;
774 const struct ConfigSetType *cst = NULL;
775 void *var = NULL;
776
777 if (he->type & D_INTERNAL_INHERITED)
778 {
779 struct Inheritance *i = he->data;
780 struct HashElem *he_base = cs_get_base(he);
781 cdef = he_base->data;
782 cst = cs_get_type_def(cs, he_base->type);
783 var = &i->var;
784 }
785 else
786 {
787 cdef = he->data;
788 cst = cs_get_type_def(cs, he->type);
789 var = &cdef->var;
790 }
791
792 if (!cst || !var || !cdef)
793 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
794
795 int rc = cst->native_set(cs, 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
813intptr_t cs_he_native_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
814{
815 if (!cs || !he)
816 return INT_MIN;
817
818 struct ConfigDef *cdef = NULL;
819 const struct ConfigSetType *cst = NULL;
820 void *var = NULL;
821
822 if (he->type & D_INTERNAL_INHERITED)
823 {
824 struct Inheritance *i = he->data;
825
826 // inherited, value not set
827 if (DTYPE(he->type) == 0)
828 return cs_he_native_get(cs, i->parent, err);
829
830 // inherited, value set
831 struct HashElem *he_base = cs_get_base(he);
832 cdef = he_base->data;
833 cst = cs_get_type_def(cs, he_base->type);
834 var = &i->var;
835 }
836 else
837 {
838 // not inherited
839 cdef = he->data;
840 cst = cs_get_type_def(cs, he->type);
841 var = &cdef->var;
842 }
843
844 if (!var || !cdef)
845 return INT_MIN; // LCOV_EXCL_LINE
846
847 if (!cst)
848 {
849 buf_printf(err, _("Option %s has an invalid type %d"), cdef->name, he->type);
850 return INT_MIN;
851 }
852
853 return cst->native_get(cs, var, cdef, err);
854}
855
864int cs_he_string_plus_equals(const struct ConfigSet *cs, struct HashElem *he,
865 const char *value, struct Buffer *err)
866{
867 if (!cs || !he)
868 return CSR_ERR_CODE;
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 struct HashElem *he_base = cs_get_base(he);
878 cdef = he_base->data;
879 cst = cs_get_type_def(cs, he_base->type);
880 var = &i->var;
881 }
882 else
883 {
884 cdef = he->data;
885 cst = cs_get_type_def(cs, he->type);
886 var = &cdef->var;
887 }
888
889 if (!var || !cdef)
890 return INT_MIN; // LCOV_EXCL_LINE
891
892 if (!cst)
893 {
894 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
895 return CSR_ERR_CODE;
896 }
897
898 if (!cst->string_plus_equals)
899 {
900 // L10N: e.g. Type 'boolean' doesn't support operation '+='
901 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "+=");
903 }
904
905 int rc = cst->string_plus_equals(cs, var, cdef, value, err);
906 if (CSR_RESULT(rc) != CSR_SUCCESS)
907 return rc;
908
909 if (he->type & D_INTERNAL_INHERITED)
910 he->type = cdef->type | D_INTERNAL_INHERITED;
911
912 return rc;
913}
914
923int cs_he_string_minus_equals(const struct ConfigSet *cs, struct HashElem *he,
924 const char *value, struct Buffer *err)
925{
926 if (!cs || !he)
927 return CSR_ERR_CODE;
928
929 struct ConfigDef *cdef = NULL;
930 const struct ConfigSetType *cst = NULL;
931 void *var = NULL;
932
933 if (he->type & D_INTERNAL_INHERITED)
934 {
935 struct Inheritance *i = he->data;
936 struct HashElem *he_base = cs_get_base(he);
937 cdef = he_base->data;
938 cst = cs_get_type_def(cs, he_base->type);
939 var = &i->var;
940 }
941 else
942 {
943 cdef = he->data;
944 cst = cs_get_type_def(cs, he->type);
945 var = &cdef->var;
946 }
947
948 if (!var || !cdef)
949 return INT_MIN; // LCOV_EXCL_LINE
950
951 if (!cst)
952 {
953 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
954 return CSR_ERR_CODE;
955 }
956
957 if (!cst->string_minus_equals)
958 {
959 // L10N: e.g. Type 'boolean' doesn't support operation '+='
960 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "-=");
962 }
963
964 int rc = cst->string_minus_equals(cs, var, cdef, value, err);
965 if (CSR_RESULT(rc) != CSR_SUCCESS)
966 return rc;
967
968 if (he->type & D_INTERNAL_INHERITED)
969 he->type = cdef->type | D_INTERNAL_INHERITED;
970
971 return rc;
972}
973
981int cs_he_delete(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
982{
983 if (!cs || !he)
984 return CSR_ERR_CODE;
985
986 mutt_hash_delete(cs->hash, he->key.strkey, he->data);
987 return CSR_SUCCESS;
988}
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:565
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:503
int cs_he_string_plus_equals(const struct ConfigSet *cs, struct HashElem *he, const char *value, struct Buffer *err)
Add to a config item by string.
Definition: set.c:864
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:438
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:318
int cs_he_reset(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
Reset a config item to its initial value.
Definition: set.c:391
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:981
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:640
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:588
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:760
struct HashElem * cs_get_base(struct HashElem *he)
Find the root Config Item.
Definition: set.c:160
int cs_he_native_set(const struct ConfigSet *cs, struct HashElem *he, intptr_t value, struct Buffer *err)
Natively set the value of a HashElem config item.
Definition: set.c:708
intptr_t cs_he_native_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
Natively get the value of a HashElem config item.
Definition: set.c:813
struct HashElem * cs_inherit_variable(const struct ConfigSet *cs, struct HashElem *he_parent, const char *name)
Create in inherited config item.
Definition: set.c:347
bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[])
Register a set of config items.
Definition: set.c:281
int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
Get a config item as a string.
Definition: set.c:663
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:461
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:529
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:923
void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
Remove an inherited config item.
Definition: set.c:376
#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:109
An inherited config item.
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
#define FREE(x)
Definition: memory.h:45
#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:253
Parse the 'set' command.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
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:85
int(* validator)(const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition: set.h:82
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:84
int(* string_get)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *result)
Definition: set.h:136
int type
Data type, e.g. DT_STRING.
Definition: set.h:97
int(* native_set)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition: set.h:154
int(* string_set)(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition: set.h:117
int(* string_plus_equals)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition: set.h:190
int(* string_minus_equals)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition: set.h:208
int(* reset)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Definition: set.h:225
void(* destroy)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
Definition: set.h:240
intptr_t(* native_get)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Definition: set.h:172
const char * name
Name of the type, e.g. "String".
Definition: set.h:98
Container for lots of config items.
Definition: set.h:252
struct ConfigSetType types[18]
All the defined config types.
Definition: set.h:254
struct HashTable * hash
Hash Table: "$name" -> ConfigDef.
Definition: set.h:253
The item stored in a Hash Table.
Definition: hash.h:43
union HashKey key
Key representing the data.
Definition: hash.h:45
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:44
void * data
User-supplied data.
Definition: hash.h:46
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 DTYPE(t)
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:46
@ DT_MYVAR
a user-defined variable (my_foo)
Definition: types.h:38
const char * strkey
String key.
Definition: hash.h:35