diff --git a/config_ini/Makefile b/config_ini/Makefile new file mode 100644 index 0000000..997dc38 --- /dev/null +++ b/config_ini/Makefile @@ -0,0 +1,14 @@ +CC = gcc +CFLAGS = -Wall -O2 + +TARGET = main.elf +SRC = main.c conf.c + +#LDFLAGS = + +$(TARGET): $(SRC) + @echo CC $@ + @$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +clean: + rm -f $(TARGET) diff --git a/config_ini/conf.c b/config_ini/conf.c new file mode 100644 index 0000000..48b5b8f --- /dev/null +++ b/config_ini/conf.c @@ -0,0 +1,80 @@ +#include "conf.h" +#include +#include +#include +#include + +#define MAX_LINE 256 +#define MAX_VAL 128 + +/* Trim leading/trailing whitespace */ +static char *trim(char *str) { + char *end; + + while (isspace((unsigned char)*str)) str++; + if (*str == 0) + return str; // only spaces + + end = str + strnlen(str, MAX_VAL) - 1; + + while (end > str && isspace((unsigned char)*end)) end--; + end[1] = '\0'; + return str; +} + +/* Load INI-style config */ +Config *config_load(const char *filename) { + FILE *f = fopen(filename, "r"); + if (!f) + return NULL; + + Config *cfg = calloc(1, sizeof(Config)); + char line[MAX_LINE]; + + while (fgets(line, sizeof(line), f)) { + char *s = trim(line); + + // Skip empty or comment lines + if (*s == '\0' || *s == '#' || *s == ';') + continue; + + char *eq = strchr(s, '='); + if (!eq) + continue; // invalid line, skip + + *eq = '\0'; + char *key = trim(s); + char *val = trim(eq + 1); + + ConfigEntry *entry = malloc(sizeof(ConfigEntry)); + entry->key = strndup(key, MAX_VAL); + entry->value = strndup(val, MAX_VAL); + entry->next = cfg->head; + cfg->head = entry; + } + + fclose(f); + return cfg; +} + +/* Get value for a key */ +const char *config_get(Config *cfg, const char *key) { + for (ConfigEntry *e = cfg->head; e; e = e->next) { + if (strncmp(e->key, key, MAX_VAL) == 0) + return e->value; + } + return NULL; +} + +/* Free the config struct */ +void config_free(Config *cfg) { + ConfigEntry *e = cfg->head; + while (e) { + ConfigEntry *next = e->next; + free(e->key); + free(e->value); + free(e); + e = next; + } + free(cfg); +} diff --git a/config_ini/conf.h b/config_ini/conf.h new file mode 100644 index 0000000..d158605 --- /dev/null +++ b/config_ini/conf.h @@ -0,0 +1,13 @@ +typedef struct ConfigEntry { + char *key; + char *value; + struct ConfigEntry *next; +} ConfigEntry; + +typedef struct { + ConfigEntry *head; +} Config; + +Config *config_load(const char *filename); +const char *config_get(Config *cfg, const char *key); +void config_free(Config *cfg); diff --git a/config_ini/config.ini b/config_ini/config.ini new file mode 100644 index 0000000..d95a88d --- /dev/null +++ b/config_ini/config.ini @@ -0,0 +1,6 @@ +# Example INI file +username = testuser +password = secret123 + +; comments work too +timeout = 30 diff --git a/config_ini/config_broken.ini b/config_ini/config_broken.ini new file mode 100644 index 0000000..c8b29aa --- /dev/null +++ b/config_ini/config_broken.ini @@ -0,0 +1,7 @@ +# Example INI file +username = testuser ; inline +password = secret123 # Comment + +; comments work too +[aa] +timeout = 30 diff --git a/config_ini/main.c b/config_ini/main.c new file mode 100644 index 0000000..b21a06f --- /dev/null +++ b/config_ini/main.c @@ -0,0 +1,20 @@ +#include "conf.h" +#include + +// Example usage +int main(void) { + Config *cfg = config_load("config.ini"); + if (!cfg) { + fprintf(stderr, "Failed to load config.ini\n"); + return 1; + } + + const char *user = config_get(cfg, "username"); + const char *pass = config_get(cfg, "password"); + + printf("Username: %s\n", user ? user : "(not set)"); + printf("Password: %s\n", pass ? pass : "(not set)"); + + config_free(cfg); + return 0; +}