From: Andy Spencer Date: Thu, 6 Oct 2011 04:59:58 +0000 (+0000) Subject: Add configuration interface X-Git-Url: http://pileus.org/git/?p=wmpus;a=commitdiff_plain;h=d28df0d848dc7e30f2df67518a251b52981a1093 Add configuration interface --- diff --git a/conf.c b/conf.c new file mode 100644 index 0000000..7f55334 --- /dev/null +++ b/conf.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2011, Andy Spencer + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + */ + +#include +#include +#include +#include + +#include "util.h" +#include "conf.h" + +/* Types */ +typedef enum { number, string } type_t; + +typedef struct { + type_t type; + char *key; + union { + int num; + char *str; + }; +} entry_t; + +/* Data */ +static void *conf; + +/* Helpers */ +static int conf_cmp(const void *_a, const void *_b) +{ + const entry_t *a = _a; + const entry_t *b = _b; + return strcmp(a->key, b->key); +} + +static entry_t *conf_get(const char *key) +{ + entry_t try = { .key = (char*)key }; + entry_t **found = tfind(&try, &conf, conf_cmp); + return found ? *found : NULL; +} + +static void conf_set(const char *key, int num, const char *str) +{ + entry_t *entry; + + /* Free old item */ + if ((entry = conf_get(key))) { + tdelete(entry, &conf, conf_cmp); + free(entry->key); + if (entry->type == string) + free(entry->str); + free(entry); + } + + /* Insert new item */ + entry = new0(entry_t); + entry->key = strdup(key); + if (str) { + entry->type = string; + entry->str = strdup(str); + } else { + entry->type = number; + entry->num = num; + } + tsearch(entry, &conf, conf_cmp); +} + +static char *strtrim(char *str) +{ + while (*str == ' ' || *str == '\t' || *str == '\n') + str++; + char *end = strchr(str, '\0'); + while (end > str && (*end == ' ' || *end == '\t' || + *end == '\n' || *end == '\0')) + *end-- = '\0'; + return str; +} + +/* Read an ini file into the configuration + * - this does not properly handle excape sequences + * - could probably make this into a real parser.. */ +static void load_file(const char *path) +{ + char line[256]={}, section[256]={}; + char key[256]={}, val[256]={}; + FILE *fd = fopen(path, "rt"); + if (!fd) return; + printf("load_file: %s\n", path); + while (fgets(line, sizeof(line), fd)) { + /* Find special characters */ + char *lbrace = strchr( line , '['); + char *rbrace = strchr((lbrace ?: line)+1, ']'); + char *equal = strchr( line , '='); + char *lquote = strchr((equal ?: line)+1, '"'); + char *rquote = strchr((lquote ?: line)+1, '"'); + char *hash = strchr((rquote ?: line)+1, '#'); + if (hash) + *hash = '\0'; + + if (lbrace && rbrace) { + /* Check for secions */ + memcpy(section, lbrace+1, rbrace-lbrace-1); + } + else if (section[0] && equal && lquote && rquote) { + /* Check for numbers/plain strings */ + memcpy(key, line, equal-line); + memcpy(val, lquote+1, rquote-lquote-1); + char *_key = strtrim(key); + conf_set_str(_key, val); + printf(" [%s.%s] = [%s]\n", section, _key, val); + } + else if (section[0] && equal) { + /* Check for strings */ + memcpy(key, line, equal-line); + strcpy(val, equal+1); + char *_key = strtrim(key); + char *_val = strtrim(val); + char *end; + int num = strtol(_val, &end, 10); + if (end != val && *end == '\0') + conf_set_int(_key, num); + else if (!strcasecmp(_val, "true")) + conf_set_int(_key, 1); + else if (!strcasecmp(_val, "false")) + conf_set_int(_key, 0); + else + conf_set_str(_key, _val); + printf(" [%s.%s] = [%s]\n", section, _key, _val); + } + } + fclose(fd); +} + +static void load_args(int argc, char **argv) +{ + /* ... */ +} + + +/* Configuration file functions */ +int conf_get_int(const char *key) +{ + entry_t *entry = conf_get(key); + return entry ? entry->num : 0; +} + +void conf_set_int(const char *key, int value) +{ + conf_set(key, value, NULL); +} + +const char *conf_get_str(const char *key) +{ + entry_t *entry = conf_get(key); + return entry ? entry->str : NULL; +} + +void conf_set_str(const char *key, const char *value) +{ + conf_set(key, 0, value); +} + +void conf_init(int argc, char **argv) +{ + /* Load configuration */ + char path[256]; + snprintf(path, sizeof(path), "%s/%s", getenv("HOME"), ".wmpus"); + load_file(path); + load_args(argc, argv); +} + +void conf_free(void) +{ +} diff --git a/conf.h b/conf.h new file mode 100644 index 0000000..c63a5bc --- /dev/null +++ b/conf.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011, Andy Spencer + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + */ + +int conf_get_int(const char *key); + +const char *conf_get_str(const char *key); + +void conf_set_int(const char *key, int value); + +void conf_set_str(const char *key, const char *value); + +void conf_init(int argc, char **argv); + +void conf_free(void); diff --git a/main.c b/main.c index 1054b7c..def49f1 100644 --- a/main.c +++ b/main.c @@ -17,15 +17,19 @@ #include #include "util.h" +#include "conf.h" #include "sys.h" #include "wm.h" int main(int argc, char **argv) { setbuf(stdout, NULL); // debug + conf_init(argc, argv); win_t *root = sys_init(); wm_init(root); + sys_run(root); + wm_free(root); sys_free(root); return 0; diff --git a/makefile b/makefile index b7a1e8c..c020215 100644 --- a/makefile +++ b/makefile @@ -10,13 +10,13 @@ endif ifeq ($(SYS),win32) CC = i686-pc-mingw32-gcc -CFLAGS += -D_NO_OLDNAMES -DMARGIN=15 +CFLAGS += -D_MODE_T_ -DMARGIN=15 PROG = wmpus.exe endif include config.mk -$(PROG): main.o util.o sys-$(SYS).o wm-$(WM).o +$(PROG): main.o conf.o util.o sys-$(SYS).o wm-$(WM).o $(CC) $(CFLAGS) -o $@ $+ $(LIBS) %.o: %.c $(wildcard *.h) makefile