219 lines
5.3 KiB
C
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");
|
|
}
|