NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
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 
37 struct ConfigSetType RegisteredTypes[18] = {
38  { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
39 };
40 
47 static 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 
56  if (type & DT_INHERITED)
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(cs, (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(cs, &cdef->var, cdef);
80 
81  /* If we allocated the initial value, clean it up */
82  if (cdef->type & DT_INITIAL_SET)
83  FREE(&cdef->initial);
84  }
85 }
86 
94 static struct HashElem *create_synonym(const struct ConfigSet *cs,
95  struct ConfigDef *cdef, struct Buffer *err)
96 {
97  if (!cs || !cdef)
98  return NULL; /* LCOV_EXCL_LINE */
99 
100  const char *name = (const char *) cdef->initial;
101  struct HashElem *parent = cs_get_elem(cs, name);
102  if (!parent)
103  {
104  mutt_buffer_printf(err, _("No such variable: %s"), name);
105  return NULL;
106  }
107 
108  struct HashElem *child =
109  mutt_hash_typed_insert(cs->hash, cdef->name, cdef->type, (void *) cdef);
110  if (!child)
111  return NULL; /* LCOV_EXCL_LINE */
112 
113  cdef->var = (intptr_t) parent;
114  return child;
115 }
116 
124 static struct HashElem *reg_one_var(const struct ConfigSet *cs,
125  struct ConfigDef *cdef, struct Buffer *err)
126 {
127  if (!cs || !cdef)
128  return NULL; /* LCOV_EXCL_LINE */
129 
130  if (DTYPE(cdef->type) == DT_SYNONYM)
131  return create_synonym(cs, cdef, err);
132 
133  const struct ConfigSetType *cst = cs_get_type_def(cs, cdef->type);
134  if (!cst)
135  {
136  mutt_buffer_printf(err, _("Variable '%s' has an invalid type %d"),
137  cdef->name, cdef->type);
138  return NULL;
139  }
140 
141  struct HashElem *he = mutt_hash_typed_insert(cs->hash, cdef->name, cdef->type, cdef);
142  if (!he)
143  return NULL; /* LCOV_EXCL_LINE */
144 
145  if (cst && cst->reset)
146  cst->reset(cs, &cdef->var, cdef, err);
147 
148  return he;
149 }
150 
156 struct ConfigSet *cs_new(size_t size)
157 {
158  struct ConfigSet *cs = mutt_mem_calloc(1, sizeof(*cs));
159 
161  mutt_hash_set_destructor(cs->hash, cs_hashelem_free, (intptr_t) cs);
162 
163  return cs;
164 }
165 
170 void cs_free(struct ConfigSet **ptr)
171 {
172  if (!ptr || !*ptr)
173  return;
174 
175  struct ConfigSet *cs = *ptr;
176 
177  mutt_hash_free(&cs->hash);
178  FREE(ptr);
179 }
180 
189 struct HashElem *cs_get_base(struct HashElem *he)
190 {
191  if (!(he->type & DT_INHERITED))
192  return he;
193 
194  struct Inheritance *i = he->data;
195  return cs_get_base(i->parent);
196 }
197 
204 struct HashElem *cs_get_elem(const struct ConfigSet *cs, const char *name)
205 {
206  if (!cs || !name)
207  return NULL;
208 
209  struct HashElem *he = mutt_hash_find_elem(cs->hash, name);
210  if (!he)
211  return NULL;
212 
213  if (DTYPE(he->type) != DT_SYNONYM)
214  return he;
215 
216  const struct ConfigDef *cdef = he->data;
217 
218  return (struct HashElem *) cdef->var;
219 }
220 
227 const struct ConfigSetType *cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
228 {
229  if (!cs)
230  return NULL;
231 
232  type = DTYPE(type);
233  if ((type < 1) || (type >= mutt_array_size(cs->types)))
234  return NULL;
235 
236  if (!cs->types[type].name)
237  return NULL;
238 
239  return &cs->types[type];
240 }
241 
248 bool cs_register_type(struct ConfigSet *cs, const struct ConfigSetType *cst)
249 {
250  if (!cs || !cst)
251  return false;
252 
253  if (!cst->name || !cst->string_set || !cst->string_get || !cst->reset ||
254  !cst->native_set || !cst->native_get)
255  {
256  return false;
257  }
258 
259  if (cst->type >= mutt_array_size(cs->types))
260  return false;
261 
262  if (cs->types[cst->type].name)
263  return false; /* already registered */
264 
265  cs->types[cst->type] = *cst;
266  return true;
267 }
268 
276 bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], uint32_t flags)
277 {
278  if (!cs || !vars)
279  return false;
280 
281  struct Buffer err = mutt_buffer_make(0);
282 
283  bool rc = true;
284 
285  for (size_t i = 0; vars[i].name; i++)
286  {
287  vars[i].type |= flags;
288  if (!reg_one_var(cs, &vars[i], &err))
289  {
290  mutt_debug(LL_DEBUG1, "%s\n", mutt_buffer_string(&err));
291  rc = false;
292  }
293  }
294 
295  mutt_buffer_dealloc(&err);
296  return rc;
297 }
298 
306 struct HashElem *cs_inherit_variable(const struct ConfigSet *cs,
307  struct HashElem *parent, const char *name)
308 {
309  if (!cs || !parent)
310  return NULL;
311 
312  struct Inheritance *i = mutt_mem_calloc(1, sizeof(*i));
313  i->parent = parent;
314  i->name = mutt_str_dup(name);
315 
316  struct HashElem *he = mutt_hash_typed_insert(cs->hash, i->name, DT_INHERITED, i);
317  if (!he)
318  {
319  FREE(&i->name);
320  FREE(&i);
321  }
322 
323  return he;
324 }
325 
331 void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
332 {
333  if (!cs || !name)
334  return;
335 
336  mutt_hash_delete(cs->hash, name, NULL);
337 }
338 
346 int cs_he_reset(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
347 {
348  if (!cs || !he)
349  return CSR_ERR_CODE;
350 
351  /* An inherited var that's already pointing to its parent.
352  * Return 'success', but don't send a notification. */
353  if ((he->type & DT_INHERITED) && (DTYPE(he->type) == 0))
354  return CSR_SUCCESS;
355 
356  int rc = CSR_SUCCESS;
357 
358  if (he->type & DT_INHERITED)
359  {
360  struct Inheritance *i = he->data;
361  struct HashElem *he_base = cs_get_base(he);
362  struct ConfigDef *cdef = he_base->data;
363  if (!cdef)
364  return CSR_ERR_CODE; // LCOV_EXCL_LINE
365 
366  const struct ConfigSetType *cst = cs_get_type_def(cs, he_base->type);
367  if (cst && cst->destroy)
368  cst->destroy(cs, (void **) &i->var, cdef);
369 
370  he->type = DT_INHERITED;
371  }
372  else
373  {
374  struct ConfigDef *cdef = he->data;
375  if (!cdef)
376  return CSR_ERR_CODE; // LCOV_EXCL_LINE
377 
378  const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
379  if (cst)
380  rc = cst->reset(cs, &cdef->var, cdef, err);
381  }
382 
383  return rc;
384 }
385 
393 int cs_str_reset(const struct ConfigSet *cs, const char *name, struct Buffer *err)
394 {
395  if (!cs || !name)
396  return CSR_ERR_CODE;
397 
398  struct HashElem *he = cs_get_elem(cs, name);
399  if (!he)
400  {
401  mutt_buffer_printf(err, _("Unknown variable '%s'"), name);
402  return CSR_ERR_UNKNOWN;
403  }
404 
405  return cs_he_reset(cs, he, err);
406 }
407 
416 int cs_he_initial_set(const struct ConfigSet *cs, struct HashElem *he,
417  const char *value, struct Buffer *err)
418 {
419  if (!cs || !he)
420  return CSR_ERR_CODE;
421 
422  struct ConfigDef *cdef = NULL;
423 
424  if (he->type & DT_INHERITED)
425  {
426  struct HashElem *he_base = cs_get_base(he);
427  cdef = he_base->data;
428  mutt_debug(LL_DEBUG1, "Variable '%s' is inherited type\n", cdef->name);
429  return CSR_ERR_CODE;
430  }
431 
432  cdef = he->data;
433  if (!cdef)
434  return CSR_ERR_CODE; // LCOV_EXCL_LINE
435 
436  const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
437  if (!cst)
438  {
439  mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
440  return CSR_ERR_CODE;
441  }
442 
443  int rc = cst->string_set(cs, NULL, cdef, value, err);
444  if (CSR_RESULT(rc) != CSR_SUCCESS)
445  return rc;
446 
447  return CSR_SUCCESS;
448 }
449 
458 int cs_str_initial_set(const struct ConfigSet *cs, const char *name,
459  const char *value, struct Buffer *err)
460 {
461  if (!cs || !name)
462  return CSR_ERR_CODE;
463 
464  struct HashElem *he = cs_get_elem(cs, name);
465  if (!he)
466  {
467  mutt_buffer_printf(err, _("Unknown variable '%s'"), name);
468  return CSR_ERR_UNKNOWN;
469  }
470 
471  return cs_he_initial_set(cs, he, value, err);
472 }
473 
484 int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
485 {
486  if (!cs || !he || !result)
487  return CSR_ERR_CODE;
488 
489  const struct ConfigDef *cdef = NULL;
490  const struct ConfigSetType *cst = NULL;
491 
492  if (he->type & DT_INHERITED)
493  {
494  struct HashElem *he_base = cs_get_base(he);
495  cdef = he_base->data;
496  cst = cs_get_type_def(cs, he_base->type);
497  }
498  else
499  {
500  cdef = he->data;
501  cst = cs_get_type_def(cs, he->type);
502  }
503 
504  if (!cst)
505  return CSR_ERR_CODE; // LCOV_EXCL_LINE
506 
507  return cst->string_get(cs, NULL, cdef, result);
508 }
509 
520 int cs_str_initial_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
521 {
522  if (!cs || !name)
523  return CSR_ERR_CODE;
524 
525  struct HashElem *he = cs_get_elem(cs, name);
526  if (!he)
527  {
528  mutt_buffer_printf(result, _("Unknown variable '%s'"), name);
529  return CSR_ERR_UNKNOWN;
530  }
531 
532  return cs_he_initial_get(cs, he, result);
533 }
534 
543 int cs_he_string_set(const struct ConfigSet *cs, struct HashElem *he,
544  const char *value, struct Buffer *err)
545 {
546  if (!cs || !he)
547  return CSR_ERR_CODE;
548 
549  struct ConfigDef *cdef = NULL;
550  const struct ConfigSetType *cst = NULL;
551  void *var = NULL;
552 
553  if (he->type & DT_INHERITED)
554  {
555  struct Inheritance *i = he->data;
556  struct HashElem *he_base = cs_get_base(he);
557  cdef = he_base->data;
558  cst = cs_get_type_def(cs, he_base->type);
559  var = &i->var;
560  }
561  else
562  {
563  cdef = he->data;
564  cst = cs_get_type_def(cs, he->type);
565  var = &cdef->var;
566  }
567 
568  if (!cdef)
569  return CSR_ERR_CODE; // LCOV_EXCL_LINE
570 
571  if (!cst)
572  {
573  mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
574  return CSR_ERR_CODE;
575  }
576 
577  int rc = cst->string_set(cs, var, cdef, value, err);
578  if (CSR_RESULT(rc) != CSR_SUCCESS)
579  return rc;
580 
581  if (he->type & DT_INHERITED)
582  he->type = cdef->type | DT_INHERITED;
583 
584  return rc;
585 }
586 
595 int cs_str_string_set(const struct ConfigSet *cs, const char *name,
596  const char *value, struct Buffer *err)
597 {
598  if (!cs || !name)
599  return CSR_ERR_CODE;
600 
601  struct HashElem *he = cs_get_elem(cs, name);
602  if (!he)
603  {
604  mutt_buffer_printf(err, _("Unknown variable '%s'"), name);
605  return CSR_ERR_UNKNOWN;
606  }
607 
608  return cs_he_string_set(cs, he, value, err);
609 }
610 
618 int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
619 {
620  if (!cs || !he || !result)
621  return CSR_ERR_CODE;
622 
623  struct ConfigDef *cdef = NULL;
624  const struct ConfigSetType *cst = NULL;
625  void *var = NULL;
626 
627  if (he->type & DT_INHERITED)
628  {
629  struct Inheritance *i = he->data;
630 
631  // inherited, value not set
632  if (DTYPE(he->type) == 0)
633  return cs_he_string_get(cs, i->parent, result);
634 
635  // inherited, value set
636  struct HashElem *he_base = cs_get_base(he);
637  cdef = he_base->data;
638  cst = cs_get_type_def(cs, he_base->type);
639  var = &i->var;
640  }
641  else
642  {
643  // not inherited
644  cdef = he->data;
645  cst = cs_get_type_def(cs, he->type);
646  var = &cdef->var;
647  }
648 
649  if (!cdef || !cst)
650  return CSR_ERR_CODE; // LCOV_EXCL_LINE
651 
652  return cst->string_get(cs, var, cdef, result);
653 }
654 
662 int cs_str_string_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
663 {
664  if (!cs || !name)
665  return CSR_ERR_CODE;
666 
667  struct HashElem *he = cs_get_elem(cs, name);
668  if (!he)
669  {
670  mutt_buffer_printf(result, _("Unknown variable '%s'"), name);
671  return CSR_ERR_UNKNOWN;
672  }
673 
674  return cs_he_string_get(cs, he, result);
675 }
676 
685 int cs_he_native_set(const struct ConfigSet *cs, struct HashElem *he,
686  intptr_t value, struct Buffer *err)
687 {
688  if (!cs || !he)
689  return CSR_ERR_CODE;
690 
691  struct ConfigDef *cdef = NULL;
692  const struct ConfigSetType *cst = NULL;
693  void *var = NULL;
694 
695  if (he->type & DT_INHERITED)
696  {
697  struct Inheritance *i = he->data;
698  struct HashElem *he_base = cs_get_base(he);
699  cdef = he_base->data;
700  cst = cs_get_type_def(cs, he_base->type);
701  var = &i->var;
702  }
703  else
704  {
705  cdef = he->data;
706  cst = cs_get_type_def(cs, he->type);
707  var = &cdef->var;
708  }
709 
710  if (!cst)
711  {
712  mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
713  return CSR_ERR_CODE;
714  }
715 
716  if (!var || !cdef)
717  return CSR_ERR_CODE; // LCOV_EXCL_LINE
718 
719  int rc = cst->native_set(cs, var, cdef, value, err);
720  if (CSR_RESULT(rc) != CSR_SUCCESS)
721  return rc;
722 
723  if (he->type & DT_INHERITED)
724  he->type = cdef->type | DT_INHERITED;
725 
726  return rc;
727 }
728 
737 int cs_str_native_set(const struct ConfigSet *cs, const char *name,
738  intptr_t value, struct Buffer *err)
739 {
740  if (!cs || !name)
741  return CSR_ERR_CODE;
742 
743  struct HashElem *he = cs_get_elem(cs, name);
744  if (!he)
745  {
746  mutt_buffer_printf(err, _("Unknown variable '%s'"), name);
747  return CSR_ERR_UNKNOWN;
748  }
749 
750  struct ConfigDef *cdef = NULL;
751  const struct ConfigSetType *cst = NULL;
752  void *var = NULL;
753 
754  if (he->type & DT_INHERITED)
755  {
756  struct Inheritance *i = he->data;
757  struct HashElem *he_base = cs_get_base(he);
758  cdef = he_base->data;
759  cst = cs_get_type_def(cs, he_base->type);
760  var = &i->var;
761  }
762  else
763  {
764  cdef = he->data;
765  cst = cs_get_type_def(cs, he->type);
766  var = &cdef->var;
767  }
768 
769  if (!cst || !var || !cdef)
770  return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
771 
772  int rc = cst->native_set(cs, var, cdef, value, err);
773  if (CSR_RESULT(rc) != CSR_SUCCESS)
774  return rc;
775 
776  if (he->type & DT_INHERITED)
777  he->type = cdef->type | DT_INHERITED;
778 
779  return rc;
780 }
781 
790 intptr_t cs_he_native_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
791 {
792  if (!cs || !he)
793  return INT_MIN;
794 
795  struct ConfigDef *cdef = NULL;
796  const struct ConfigSetType *cst = NULL;
797  void *var = NULL;
798 
799  if (he->type & DT_INHERITED)
800  {
801  struct Inheritance *i = he->data;
802 
803  // inherited, value not set
804  if (DTYPE(he->type) == 0)
805  return cs_he_native_get(cs, i->parent, err);
806 
807  // inherited, value set
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  // not inherited
816  cdef = he->data;
817  cst = cs_get_type_def(cs, he->type);
818  var = &cdef->var;
819  }
820 
821  if (!var || !cdef)
822  return INT_MIN; // LCOV_EXCL_LINE
823 
824  if (!cst)
825  {
826  mutt_buffer_printf(err, _("Variable '%s' has an invalid type %d"), cdef->name, he->type);
827  return INT_MIN;
828  }
829 
830  return cst->native_get(cs, var, cdef, err);
831 }
832 
841 intptr_t cs_str_native_get(const struct ConfigSet *cs, const char *name, struct Buffer *err)
842 {
843  if (!cs || !name)
844  return INT_MIN;
845 
846  struct HashElem *he = cs_get_elem(cs, name);
847  return cs_he_native_get(cs, he, err);
848 }
849 
858 int cs_he_string_plus_equals(const struct ConfigSet *cs, struct HashElem *he,
859  const char *value, struct Buffer *err)
860 {
861  if (!cs || !he)
862  return CSR_ERR_CODE;
863 
864  struct ConfigDef *cdef = NULL;
865  const struct ConfigSetType *cst = NULL;
866  void *var = NULL;
867 
868  if (he->type & DT_INHERITED)
869  {
870  struct Inheritance *i = he->data;
871  struct HashElem *he_base = cs_get_base(he);
872  cdef = he_base->data;
873  cst = cs_get_type_def(cs, he_base->type);
874  var = &i->var;
875  }
876  else
877  {
878  cdef = he->data;
879  cst = cs_get_type_def(cs, he->type);
880  var = &cdef->var;
881  }
882 
883  if (!var || !cdef)
884  return INT_MIN; // LCOV_EXCL_LINE
885 
886  if (!cst)
887  {
888  mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
889  return CSR_ERR_CODE;
890  }
891 
892  if (!cst->string_plus_equals)
893  {
894  // L10N: e.g. Type 'boolean' doesn't support operation '+='
895  mutt_buffer_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "+=");
897  }
898 
899  int rc = cst->string_plus_equals(cs, var, cdef, value, err);
900  if (CSR_RESULT(rc) != CSR_SUCCESS)
901  return rc;
902 
903  if (he->type & DT_INHERITED)
904  he->type = cdef->type | DT_INHERITED;
905 
906  return rc;
907 }
908 
917 int cs_str_string_plus_equals(const struct ConfigSet *cs, const char *name,
918  const char *value, struct Buffer *err)
919 {
920  if (!cs || !name)
921  return CSR_ERR_CODE;
922 
923  struct HashElem *he = cs_get_elem(cs, name);
924  if (!he)
925  {
926  mutt_buffer_printf(err, _("Unknown variable '%s'"), name);
927  return CSR_ERR_UNKNOWN;
928  }
929 
930  return cs_he_string_plus_equals(cs, he, value, err);
931 }
932 
941 int cs_he_string_minus_equals(const struct ConfigSet *cs, struct HashElem *he,
942  const char *value, struct Buffer *err)
943 {
944  if (!cs || !he)
945  return CSR_ERR_CODE;
946 
947  struct ConfigDef *cdef = NULL;
948  const struct ConfigSetType *cst = NULL;
949  void *var = NULL;
950 
951  if (he->type & DT_INHERITED)
952  {
953  struct Inheritance *i = he->data;
954  struct HashElem *he_base = cs_get_base(he);
955  cdef = he_base->data;
956  cst = cs_get_type_def(cs, he_base->type);
957  var = &i->var;
958  }
959  else
960  {
961  cdef = he->data;
962  cst = cs_get_type_def(cs, he->type);
963  var = &cdef->var;
964  }
965 
966  if (!var || !cdef)
967  return INT_MIN; // LCOV_EXCL_LINE
968 
969  if (!cst)
970  {
971  mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
972  return CSR_ERR_CODE;
973  }
974 
975  if (!cst->string_minus_equals)
976  {
977  // L10N: e.g. Type 'boolean' doesn't support operation '+='
978  mutt_buffer_printf(err, _("Type '%s' doesn't support operation '%s'"), cst->name, "-=");
980  }
981 
982  int rc = cst->string_minus_equals(cs, var, cdef, value, err);
983  if (CSR_RESULT(rc) != CSR_SUCCESS)
984  return rc;
985 
986  if (he->type & DT_INHERITED)
987  he->type = cdef->type | DT_INHERITED;
988 
989  return rc;
990 }
991 
1000 int cs_str_string_minus_equals(const struct ConfigSet *cs, const char *name,
1001  const char *value, struct Buffer *err)
1002 {
1003  if (!cs || !name)
1004  return CSR_ERR_CODE;
1005 
1006  struct HashElem *he = cs_get_elem(cs, name);
1007  if (!he)
1008  {
1009  mutt_buffer_printf(err, _("Unknown variable '%s'"), name);
1010  return CSR_ERR_UNKNOWN;
1011  }
1012 
1013  return cs_he_string_minus_equals(cs, he, value, err);
1014 }
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
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:1000
void(* destroy)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
Definition: set.h:248
bool cs_register_type(struct ConfigSet *cs, const struct ConfigSetType *cst)
Register a type of config item.
Definition: set.c:248
Container for lots of config items.
Definition: set.h:259
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
int type
Data type, e.g. DT_STRING.
Definition: set.h:97
int(* string_set)(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition: set.h:118
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:38
Constants for all the config types.
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:449
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:94
void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
Remove an inherited config item.
Definition: set.c:331
A collection of config items.
struct ConfigSetType types[18]
All the defined config types.
Definition: set.h:262
intptr_t initial
Initial value.
Definition: set.h:67
int(* string_get)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *result)
Definition: set.h:138
struct HashElem * cs_inherit_variable(const struct ConfigSet *cs, struct HashElem *parent, const char *name)
Create in inherited config item.
Definition: set.c:306
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
#define CSV_INV_NOT_IMPL
Operation not permitted for the type.
Definition: set.h:49
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define DT_INITIAL_SET
Config item must have its initial value freed.
Definition: types.h:79
#define _(a)
Definition: message.h:28
const char * name
Name of this config item.
Definition: inheritance.h:34
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:595
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Definition: set.h:63
int(* native_set)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition: set.h:157
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:44
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:369
#define CSR_RESULT(x)
Definition: set.h:52
An inherited config item.
Definition: inheritance.h:31
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
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:790
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:346
#define mutt_array_size(x)
Definition: memory.h:33
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:841
struct ConfigSet * cs_new(size_t size)
Create a new Config Set.
Definition: set.c:156
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:520
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:416
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], uint32_t flags)
Register a set of config items.
Definition: set.c:276
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:458
const char * name
User-visible name.
Definition: set.h:65
#define CSR_ERR_UNKNOWN
Unrecognised config item.
Definition: set.h:37
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:941
static void cs_hashelem_free(int type, void *obj, intptr_t data)
Callback function for the Hash Table - Implements hash_hdata_free_t.
Definition: set.c:47
struct HashTable * hash
HashTable storing the config items.
Definition: set.h:261
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:293
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:917
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:858
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:484
int(* string_minus_equals)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition: set.h:214
uint32_t type
Variable type, e.g. DT_STRING.
Definition: set.h:66
struct HashElem * cs_get_base(struct HashElem *he)
Find the root Config Item.
Definition: set.c:189
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
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:543
void * data
User-supplied data.
Definition: hash.h:47
void cs_free(struct ConfigSet **ptr)
Free a Config Set.
Definition: set.c:170
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:309
intptr_t var
Storage for the variable.
Definition: set.h:85
#define DT_SYNONYM
synonym for another variable
Definition: types.h:42
Log at debug level 1.
Definition: logging.h:40
An inherited config item.
const char * name
Name of the type, e.g. "String".
Definition: set.h:98
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:45
#define FREE(x)
Definition: memory.h:40
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:419
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:618
The item stored in a Hash Table.
Definition: hash.h:43
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:737
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:393
#define CSR_ERR_CODE
Problem with the code.
Definition: set.h:36
int(* string_plus_equals)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Definition: set.h:195
struct HashElem * parent
HashElem of parent config item.
Definition: inheritance.h:33
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:685
static struct HashElem * reg_one_var(const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err)
Register one config item.
Definition: set.c:124
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:662
Convenience wrapper for the library headers.
const struct ConfigSetType * cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
Get the definition for a type.
Definition: set.c:227
struct HashElem * cs_get_elem(const struct ConfigSet *cs, const char *name)
Get the HashElem representing a config item.
Definition: set.c:204
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:251
#define MUTT_HASH_NO_FLAGS
No flags are set.
Definition: hash.h:100
intptr_t(* native_get)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Definition: set.h:176
#define DT_INHERITED
Config item is inherited.
Definition: types.h:78
intptr_t var
(Pointer to) value, of config item
Definition: inheritance.h:35
int(* reset)(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Definition: set.h:232