]> Pileus Git - lackey/commitdiff
Add simple config file parser
authorAndy Spencer <andy753421@gmail.com>
Tue, 4 Jun 2013 04:36:02 +0000 (04:36 +0000)
committerAndy Spencer <andy753421@gmail.com>
Mon, 10 Jun 2013 04:57:24 +0000 (04:57 +0000)
13 files changed:
cals/dummy.c
cals/ical.c
makefile
src/cal.c
src/cal.h
src/conf.c [new file with mode: 0644]
src/conf.h [new file with mode: 0644]
src/main.c
src/test.c
src/util.c
src/util.h
src/view.c
src/view.h

index 1926bdbff99f299fdf2fc4e69bd9ef86d7b37628..4e55adef9823db5bba27c84657e60154df78dee9 100644 (file)
@@ -18,6 +18,7 @@
 #include <stdlib.h>
 
 #include "util.h"
+#include "conf.h"
 #include "date.h"
 #include "cal.h"
 
@@ -46,6 +47,13 @@ static todo_t todo = {
 
 static int     enable;
 
+/* Config parser */
+void dummy_config(const char *group, const char *name, const char *key, const char *value)
+{
+       if (match(group, "dummy") && match(key, "enable"))
+               enable = get_bool(value);
+}
+
 /* Event functions */
 event_t *dummy_events(date_t start, date_t end)
 {
index 30653edf279cca356650da044d1a183e14e0bb60..c8147371411db4a77c185eb8411e0b3348caabbd 100644 (file)
@@ -23,6 +23,7 @@
 #include <libical/ical.h>
 
 #include "util.h"
+#include "conf.h"
 #include "date.h"
 #include "cal.h"
 
@@ -43,9 +44,7 @@ typedef struct ical_t {
 } ical_t;
 
 /* Static data */
-static ical_t  calendars[] = {
-       { .location = "data/all.ics" },
-};
+static ical_t *calendars;
 
 /* Helper functions */
 static int ical_compare(const void *_a, const void *_b)
@@ -238,6 +237,40 @@ static void print_todos(todo_t *start)
                        cur->name ?: cur->desc ?: "[no summary]");
 }
 
+/* Config parser */
+void ical_config(const char *group, const char *name, const char *key, const char *value)
+{
+       ical_t *cal = NULL, *last = NULL;
+
+       /* Make sure it's valid */
+       if (!match(group, "ical") || !name)
+               return;
+
+       /* Find existing calendar */
+       for (cal = calendars; cal; last = cal, cal = cal->next)
+               if (match(cal->name, name))
+                       break;
+
+       /* Create new calendar */
+       if (!cal) {
+               cal = new0(ical_t);
+               cal->name = get_name(name);
+               if (last)
+                       last->next = cal;
+               else
+                       calendars = cal;
+               return;
+       }
+
+       /* Set calendar values */
+       if (match(key, "location"))
+               cal->location = get_string(value);
+       else if (match(key, "username"))
+               cal->username = get_string(value);
+       else if (match(key, "password"))
+               cal->password = get_string(value);
+}
+
 /* Event functions */
 event_t *ical_events(date_t _start, date_t _end)
 {
index ec91b830da4a2d8d1e50e99f47a53a7bd851aa82..c1acd8f3a9169828df4d19f7587aae47bb371f10 100644 (file)
--- a/makefile
+++ b/makefile
@@ -16,9 +16,9 @@ LDFLAGS   ?= -lncursesw -lical
 
 # Sources
 PROG      ?= lackey
-PROG_SRC  ?= main view date cal util
+PROG_SRC  ?= main view date cal conf util
 TEST      ?= test
-TEST_SRC  ?= test date cal util
+TEST_SRC  ?= test date cal conf util
 VIEWS     ?= day week month year events todo settings help
 CALS      ?= dummy ical
 
index 435bd336f81c6ecf3caa6404ff51e437b80e5b29..627feaee9ff18799607fbec24ad5ff8e05e2be49 100644 (file)
--- a/src/cal.c
+++ b/src/cal.c
@@ -23,6 +23,7 @@
 
 /* Macros */
 #define CAL(name) \
+       void     name##_config(const char *group, const char *name, const char *key, const char *value); \
        event_t *name##_events(date_t start, date_t end); \
        todo_t  *name##_todos(date_t start, date_t end)
 
@@ -150,3 +151,12 @@ void cal_load(year_t year, month_t month, day_t day, int days)
                 ical_todos(start, end));
 
 }
+
+/* Config parser */
+void cal_config(const char *group, const char *name, const char *key, const char *value)
+{
+       if (match(group, "dummy"))
+               dummy_config(group, name, key, value);
+       else if (match(group, "ical"))
+               ical_config(group, name, key, value);
+}
index ae41f3b1fc070371f0df3bfae34f334775730a65..48e1af4d20b1b0daf2cb0846c862283f76a9ae41 100644 (file)
--- a/src/cal.h
+++ b/src/cal.h
@@ -58,3 +58,4 @@ extern todo_t  *TODOS;
 /* Calendar functions */
 void cal_init(void);
 void cal_load(year_t year, month_t month, day_t day, int days);
+void cal_config(const char *group, const char *name, const char *key, const char *value);
diff --git a/src/conf.c b/src/conf.c
new file mode 100644 (file)
index 0000000..5d59d22
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+ * Copyright (C) 2013 Andy Spencer <andy753421@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "util.h"
+#include "conf.h"
+
+/* Saved formattnig struct */
+typedef struct line_t {
+       char *group;
+       char *name;
+       char *key;
+       char *value;
+       char *text;
+       int   dirty;
+       struct line_t *next;
+} line_t;
+
+/* Constat data */
+static const char *booleans[] = {
+       "false",
+       "true"
+};
+
+/* Setup info */
+static char     *filename;
+static parser_t  parser;
+static int       argc;
+static char    **argv;
+
+/* Static data */
+static line_t   *settings;
+
+/* Parsing and saving */
+static int       wasfound;
+static int       needsave;
+
+static char     *lastgroup;
+static char     *lastname;
+static char     *lastkey;
+
+/* Helper functions */
+static void conf_error(const char *value)
+{
+       if (lastname)
+               error("invalid value '%s' for %s.%s.%s",
+                               value, lastgroup, lastname, lastkey);
+       else
+               error("invalid value '%s' for %s.%s",
+                               value, lastgroup, lastkey);
+}
+
+static void set_value(const char *group, const char *name,
+               const char *key, const char *value)
+{
+       int     ingroup  = 0;
+       line_t *groupend = NULL;
+       line_t *fileend  = NULL;
+
+       /* Queue a save next time around */
+       needsave = 1;
+
+       /* Look though for existing items */
+       for (line_t *line = settings; line; line = line->next) {
+               /* Search for the correct group */
+               if (line->group)
+                       ingroup = match(line->group, group) &&
+                                 match(line->name,  name);
+               /* Set value */
+               if (ingroup && match(line->key, key)) {
+                       free(line->value);
+                       line->value = strcopy(value);
+                       line->dirty = 1;
+                       return;
+               }
+               /* Record positions for new keys */
+               if (ingroup && line->key && line->value)
+                       groupend = line;
+               else
+                       fileend = line;
+       }
+
+       /* Create new items */
+       if (groupend) {
+               /* Append to group */
+               line_t *line = new0(line_t);
+               groupend->next = line;
+               line->key      = strcopy(key);
+               line->value    = strcopy(value);
+               line->next     = groupend->next;
+       } else if (fileend)  {
+               /* Create new group */
+               line_t *blank  = new0(line_t);
+               line_t *header = new0(line_t);
+               line_t *line   = new0(line_t);
+               fileend->next = blank;
+               blank->next   = header;
+               header->group = strcopy(group);
+               header->name  = strcopy(name);
+               header->next  = line;
+               line->key     = strcopy(key);
+               line->value   = strcopy(value);
+       } else {
+               /* Create new file */
+               line_t *header = new0(line_t);
+               line_t *line   = new0(line_t);
+               settings      = header;
+               header->group = strcopy(group);
+               header->name  = strcopy(name);
+               header->next  = line;
+               line->key     = strcopy(key);
+               line->value   = strcopy(value);
+       }
+}
+
+/* Parsing functions */
+static char *scan_white(char *src)
+{
+       while (*src == ' ' || *src == '\t')
+               src++;
+       return src;
+}
+
+static char *scan_word(char *dst, char *src)
+{
+       while (islower(*src))
+               *dst++ = *src++;
+       *dst = '\0';
+       return src;
+}
+
+static char *scan_value(char *dst, char *src)
+{
+       char *start = dst;
+       while (*src != '#' && *src != '\0')
+               *dst++ = *src++;
+       do
+               *dst-- = '\0';
+       while (dst > start && (*dst == ' ' || *dst == '\t'));
+       return src;
+}
+
+static char *scan_quote(char *dst, char *src)
+{
+       while (*src != '"' && *src != '\0') {
+               if (*src == '\\') {
+                       switch (*++src) {
+                               case '\0': *dst++ = '\0';        break;
+                               case '\\': *dst++ = '\\'; src++; break;
+                               case 't':  *dst++ = '\t'; src++; break;
+                               case 'r':  *dst++ = '\r'; src++; break;
+                               case 'n':  *dst++ = '\n'; src++; break;
+                               default:   *dst++ = *src; src++; break;
+                       }
+               } else {
+                       *dst++ = *src++;
+               }
+       }
+       if (*src == '"')
+               src++;
+       *dst = '\0';
+       return src;
+}
+
+static void parse_line(line_t *dst, char *text, const char *file, int lnum)
+{
+       char *chr = scan_white(text);
+       if (*chr == '[') {
+               dst->group = malloc(strlen(chr)+1);
+               chr = scan_white(chr+1);
+               chr = scan_word(dst->group, chr);
+               chr = scan_white(chr);
+               if (*chr == '"') {
+                       dst->name = malloc(strlen(chr)+1);
+                       chr = scan_quote(dst->name, chr+1);
+                       chr = scan_white(chr);
+               }
+               if (*chr != ']')
+                       error("parsing group at %s:%d,%d -- '%.8s..'",
+                                       file, lnum, 1+chr-text, chr);
+       }
+       else if (islower(*chr)) {
+               dst->key = malloc(strlen(chr)+1);
+               chr = scan_white(chr);
+               chr = scan_word(dst->key, chr);
+               chr = scan_white(chr);
+               if (*chr != '=')
+                       error("parsing key at %s:%d,%d -- '%.8s..'",
+                                       file, lnum, 1+chr-text, chr);
+               else
+                       chr++;
+               chr = scan_white(chr);
+               dst->value = malloc(strlen(chr)+1);
+               if (*chr == '"')
+                       chr = scan_quote(dst->value, chr+1);
+               else
+                       chr = scan_value(dst->value, chr);
+       } else if (*chr != '#' && *chr != '\n' && *chr != '\0') {
+               error("parsing file at %s:%d,%d -- '%.8s..'",
+                               file, lnum, 1+chr-text, chr);
+       }
+}
+
+/* File I/O functions */
+static void conf_load(const char *path, parser_t parser)
+{
+       line_t *prev = NULL;
+       char *group = NULL, *name = NULL;
+
+       /* read the whole file */
+       int   len;
+       char *start = read_file(path, &len);
+       if (!start)
+               return;
+
+       /* run parser */
+       int lnum;
+       char *sol, *eol;
+       for (lnum = 1, sol = start; sol < (start+len); lnum++, sol = eol+1) {
+               eol = strchr(sol, '\n') ?: &start[len];
+               eol[0] = '\0';
+
+               /* update current group info */
+               line_t *line = new0(line_t);
+               line->text = strcopy(sol);
+               parse_line(line, sol, path, lnum);
+               group = line->group ? line->group : group;
+               name  = line->group ? line->name  : name;
+
+               /* Parse dynamic groups */
+               if (line->group && line->name) {
+                       wasfound  = 0;
+                       lastgroup = line->group;
+                       lastname  = line->name;
+                       lastkey   = NULL;
+                       parser(line->group, line->name, "", "");
+                       if (!wasfound)
+                               error("unknown group: line %d - [%s \"%s\"]",
+                                               lnum, group, name ?: "");
+               }
+
+               /* Parse static key/value pairs */
+               if (group && line->key && line->value) {
+                       wasfound  = 0;
+                       lastgroup = group;
+                       lastname  = name;
+                       lastkey   = line->key;
+                       parser(group, name?:"", line->key, line->value);
+                       if (!wasfound)
+                               error("unknown setting: line %d - %s.%s.%s = '%s'\n",
+                                               lnum, group, name?:"", line->key, line->value);
+               }
+
+               /* debug printout */
+               printf("parse: %s.%s.%s = '%s'\n", group, name, line->key, line->value);
+
+               /* save line formatting for the next write */
+               if (prev == NULL)
+                       settings = line;
+               else
+                       prev->next = line;
+               prev = line;
+
+       }
+       free(start);
+}
+
+void conf_save(const char *path)
+{
+       FILE *fd = fopen(path, "wt+");
+       if (!fd)
+               return;
+
+       for (line_t *cur = settings; cur; cur = cur->next) {
+               /* Output existing items */
+               if (cur->text && !cur->dirty)
+                       fprintf(fd, "%s\n", cur->text);
+
+               /* Output group and name headers */
+               else if (cur->group && cur->name)
+                       fprintf(fd, "[%s \"%s\"]\n", cur->group, cur->name);
+
+               /* Output group only headers */
+               else if (cur->group)
+                       fprintf(fd, "[%s]\n", cur->group);
+
+               /* Output key/value pairs - todo: add quotes */
+               else if (cur->key && cur->value)
+                       fprintf(fd, "\t%s = %s\n", cur->key, cur->value);
+
+               /* Output blank lines */
+               else
+                       fprintf(fd, "\n");
+       }
+
+       fclose(fd);
+}
+
+/* Initialize */
+void conf_setup(int _argc, char **_argv, const char *_name, parser_t _parser)
+{
+       const char *home = getenv("HOME");
+       filename = alloc0(strlen(home) + 1 + strlen(_name) + 1);
+       sprintf(filename, "%s/%s", home, _name);
+       parser   = _parser;
+       argc     = _argc;
+       argv     = _argv;
+}
+
+/* Initialize */
+void conf_init(void)
+{
+       conf_load(filename, parser);
+}
+
+/* Update */
+void conf_sync(void)
+{
+       if (needsave)
+               conf_save(filename);
+       needsave = 0;
+}
+
+/* Getters */
+int get_enum(const char *value, const char **map, int n)
+{
+       wasfound = 1;
+       for (int i = 0; i < n; i++)
+               if (match(map[i], value))
+                       return i;
+       conf_error(value);
+       return 0;
+}
+
+int get_bool(const char *value)
+{
+       wasfound = 1;
+       return get_enum(value, booleans, N_ELEMENTS(booleans));
+}
+
+int get_number(const char *value)
+{
+       wasfound = 1;
+       errno = 0;
+       int rval = atoi(value);
+       if (errno)
+               conf_error(value);
+       return rval;
+}
+
+char *get_string(const char *value)
+{
+       wasfound = 1;
+       return (char*)value;
+}
+
+char *get_name(const char *name)
+{
+       wasfound = 1;
+       return (char*)name;
+}
+
+/* Setters */
+void set_enum(const char *group, const char *name,
+               const char *key, int value,
+               const char **map, int n)
+{
+       if (value >= 0 && value < n)
+               set_value(group, name, key, map[value]);
+}
+
+void set_bool(const char *group, const char *name,
+               const char *key, int value)
+{
+       set_enum(group, name, key, value,
+                       booleans, N_ELEMENTS(booleans));
+}
+
+void set_number(const char *group, const char *name,
+               const char *key, int value)
+{
+       char buf[32];
+       snprintf(buf, sizeof(buf), "%d", value);
+       set_value(group, name, key, buf);
+}
+
+void set_string(const char *group, const char *name,
+               const char *key, const char *value)
+{
+       set_value(group, name, key, value);
+}
+
+void set_name(const char *group, const char *name, const char *value)
+{
+       for (line_t *line = settings; line; line = line->next) {
+               if (match(line->group, group) &&
+                   match(line->name,  name)) {
+                       free(line->name);
+                       line->name = strcopy(value);
+                       line->dirty = 1;
+                       break;
+               }
+       }
+}
+
+/* Config parser */
+static const char *colors[] = {"red", "green", "blue"};
+
+static int   test_bin = 1;
+static int   test_num = 42;
+static char *test_str = "str";
+static int   test_clr = 0;
+
+static void  test_parser(const char *group, const char *name,
+               const char *key, const char *value)
+{
+       if (match(group, "test")) {
+               if (match(key, "bin"))
+                       test_bin = get_bool(value);
+               else if (match(key, "clr"))
+                       test_clr = get_enum(value, colors, N_ELEMENTS(colors));
+               else if (match(key, "num"))
+                       test_num = get_number(value);
+               else if (match(key, "str"))
+                       test_str = get_string(value);
+       }
+}
+
+void conf_test(void)
+{
+       printf("conf_test:\n");
+
+       /* Read values from a file */
+       conf_load("data/test.rc", test_parser);
+
+       printf("\nload:\n");
+       printf("  bin: %-8d\n", test_bin);
+       printf("  clr: %-8s\n", colors[test_clr]);
+       printf("  num: %-8d\n", test_num);
+       printf("  str: %-8s\n", test_str);
+
+       /* Update values */
+       set_bool  ("test", 0,      "bin",  1);
+       set_enum  ("test", 0,      "clr",  2, colors, N_ELEMENTS(colors));
+       set_number("test", 0,      "num",  -9999);
+       set_string("test", 0,      "str",  "hello");
+
+       set_string("test", 0,      "new",  "new0");
+       set_string("test", "new",  "new",  "new1");
+       set_string("new",  0,      "newa", "new2");
+       set_string("new",  0,      "newb", "new3");
+       set_string("new",  "new",  "newa", "new4");
+       set_string("new",  "new",  "newb", "new5");
+
+       set_name  ("func", "name", "test");
+
+       /* Write back to file */
+       conf_save("data/test_out.rc");
+}
diff --git a/src/conf.h b/src/conf.h
new file mode 100644 (file)
index 0000000..ab2c885
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 Andy Spencer <andy753421@gmail.com>
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Handlers */
+typedef void (*parser_t)(const char *group, const char *name,
+                        const char *key, const char *value);
+
+/* Getters */
+int get_enum(const char *value, const char **map, int n);
+int get_bool(const char *value);
+int get_number(const char *value);
+char *get_string(const char *value);
+char *get_name(const char *name);
+
+/* Setters */
+void set_enum(const char *group, const char *name,
+               const char *key, int value,
+               const char **map, int n);
+void set_bool(const char *group, const char *name,
+               const char *key, int value);
+void set_number(const char *group, const char *name,
+               const char *key, int value);
+void set_string(const char *group, const char *name,
+               const char *key, const char *value);
+void set_name(const char *group, const char *name,
+               const char *value);
+
+/* Functions */
+void conf_setup(int argc, char **argv, const char *name, parser_t parser);
+void conf_init(void);
+void conf_sync(void);
index af019b36d17f41953b0a05b1dd111fdab4dcba3b..d3fa34d2c1120d2624e20779e4cb9aca68d59695 100644 (file)
 #include <ncurses.h>
 
 #include "util.h"
+#include "conf.h"
 #include "date.h"
 #include "cal.h"
 #include "view.h"
 
+/* Config parser */
+static void on_config(const char *group, const char *name, const char *key, const char *value)
+{
+       view_config(group, name, key, value);
+       cal_config(group, name, key, value);
+}
+
 /* Control-C handler, so we don't hose the therminal */
 static void on_sigint(int signum)
 {
@@ -61,8 +69,12 @@ int main(int argc, char **argv)
        init_pair(COLOR_WORK,  COLOR_MAGENTA, -1);
        init_pair(COLOR_OTHER, COLOR_RED,     -1);
 
+       /* Configuration */
+       conf_setup(argc, argv, ".lackeyrc", on_config);
+
        /* Initialize */
        util_init();
+       conf_init();
        date_init();
        cal_init();
        view_init();
@@ -73,6 +85,7 @@ int main(int argc, char **argv)
        /* Run */
        while (1) {
                MEVENT btn;
+               conf_sync();
                int chr = getch();
                if (chr == 'q')
                        break;
index a9ed06c4c9c958616d0d81ebdd0bf6dceede8bd3..d6f9d4564eb555a931e5eb0bc29c5cf3db1aee73 100644 (file)
 
 #include "date.h"
 #include "cal.h"
+#include "conf.h"
 #include "util.h"
 
 void date_test(void);
 void ical_test(void);
+void conf_test(void);
 
 int main(int argc, char **argv)
 {
        for (int i = 1; i < argc; i++) {
                if (match(argv[i], "date")) date_test();
                if (match(argv[i], "ical")) ical_test();
+               if (match(argv[i], "conf")) conf_test();
        }
        return 0;
 }
index 197f3d8ea17ca09f95b485701357d296feb1190c..d6c2b50f481163b49d2544d8223a118fde143418 100644 (file)
@@ -109,6 +109,39 @@ void *alloc0(int size)
        return data;
 }
 
+/* File functions */
+char *read_file(const char *path, int *len)
+{
+       /* we could use stat, but we'll try to be portable */
+       FILE *fd = fopen(path, "rt+");
+       if (!fd)
+               return NULL;
+
+       int   block = 512; // read size
+       int   size  = 512; // buffer size
+       int   slen  = 0;   // string length
+       char *buf   = malloc(size);
+       if (!buf)
+               goto err;
+
+       while (!feof(fd)) {
+               if (slen + block + 1 > size) {
+                       size *= 2;
+                       buf   = realloc(buf, size);
+                       if (!buf)
+                               goto err;
+               }
+               slen += fread(&buf[slen], 1, block, fd);
+               buf[slen] = '\0';
+       }
+
+err:
+       if (len)
+               *len = slen;
+       fclose(fd);
+       return buf;
+}
+
 /* Debugging functions */
 void debug(char *fmt, ...)
 {
index 5427686279adb96a26b812d826854376bd88f195..39c07495d5ddce724492b99aa9b2c851eb102b8a 100644 (file)
@@ -35,6 +35,9 @@ int match(const char *a, const char *b);
 /* Memory functions */
 void *alloc0(int size);
 
+/* File functions */
+char *read_file(const char *path, int *len);
+
 /* Debug functions */
 void debug(char *fmt, ...);
 void error(char *fmt, ...);
index 3417676c783a7d163cc36bb612a1f186a94d81e2..1c29d5418a0a3b57146a27cc3a76d67c7370e74e 100644 (file)
@@ -21,6 +21,7 @@
 #include <ncurses.h>
 
 #include "util.h"
+#include "conf.h"
 #include "date.h"
 #include "cal.h"
 #include "view.h"
@@ -54,6 +55,12 @@ VIEW(settings);
 VIEW(help);
 
 /* View data */
+static const char *names[] = {
+       "day", "week", "month", "year",
+       "|", "events", "todo",
+       "|", "settings", "help",
+};
+
 view_t views[] = {
        { "Day",      day_init,      day_size,      day_draw,      day_run,      {KEY_F(1), '1',    } },
        { "Week",     week_init,     week_size,     week_draw,     week_run,     {KEY_F(2), '2',    } },
@@ -228,6 +235,17 @@ void view_init(void)
        }
 }
 
+/* Config parser */
+void view_config(const char *group, const char *name, const char *key, const char *value)
+{
+       if (match(group, "view")) {
+               if (match(key, "compact"))
+                       COMPACT = get_bool(value);
+               else if (match(key, "active"))
+                       ACTIVE = get_enum(value, names, N_ELEMENTS(names));
+       }
+}
+
 /* View draw */
 void view_resize(void)
 {
@@ -256,6 +274,8 @@ int view_set(int num)
 {
        if (ACTIVE != num) {
                ACTIVE = num;
+               set_enum("view", 0, "active", ACTIVE,
+                               names, N_ELEMENTS(names));
                view_draw();
        }
        return 1;
@@ -267,6 +287,7 @@ int view_run(int key, mmask_t btn, int row, int col)
        /* Check for compact mode toggle */
        if (key == 'c') {
                COMPACT ^= 1;
+               set_bool("view", 0, "compact", COMPACT);
                view_resize();
                view_draw();
                return 1;
index 64e8301cf51dcdc65a5cf11e78da9da148919f21..352359f8a98d542367403c72935499225fd51f93 100644 (file)
@@ -43,6 +43,7 @@ void todo_line(WINDOW *win, todo_t *todo, int y, int x, int w, int full);
 
 /* View functions */
 void view_init(void);
+void view_config(const char *group, const char *name, const char *key, const char *value);
 void view_resize(void);
 void view_draw(void);
 int  view_run(int key, mmask_t btn, int row, int col);