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