From 41310d2e0e7a50fad562e907de0266a2847a110d Mon Sep 17 00:00:00 2001 From: derselbst Date: Sat, 23 Sep 2017 19:31:35 +0200 Subject: [PATCH 01/12] fluid_settings: fix alignment warnings by using a union for fluid_setting_node_t --- src/utils/fluid_settings.c | 287 ++++++++++++++++++++----------------- 1 file changed, 152 insertions(+), 135 deletions(-) diff --git a/src/utils/fluid_settings.c b/src/utils/fluid_settings.c index 4dfd2843..bf1d71e9 100644 --- a/src/utils/fluid_settings.c +++ b/src/utils/fluid_settings.c @@ -42,11 +42,6 @@ static int fluid_settings_tokenize(const char *s, char *buf, char **ptr); /* Common structure to all settings nodes */ typedef struct { - int type; /**< fluid_types_enum */ -} fluid_setting_node_t; - -typedef struct { - fluid_setting_node_t node; char* value; char* def; int hints; @@ -56,7 +51,6 @@ typedef struct { } fluid_str_setting_t; typedef struct { - fluid_setting_node_t node; double value; double def; double min; @@ -67,7 +61,6 @@ typedef struct { } fluid_num_setting_t; typedef struct { - fluid_setting_node_t node; int value; int def; int min; @@ -78,152 +71,184 @@ typedef struct { } fluid_int_setting_t; typedef struct { - fluid_setting_node_t node; fluid_hashtable_t *hashtable; } fluid_set_setting_t; +typedef struct { + int type; /**< fluid_types_enum */ + + union + { + fluid_str_setting_t str; + fluid_num_setting_t num; + fluid_int_setting_t i; + fluid_set_setting_t set; + }; +} fluid_setting_node_t; -static fluid_str_setting_t* +static fluid_setting_node_t* new_fluid_str_setting(const char* value, const char* def, int hints, fluid_str_update_t fun, void* data) { + fluid_setting_node_t* node; fluid_str_setting_t* str; + + node = FLUID_NEW(fluid_setting_node_t); - str = FLUID_NEW(fluid_str_setting_t); - - if (!str) + if (!node) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } - str->node.type = FLUID_STR_TYPE; + node->type = FLUID_STR_TYPE; + str = &node->str; + str->value = value? FLUID_STRDUP(value) : NULL; str->def = def? FLUID_STRDUP(def) : NULL; str->hints = hints; str->options = NULL; str->update = fun; str->data = data; - return str; + return node; } static void -delete_fluid_str_setting(fluid_str_setting_t* str) +delete_fluid_str_setting(fluid_setting_node_t* node) { - if (!str) return; + if (!node) return; + + FLUID_ASSERT(node->type, FLUID_STR_TYPE); - if (str->value) FLUID_FREE(str->value); - if (str->def) FLUID_FREE(str->def); + FLUID_FREE(node->str.value); + FLUID_FREE(node->str.def); - if (str->options) { - fluid_list_t* list = str->options; + if (node->str.options) { + fluid_list_t* list = node->str.options; while (list) { FLUID_FREE (list->data); list = fluid_list_next(list); } - delete_fluid_list(str->options); + delete_fluid_list(node->str.options); } - FLUID_FREE(str); + FLUID_FREE(node); } -static fluid_num_setting_t* +static fluid_setting_node_t* new_fluid_num_setting(double min, double max, double def, int hints, fluid_num_update_t fun, void* data) { - fluid_num_setting_t* setting; + fluid_setting_node_t* node; + fluid_num_setting_t* num; - setting = FLUID_NEW(fluid_num_setting_t); + node = FLUID_NEW(fluid_setting_node_t); - if (!setting) + if (!node) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } - setting->node.type = FLUID_NUM_TYPE; - setting->value = def; - setting->def = def; - setting->min = min; - setting->max = max; - setting->hints = hints; - setting->update = fun; - setting->data = data; - return setting; + node->type = FLUID_NUM_TYPE; + num = &node->num; + + num->value = def; + num->def = def; + num->min = min; + num->max = max; + num->hints = hints; + num->update = fun; + num->data = data; + + return node; } static void -delete_fluid_num_setting(fluid_num_setting_t* setting) +delete_fluid_num_setting(fluid_setting_node_t* node) { - if (setting) FLUID_FREE(setting); + if (!node) return; + + FLUID_ASSERT (node->type, FLUID_NUM_TYPE); + FLUID_FREE(node); } -static fluid_int_setting_t* +static fluid_setting_node_t* new_fluid_int_setting(int min, int max, int def, int hints, fluid_int_update_t fun, void* data) { - fluid_int_setting_t* setting; + fluid_setting_node_t* node; + fluid_int_setting_t* i; - setting = FLUID_NEW(fluid_int_setting_t); + node = FLUID_NEW(fluid_setting_node_t); - if (!setting) + if (!node) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } - setting->node.type = FLUID_INT_TYPE; - setting->value = def; - setting->def = def; - setting->min = min; - setting->max = max; - setting->hints = hints; - setting->update = fun; - setting->data = data; - return setting; + node->type = FLUID_INT_TYPE; + i = &node->i; + + i->value = def; + i->def = def; + i->min = min; + i->max = max; + i->hints = hints; + i->update = fun; + i->data = data; + return node; } static void -delete_fluid_int_setting(fluid_int_setting_t* setting) +delete_fluid_int_setting(fluid_setting_node_t* node) { - if (setting) FLUID_FREE(setting); + if (!node) return; + + FLUID_ASSERT (node->type, FLUID_INT_TYPE); + FLUID_FREE(node); } -static fluid_set_setting_t* +static fluid_setting_node_t* new_fluid_set_setting(void) { - fluid_set_setting_t* setting; + fluid_setting_node_t* node; + fluid_set_setting_t* set; - setting = FLUID_NEW(fluid_set_setting_t); + node = FLUID_NEW(fluid_setting_node_t); - if (!setting) + if (!node) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } - setting->node.type = FLUID_SET_TYPE; - setting->hashtable = new_fluid_hashtable_full(fluid_str_hash, fluid_str_equal, + node->type = FLUID_SET_TYPE; + set = &node->set; + + set->hashtable = new_fluid_hashtable_full(fluid_str_hash, fluid_str_equal, fluid_settings_key_destroy_func, fluid_settings_value_destroy_func); - if (!setting->hashtable) + if (!set->hashtable) { - FLUID_FREE (setting); + FLUID_FREE (node); return NULL; } - return setting; + return node; } static void -delete_fluid_set_setting(fluid_set_setting_t* setting) +delete_fluid_set_setting(fluid_setting_node_t* node) { - if (setting) + if (node) { - delete_fluid_hashtable(setting->hashtable); - FLUID_FREE(setting); + FLUID_ASSERT (node->type, FLUID_SET_TYPE); + delete_fluid_hashtable(node->set.hashtable); + FLUID_FREE(node); } } @@ -274,16 +299,16 @@ fluid_settings_value_destroy_func(void* value) switch (node->type) { case FLUID_NUM_TYPE: - delete_fluid_num_setting((fluid_num_setting_t*) value); + delete_fluid_num_setting(node); break; case FLUID_INT_TYPE: - delete_fluid_int_setting((fluid_int_setting_t*) value); + delete_fluid_int_setting(node); break; case FLUID_STR_TYPE: - delete_fluid_str_setting((fluid_str_setting_t*) value); + delete_fluid_str_setting(node); break; case FLUID_SET_TYPE: - delete_fluid_set_setting((fluid_set_setting_t*) value); + delete_fluid_set_setting(node); break; } } @@ -359,7 +384,7 @@ fluid_settings_get(fluid_settings_t* settings, const char *name, node = fluid_hashtable_lookup(table, tokens[n]); if (!node) return FLUID_FAILED; - table = (node->type == FLUID_SET_TYPE) ? ((fluid_set_setting_t *)node)->hashtable : NULL; + table = (node->type == FLUID_SET_TYPE) ? node->set.hashtable : NULL; } if (value) *value = node; @@ -376,7 +401,7 @@ fluid_settings_get(fluid_settings_t* settings, const char *name, * @return #FLUID_OK if the value has been set, #FLUID_FAILED otherwise */ static int -fluid_settings_set(fluid_settings_t* settings, const char *name, void* value) +fluid_settings_set(fluid_settings_t* settings, const char *name, fluid_setting_node_t* value) { fluid_hashtable_t* table = settings; fluid_setting_node_t *node; @@ -396,7 +421,7 @@ fluid_settings_set(fluid_settings_t* settings, const char *name, void* value) if (node) { if (node->type == FLUID_SET_TYPE) { - table = ((fluid_set_setting_t *)node)->hashtable; + table = node->set.hashtable; } else { /* path ends prematurely */ FLUID_LOG(FLUID_WARN, "'%s' is not a node", name[n]); @@ -405,7 +430,7 @@ fluid_settings_set(fluid_settings_t* settings, const char *name, void* value) } else { /* create a new node */ - fluid_set_setting_t* setnode; + fluid_setting_node_t* setnode; dupname = FLUID_STRDUP (tokens[n]); setnode = new_fluid_set_setting (); @@ -421,7 +446,7 @@ fluid_settings_set(fluid_settings_t* settings, const char *name, void* value) } fluid_hashtable_insert(table, dupname, setnode); - table = setnode->hashtable; + table = setnode->set.hashtable; } } @@ -454,7 +479,6 @@ fluid_settings_register_str(fluid_settings_t* settings, const char* name, const fluid_str_update_t fun, void* data) { fluid_setting_node_t *node; - fluid_str_setting_t* setting; int retval = FLUID_FAILED; fluid_return_val_if_fail (settings != NULL, retval); @@ -464,13 +488,13 @@ fluid_settings_register_str(fluid_settings_t* settings, const char* name, const fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node) != FLUID_OK) { - setting = new_fluid_str_setting(def, def, hints, fun, data); - retval = fluid_settings_set(settings, name, setting); - if (retval != FLUID_OK) delete_fluid_str_setting (setting); + node = new_fluid_str_setting(def, def, hints, fun, data); + retval = fluid_settings_set(settings, name, node); + if (retval != FLUID_OK) delete_fluid_str_setting (node); } else { /* if variable already exists, don't change its value. */ if (node->type == FLUID_STR_TYPE) { - setting = (fluid_str_setting_t*) node; + fluid_str_setting_t* setting = &node->str; setting->update = fun; setting->data = data; setting->def = def? FLUID_STRDUP(def) : NULL; @@ -518,14 +542,13 @@ fluid_settings_register_num(fluid_settings_t* settings, const char* name, double if (fluid_settings_get(settings, name, &node) != FLUID_OK) { /* insert a new setting */ - fluid_num_setting_t* setting; - setting = new_fluid_num_setting(min, max, def, hints, fun, data); - retval = fluid_settings_set(settings, name, setting); - if (retval != FLUID_OK) delete_fluid_num_setting (setting); + node = new_fluid_num_setting(min, max, def, hints, fun, data); + retval = fluid_settings_set(settings, name, node); + if (retval != FLUID_OK) delete_fluid_num_setting (node); } else { if (node->type == FLUID_NUM_TYPE) { /* update the existing setting but don't change its value */ - fluid_num_setting_t* setting = (fluid_num_setting_t*) node; + fluid_num_setting_t* setting = &node->num; setting->update = fun; setting->data = data; setting->min = min; @@ -576,14 +599,13 @@ fluid_settings_register_int(fluid_settings_t* settings, const char* name, int de if (fluid_settings_get(settings, name, &node) != FLUID_OK) { /* insert a new setting */ - fluid_int_setting_t* setting; - setting = new_fluid_int_setting(min, max, def, hints, fun, data); - retval = fluid_settings_set(settings, name, setting); - if (retval != FLUID_OK) delete_fluid_int_setting (setting); + node = new_fluid_int_setting(min, max, def, hints, fun, data); + retval = fluid_settings_set(settings, name, node); + if (retval != FLUID_OK) delete_fluid_int_setting (node); } else { if (node->type == FLUID_INT_TYPE) { /* update the existing setting but don't change its value */ - fluid_int_setting_t* setting = (fluid_int_setting_t*) node; + fluid_int_setting_t* setting = &node->i; setting->update = fun; setting->data = data; setting->min = min; @@ -650,15 +672,15 @@ fluid_settings_get_hints(fluid_settings_t* settings, const char *name, int* hint if (fluid_settings_get(settings, name, &node) == FLUID_OK) { if (node->type == FLUID_NUM_TYPE) { - fluid_num_setting_t* setting = (fluid_num_setting_t*) node; + fluid_num_setting_t* setting = &node->num; *hints = setting->hints; retval = FLUID_OK; } else if (node->type == FLUID_STR_TYPE) { - fluid_str_setting_t* setting = (fluid_str_setting_t*) node; + fluid_str_setting_t* setting = &node->str; *hints = setting->hints; retval = FLUID_OK; } else if (node->type == FLUID_INT_TYPE) { - fluid_int_setting_t* setting = (fluid_int_setting_t*) node; + fluid_int_setting_t* setting = &node->i; *hints = setting->hints; retval = FLUID_OK; } @@ -690,13 +712,13 @@ fluid_settings_is_realtime(fluid_settings_t* settings, const char *name) if (fluid_settings_get(settings, name, &node) == FLUID_OK) { if (node->type == FLUID_NUM_TYPE) { - fluid_num_setting_t* setting = (fluid_num_setting_t*) node; + fluid_num_setting_t* setting = &node->num; isrealtime = setting->update != NULL; } else if (node->type == FLUID_STR_TYPE) { - fluid_str_setting_t* setting = (fluid_str_setting_t*) node; + fluid_str_setting_t* setting = &node->str; isrealtime = setting->update != NULL; } else if (node->type == FLUID_INT_TYPE) { - fluid_int_setting_t* setting = (fluid_int_setting_t*) node; + fluid_int_setting_t* setting = &node->i; isrealtime = setting->update != NULL; } } @@ -728,7 +750,7 @@ fluid_settings_setstr(fluid_settings_t* settings, const char *name, const char * if (fluid_settings_get (settings, name, &node) == FLUID_OK) { if (node->type == FLUID_STR_TYPE) { - fluid_str_setting_t *setting = (fluid_str_setting_t *)node; + fluid_str_setting_t *setting = &node->str; if (setting->value) FLUID_FREE (setting->value); setting->value = str ? FLUID_STRDUP (str) : NULL; @@ -739,7 +761,7 @@ fluid_settings_setstr(fluid_settings_t* settings, const char *name, const char * } else if (node->type == FLUID_INT_TYPE) /* Handle yes/no for boolean values for backwards compatibility */ { - fluid_int_setting_t *setting = (fluid_int_setting_t *)node; + fluid_int_setting_t *setting = &node->i; if (setting->hints & FLUID_HINT_TOGGLED) { @@ -759,10 +781,9 @@ fluid_settings_setstr(fluid_settings_t* settings, const char *name, const char * } } else { /* insert a new setting */ - fluid_str_setting_t* setting; - setting = new_fluid_str_setting(str, NULL, 0, NULL, NULL); - retval = fluid_settings_set(settings, name, setting); - if (retval != FLUID_OK) delete_fluid_str_setting (setting); + node = new_fluid_str_setting(str, NULL, 0, NULL, NULL); + retval = fluid_settings_set(settings, name, node); + if (retval != FLUID_OK) delete_fluid_str_setting (node); } fluid_rec_mutex_unlock (settings->mutex); @@ -803,7 +824,7 @@ fluid_settings_copystr(fluid_settings_t* settings, const char *name, { if (node->type == FLUID_STR_TYPE) { - fluid_str_setting_t *setting = (fluid_str_setting_t *)node; + fluid_str_setting_t *setting = &node->str; if (setting->value) { @@ -815,7 +836,7 @@ fluid_settings_copystr(fluid_settings_t* settings, const char *name, } else if (node->type == FLUID_INT_TYPE) /* Handle boolean integers for backwards compatibility */ { - fluid_int_setting_t *setting = (fluid_int_setting_t *)node; + fluid_int_setting_t *setting = &node->i; if (setting->hints & FLUID_HINT_TOGGLED) { @@ -860,7 +881,7 @@ fluid_settings_dupstr(fluid_settings_t* settings, const char *name, char** str) { if (node->type == FLUID_STR_TYPE) { - fluid_str_setting_t *setting = (fluid_str_setting_t *)node; + fluid_str_setting_t *setting = &node->str; if (setting->value) { @@ -872,7 +893,7 @@ fluid_settings_dupstr(fluid_settings_t* settings, const char *name, char** str) } else if (node->type == FLUID_INT_TYPE) /* Handle boolean integers for backwards compatibility */ { - fluid_int_setting_t *setting = (fluid_int_setting_t *)node; + fluid_int_setting_t *setting = &node->i; if (setting->hints & FLUID_HINT_TOGGLED) { @@ -915,13 +936,13 @@ fluid_settings_str_equal (fluid_settings_t* settings, const char *name, const ch { if (node->type == FLUID_STR_TYPE) { - fluid_str_setting_t *setting = (fluid_str_setting_t *)node; + fluid_str_setting_t *setting = &node->str; if (setting->value) retval = FLUID_STRCMP (setting->value, s) == 0; } else if (node->type == FLUID_INT_TYPE) /* Handle boolean integers for backwards compatibility */ { - fluid_int_setting_t *setting = (fluid_int_setting_t *)node; + fluid_int_setting_t *setting = &node->i; if (setting->hints & FLUID_HINT_TOGGLED) retval = FLUID_STRCMP (setting->value ? "yes" : "no", s) == 0; @@ -957,12 +978,12 @@ fluid_settings_getstr_default(fluid_settings_t* settings, const char *name) { if (node->type == FLUID_STR_TYPE) { - fluid_str_setting_t* setting = (fluid_str_setting_t*) node; + fluid_str_setting_t* setting = &node->str; retval = setting->def; } else if (node->type == FLUID_INT_TYPE) /* Handle boolean integers for backwards compatibility */ { - fluid_int_setting_t *setting = (fluid_int_setting_t *)node; + fluid_int_setting_t *setting = &node->i; if (setting->hints & FLUID_HINT_TOGGLED) retval = setting->def ? "yes" : "no"; @@ -998,7 +1019,7 @@ fluid_settings_add_option(fluid_settings_t* settings, const char *name, const ch if (fluid_settings_get(settings, name, &node) == FLUID_OK && (node->type == FLUID_STR_TYPE)) { - fluid_str_setting_t* setting = (fluid_str_setting_t*) node; + fluid_str_setting_t* setting = &node->str; char* copy = FLUID_STRDUP(s); setting->options = fluid_list_append(setting->options, copy); setting->hints |= FLUID_HINT_OPTIONLIST; @@ -1033,7 +1054,7 @@ fluid_settings_remove_option(fluid_settings_t* settings, const char *name, const if (fluid_settings_get(settings, name, &node) == FLUID_OK && (node->type == FLUID_STR_TYPE)) { - fluid_str_setting_t* setting = (fluid_str_setting_t*) node; + fluid_str_setting_t* setting = &node->str; fluid_list_t* list = setting->options; while (list) { @@ -1065,7 +1086,6 @@ int fluid_settings_setnum(fluid_settings_t* settings, const char *name, double val) { fluid_setting_node_t *node; - fluid_num_setting_t* setting; int retval = FLUID_FAILED; fluid_return_val_if_fail (settings != NULL, retval); @@ -1076,7 +1096,7 @@ fluid_settings_setnum(fluid_settings_t* settings, const char *name, double val) if (fluid_settings_get(settings, name, &node) == FLUID_OK) { if (node->type == FLUID_NUM_TYPE) { - setting = (fluid_num_setting_t*) node; + fluid_num_setting_t* setting = &node->num; if (val < setting->min) val = setting->min; else if (val > setting->max) val = setting->max; @@ -1089,11 +1109,10 @@ fluid_settings_setnum(fluid_settings_t* settings, const char *name, double val) } } else { /* insert a new setting */ - fluid_num_setting_t* setting; - setting = new_fluid_num_setting(-1e10, 1e10, 0.0f, 0, NULL, NULL); - setting->value = val; - retval = fluid_settings_set(settings, name, setting); - if (retval != FLUID_OK) delete_fluid_num_setting (setting); + node = new_fluid_num_setting(-1e10, 1e10, 0.0f, 0, NULL, NULL); + node->num.value = val; + retval = fluid_settings_set(settings, name, node); + if (retval != FLUID_OK) delete_fluid_num_setting (node); } fluid_rec_mutex_unlock (settings->mutex); @@ -1124,7 +1143,7 @@ fluid_settings_getnum(fluid_settings_t* settings, const char *name, double* val) if (fluid_settings_get(settings, name, &node) == FLUID_OK && (node->type == FLUID_NUM_TYPE)) { - fluid_num_setting_t* setting = (fluid_num_setting_t*) node; + fluid_num_setting_t* setting = &node->num; *val = setting->value; retval = FLUID_OK; } @@ -1160,7 +1179,7 @@ fluid_settings_getnum_range(fluid_settings_t* settings, const char *name, if (fluid_settings_get(settings, name, &node) == FLUID_OK && (node->type == FLUID_NUM_TYPE)) { - fluid_num_setting_t* setting = (fluid_num_setting_t*) node; + fluid_num_setting_t* setting = &node->num; *min = setting->min; *max = setting->max; retval = FLUID_OK; @@ -1194,7 +1213,7 @@ fluid_settings_getnum_default(fluid_settings_t* settings, const char *name, doub if (fluid_settings_get(settings, name, &node) == FLUID_OK && (node->type == FLUID_NUM_TYPE)) { - fluid_num_setting_t* setting = (fluid_num_setting_t*) node; + fluid_num_setting_t* setting = &node->num; *val = setting->def; retval = FLUID_OK; } @@ -1216,7 +1235,6 @@ int fluid_settings_setint(fluid_settings_t* settings, const char *name, int val) { fluid_setting_node_t *node; - fluid_int_setting_t* setting; int retval = FLUID_FAILED; fluid_return_val_if_fail (settings != NULL, retval); @@ -1227,7 +1245,7 @@ fluid_settings_setint(fluid_settings_t* settings, const char *name, int val) if (fluid_settings_get(settings, name, &node) == FLUID_OK) { if (node->type == FLUID_INT_TYPE) { - setting = (fluid_int_setting_t*) node; + fluid_int_setting_t* setting = &node->i; if (val < setting->min) val = setting->min; else if (val > setting->max) val = setting->max; @@ -1240,11 +1258,10 @@ fluid_settings_setint(fluid_settings_t* settings, const char *name, int val) } } else { /* insert a new setting */ - fluid_int_setting_t* setting; - setting = new_fluid_int_setting(INT_MIN, INT_MAX, 0, 0, NULL, NULL); - setting->value = val; - retval = fluid_settings_set(settings, name, setting); - if (retval != FLUID_OK) delete_fluid_int_setting (setting); + node = new_fluid_int_setting(INT_MIN, INT_MAX, 0, 0, NULL, NULL); + node->i.value = val; + retval = fluid_settings_set(settings, name, node); + if (retval != FLUID_OK) delete_fluid_int_setting (node); } fluid_rec_mutex_unlock (settings->mutex); @@ -1275,7 +1292,7 @@ fluid_settings_getint(fluid_settings_t* settings, const char *name, int* val) if (fluid_settings_get(settings, name, &node) == FLUID_OK && (node->type == FLUID_INT_TYPE)) { - fluid_int_setting_t* setting = (fluid_int_setting_t*) node; + fluid_int_setting_t* setting = &node->i; *val = setting->value; retval = FLUID_OK; } @@ -1310,7 +1327,7 @@ fluid_settings_getint_range(fluid_settings_t* settings, const char *name, if (fluid_settings_get(settings, name, &node) == FLUID_OK && (node->type == FLUID_INT_TYPE)) { - fluid_int_setting_t* setting = (fluid_int_setting_t*) node; + fluid_int_setting_t* setting = &node->i; *min = setting->min; *max = setting->max; retval = FLUID_OK; @@ -1343,7 +1360,7 @@ int fluid_settings_getint_default(fluid_settings_t* settings, const char *name, if (fluid_settings_get(settings, name, &node) == FLUID_OK && (node->type == FLUID_INT_TYPE)) { - fluid_int_setting_t* setting = (fluid_int_setting_t*) node; + fluid_int_setting_t* setting = &node->i; *val = setting->def; retval = FLUID_OK; } @@ -1387,7 +1404,7 @@ fluid_settings_foreach_option (fluid_settings_t* settings, const char *name, return; } - setting = (fluid_str_setting_t*)node; + setting = &node->str; /* Duplicate option list */ for (p = setting->options; p; p = p->next) @@ -1425,7 +1442,7 @@ fluid_settings_option_count (fluid_settings_t *settings, const char *name) fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node) == FLUID_OK && node->type == FLUID_STR_TYPE) - count = fluid_list_size (((fluid_str_setting_t *)node)->options); + count = fluid_list_size (node->str.options); fluid_rec_mutex_unlock (settings->mutex); return (count); @@ -1465,7 +1482,7 @@ fluid_settings_option_concat (fluid_settings_t *settings, const char *name, return (NULL); } - setting = (fluid_str_setting_t*)node; + setting = &node->str; /* Duplicate option list, count options and get total string length */ for (p = setting->options, count = 0, len = 0; p; p = p->next, count++) @@ -1541,7 +1558,7 @@ fluid_settings_foreach_iter (void* key, void* value, void* data) if (s) bag->names = fluid_list_append (bag->names, s); break; case FLUID_SET_TYPE: - fluid_hashtable_foreach(((fluid_set_setting_t *)value)->hashtable, + fluid_hashtable_foreach(node->set.hashtable, fluid_settings_foreach_iter, bag); break; } From eb42279d7117a6df329bfd270653c097e0cdbd83 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Oct 2017 18:57:08 +0200 Subject: [PATCH 02/12] Evaluate the synth.ladspa.active setting and check for the existance of LADSPA_FxUnit in all command handlers. --- src/bindings/fluid_ladspa.c | 30 +++++++++++++++++++++++++----- src/synth/fluid_synth.c | 15 ++++++++++----- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/bindings/fluid_ladspa.c b/src/bindings/fluid_ladspa.c index 0fa87ca7..368e57d7 100644 --- a/src/bindings/fluid_ladspa.c +++ b/src/bindings/fluid_ladspa.c @@ -221,7 +221,11 @@ fluid_LADSPA_handle_start(fluid_synth_t* synth, int ac, char** av, fluid_ostream L(fluid_ostream_printf(out,"ladspa_start: starting...")); assert(synth); - FxUnit=synth->LADSPA_FxUnit; assert(FxUnit); + FxUnit=synth->LADSPA_FxUnit; + if (!FxUnit) { + fluid_ostream_printf(out, "ladspa not active!\n"); + return FLUID_FAILED; + } /* When calling fluid_ladspastart, the Fx unit must be 'cleared' (no plugins, no libs, no nodes). Verify this here. */ if (FxUnit->NumberPlugins || FxUnit->NumberLibs){ @@ -990,7 +994,11 @@ int fluid_LADSPA_handle_add(fluid_synth_t* synth, int ac, char** av, fluid_ostre char ** CommandLine; fluid_LADSPA_FxUnit_t* FxUnit; assert(synth); - FxUnit=synth->LADSPA_FxUnit; assert(FxUnit); + FxUnit=synth->LADSPA_FxUnit; + if (!FxUnit) { + fluid_ostream_printf(out, "ladspa not active!\n"); + return FLUID_FAILED; + } if (ac>=FLUID_LADSPA_MaxTokens){ /* Can't be tested. fluidsynth limits the number of tokens. */ printf("***Error001***\n" @@ -1036,7 +1044,11 @@ int fluid_LADSPA_handle_declnode(fluid_synth_t* synth, int ac, char** av, fluid_ fluid_real_t NodeValue; fluid_LADSPA_FxUnit_t* FxUnit; assert(synth); - FxUnit=synth->LADSPA_FxUnit; assert(FxUnit); + FxUnit=synth->LADSPA_FxUnit; + if (!FxUnit) { + fluid_ostream_printf(out, "ladspa not active!\n"); + return FLUID_FAILED; + } if (ac<2){ printf("***Error028***\n" @@ -1067,7 +1079,11 @@ int fluid_LADSPA_handle_setnode(fluid_synth_t* synth, int ac, char** av, fluid_o fluid_LADSPA_FxUnit_t* FxUnit; fluid_LADSPA_Node_t* CurrentNode; assert(synth); - FxUnit=synth->LADSPA_FxUnit; assert(FxUnit); + FxUnit=synth->LADSPA_FxUnit; + if (!FxUnit) { + fluid_ostream_printf(out, "ladspa not active!\n"); + return FLUID_FAILED; + } if (ac!=2){ printf("***Error029***\n" @@ -1102,7 +1118,11 @@ int fluid_LADSPA_handle_setnode(fluid_synth_t* synth, int ac, char** av, fluid_o int fluid_LADSPA_handle_clear(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out){ fluid_LADSPA_FxUnit_t* FxUnit; assert(synth); - FxUnit=synth->LADSPA_FxUnit; assert(FxUnit); + FxUnit=synth->LADSPA_FxUnit; + if (!FxUnit) { + fluid_ostream_printf(out, "ladspa not active!\n"); + return FLUID_FAILED; + } fluid_LADSPA_clear(FxUnit); return(FLUID_OK); }; diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index 49d97666..f724046a 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -555,7 +555,7 @@ new_fluid_synth(fluid_settings_t *settings) fluid_sfloader_t* loader; double gain; int i, nbuf; - + int with_ladspa = 0; /* initialize all the conversion tables and other stuff */ if (fluid_synth_initialized == 0) @@ -694,8 +694,11 @@ new_fluid_synth(fluid_settings_t *settings) #ifdef LADSPA /* Create and initialize the Fx unit.*/ - synth->LADSPA_FxUnit = new_fluid_LADSPA_FxUnit(synth); - fluid_rvoice_mixer_set_ladspa(synth->eventhandler->mixer, synth->LADSPA_FxUnit); + fluid_settings_getint(settings, "synth.ladspa.active", &with_ladspa); + if (with_ladspa) { + synth->LADSPA_FxUnit = new_fluid_LADSPA_FxUnit(synth); + fluid_rvoice_mixer_set_ladspa(synth->eventhandler->mixer, synth->LADSPA_FxUnit); + } #endif /* allocate and add the default sfont loader */ @@ -905,8 +908,10 @@ delete_fluid_synth(fluid_synth_t* synth) #ifdef LADSPA /* Release the LADSPA Fx unit */ - fluid_LADSPA_shutdown(synth->LADSPA_FxUnit); - FLUID_FREE(synth->LADSPA_FxUnit); + if (synth->LADSPA_FxUnit) { + fluid_LADSPA_shutdown(synth->LADSPA_FxUnit); + FLUID_FREE(synth->LADSPA_FxUnit); + } #endif fluid_rec_mutex_destroy(synth->mutex); From 5ac826d0e0ee93f12a5053ae97e684aec47402df Mon Sep 17 00:00:00 2001 From: Tom M Date: Wed, 4 Oct 2017 19:54:57 +0200 Subject: [PATCH 03/12] fail if LADSPA alloc fails but was requested by user --- src/synth/fluid_synth.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index f724046a..16466edc 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -697,6 +697,10 @@ new_fluid_synth(fluid_settings_t *settings) fluid_settings_getint(settings, "synth.ladspa.active", &with_ladspa); if (with_ladspa) { synth->LADSPA_FxUnit = new_fluid_LADSPA_FxUnit(synth); + if(synth->LADSPA_FxUnit == NULL) { + FLUID_LOG(FLUID_ERR, "Out of memory"); + goto error_recovery; + } fluid_rvoice_mixer_set_ladspa(synth->eventhandler->mixer, synth->LADSPA_FxUnit); } #endif From 10c4cfa29e6a041c02335d255a1cfd27677812a0 Mon Sep 17 00:00:00 2001 From: Tom M Date: Wed, 4 Oct 2017 19:59:31 +0200 Subject: [PATCH 04/12] return NULL if LADSPA alloc fails instead of assertion fail --- src/bindings/fluid_ladspa.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/bindings/fluid_ladspa.c b/src/bindings/fluid_ladspa.c index 368e57d7..0d714bdd 100644 --- a/src/bindings/fluid_ladspa.c +++ b/src/bindings/fluid_ladspa.c @@ -40,9 +40,13 @@ #define L(x); fluid_LADSPA_FxUnit_t* new_fluid_LADSPA_FxUnit(fluid_synth_t* synth){ + if(synth == NULL) + return NULL; + fluid_LADSPA_FxUnit_t* FxUnit=FLUID_NEW(fluid_LADSPA_FxUnit_t); - assert(FxUnit); - assert(synth); + if(FxUnit == NULL) + return NULL; + /* The default state is 'bypassed'. The Fx unit has to be turned on explicitly by the user. */ /* Those settings have to be done in order to allow fluid_LADSPA_clean. */ FxUnit->Bypass=fluid_LADSPA_Bypassed; From dd39761dbda7d5bec14711e0158cc65bb47e6516 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Oct 2017 19:37:00 +0200 Subject: [PATCH 05/12] Retrieve channel config from synth instance The audio-groups, audio-channels and effect-channels settings have already been read and set on the synth instance. No need to read them in again, especially not in fluid_LADSPA_run, as that is called very often. --- src/bindings/fluid_ladspa.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/bindings/fluid_ladspa.c b/src/bindings/fluid_ladspa.c index 0d714bdd..010cbac0 100644 --- a/src/bindings/fluid_ladspa.c +++ b/src/bindings/fluid_ladspa.c @@ -68,19 +68,12 @@ void fluid_LADSPA_CreateSystemNodes(fluid_LADSPA_FxUnit_t* FxUnit){ int nr_input_nodes; int nr_fx_input_nodes; int nr_output_nodes; - int temp; int i; /* Retrieve the number of synth / audio out / Fx send nodes */ - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-groups", &temp) == FLUID_OK); - nr_input_nodes=(int) temp; - printf("%i audio groups\n", nr_input_nodes); - - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-channels", &temp) == FLUID_OK); - nr_output_nodes=temp; - - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.effects-channels", &temp) == FLUID_OK); - nr_fx_input_nodes=temp; + nr_input_nodes = FxUnit->synth->audio_groups; + nr_output_nodes = FxUnit->synth->audio_channels; + nr_fx_input_nodes = FxUnit->synth->effects_channels; /* Create regular input nodes (associated with audio groups) */ for (i=0; i < nr_input_nodes; i++){ @@ -714,17 +707,11 @@ fluid_LADSPA_run(fluid_LADSPA_FxUnit_t* FxUnit, fluid_real_t* left_buf[], fluid_ int byte_size = FLUID_BUFSIZE * sizeof(fluid_real_t); char str[99]; fluid_LADSPA_Node_t* n; - int temp; /* Retrieve the number of synth / audio out / Fx send nodes */ - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-groups", &temp) == FLUID_OK); - nr_groups=(int) temp; - - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-channels", &temp) == FLUID_OK); - nr_audio_channels=temp; - - assert(fluid_settings_getint(FxUnit->synth->settings, "synth.effects-channels", &temp) == FLUID_OK); - nr_fx_sends=temp; + nr_groups = FxUnit->synth->audio_groups; + nr_audio_channels = FxUnit->synth->audio_channels; + nr_fx_sends = FxUnit->synth->effects_channels; /* Fixme: Retrieving nodes via names is inefficient * (but not that bad, because the interesting nodes are always at the start of the list). From e7ab4f3b8d890c22cd067790152c3491163c6b3f Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Oct 2017 21:35:13 +0200 Subject: [PATCH 06/12] Create the correct number of output nodes (also removed unused variable warning) --- src/bindings/fluid_ladspa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/fluid_ladspa.c b/src/bindings/fluid_ladspa.c index 010cbac0..b31af6bd 100644 --- a/src/bindings/fluid_ladspa.c +++ b/src/bindings/fluid_ladspa.c @@ -92,7 +92,7 @@ void fluid_LADSPA_CreateSystemNodes(fluid_LADSPA_FxUnit_t* FxUnit){ }; /* Create output nodes (usually towards the sound card) */ - for (i=0; i < nr_input_nodes; i++){ + for (i=0; i < nr_output_nodes; i++){ sprintf(str, "out%i_L",(i+1)); fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_sink); sprintf(str, "out%i_R",(i+1)); From 30dc8f399a33740b0df67b2a5bfd2aadaa473410 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Oct 2017 21:40:15 +0200 Subject: [PATCH 07/12] Constant nodes now use '$' as first char. '#' is being treated as a comment by g_shell_parse_argv --- src/bindings/fluid_ladspa.c | 8 ++++---- src/bindings/fluid_ladspa.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bindings/fluid_ladspa.c b/src/bindings/fluid_ladspa.c index b31af6bd..e142dfde 100644 --- a/src/bindings/fluid_ladspa.c +++ b/src/bindings/fluid_ladspa.c @@ -858,8 +858,8 @@ fluid_LADSPA_CreateNode(fluid_LADSPA_FxUnit_t* FxUnit, char * Name, int flags){ printf( "***Error026***\n" "The node name %s starts with a digit / minus sign!\n" "Please use a letter to start a node name.\n" - "A constant node is created by using `#' as first character,\n" - "for example #-2.5.\n", + "A constant node is created by using `$' as first character,\n" + "for example $-2.5.\n", Name); fluid_LADSPA_clear(FxUnit); return NULL; @@ -889,8 +889,8 @@ fluid_LADSPA_CreateNode(fluid_LADSPA_FxUnit_t* FxUnit, char * Name, int flags){ NewNode->OutCount=0; NewNode->flags=flags; - /* A nodename starting with "#" means that the node holds a constant value. */ - if (NewNode->Name[0] == '#'){ + /* A nodename starting with "$" means that the node holds a constant value. */ + if (NewNode->Name[0] == '$'){ assert(flags & fluid_LADSPA_node_is_control); /* Skip the first character => +1 */ NewNode->buf[0]=(LADSPA_Data)atof(NewNode->Name+1); diff --git a/src/bindings/fluid_ladspa.h b/src/bindings/fluid_ladspa.h index eb07ffe6..581c0bc4 100644 --- a/src/bindings/fluid_ladspa.h +++ b/src/bindings/fluid_ladspa.h @@ -122,7 +122,7 @@ typedef struct { /* List of Command lines * During the setup phase, each ladspa_add command creates one command sequence. For example: - * ./aw.so alienwah_stereo Input <- Master_L_Synth Output -> Master_R_Synth Parameter <- #42.0 + * ./aw.so alienwah_stereo Input <- Master_L_Synth Output -> Master_R_Synth Parameter <- $42.0 * Those lists are stored in LADSPA_Command_Sequence. * One command line results in one plugin => size MaxPlugins. */ From 842d8ba963bde751d51ae7368d078275018e2b10 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Oct 2017 22:38:49 +0200 Subject: [PATCH 08/12] Use proper type of node->buf for later memset to avoid buffer overflows --- src/bindings/fluid_ladspa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/fluid_ladspa.c b/src/bindings/fluid_ladspa.c index e142dfde..89b9ae6e 100644 --- a/src/bindings/fluid_ladspa.c +++ b/src/bindings/fluid_ladspa.c @@ -704,7 +704,7 @@ fluid_LADSPA_run(fluid_LADSPA_FxUnit_t* FxUnit, fluid_real_t* left_buf[], fluid_ int nr_audio_channels; int nr_fx_sends; int nr_groups; - int byte_size = FLUID_BUFSIZE * sizeof(fluid_real_t); + int byte_size = FLUID_BUFSIZE * sizeof(LADSPA_Data); char str[99]; fluid_LADSPA_Node_t* n; From 84fe779b989464946b4630005ca93dbd9a939b65 Mon Sep 17 00:00:00 2001 From: derselbst Date: Fri, 6 Oct 2017 10:25:38 +0200 Subject: [PATCH 09/12] jack: atomically get audio_driver --- src/drivers/fluid_jack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/fluid_jack.c b/src/drivers/fluid_jack.c index fe824209..51f63a96 100644 --- a/src/drivers/fluid_jack.c +++ b/src/drivers/fluid_jack.c @@ -554,7 +554,7 @@ fluid_jack_driver_process (jack_nframes_t nframes, void *arg) } } - audio_driver = client->audio_driver; + audio_driver = fluid_atomic_pointer_get (&client->audio_driver); if (!audio_driver) return 0; if (audio_driver->callback != NULL) From 3a4385c7f6bd8d3bf57bfe3a79f20adbe4016eeb Mon Sep 17 00:00:00 2001 From: derselbst Date: Fri, 6 Oct 2017 10:28:28 +0200 Subject: [PATCH 10/12] settings: avoid silent error hiding fail if param out of range, addresses #225 --- src/utils/fluid_settings.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/utils/fluid_settings.c b/src/utils/fluid_settings.c index bf1d71e9..8bdc3035 100644 --- a/src/utils/fluid_settings.c +++ b/src/utils/fluid_settings.c @@ -1098,8 +1098,11 @@ fluid_settings_setnum(fluid_settings_t* settings, const char *name, double val) if (node->type == FLUID_NUM_TYPE) { fluid_num_setting_t* setting = &node->num; - if (val < setting->min) val = setting->min; - else if (val > setting->max) val = setting->max; + if (val < setting->min || val > setting->max) + { + FLUID_LOG(FLUID_DBG, "requested set value for %s out of range", name); + return retval; + } setting->value = val; @@ -1247,8 +1250,11 @@ fluid_settings_setint(fluid_settings_t* settings, const char *name, int val) if (node->type == FLUID_INT_TYPE) { fluid_int_setting_t* setting = &node->i; - if (val < setting->min) val = setting->min; - else if (val > setting->max) val = setting->max; + if (val < setting->min || val > setting->max) + { + FLUID_LOG(FLUID_DBG, "requested set value for %s out of range", name); + return retval; + } setting->value = val; From 6e3644d1aa71626b6f1abfc83153c68f5d22733f Mon Sep 17 00:00:00 2001 From: derselbst Date: Fri, 6 Oct 2017 10:31:44 +0200 Subject: [PATCH 11/12] cleanup fluidsynth.c --- src/fluidsynth.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/fluidsynth.c b/src/fluidsynth.c index 822c118c..8495d562 100644 --- a/src/fluidsynth.c +++ b/src/fluidsynth.c @@ -42,10 +42,6 @@ #include "config_win32.h" #endif -#ifdef HAVE_SIGNAL_H -#include "signal.h" -#endif - #include "fluid_lash.h" #ifndef WITH_MIDI @@ -263,16 +259,6 @@ fast_render_loop(fluid_settings_t* settings, fluid_synth_t* synth, fluid_player_ delete_fluid_file_renderer(renderer); } -#ifdef HAVE_SIGNAL_H -/* - * handle_signal - */ -void handle_signal(int sig_num) -{ -} -#endif - - /* * main */ @@ -632,10 +618,6 @@ int main(int argc, char** argv) argv[i]); } -#ifdef HAVE_SIGNAL_H -/* signal(SIGINT, handle_signal); */ -#endif - /* start the synthesis thread */ if (!fast_render) { adriver = new_fluid_audio_driver(settings, synth); @@ -682,9 +664,9 @@ int main(int argc, char** argv) /* run commands specified in config file */ if (config_file != NULL) { fluid_source(cmd_handler, config_file); - } else if (fluid_get_userconf(buf, 512) != NULL) { + } else if (fluid_get_userconf(buf, sizeof(buf)*sizeof(buf[0])) != NULL) { fluid_source(cmd_handler, buf); - } else if (fluid_get_sysconf(buf, 512) != NULL) { + } else if (fluid_get_sysconf(buf, sizeof(buf)*sizeof(buf[0])) != NULL) { fluid_source(cmd_handler, buf); } From 2b861a12eb20c5f2a10b26d62ad9293dbfc2b426 Mon Sep 17 00:00:00 2001 From: derselbst Date: Fri, 6 Oct 2017 10:34:35 +0200 Subject: [PATCH 12/12] assure audio_groups is not overwritten with an unset value, fixes #225 --- src/fluidsynth.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/fluidsynth.c b/src/fluidsynth.c index 8495d562..860622fa 100644 --- a/src/fluidsynth.c +++ b/src/fluidsynth.c @@ -575,14 +575,18 @@ int main(int argc, char** argv) } #endif - /* The 'groups' setting is only relevant for LADSPA operation + /* The 'groups' setting is relevant for LADSPA operation and channel mapping + * in rvoice_mixer. * If not given, set number groups to number of audio channels, because * they are the same (there is nothing between synth output and 'sound card') */ if ((audio_groups == 0) && (audio_channels != 0)) { audio_groups = audio_channels; } - fluid_settings_setint(settings, "synth.audio-groups", audio_groups); + if (audio_groups != 0) + { + fluid_settings_setint(settings, "synth.audio-groups", audio_groups); + } if (fast_render) { midi_in = 0;