git: initial import (.gitignore)
[evilwm.git] / xconfig.c
blobf86d326965e625db6681ff27c8b396a48f237772
1 /* evilwm - Minimalist Window Manager for X
2 * Copyright (C) 1999-2009 Ciaran Anscomb
3 * see README for license and other details. */
5 #include <ctype.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
10 #include "xconfig.h"
12 static struct xconfig_option *find_option(struct xconfig_option *options,
13 const char *opt) {
14 int i;
15 for (i = 0; options[i].type != XCONFIG_END; i++) {
16 if (0 == strcmp(options[i].name, opt)) {
17 return &options[i];
20 return NULL;
23 static void set_option(struct xconfig_option *option, const char *arg) {
24 switch (option->type) {
25 case XCONFIG_BOOL:
26 *(int *)option->dest = 1;
27 break;
28 case XCONFIG_INT:
29 *(int *)option->dest = strtol(arg, NULL, 0);
30 break;
31 case XCONFIG_STRING:
32 *(char **)option->dest = strdup(arg);
33 break;
34 case XCONFIG_CALL_0:
35 ((void (*)(void))option->dest)();
36 break;
37 case XCONFIG_CALL_1:
38 ((void (*)(const char *))option->dest)(arg);
39 break;
40 default:
41 break;
45 /* Simple parser: one directive per line, "option argument" */
46 enum xconfig_result xconfig_parse_file(struct xconfig_option *options,
47 const char *filename) {
48 struct xconfig_option *option;
49 char buf[256];
50 char *line, *opt, *arg;
51 FILE *cfg;
52 cfg = fopen(filename, "r");
53 if (cfg == NULL) return XCONFIG_FILE_ERROR;
54 while ((line = fgets(buf, sizeof(buf), cfg))) {
55 while (isspace((int)*line))
56 line++;
57 if (*line == 0 || *line == '#')
58 continue;
59 opt = strtok(line, "\t\n\v\f\r =");
60 if (opt == NULL) continue;
61 arg = strtok(NULL, "\t\n\v\f\r =");
62 option = find_option(options, opt);
63 if (option == NULL) {
64 fclose(cfg);
65 return XCONFIG_BAD_OPTION;
67 set_option(option, arg);
69 fclose(cfg);
70 return XCONFIG_OK;
73 enum xconfig_result xconfig_parse_cli(struct xconfig_option *options,
74 int argc, char **argv, int *argn) {
75 struct xconfig_option *option;
76 int _argn;
77 char *optstr;
78 _argn = argn ? *argn : 1;
80 while (_argn < argc) {
81 if (argv[_argn][0] != '-') {
82 break;
84 if (0 == strcmp("--", argv[_argn])) {
85 _argn++;
86 break;
88 optstr = argv[_argn]+1;
89 if (*optstr == '-') optstr++;
90 option = find_option(options, optstr);
91 if (option == NULL) {
92 if (argn) *argn = _argn;
93 return XCONFIG_BAD_OPTION;
95 if (option->type == XCONFIG_BOOL
96 || option->type == XCONFIG_CALL_0) {
97 set_option(option, NULL);
98 _argn++;
99 continue;
101 if ((_argn + 1) >= argc) {
102 if (argn) *argn = _argn;
103 return XCONFIG_MISSING_ARG;
105 set_option(option, argv[_argn+1]);
106 _argn += 2;
108 if (argn) *argn = _argn;
109 return XCONFIG_OK;