Files
blisp/src/config.c
T
Arthur Barraux ee2a34a3b1 test functions
2025-09-18 13:52:46 +02:00

219 lines
5.3 KiB
C

#include "../include/config.h"
#include "../include/utils.h"
ConfigValue *get_config_var(const char *name) {
Value *val = env_get(global_env, name);
if (!val)
return NULL;
ConfigValue *config = malloc(sizeof(ConfigValue));
switch (val->type) {
case VAL_NUMBER:
if (val->data.number == (int)val->data.number) {
config->type = CONFIG_INT;
config->value.int_val = (int)val->data.number;
} else {
config->type = CONFIG_FLOAT;
config->value.float_val = val->data.number;
}
break;
case VAL_STRING:
config->type = CONFIG_STRING;
config->value.string_val = strdup(val->data.string);
break;
case VAL_SYMBOL:
if (strcmp(val->data.symbol, "true") == 0) {
config->type = CONFIG_BOOL;
config->value.bool_val = true;
} else if (strcmp(val->data.symbol, "false") == 0) {
config->type = CONFIG_BOOL;
config->value.bool_val = false;
} else {
config->type = CONFIG_STRING;
config->value.string_val = strdup(val->data.symbol);
}
break;
case VAL_LIST: {
config->type = CONFIG_LIST;
config->value.list_val.count = list_length(val);
config->value.list_val.items =
malloc(sizeof(char *) * config->value.list_val.count);
Value *curr = val;
int i = 0;
while (curr->type == VAL_LIST && i < config->value.list_val.count) {
Value *item = car(curr);
if (item->type == VAL_STRING) {
config->value.list_val.items[i] = strdup(item->data.string);
} else if (item->type == VAL_SYMBOL) {
config->value.list_val.items[i] = strdup(item->data.symbol);
} else if (item->type == VAL_NUMBER) {
char buffer[32];
snprintf(buffer, sizeof(buffer), "%.2f", item->data.number);
config->value.list_val.items[i] = strdup(buffer);
} else {
config->value.list_val.items[i] = strdup("unknown");
}
curr = cdr(curr);
i++;
}
break;
}
default:
config->type = CONFIG_UNKNOWN;
break;
}
return config;
}
// Convenience functions for common types
int get_config_int(const char *name, int default_val) {
ConfigValue *val = get_config_var(name);
if (!val)
return default_val;
int result = default_val;
if (val->type == CONFIG_INT) {
result = val->value.int_val;
} else if (val->type == CONFIG_FLOAT) {
result = (int)val->value.float_val;
}
free_config_value(val);
return result;
}
double get_config_float(const char *name, double default_val) {
ConfigValue *val = get_config_var(name);
if (!val)
return default_val;
double result = default_val;
if (val->type == CONFIG_FLOAT) {
result = val->value.float_val;
} else if (val->type == CONFIG_INT) {
result = (double)val->value.int_val;
}
free_config_value(val);
return result;
}
char *get_config_string(const char *name, const char *default_val) {
ConfigValue *val = get_config_var(name);
if (!val)
return default_val ? strdup(default_val) : NULL;
char *result = NULL;
if (val->type == CONFIG_STRING) {
result = strdup(val->value.string_val);
} else if (default_val) {
result = strdup(default_val);
}
free_config_value(val);
return result;
}
bool get_config_bool(const char *name, bool default_val) {
ConfigValue *val = get_config_var(name);
if (!val)
return default_val;
bool result = default_val;
if (val->type == CONFIG_BOOL) {
result = val->value.bool_val;
} else if (val->type == CONFIG_INT) {
result = val->value.int_val != 0;
}
free_config_value(val);
return result;
}
char **get_config_list(const char *name, int *count) {
ConfigValue *val = get_config_var(name);
if (!val || val->type != CONFIG_LIST) {
if (count)
*count = 0;
return NULL;
}
char **result = malloc(sizeof(char *) * val->value.list_val.count);
for (int i = 0; i < val->value.list_val.count; i++) {
result[i] = strdup(val->value.list_val.items[i]);
}
if (count)
*count = val->value.list_val.count;
free_config_value(val);
return result;
}
// Free ConfigValue
void free_config_value(ConfigValue *val) {
if (!val)
return;
switch (val->type) {
case CONFIG_STRING:
free(val->value.string_val);
break;
case CONFIG_LIST:
for (int i = 0; i < val->value.list_val.count; i++) {
free(val->value.list_val.items[i]);
}
free(val->value.list_val.items);
break;
default:
break;
}
free(val);
}
// Check if variable exists
bool config_var_exists(const char *name) {
return env_get(global_env, name) != NULL;
}
// Set variables from C code
void set_config_int(const char *name, int value) {
env_set(global_env, name, make_number(value));
}
void set_config_float(const char *name, double value) {
env_set(global_env, name, make_number(value));
}
void set_config_string(const char *name, const char *value) {
env_set(global_env, name, make_string(value));
}
void set_config_bool(const char *name, bool value) {
env_set(global_env, name, make_symbol(value ? "true" : "false"));
}
// Print all variables (for debugging)
void print_all_config_vars(void) {
printf("\n=== Configuration Variables ===\n");
Env *env = global_env;
while (env) {
for (int i = 0; i < env->count; i++) {
printf("%-20s = ", env->names[i]);
print_value(env->values[i]);
printf("\n");
}
env = env->parent;
}
printf("==============================\n\n");
}