/*
- * Copyright (c) 2011, Andy Spencer <andy753421@gmail.com>
+ * Copyright (c) 2011-2012, Andy Spencer <andy753421@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
#include <stdio.h>
#include <string.h>
#include <search.h>
+#include <getopt.h>
#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;
} 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)
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);
}
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);
}
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 , '[');
/* 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)
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)
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)