NeoMutt  2023-11-03-107-g582dc1
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
set.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <limits.h>
31#include <stdio.h>
32#include "mutt/lib.h"
33#include "set.h"
34#include "inheritance.h"
35#include "types.h"
36
43static void cs_hashelem_free(int type, void *obj, intptr_t data)
44{
45 if (data == 0)
46 return; /* LCOV_EXCL_LINE */
47
48 struct ConfigSet *cs = (struct ConfigSet *) data;
49
50 const struct ConfigSetType *cst = NULL;
51
52 if (type & DT_INHERITED)
53 {
54 struct Inheritance *i = obj;
55
56 struct HashElem *he_base = cs_get_base(i->parent);
57 struct ConfigDef *cdef = he_base->data;
58
59 if (!cdef)
60 return; // LCOV_EXCL_LINE
61
62 cst = cs_get_type_def(cs, he_base->type);
63 if (cst && cst->destroy)
64 cst->destroy(cs, (void **) &i->var, cdef);
65
66 FREE(&i->name);
67 FREE(&i);
68 }
69 else
70 {
71 struct ConfigDef *cdef = obj;
72
73 cst = cs_get_type_def(cs, type);
74 if (cst && cst->destroy)
75 cst->destroy(cs, &cdef->var, cdef);
76
77 /* If we allocated the initial value, clean it up */
78 if (cdef->type & DT_INITIAL_SET)
79 FREE(&cdef->initial);
80 if (cdef->type & DT_FREE_CONFIGDEF)
81 {
82 FREE(&cdef->name);
83 FREE(&cdef->docs);
84 FREE(&cdef);
85 }
86 }
87}
88
96static struct HashElem *create_synonym(const struct ConfigSet *cs,
97 struct ConfigDef *cdef, struct Buffer *err)
98{
99 if (!cs || !cdef)
100 return NULL; /* LCOV_EXCL_LINE */
101
102 const char *name = (const char *) cdef->initial;
103 struct HashElem *he_parent = cs_get_elem(cs, name);
104 if (!he_parent)
105 {
106 buf_printf(err, _("No such variable: %s"), name);
107 return NULL;
108 }
109
110 struct HashElem *he_child = mutt_hash_typed_insert(cs->hash, cdef->name,
111 cdef->type, (void *) cdef);
112 if (!he_child)
113 return NULL; /* LCOV_EXCL_LINE */
114
115 cdef->var = (intptr_t) he_parent;
116 return he_child;
117}
118
124struct ConfigSet *cs_new(size_t size)
125{
126 struct ConfigSet *cs = mutt_mem_calloc(1, sizeof(*cs));
127
130
131 return cs;
132}
133
138void cs_free(struct ConfigSet **ptr)
139{
140 if (!ptr || !*ptr)
141 return;
142
143 struct ConfigSet *cs = *ptr;
144
145 mutt_hash_free(&cs->hash);
146 FREE(ptr);
147}
148
157struct HashElem *cs_get_base(struct HashElem *he)
158{
159 if (!(he->type & DT_INHERITED))
160 return he;
161
162 struct Inheritance *i = he->data;
163 return cs_get_base(i->parent);
164}
165
172struct HashElem *cs_get_elem(const struct ConfigSet *cs, const char *name)
173{
174 if (!cs || !name)
175 return NULL;
176
177 struct HashElem *he = mutt_hash_find_elem(cs->hash, name);
178 if (!he)
179 return NULL;
180
181 if (DTYPE(he->type) != DT_SYNONYM)
182 return he;
183
184 const struct ConfigDef *cdef = he->data;
185
186 return (struct HashElem *) cdef->var;
187}
188
195const struct ConfigSetType *cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
196{
197 if (!cs)
198 return NULL;
199
200 type = DTYPE(type);
201 if (type >= mutt_array_size(cs->types))
202 return NULL;
203
204 if (!cs->types[type].name)
205 return NULL;
206
207 return &cs->types[type];
208}
209
216bool cs_register_type(struct ConfigSet *cs, const struct ConfigSetType *cst)
217{
218 if (!cs || !cst)
219 return false;
220
221 if (!cst->name || !cst->string_set || !cst->string_get || !cst->reset ||
222 !cst->native_set || !cst->native_get)
223 {
224 return false;
225 }
226
227 if (cst->type >= mutt_array_size(cs->types))
228 return false;
229
230 if (cs->types[cst->type].name)
231 return false; /* already registered */
232
233 cs->types[cst->type] = *cst;
234 return true;
235}
236
246struct HashElem *cs_register_variable(const struct ConfigSet *cs,
247 struct ConfigDef *cdef, struct Buffer *err)
248{
249 if (!cs || !cdef)
250 return NULL; /* LCOV_EXCL_LINE */
251
252 if (DTYPE(cdef->type) == DT_SYNONYM)
253 return create_synonym(cs, cdef, err);
254
255 const struct ConfigSetType *cst = cs_get_type_def(cs, cdef->type);
256 if (!cst)
257 {
258 buf_printf(err, _("Variable '%s' has an invalid type %d"), cdef->name, cdef->type);
259 return NULL;
260 }
261
262 struct HashElem *he = mutt_hash_typed_insert(cs->hash, cdef->name, cdef->type, cdef);
263 if (!he)
264 return NULL; /* LCOV_EXCL_LINE */
265
266 if (cst->reset)
267 cst->reset(cs, &cdef->var, cdef, err);
268
269 return he;
270}
271
279bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], uint32_t flags)
280{
281 if (!cs || !vars)
282 return false;
283
284 struct Buffer *err = buf_pool_get();
285
286 bool rc = true;
287
288 for (size_t i = 0; vars[i].name; i++)
289 {
290 vars[i].type |= flags;
291 if (!cs_register_variable(cs, &vars[i], err))
292 {
293 mutt_debug(LL_DEBUG1, "%s\n", buf_string(err));
294 rc = false;
295 }
296 }
297
298 buf_pool_release(&err);
299 return rc;
300}
301
317struct HashElem *cs_create_variable(const struct ConfigSet *cs,
318 struct ConfigDef *cdef, struct Buffer *err)
319{
320 struct ConfigDef *cdef_copy = mutt_mem_calloc(1, sizeof(struct ConfigDef));
321 cdef_copy->name = mutt_str_dup(cdef->name);
322 cdef_copy->type = cdef->type | DT_FREE_CONFIGDEF;
323 cdef_copy->initial = cdef->initial;
324 cdef_copy->data = cdef->data;
325 cdef_copy->validator = cdef->validator;
326 cdef_copy->docs = mutt_str_dup(cdef->name);
327 cdef_copy->var = cdef->var;
328
329 struct HashElem *he = cs_register_variable(cs, cdef_copy, err);
330 if (!he)
331 {
332 FREE(&cdef_copy->name);
333 FREE(&cdef_copy->docs);
334 FREE(&cdef_copy);
335 }
336 return he;
337}
338
346struct HashElem *cs_inherit_variable(const struct ConfigSet *cs,
347 struct HashElem *he_parent, const char *name)
348{
349 if (!cs || !he_parent)
350 return NULL;
351
352 /* MyVars cannot be inherited, as they might get deleted */
353 if (DTYPE(he_parent->type) == DT_MYVAR)
354 return NULL;
355
356 struct Inheritance *i = mutt_mem_calloc(1, sizeof(*i));
357 i->parent = he_parent;
358 i->name = mutt_str_dup(name);
359
360 struct HashElem *he = mutt_hash_typed_insert(cs->hash, i->name, DT_INHERITED, i);
361 if (!he)
362 {
363 FREE(&i->name);
364 FREE(&i);
365 }
366
367 return he;
368}
369
375void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
376{
377 if (!cs || !name)
378 return;
379
380 mutt_hash_delete(cs->hash, name, NULL);
381}
382
390int cs_he_reset(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
391{
392 if (!cs || !he)
393 return CSR_ERR_CODE;
394
395 /* An inherited var that's already pointing to its parent.
396 * Return 'success', but don't send a notification. */
397 if ((he->type & DT_INHERITED) && (DTYPE(he->type) == 0))
398 return CSR_SUCCESS;
399
400 int rc = CSR_SUCCESS;
401
402 if (he->type & DT_INHERITED)
403 {
404 struct Inheritance *i = he->data;
405 struct HashElem *he_base = cs_get_base(he);
406 struct ConfigDef *cdef = he_base->data;
407 if (!cdef)
408 return CSR_ERR_CODE; // LCOV_EXCL_LINE
409
410 const struct ConfigSetType *cst = cs_get_type_def(cs, he_base->type);
411 if (cst && cst->destroy)
412 cst->destroy(cs, (void **) &i->var, cdef);
413
414 he->type = DT_INHERITED;
415 }
416 else
417 {
418 struct ConfigDef *cdef = he->data;
419 if (!cdef)
420 return CSR_ERR_CODE; // LCOV_EXCL_LINE
421
422 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
423 if (cst)
424 rc = cst->reset(cs, &cdef->var, cdef, err);
425 }
426
427 return rc;
428}
429
437int cs_str_reset(const struct ConfigSet *cs, const char *name, struct Buffer *err)
438{
439 if (!cs || !name)
440 return CSR_ERR_CODE;
441
442 struct HashElem *he = cs_get_elem(cs, name);
443 if (!he)
444 {
445 buf_printf(err, _("Unknown variable '%s'"), name);
446 return CSR_ERR_UNKNOWN;
447 }
448
449 return cs_he_reset(cs, he, err);
450}
451
460int cs_he_initial_set(const struct ConfigSet *cs, struct HashElem *he,
461 const char *value, struct Buffer *err)
462{
463 if (!cs || !he)
464 return CSR_ERR_CODE;
465
466 struct ConfigDef *cdef = NULL;
467
468 if (he->type & DT_INHERITED)
469 {
470 struct HashElem *he_base = cs_get_base(he);
471 cdef = he_base->data;
472 mutt_debug(LL_DEBUG1, "Variable '%s' is inherited type\n", cdef->name);
473 return CSR_ERR_CODE;
474 }
475
476 cdef = he->data;
477 if (!cdef)
478 return CSR_ERR_CODE; // LCOV_EXCL_LINE
479
480 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
481 if (!cst)
482 {
483 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
484 return CSR_ERR_CODE;
485 }
486
487 int rc = cst->string_set(cs, NULL, cdef, value, err);
488 if (CSR_RESULT(rc) != CSR_SUCCESS)
489 return rc;
490
491 return CSR_SUCCESS;
492}
493
502int cs_str_initial_set(const struct ConfigSet *cs, const char *name,
503 const char *value, struct Buffer *err)
504{
505 if (!cs || !name)
506 return CSR_ERR_CODE;
507
508 struct HashElem *he = cs_get_elem(cs, name);
509 if (!he)
510 {
511 buf_printf(err, _("Unknown variable '%s'"), name);
512 return CSR_ERR_UNKNOWN;
513 }
514
515 return cs_he_initial_set(cs, he, value, err);
516}
517
528int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
529{
530 if (!cs || !he || !result)
531 return CSR_ERR_CODE;
532
533 const struct ConfigDef *cdef = NULL;
534 const struct ConfigSetType *cst = NULL;
535
536 if (he->type & DT_INHERITED)
537 {
538 struct HashElem *he_base = cs_get_base(he);
539 cdef = he_base->data;
540 cst = cs_get_type_def(cs, he_base->type);
541 }
542 else
543 {
544 cdef = he->data;
545 cst = cs_get_type_def(cs, he->type);
546 }
547
548 if (!cst)
549 return CSR_ERR_CODE; // LCOV_EXCL_LINE
550
551 return cst->string_get(cs, NULL, cdef, result);
552}
553
564int cs_str_initial_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
565{
566 if (!cs || !name)
567 return CSR_ERR_CODE;
568
569 struct HashElem *he = cs_get_elem(cs, name);
570 if (!he)
571 {
572 buf_printf(result, _("Unknown variable '%s'"), name);
573 return CSR_ERR_UNKNOWN;
574 }
575
576 return cs_he_initial_get(cs, he, result);
577}
578
587int cs_he_string_set(const struct ConfigSet *cs, struct HashElem *he,
588 const char *value, struct Buffer *err)
589{
590 if (!cs || !he)
591 return CSR_ERR_CODE;
592
593 struct ConfigDef *cdef = NULL;
594 const struct ConfigSetType *cst = NULL;
595 void *var = NULL;
596
597 if (he->type & DT_INHERITED)
598 {
599 struct Inheritance *i = he->data;
600 struct HashElem *he_base = cs_get_base(he);
601 cdef = he_base->data;
602 cst = cs_get_type_def(cs, he_base->type);
603 var = &i->var;
604 }
605 else
606 {
607 cdef = he->data;
608 cst = cs_get_type_def(cs, he->type);
609 var = &cdef->var;
610 }
611
612 if (!cdef)
613 return CSR_ERR_CODE; // LCOV_EXCL_LINE
614
615 if (!cst)
616 {
617 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
618 return CSR_ERR_CODE;
619 }
620
621 int rc = cst->string_set(cs, var, cdef, value, err);
622 if (CSR_RESULT(rc) != CSR_SUCCESS)
623 return rc;
624
625 if (he->type & DT_INHERITED)
626 he->type = cdef->type | DT_INHERITED;
627
628 return rc;
629}
630
639int cs_str_string_set(const struct ConfigSet *cs, const char *name,
640 const char *value, struct Buffer *err)
641{
642 if (!cs || !name)
643 return CSR_ERR_CODE;
644
645 struct HashElem *he = cs_get_elem(cs, name);
646 if (!he)
647 {
648 buf_printf(err, _("Unknown variable '%s'"), name);
649 return CSR_ERR_UNKNOWN;
650 }
651
652 return cs_he_string_set(cs, he, value, err);
653}
654
662int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
663{
664 if (!cs || !he || !result)
665 return CSR_ERR_CODE;
666
667 struct ConfigDef *cdef = NULL;
668 const struct ConfigSetType *cst = NULL;
669 void *var = NULL;
670
671 if (he->type & DT_INHERITED)
672 {
673 struct Inheritance *i = he->data;
674
675 // inherited, value not set
676 if (DTYPE(he->type) == 0)
677 return cs_he_string_get(cs, i->parent, result);
678
679 // inherited, value set
680 struct HashElem *he_base = cs_get_base(he);
681 cdef = he_base->data;
682 cst = cs_get_type_def(cs, he_base->type);
683 var = &i->var;
684 }
685 else
686 {
687 // not inherited
688 cdef = he->data;
689 cst = cs_get_type_def(cs, he->type);
690 var = &cdef->var;
691 }
692
693 if (!cdef || !cst)
694 return CSR_ERR_CODE; // LCOV_EXCL_LINE
695
696 return cst->string_get(cs, var, cdef, result);
697}
698
706int cs_str_string_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
707{
708 if (!cs || !name)
709 return CSR_ERR_CODE;
710
711 struct HashElem *he = cs_get_elem(cs, name);
712 if (!he)
713 {
714 buf_printf(result, _("Unknown variable '%s'"), name);
715 return CSR_ERR_UNKNOWN;
716 }
717
718 return cs_he_string_get(cs, he, result);
719}
720
729int cs_he_native_set(const struct ConfigSet *cs, struct HashElem *he,
730 intptr_t value, struct Buffer *err)
731{
732 if (!cs || !he)
733 return CSR_ERR_CODE;
734
735 struct ConfigDef *cdef = NULL;
736 const struct ConfigSetType *cst = NULL;
737 void *var = NULL;
738
739 if (he->type & DT_INHERITED)
740 {
741 struct Inheritance *i = he->data;
742 struct HashElem *he_base = cs_get_base(he);
743 cdef = he_base->data;
744 cst = cs_get_type_def(cs, he_base->type);
745 var = &i->var;
746 }
747 else
748 {
749 cdef = he->data;
750 cst = cs_get_type_def(cs, he->type);
751 var = &cdef->var;
752 }
753
754 if (!cst)
755 {
756 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
757 return CSR_ERR_CODE;
758 }
759
760 if (!var || !cdef)
761 return CSR_ERR_CODE; // LCOV_EXCL_LINE
762
763 int rc = cst->native_set(cs, var, cdef, value, err);
764 if (CSR_RESULT(rc) != CSR_SUCCESS)
765 return rc;
766
767 if (he->type & DT_INHERITED)
768 he->type = cdef->type | DT_INHERITED;
769
770 return rc;
771}
772
781int cs_str_native_set(const struct ConfigSet *cs, const char *name,
782 intptr_t value, struct Buffer *err)
783{
784 if (!cs || !name)
785 return CSR_ERR_CODE;
786
787 struct HashElem *he = cs_get_elem(cs, name);
788 if (!he)
789 {
790 buf_printf(err, _("Unknown variable '%s'"), name);
791 return CSR_ERR_UNKNOWN;
792 }
793
794 struct ConfigDef *cdef = NULL;
795 const struct ConfigSetType *cst = NULL;
796 void *var = NULL;
797
798 if (he->type & DT_INHERITED)
799 {
800 struct Inheritance *i = he->data;
801 struct HashElem *he_base = cs_get_base(he);
802 cdef = he_base->data;
803 cst = cs_get_type_def(cs, he_base->type);
804 var = &i->var;
805 }
806 else
807 {
808 cdef = he->data;
809 cst = cs_get_type_def(cs, he->type);
810 var = &cdef->var;
811 }
812
813 if (!cst || !var || !cdef)
814 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
815
816 int rc = cst->native_set(cs, var, cdef, value, err);
817 if (CSR_RESULT(rc) != CSR_SUCCESS)
818 return rc;
819
820 if (he->type & DT_INHERITED)
821 he->type = cdef->type | DT_INHERITED;
822
823 return rc;
824}
825
834intptr_t cs_he_native_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
835{
836 if (!cs || !he)
837 return INT_MIN;
838
839 struct ConfigDef *cdef = NULL;
840 const struct ConfigSetType *cst = NULL;
841 void *var = NULL;
842
843 if (he->type & DT_INHERITED)
844 {
845 struct Inheritance *i = he->data;
846
847 // inherited, value not set
848 if (DTYPE(he->type) == 0)
849 return cs_he_native_get(cs, i->parent, err);
850
851 // inherited, value set
852 struct HashElem *he_base = cs_get_base(he);
853 cdef = he_base->data;
854 cst = cs_get_type_def(cs, he_base->type);
855 var = &i->var;
856 }
857 else
858 {
859 // not inherited
860 cdef = he->data;
861 cst = cs_get_type_def(cs, he->type);
862 var = &cdef->var;
863 }
864
865 if (!var || !cdef)
866 return INT_MIN; // LCOV_EXCL_LINE
867
868 if (!cst)
869 {
870 buf_printf(err, _("Variable '%s' has an invalid type %d"), cdef->name, he->type);
871 return INT_MIN;
872 }
873
874 return cst->native_get(cs, var, cdef, err);
875}
876
885intptr_t cs_str_native_get(const struct ConfigSet *cs, const char *name, struct Buffer *err)
886{
887 if (!cs || !name)
888 return INT_MIN;
889
890 struct HashElem *he = cs_get_elem(cs, name);
891 return cs_he_native_get(cs, he, err);
892}
893
902int cs_he_string_plus_equals(const struct ConfigSet *cs, struct HashElem *he,
903 const char *value, struct Buffer *err)
904{
905 if (!cs || !he)
906 return CSR_ERR_CODE;
907
908 struct ConfigDef *cdef = NULL;
909 const struct ConfigSetType *cst = NULL;
910 void *var = NULL;
911
912 if (he->type & DT_INHERITED)
913 {
914 struct Inheritance *i = he->data;
915 struct HashElem *he_base = cs_get_base(he);
916 cdef = he_base->data;
917 cst = cs_get_type_def(cs, he_base->type);
918 var = &i->var;
919 }
920 else
921 {
922 cdef = he->data;
923 cst = cs_get_type_def(cs, he->type);
924 var = &cdef->var;
925 }
926
927 if (!var || !cdef)
928 return INT_MIN; // LCOV_EXCL_LINE
929
930 if (!cst)
931 {
932 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
933 return CSR_ERR_CODE;
934 }
935
936 if (!cst->string_plus_equals)
937 {
938 // L10N: e.g. Type 'boolean' doesn't support operation '+='
939 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "+=");
941 }
942
943 int rc = cst->string_plus_equals(cs, var, cdef, value, err);
944 if (CSR_RESULT(rc) != CSR_SUCCESS)
945 return rc;
946
947 if (he->type & DT_INHERITED)
948 he->type = cdef->type | DT_INHERITED;
949
950 return rc;
951}
952
961int cs_str_string_plus_equals(const struct ConfigSet *cs, const char *name,
962 const char *value, struct Buffer *err)
963{
964 if (!cs || !name)
965 return CSR_ERR_CODE;
966
967 struct HashElem *he = cs_get_elem(cs, name);
968 if (!he)
969 {
970 buf_printf(err, _("Unknown variable '%s'"), name);
971 return CSR_ERR_UNKNOWN;
972 }
973
974 return cs_he_string_plus_equals(cs, he, value, err);
975}
976
985int cs_he_string_minus_equals(const struct ConfigSet *cs, struct HashElem *he,
986 const char *value, struct Buffer *err)
987{
988 if (!cs || !he)
989 return CSR_ERR_CODE;
990
991 struct ConfigDef *cdef = NULL;
992 const struct ConfigSetType *cst = NULL;
993 void *var = NULL;
994
995 if (he->type & DT_INHERITED)
996 {
997 struct Inheritance *i = he->data;
998 struct HashElem *he_base = cs_get_base(he);
999 cdef = he_base->data;
1000 cst = cs_get_type_def(cs, he_base->type);
1001 var = &i->var;
1002 }
1003 else
1004 {
1005 cdef = he->data;
1006 cst = cs_get_type_def(cs, he->type);
1007 var = &cdef->var;
1008 }
1009
1010 if (!var || !cdef)
1011 return INT_MIN; // LCOV_EXCL_LINE
1012
1013 if (!cst)
1014 {
1015 mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
1016 return CSR_ERR_CODE;
1017 }
1018
1019 if (!cst->string_minus_equals)
1020 {
1021 // L10N: e.g. Type 'boolean' doesn't support operation '+='
1022 buf_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "-=");
1024 }
1025
1026 int rc = cst->string_minus_equals(cs, var, cdef, value, err);
1027 if (CSR_RESULT(rc) != CSR_SUCCESS)
1028 return rc;
1029
1030 if (he->type & DT_INHERITED)
1031 he->type = cdef->type | DT_INHERITED;
1032
1033 return rc;
1034}
1035
1044int cs_str_string_minus_equals(const struct ConfigSet *cs, const char *name,
1045 const char *value, struct Buffer *err)
1046{
1047 if (!cs || !name)
1048 return CSR_ERR_CODE;
1049
1050 struct HashElem *he = cs_get_elem(cs, name);
1051 if (!he)
1052 {
1053 buf_printf(err, _("Unknown variable '%s'"), name);
1054 return CSR_ERR_UNKNOWN;
1055 }
1056
1057 return cs_he_string_minus_equals(cs, he, value, err);
1058}
1059
1067int cs_he_delete(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
1068{
1069 if (!cs || !he)
1070 return CSR_ERR_CODE;
1071
1072 mutt_hash_delete(cs->hash, he->key.strkey, he->data);
1073 return CSR_SUCCESS;
1074}
1075
1083int cs_str_delete(const struct ConfigSet *cs, const char *name, struct Buffer *err)
1084{
1085 if (!cs || !name)
1086 return CSR_ERR_CODE;
1087
1088 struct HashElem *he = cs_get_elem(cs, name);
1089 if (!he)
1090 {
1091 buf_printf(err, _("Unknown variable '%s'"), name);
1092 return CSR_ERR_UNKNOWN;
1093 }
1094
1095 return cs_he_delete(cs, he, err);
1096}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:173
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:93
bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], uint32_t flags)
Register a set of config items.
Definition: set.c:279
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:564
struct HashElem * cs_get_elem(const struct ConfigSet *cs, const char *name)
Get the HashElem representing a config item.
Definition: set.c:172
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:502
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:902
void cs_free(struct ConfigSet **ptr)
Free a Config Set.
Definition: set.c:138
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:437
struct ConfigSet * cs_new(size_t size)
Create a new Config Set.
Definition: set.c:124
struct HashElem * cs_create_variable(const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err)
Create and register one config item.
Definition: set.c:317
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:390
const struct ConfigSetType * cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
Get the definition for a type.
Definition: set.c:195
int cs_he_delete(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
Delete config item from a config set.
Definition: set.c:1067
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:639
int cs_str_delete(const struct ConfigSet *cs, const char *name, struct Buffer *err)
Delete config item from a config set.
Definition: set.c:1083
int cs_str_string_plus_equals(const struct ConfigSet *cs, const char *name, const char *value, struct Buffer *err)
Add to a config item by string.
Definition: set.c:961
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:96
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:587
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:781
int cs_str_string_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
Get a config item as a string.
Definition: set.c:706
struct HashElem * cs_get_base(struct HashElem *he)
Find the root Config Item.
Definition: set.c:157
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:729
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:834
struct HashElem * cs_inherit_variable(const struct ConfigSet *cs, struct HashElem *he_parent, const char *name)
Create in inherited config item.
Definition: set.c:346
intptr_t cs_str_native_get(const struct ConfigSet *cs, const char *name, struct Buffer *err)
Natively get the value of a string config item.
Definition: set.c:885
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:662
struct HashElem * cs_register_variable(const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err)
Register one config item.
Definition: set.c:246
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:460
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:528
bool cs_register_type(struct ConfigSet *cs, const struct ConfigSetType *cst)
Register a type of config item.
Definition: set.c:216
int cs_str_string_minus_equals(const struct ConfigSet *cs, const char *name, const char *value, struct Buffer *err)
Remove from a config item by string.
Definition: set.c:1044
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:985
void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
Remove an inherited config item.
Definition: set.c:375
#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:43
#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:110
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:50
#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:251
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:34
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: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 DTYPE(x)
Mask for the Data Type.
Definition: types.h:45
#define DT_INITIAL_SET
Config item must have its initial value freed.
Definition: types.h:80
#define DT_MYVAR
a user-defined variable (my_foo)
Definition: types.h:43
#define DT_SYNONYM
synonym for another variable
Definition: types.h:42
#define DT_INHERITED
Config item is inherited.
Definition: types.h:79
#define DT_FREE_CONFIGDEF
Config item must have its ConfigDef freed.
Definition: types.h:77
const char * strkey
String key.
Definition: hash.h:36