X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=conf.c;h=889bda6e4327839927c022626a816a186b61274b;hb=f63e805feb5cc4e71fa9679f6b3bc62a5954b7f2;hp=7f55334b120d2e67d25e750172800cc22a1abad8;hpb=d28df0d848dc7e30f2df67518a251b52981a1093;p=wmpus diff --git a/conf.c b/conf.c index 7f55334..889bda6 100644 --- a/conf.c +++ b/conf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Andy Spencer + * Copyright (c) 2011-2012, 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 @@ -17,15 +17,17 @@ #include #include #include +#include #include "util.h" #include "conf.h" /* Types */ -typedef enum { number, string } type_t; - typedef struct { - type_t type; + enum { + NUMBER, + STRING, + } type; char *key; union { int num; @@ -34,7 +36,10 @@ typedef struct { } entry_t; /* Data */ -static void *conf; +static void *conf; +static int conf_argc; +static char **conf_argv; +static char conf_path[256]; /* Helpers */ static int conf_cmp(const void *_a, const void *_b) @@ -59,7 +64,7 @@ static void conf_set(const char *key, int num, const char *str) if ((entry = conf_get(key))) { tdelete(entry, &conf, conf_cmp); free(entry->key); - if (entry->type == string) + if (entry->type == STRING) free(entry->str); free(entry); } @@ -68,11 +73,13 @@ static void conf_set(const char *key, int num, const char *str) entry = new0(entry_t); entry->key = strdup(key); if (str) { - entry->type = string; + entry->type = STRING; entry->str = strdup(str); + //printf("set_str: %s = %s\n", key, str); } else { - entry->type = number; + entry->type = NUMBER; entry->num = num; + //printf("set_num: %s = %d\n", key, num); } tsearch(entry, &conf, conf_cmp); } @@ -94,10 +101,10 @@ static char *strtrim(char *str) static void load_file(const char *path) { char line[256]={}, section[256]={}; - char key[256]={}, val[256]={}; + char key[256]={}, val[256]={}, fullkey[256]={}; FILE *fd = fopen(path, "rt"); if (!fd) return; - printf("load_file: %s\n", path); + //printf("load_file: %s\n", path); while (fgets(line, sizeof(line), fd)) { /* Find special characters */ char *lbrace = strchr( line , '['); @@ -117,43 +124,110 @@ static void load_file(const char *path) /* 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); + snprintf(fullkey, sizeof(key), "%s.%s", + section, strtrim(key)); + if (!strchr(fullkey, ' ')) { + conf_set_str(fullkey, val); + //printf(" [%s] = [%s]\n", fullkey, 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); + snprintf(fullkey, sizeof(key), "%s.%s", + section, strtrim(key)); + if (!strchr(fullkey, ' ')) { + char *end, *trim = strtrim(val); + int num = strtol(trim, &end, 10); + if (end != val && *end == '\0') + conf_set_int(fullkey, num); + else if (!strcasecmp(trim, "true")) + conf_set_int(fullkey, 1); + else if (!strcasecmp(trim, "false")) + conf_set_int(fullkey, 0); + else + conf_set_str(fullkey, trim); + //printf(" [%s] = [%s]\n", fullkey, trim); + } } } fclose(fd); } +/* Load config from command line options */ +static struct option long_options[] = { + /* name hasarg flag val */ + {"no-capture", 0, NULL, 'n'}, + {"border", 2, NULL, 'b'}, + {"margin", 2, NULL, 'm'}, + {"int", 1, NULL, 'i'}, + {"str", 1, NULL, 's'}, + {"help", 0, NULL, 'h'}, + {NULL, 0, NULL, 0 }, +}; + +static void usage(int argc, char **argv) +{ + printf("Usage:\n"); + printf(" %s [OPTION...]\n", argv[0]); + printf("\n"); + printf("Options:\n"); + printf(" -n, --no-capture Do not arrange pre existing windows\n"); + printf(" -b, --border=n Draw an n pixel window border\n"); + printf(" -m, --margin=n Leave an n pixel margin around windows\n"); + printf(" -i, --int=key=num Set integer config option\n"); + printf(" -s, --str=key=str Set string config option\n"); + printf(" -h, --help Print usage information\n"); +} + static void load_args(int argc, char **argv) { - /* ... */ + char *key, *val; + while (1) { + int c = getopt_long(argc, argv, "nb:m:i:s:h", long_options, NULL); + if (c == -1) + break; + switch (c) { + case 'n': + conf_set_int("main.no-capture", 1); + break; + case 'b': + conf_set_int("main.border", str2num(optarg, 2)); + break; + case 'm': + conf_set_int("main.margin", str2num(optarg, 15)); + break; + case 'i': + case 's': + key = strdup(optarg); + val = strchr(key, '='); + if (val) { + *val++ = '\0'; + if (c == 's') + conf_set_str(key, val); + else + conf_set_int(key, atol(val)); + } + free(key); + break; + case 'h': + usage(argc, argv); + exit(0); + default: + usage(argc, argv); + exit(-1); + } + } } /* Configuration file functions */ -int conf_get_int(const char *key) +int conf_get_int(const char *key, int def) { entry_t *entry = conf_get(key); - return entry ? entry->num : 0; + return entry && entry->type == NUMBER + ? entry->num : def; } void conf_set_int(const char *key, int value) @@ -161,10 +235,11 @@ void conf_set_int(const char *key, int value) conf_set(key, value, NULL); } -const char *conf_get_str(const char *key) +const char *conf_get_str(const char *key, const char *def) { entry_t *entry = conf_get(key); - return entry ? entry->str : NULL; + return entry && entry->type == STRING + ? entry->str : def; } void conf_set_str(const char *key, const char *value) @@ -172,13 +247,20 @@ void conf_set_str(const char *key, const char *value) conf_set(key, 0, value); } +void conf_reload(void) +{ + load_file(conf_path); + load_args(conf_argc, conf_argv); +} + 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); + conf_argc = argc; + conf_argv = argv; + snprintf(conf_path, sizeof(conf_path), "%s/%s", + getenv("HOME") ?: getenv("HOMEPATH") ?: ".", + ".wmpus"); + conf_reload(); } void conf_free(void)