#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"); }