NeoMutt  2019-11-11
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 <string.h>
33 #include "mutt/mutt.h"
34 #include "set.h"
35 #include "inheritance.h"
36 #include "types.h"
37 
38 struct ConfigSetType RegisteredTypes[18] = {
39  { NULL, NULL, NULL, NULL, NULL, NULL, NULL },
40 };
41 
50 struct HashElem *get_base(struct HashElem *he)
51 {
52  if (!(he->type & DT_INHERITED))
53  return he;
54 
55  struct Inheritance *i = he->data;
56  return get_base(i->parent);
57 }
58 
65 static void destroy(int type, void *obj, intptr_t data)
66 {
67  if (!obj || (data == 0))
68  return; /* LCOV_EXCL_LINE */
69 
70  struct ConfigSet *cs = (struct ConfigSet *) data;
71 
72  const struct ConfigSetType *cst = NULL;
73 
74  if (type & DT_INHERITED)
75  {
76  struct Inheritance *i = obj;
77 
78  struct HashElem *he_base = get_base(i->parent);
79  struct ConfigDef *cdef = he_base->data;
80 
81  cst = cs_get_type_def(cs, he_base->type);
82  if (cst && cst->destroy)
83  cst->destroy(cs, (void **) &i->var, cdef);
84 
85  FREE(&i->name);
86  FREE(&i);
87  }
88  else
89  {
90  struct ConfigDef *cdef = obj;
91 
92  cst = cs_get_type_def(cs, type);
93  if (cst && cst->destroy)
94  cst->destroy(cs, cdef->var, cdef);
95 
96  /* If we allocated the initial value, clean it up */
97  if (cdef->type & DT_INITIAL_SET)
98  FREE(&cdef->initial);
99  }
100 }
101 
109 static struct HashElem *create_synonym(const struct ConfigSet *cs,
110  struct ConfigDef *cdef, struct Buffer *err)
111 {
112  if (!cs || !cdef)
113  return NULL; /* LCOV_EXCL_LINE */
114 
115  const char *name = (const char *) cdef->initial;
116  struct HashElem *parent = cs_get_elem(cs, name);
117  if (!parent)
118  {
119  mutt_buffer_printf(err, "No such variable: %s", name);
120  return NULL;
121  }
122 
123  struct HashElem *child =
124  mutt_hash_typed_insert(cs->hash, cdef->name, cdef->type, (void *) cdef);
125  if (!child)
126  return NULL; /* LCOV_EXCL_LINE */
127 
128  cdef->var = parent;
129  return child;
130 }
131 
139 static struct HashElem *reg_one_var(const struct ConfigSet *cs,
140  struct ConfigDef *cdef, struct Buffer *err)
141 {
142  if (!cs || !cdef)
143  return NULL; /* LCOV_EXCL_LINE */
144 
145  if (cdef->type == DT_SYNONYM)
146  return create_synonym(cs, cdef, err);
147 
148  const struct ConfigSetType *cst = cs_get_type_def(cs, cdef->type);
149  if (!cst)
150  {
151  mutt_buffer_printf(err, "Variable '%s' has an invalid type %d", cdef->name, cdef->type);
152  return NULL;
153  }
154 
155  struct HashElem *he =
156  mutt_hash_typed_insert(cs->hash, cdef->name, cdef->type, (void *) cdef);
157  if (!he)
158  return NULL; /* LCOV_EXCL_LINE */
159 
160  if (cst && cst->reset)
161  cst->reset(cs, cdef->var, cdef, err);
162 
163  return he;
164 }
165 
171 struct ConfigSet *cs_new(size_t size)
172 {
173  struct ConfigSet *cs = mutt_mem_malloc(sizeof(*cs));
174  cs_init(cs, size);
175  return cs;
176 }
177 
183 void cs_init(struct ConfigSet *cs, size_t size)
184 {
185  if (!cs)
186  return;
187 
188  memset(cs, 0, sizeof(*cs));
190  mutt_hash_set_destructor(cs->hash, destroy, (intptr_t) cs);
191  cs->notify = notify_new(cs, NT_CONFIG);
192 }
193 
198 void cs_free(struct ConfigSet **ptr)
199 {
200  if (!ptr || !*ptr)
201  return;
202 
203  struct ConfigSet *cs = *ptr;
204 
205  mutt_hash_free(&cs->hash);
206  notify_free(&cs->notify);
207  FREE(ptr);
208 }
209 
216 struct HashElem *cs_get_elem(const struct ConfigSet *cs, const char *name)
217 {
218  if (!cs || !name)
219  return NULL;
220 
221  struct HashElem *he = mutt_hash_find_elem(cs->hash, name);
222  if (!he)
223  return NULL;
224 
225  if (he->type != DT_SYNONYM)
226  return he;
227 
228  const struct ConfigDef *cdef = he->data;
229 
230  return cdef->var;
231 }
232 
239 const struct ConfigSetType *cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
240 {
241  if (!cs)
242  return NULL;
243 
244  type = DTYPE(type);
245  if ((type < 1) || (type >= mutt_array_size(cs->types)))
246  return NULL;
247 
248  if (!cs->types[type].name)
249  return NULL;
250 
251  return &cs->types[type];
252 }
253 
261 bool cs_register_type(struct ConfigSet *cs, unsigned int type, const struct ConfigSetType *cst)
262 {
263  if (!cs || !cst)
264  return false;
265 
266  if (!cst->name || !cst->string_set || !cst->string_get || !cst->reset ||
267  !cst->native_set || !cst->native_get)
268  {
269  return false;
270  }
271 
272  if (type >= mutt_array_size(cs->types))
273  return false;
274 
275  if (cs->types[type].name)
276  return false; /* already registered */
277 
278  cs->types[type] = *cst;
279  return true;
280 }
281 
289 bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], int flags)
290 {
291  if (!cs || !vars)
292  return false;
293 
294  struct Buffer err = mutt_buffer_make(0);
295 
296  bool rc = true;
297 
298  for (size_t i = 0; vars[i].name; i++)
299  {
300  if (!reg_one_var(cs, &vars[i], &err))
301  {
302  mutt_debug(LL_DEBUG1, "%s\n", mutt_b2s(&err));
303  rc = false;
304  }
305  }
306 
307  mutt_buffer_dealloc(&err);
308  return rc;
309 }
310 
318 struct HashElem *cs_inherit_variable(const struct ConfigSet *cs,
319  struct HashElem *parent, const char *name)
320 {
321  if (!cs || !parent)
322  return NULL;
323 
324  struct Inheritance *i = mutt_mem_calloc(1, sizeof(*i));
325  i->parent = parent;
326  i->name = mutt_str_strdup(name);
327 
328  struct HashElem *he = mutt_hash_typed_insert(cs->hash, i->name, DT_INHERITED, i);
329  if (!he)
330  {
331  FREE(&i->name);
332  FREE(&i);
333  }
334 
335  return he;
336 }
337 
343 void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
344 {
345  if (!cs || !name)
346  return;
347 
348  mutt_hash_delete(cs->hash, name, NULL);
349 }
350 
358 void cs_notify_observers(const struct ConfigSet *cs, struct HashElem *he,
359  const char *name, enum NotifyConfig ev)
360 {
361  if (!cs || !he || !name)
362  return;
363 
364  struct EventConfig ec = { cs, he, name };
365  notify_send(cs->notify, NT_CONFIG, ev, IP & ec);
366 }
367 
375 int cs_he_reset(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
376 {
377  if (!cs || !he)
378  return CSR_ERR_CODE;
379 
380  /* An inherited var that's already pointing to its parent.
381  * Return 'success', but don't send a notification. */
382  if ((he->type & DT_INHERITED) && (DTYPE(he->type) == 0))
383  return CSR_SUCCESS;
384 
385  const struct ConfigDef *cdef = NULL;
386  const struct ConfigSetType *cst = NULL;
387 
388  int rc = CSR_SUCCESS;
389 
390  if (he->type & DT_INHERITED)
391  {
392  struct Inheritance *i = he->data;
393  struct HashElem *he_base = get_base(he);
394  cdef = he_base->data;
395  cst = cs_get_type_def(cs, he_base->type);
396 
397  if (cst && cst->destroy)
398  cst->destroy(cs, (void **) &i->var, cdef);
399 
400  he->type = DT_INHERITED;
401  }
402  else
403  {
404  cdef = he->data;
405  cst = cs_get_type_def(cs, he->type);
406 
407  if (cst)
408  rc = cst->reset(cs, cdef->var, cdef, err);
409  }
410 
411  if ((CSR_RESULT(rc) == CSR_SUCCESS) && !(rc & CSR_SUC_NO_CHANGE))
413  return rc;
414 }
415 
423 int cs_str_reset(const struct ConfigSet *cs, const char *name, struct Buffer *err)
424 {
425  if (!cs || !name)
426  return CSR_ERR_CODE;
427 
428  struct HashElem *he = cs_get_elem(cs, name);
429  if (!he)
430  {
431  mutt_buffer_printf(err, "Unknown var '%s'", name);
432  return CSR_ERR_UNKNOWN;
433  }
434 
435  return cs_he_reset(cs, he, err);
436 }
437 
446 int cs_he_initial_set(const struct ConfigSet *cs, struct HashElem *he,
447  const char *value, struct Buffer *err)
448 {
449  if (!cs || !he)
450  return CSR_ERR_CODE;
451 
452  struct ConfigDef *cdef = NULL;
453  const struct ConfigSetType *cst = NULL;
454 
455  if (he->type & DT_INHERITED)
456  {
457  struct HashElem *he_base = get_base(he);
458  cdef = he_base->data;
459  mutt_debug(LL_DEBUG1, "Variable '%s' is inherited type\n", cdef->name);
460  return CSR_ERR_CODE;
461  }
462 
463  cdef = he->data;
464  cst = cs_get_type_def(cs, he->type);
465  if (!cst)
466  {
467  mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
468  return CSR_ERR_CODE;
469  }
470 
471  int rc = cst->string_set(cs, NULL, cdef, value, err);
472  if (CSR_RESULT(rc) != CSR_SUCCESS)
473  return rc;
474 
476  return CSR_SUCCESS;
477 }
478 
487 int cs_str_initial_set(const struct ConfigSet *cs, const char *name,
488  const char *value, struct Buffer *err)
489 {
490  if (!cs || !name)
491  return CSR_ERR_CODE;
492 
493  struct HashElem *he = cs_get_elem(cs, name);
494  if (!he)
495  {
496  mutt_buffer_printf(err, "Unknown var '%s'", name);
497  return CSR_ERR_UNKNOWN;
498  }
499 
500  return cs_he_initial_set(cs, he, value, err);
501 }
502 
513 int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
514 {
515  if (!cs || !he)
516  return CSR_ERR_CODE;
517 
518  const struct ConfigDef *cdef = NULL;
519  const struct ConfigSetType *cst = NULL;
520 
521  if (he->type & DT_INHERITED)
522  {
523  struct HashElem *he_base = get_base(he);
524  cdef = he_base->data;
525  cst = cs_get_type_def(cs, he_base->type);
526  }
527  else
528  {
529  cdef = he->data;
530  cst = cs_get_type_def(cs, he->type);
531  }
532 
533  if (!cst)
534  {
535  mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name,
536  DTYPE(he->type));
537  return CSR_ERR_CODE;
538  }
539 
540  return cst->string_get(cs, NULL, cdef, result);
541 }
542 
553 int cs_str_initial_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
554 {
555  if (!cs || !name)
556  return CSR_ERR_CODE;
557 
558  struct HashElem *he = cs_get_elem(cs, name);
559  if (!he)
560  {
561  mutt_buffer_printf(result, "Unknown var '%s'", name);
562  return CSR_ERR_UNKNOWN;
563  }
564 
565  return cs_he_initial_get(cs, he, result);
566 }
567 
576 int cs_he_string_set(const struct ConfigSet *cs, struct HashElem *he,
577  const char *value, struct Buffer *err)
578 {
579  if (!cs || !he)
580  return CSR_ERR_CODE;
581 
582  struct ConfigDef *cdef = NULL;
583  const struct ConfigSetType *cst = NULL;
584  void *var = NULL;
585 
586  if (he->type & DT_INHERITED)
587  {
588  struct Inheritance *i = he->data;
589  struct HashElem *he_base = get_base(he);
590  cdef = he_base->data;
591  cst = cs_get_type_def(cs, he_base->type);
592  var = &i->var;
593  }
594  else
595  {
596  cdef = he->data;
597  cst = cs_get_type_def(cs, he->type);
598  var = cdef->var;
599  }
600 
601  if (!cst)
602  {
603  mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
604  return CSR_ERR_CODE;
605  }
606 
607  int rc = cst->string_set(cs, var, cdef, value, err);
608  if (CSR_RESULT(rc) != CSR_SUCCESS)
609  return rc;
610 
611  if (he->type & DT_INHERITED)
612  he->type = cdef->type | DT_INHERITED;
613 
614  if (!(rc & CSR_SUC_NO_CHANGE))
616  return rc;
617 }
618 
627 int cs_str_string_set(const struct ConfigSet *cs, const char *name,
628  const char *value, struct Buffer *err)
629 {
630  if (!cs || !name)
631  return CSR_ERR_CODE;
632 
633  struct HashElem *he = cs_get_elem(cs, name);
634  if (!he)
635  {
636  mutt_buffer_printf(err, "Unknown var '%s'", name);
637  return CSR_ERR_UNKNOWN;
638  }
639 
640  return cs_he_string_set(cs, he, value, err);
641 }
642 
650 int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
651 {
652  if (!cs || !he)
653  return CSR_ERR_CODE;
654 
655  const struct ConfigDef *cdef = NULL;
656  const struct ConfigSetType *cst = NULL;
657  void *var = NULL;
658 
659  if (he->type & DT_INHERITED)
660  {
661  struct Inheritance *i = he->data;
662 
663  // inherited, value not set
664  if (DTYPE(he->type) == 0)
665  return cs_he_string_get(cs, i->parent, result);
666 
667  // inherited, value set
668  struct HashElem *he_base = get_base(he);
669  cdef = he_base->data;
670  cst = cs_get_type_def(cs, he_base->type);
671  var = &i->var;
672  }
673  else
674  {
675  // not inherited
676  cdef = he->data;
677  cst = cs_get_type_def(cs, he->type);
678  var = cdef->var;
679  }
680 
681  if (!cst)
682  {
683  mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name,
684  DTYPE(he->type));
685  return CSR_ERR_CODE;
686  }
687 
688  return cst->string_get(cs, var, cdef, result);
689 }
690 
698 int cs_str_string_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
699 {
700  if (!cs || !name)
701  return CSR_ERR_CODE;
702 
703  struct HashElem *he = cs_get_elem(cs, name);
704  if (!he)
705  {
706  mutt_buffer_printf(result, "Unknown var '%s'", name);
707  return CSR_ERR_UNKNOWN;
708  }
709 
710  return cs_he_string_get(cs, he, result);
711 }
712 
721 int cs_he_native_set(const struct ConfigSet *cs, struct HashElem *he,
722  intptr_t value, struct Buffer *err)
723 {
724  if (!cs || !he)
725  return CSR_ERR_CODE;
726 
727  const struct ConfigDef *cdef = NULL;
728  const struct ConfigSetType *cst = NULL;
729  void *var = NULL;
730 
731  if (he->type & DT_INHERITED)
732  {
733  struct Inheritance *i = he->data;
734  struct HashElem *he_base = get_base(he);
735  cdef = he_base->data;
736  cst = cs_get_type_def(cs, he_base->type);
737  var = &i->var;
738  }
739  else
740  {
741  cdef = he->data;
742  cst = cs_get_type_def(cs, he->type);
743  var = cdef->var;
744  }
745 
746  if (!cst)
747  {
748  mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type);
749  return CSR_ERR_CODE;
750  }
751 
752  int rc = cst->native_set(cs, var, cdef, value, err);
753  if (CSR_RESULT(rc) != CSR_SUCCESS)
754  return rc;
755 
756  if (he->type & DT_INHERITED)
757  he->type = cdef->type | DT_INHERITED;
758 
759  if (!(rc & CSR_SUC_NO_CHANGE))
760  cs_notify_observers(cs, he, cdef->name, NT_CONFIG_SET);
761  return rc;
762 }
763 
772 int cs_str_native_set(const struct ConfigSet *cs, const char *name,
773  intptr_t value, struct Buffer *err)
774 {
775  if (!cs || !name)
776  return CSR_ERR_CODE;
777 
778  struct HashElem *he = cs_get_elem(cs, name);
779  if (!he)
780  {
781  mutt_buffer_printf(err, "Unknown var '%s'", name);
782  return CSR_ERR_UNKNOWN;
783  }
784 
785  const struct ConfigDef *cdef = NULL;
786  const struct ConfigSetType *cst = NULL;
787  void *var = NULL;
788 
789  if (he->type & DT_INHERITED)
790  {
791  struct Inheritance *i = he->data;
792  struct HashElem *he_base = get_base(he);
793  cdef = he_base->data;
794  cst = cs_get_type_def(cs, he_base->type);
795  var = &i->var;
796  }
797  else
798  {
799  cdef = he->data;
800  cst = cs_get_type_def(cs, he->type);
801  var = cdef->var;
802  }
803 
804  if (!cst)
805  return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
806 
807  int rc = cst->native_set(cs, var, cdef, value, err);
808  if (CSR_RESULT(rc) != CSR_SUCCESS)
809  return rc;
810 
811  if (he->type & DT_INHERITED)
812  he->type = cdef->type | DT_INHERITED;
813 
814  if (!(rc & CSR_SUC_NO_CHANGE))
815  cs_notify_observers(cs, he, cdef->name, NT_CONFIG_SET);
816  return rc;
817 }
818 
827 intptr_t cs_he_native_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
828 {
829  if (!cs || !he)
830  return INT_MIN;
831 
832  const struct ConfigDef *cdef = NULL;
833  const struct ConfigSetType *cst = NULL;
834  void *var = NULL;
835 
836  if (he->type & DT_INHERITED)
837  {
838  struct Inheritance *i = he->data;
839 
840  // inherited, value not set
841  if (DTYPE(he->type) == 0)
842  return cs_he_native_get(cs, i->parent, err);
843 
844  // inherited, value set
845  struct HashElem *he_base = get_base(he);
846  cdef = he_base->data;
847  cst = cs_get_type_def(cs, he_base->type);
848  var = &i->var;
849  }
850  else
851  {
852  // not inherited
853  cdef = he->data;
854  cst = cs_get_type_def(cs, he->type);
855  var = cdef->var;
856  }
857 
858  if (!cst)
859  {
860  mutt_buffer_printf(err, "Variable '%s' has an invalid type %d", cdef->name, he->type);
861  return INT_MIN;
862  }
863 
864  return cst->native_get(cs, var, cdef, err);
865 }
866 
875 intptr_t cs_str_native_get(const struct ConfigSet *cs, const char *name, struct Buffer *err)
876 {
877  if (!cs || !name)
878  return INT_MIN;
879 
880  struct HashElem *he = cs_get_elem(cs, name);
881  return cs_he_native_get(cs, he, err);
882 }
union HashKey key
Definition: hash.h:45
Type definition for a config item.
Definition: set.h:168
void mutt_hash_delete(struct Hash *table, const char *strkey, const void *data)
Remove an element from a Hash table.
Definition: hash.c:443
Container for lots of config items.
Definition: set.h:187
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
struct Hash * hash
HashTable storing the config items.
Definition: set.h:189
cst_reset reset
Reset the variable to its initial, or parent, value.
Definition: set.h:175
Constants for all the config types.
#define CSR_RESULT(x)
Definition: set.h:62
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:627
struct ConfigSetType types[18]
All the defined config types.
Definition: set.h:190
static void destroy(int type, void *obj, intptr_t data)
Callback function for the Hash Table - Implements hashelem_free_t.
Definition: set.c:65
intptr_t initial
Initial value.
Definition: set.h:158
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:553
void cs_uninherit_variable(const struct ConfigSet *cs, const char *name)
Remove an inherited config item.
Definition: set.c:343
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:318
A config-change event.
Definition: set.h:199
String manipulation buffer.
Definition: buffer.h:33
#define DT_INITIAL_SET
Config item must have its initial value freed.
Definition: types.h:79
cst_string_get string_get
Initialise a variable from a string.
Definition: set.h:172
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:875
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:153
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:43
NotifyConfig
Config notification types.
Definition: set.h:38
struct Notify * notify_new(void *object, enum NotifyType type)
Create a new notifications handler.
Definition: notify.c:54
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:487
#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:139
struct HashElem * he
Config item that changed.
Definition: set.h:202
const struct ConfigSet * cs
Config set.
Definition: set.h:201
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:109
const char * name
Definition: pgpmicalg.c:45
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:375
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:698
void cs_notify_observers(const struct ConfigSet *cs, struct HashElem *he, const char *name, enum NotifyConfig ev)
Notify all observers of an event.
Definition: set.c:358
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:721
struct HashElem * mutt_hash_find_elem(const struct Hash *table, const char *strkey)
Find the HashElem in a Hash table element using a key.
Definition: hash.c:393
const char * name
User-visible name.
Definition: set.h:155
cst_native_get native_get
Get the variable&#39;s value as a C-native type.
Definition: set.h:174
struct HashElem * cs_get_elem(const struct ConfigSet *cs, const char *name)
Get the HashElem representing a config item.
Definition: set.c:216
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:46
#define mutt_b2s(buf)
Definition: buffer.h:41
void cs_init(struct ConfigSet *cs, size_t size)
Initialise a Config Set.
Definition: set.c:183
#define CSR_ERR_UNKNOWN
Unrecognised config item.
Definition: set.h:48
A collection of config items.
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
cst_string_set string_set
Convert the variable to a string.
Definition: set.h:171
struct Hash * mutt_hash_new(size_t nelem, HashFlags flags)
Create a new Hash table (with string keys)
Definition: hash.c:275
cst_native_set native_set
Set the variable using a C-native type.
Definition: set.h:173
Config item has been reset to initial, or parent, value.
Definition: set.h:41
cst_destroy destroy
Free the resources for a variable.
Definition: set.h:176
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:513
Config item has been set.
Definition: set.h:40
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:446
void cs_free(struct ConfigSet **ptr)
Free a Config Set.
Definition: set.c:198
struct ConfigSet * cs_new(size_t size)
Create a new Config Set.
Definition: set.c:171
void notify_free(struct Notify **ptr)
Free a notification handler.
Definition: notify.c:69
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:650
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:423
Config has changed.
Definition: notify_type.h:33
void * data
Definition: hash.h:46
void * var
Pointer to the global variable.
Definition: set.h:157
#define CSR_ERR_CODE
Problem with the code.
Definition: set.h:47
unsigned int type
Variable type, e.g. DT_STRING.
Definition: set.h:156
#define DT_SYNONYM
synonym for another variable
Definition: types.h:41
const struct ConfigSetType * cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
Get the definition for a type.
Definition: set.c:239
Log at debug level 1.
Definition: logging.h:56
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
An inherited config item.
struct Notify * notify
Notifications system.
Definition: set.h:191
const char * name
Name of the type, e.g.
Definition: set.h:170
const char * strkey
Definition: hash.h:35
#define IP
Definition: set.h:144
int type
Definition: hash.h:44
#define FREE(x)
Definition: memory.h:40
The item stored in a Hash Table.
Definition: hash.h:42
bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], int flags)
Register a set of config items.
Definition: set.c:289
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
void mutt_hash_set_destructor(struct Hash *table, hashelem_free_t fn, intptr_t fn_data)
Set the destructor for a Hash Table.
Definition: hash.c:317
Config item&#39;s initial value has been set.
Definition: set.h:42
struct HashElem * parent
HashElem of parent config item.
Definition: inheritance.h:33
void mutt_hash_free(struct Hash **ptr)
free_hdata a hash table
Definition: hash.c:471
bool cs_register_type(struct ConfigSet *cs, unsigned int type, const struct ConfigSetType *cst)
Register a type of config item.
Definition: set.c:261
bool notify_send(struct Notify *notify, int type, int subtype, intptr_t data)
Send out a notification message.
Definition: notify.c:145
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:827
#define CSR_SUC_NO_CHANGE
The value hasn&#39;t changed.
Definition: set.h:55
#define MUTT_HASH_NO_FLAGS
No flags are set.
Definition: hash.h:74
struct HashElem * get_base(struct HashElem *he)
Find the root Config Item.
Definition: set.c:50
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:576
#define DT_INHERITED
Config item is inherited.
Definition: types.h:78
struct HashElem * mutt_hash_typed_insert(struct Hash *table, const char *strkey, int type, void *data)
Insert a string with type info into a Hash Table.
Definition: hash.c:333
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:772
intptr_t var
(Pointer to) value, of config item
Definition: inheritance.h:35