immovable

This commit is contained in:
2020-03-19 09:13:10 +01:00
parent fe13be2fd0
commit 29f04fbfd3
3 changed files with 49 additions and 16 deletions

45
cfg.h
View File

@@ -149,7 +149,7 @@ size_t string_hash(string* s) {
///// list is a list with a length and on-demand growing/shrinking
#define LIST(type) \
#define LIST(type, cleanup) \
typedef struct list_##type { \
size_t len; \
size_t cap; \
@@ -169,6 +169,8 @@ list_##type new_list_##type() { \
} \
\
void free_list_##type(list_##type l) { \
size_t i; \
for (i = 0; i < l.len; i++) cleanup(l.data[i]); \
free(l.data); \
} \
\
@@ -208,16 +210,22 @@ void list_set_nth_##type(list_##type* l, size_t n, type elem) { \
///// map is a hashmap
#define MAP(key_type, val_type, hash, cmp) \
#define MAP(key_type, val_type, hash, cmp, key_cleanup, val_cleanup) \
typedef struct entry_##key_type##_##val_type { \
key_type key; \
val_type val; \
} entry_##key_type##_##val_type; \
\
LIST(entry_##key_type##_##val_type); \
LIST(list_entry_##key_type##_##val_type); \
LIST(key_type); \
LIST(val_type); \
\
void entry_##key_type##_##val_type##_cleanup(entry_##key_type##_##val_type e) {\
key_cleanup(e.key);\
val_cleanup(e.val);\
}\
\
LIST(entry_##key_type##_##val_type, entry_##key_type##_##val_type##_cleanup); \
LIST(list_entry_##key_type##_##val_type, free_list_entry_##key_type##_##val_type); \
LIST(key_type, key_cleanup); \
LIST(val_type, val_cleanup); \
\
typedef struct map_##key_type##_##val_type { \
list_list_entry_##key_type##_##val_type entries; \
@@ -333,7 +341,9 @@ typedef struct config_value {
config_value zero_config_value = {0};
MAP(string, config_value, string_hash, string_compare);
void free_config_value(config_value);
MAP(string, config_value, string_hash, string_compare, free_string, free_config_value);
struct config {
map_string_config_value values;
@@ -346,7 +356,26 @@ struct config {
//// Functions
////// config value functions
void free_config(config c) {
free_map_string_config_value(c.values);
}
void free_config_value(config_value c) {
switch (c.tag) {
case config_value_section:
free_config(*c.section);
free(c.section);
break;
case config_value_string:
free_string(c.s);
break;
case config_value_list:
free_list_config_value(*c.l);
free(c.l);
break;
// number does not need to be freed
}
}
bool config_value_compare(config_value* a, config_value* b) {
if (a->tag != b->tag) return false;