]> git.deb.at Git - pkg/abook.git/commitdiff
new configuration system
authorJaakko Heinonen <jheinonen@users.sourceforge.net>
Mon, 18 Mar 2002 10:30:14 +0000 (10:30 +0000)
committerJaakko Heinonen <jheinonen@users.sourceforge.net>
Mon, 18 Mar 2002 10:30:14 +0000 (10:30 +0000)
19 files changed:
ChangeLog
Makefile.am
Makefile.in
TODO
abook.c
abook.h
abook_rl.c
conff.c [deleted file]
conff.h [deleted file]
database.c
edit.c
filter.c
list.c
list.h
misc.c
options.c
options.h
ui.c
ui.h

index cde9daff81c5cafa72eec6eda1739e134c6014ae..7cad6e55a3e82849745c8d2dd44ff478201978f4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,5 @@
 2002-xx-xx
+ - options.c rewritten (new mutt style rc file support)
  - added a spec file for rpm support
  - bugfixes
 
index e2273be173703b9764873c284ab0529eed3f6dc8..46ca6057906c135cc4400de538d5d8349913d166 100644 (file)
@@ -1,10 +1,10 @@
 
 bin_PROGRAMS = abook
 
-abook_SOURCES = abook.c database.c filter.c list.c misc.c conff.c \
+abook_SOURCES = abook.c database.c filter.c list.c misc.c \
                options.c edit.c ldif.c ui.c getname.c \
                getopt.c getopt1.c abook_rl.c \
-               abook.h database.h filter.h list.h misc.h help.h conff.h \
+               abook.h database.h filter.h list.h misc.h help.h \
                options.h edit.h ldif.h abook_curses.h ui.h getname.h \
                getopt.h abook_rl.h
 
index bbfc365b9360ff3deada3973d9c431a7734653ce..d209d76a4e7cf6e919b65e1eda92a30e5db3eff9 100644 (file)
@@ -68,10 +68,10 @@ VERSION = @VERSION@
 
 bin_PROGRAMS = abook
 
-abook_SOURCES = abook.c database.c filter.c list.c misc.c conff.c \
+abook_SOURCES = abook.c database.c filter.c list.c misc.c \
                options.c edit.c ldif.c ui.c getname.c \
                getopt.c getopt1.c abook_rl.c \
-               abook.h database.h filter.h list.h misc.h help.h conff.h \
+               abook.h database.h filter.h list.h misc.h help.h \
                options.h edit.h ldif.h abook_curses.h ui.h getname.h \
                getopt.h abook_rl.h
 
@@ -88,8 +88,8 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I.
 CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
-abook_OBJECTS =  abook.o database.o filter.o list.o misc.o conff.o \
-options.o edit.o ldif.o ui.o getname.o getopt.o getopt1.o abook_rl.o
+abook_OBJECTS =  abook.o database.o filter.o list.o misc.o options.o \
+edit.o ldif.o ui.o getname.o getopt.o getopt1.o abook_rl.o
 abook_LDADD = $(LDADD)
 abook_DEPENDENCIES = 
 abook_LDFLAGS = 
@@ -107,10 +107,10 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
-DEP_FILES =  .deps/abook.P .deps/abook_rl.P .deps/conff.P \
-.deps/database.P .deps/edit.P .deps/filter.P .deps/getname.P \
-.deps/getopt.P .deps/getopt1.P .deps/ldif.P .deps/list.P .deps/misc.P \
-.deps/options.P .deps/ui.P
+DEP_FILES =  .deps/abook.P .deps/abook_rl.P .deps/database.P \
+.deps/edit.P .deps/filter.P .deps/getname.P .deps/getopt.P \
+.deps/getopt1.P .deps/ldif.P .deps/list.P .deps/misc.P .deps/options.P \
+.deps/ui.P
 SOURCES = $(abook_SOURCES)
 OBJECTS = $(abook_OBJECTS)
 
diff --git a/TODO b/TODO
index eaddd222d004b24c975100a3dbfbbb9391f4f35e..f344b0b9837620cc1e8b77e26706197c63bc2044 100644 (file)
--- a/TODO
+++ b/TODO
@@ -3,4 +3,5 @@
  - new file format (xml?)
  - new configuration system (maybe not yet in 0.5)
    - custom views, keybindings
+ - update man pages
 
diff --git a/abook.c b/abook.c
index fd3e336b76da349f10ac9418384113f13d5197c2..101dd69d6b41fe787c2cce462e844163a8f612d9 100644 (file)
--- a/abook.c
+++ b/abook.c
@@ -103,7 +103,8 @@ init_abook()
 {
        set_filenames();
        check_abook_directory();
-       init_options();
+       init_opts();
+       load_opts(rcfile);
 
        signal(SIGKILL, quit_abook_sig);
        signal(SIGTERM, quit_abook_sig);
@@ -121,7 +122,7 @@ init_abook()
                if(load_database(datafile) || !statusline_ask_boolean(
                                        "If you continue all changes will "
                                "be lost. Do you want to continue?", FALSE)) {
-                       close_config();
+                       free_opts();
                        /*close_database();*/
                        close_ui();
                        exit(1);
@@ -135,12 +136,12 @@ init_abook()
 void
 quit_abook()
 {
-       if( options_get_int("autosave") )
+       if( opt_get_bool(BOOL_AUTOSAVE) )
                save_database();
        else if( statusline_ask_boolean("Save database", TRUE) )
                save_database();
 
-       close_config();
+       free_opts();
        close_database();
 
        close_ui();
@@ -404,7 +405,7 @@ static void
 quit_mutt_query(int status)
 {
        close_database();
-       close_config();
+       free_opts();
 
        exit(status);
 }
@@ -417,7 +418,7 @@ muttq_print_item(FILE *file, int item)
 
        split_emailstr(item, emails);
 
-       for(i = 0; i < (options_get_int("mutt_return_all_emails") ?
+       for(i = 0; i < (opt_get_bool(BOOL_MUTT_RETURN_ALL_EMAILS) ?
                        MAX_EMAILS : 1) ; i++)
                if( *emails[i] )
                        fprintf(file, "%s\t%s\t%s\n", emails[i],
@@ -458,7 +459,8 @@ static void
 init_mutt_query()
 {
        set_filenames();
-       init_options();
+       init_opts();
+       load_opts(rcfile);
 
        if( load_database(datafile) ) {
                printf("Cannot open database\n");
@@ -506,7 +508,7 @@ void
 launch_mutt(int item)
 {
        char *cmd = NULL, *mailstr = NULL;
-       char *mutt_command = options_get_str("mutt_command");
+       char *mutt_command = opt_get_str(STR_MUTT_COMMAND);
 
        if(mutt_command == NULL || !*mutt_command)
                return;
@@ -550,7 +552,7 @@ launch_wwwbrowser(int item)
 
        if( database[item][URL] )
                cmd = mkstr("%s '%s'",
-                               options_get_str("www_command"),
+                               opt_get_str(STR_WWW_COMMAND),
                                safe_str(database[item][URL]));
        else
                return;
@@ -633,7 +635,8 @@ convert(char *srcformat, char *srcfile, char *dstformat, char *dstfile)
 #endif
 
        set_filenames();
-       init_options();
+       init_opts();
+       load_opts(rcfile);
 
        switch( import_file(srcformat, srcfile) ) {
                case -1:
@@ -663,7 +666,7 @@ convert(char *srcformat, char *srcfile, char *dstformat, char *dstfile)
                }
 
        close_database();
-       close_config();
+       free_opts();
        exit(ret);
 }
 
@@ -700,8 +703,9 @@ init_add_email()
 {
        set_filenames();
        atexit(free_filenames);
-       init_options();
-       atexit(close_config);
+       init_opts();
+       load_opts(rcfile);
+       atexit(free_opts);
 
        /*
         * we don't actually care if loading fails or not
diff --git a/abook.h b/abook.h
index d9f401c646f0fd4133c920caa5a829acdc500ae9..790d0523cd566b73e339397382cfb9c909101330 100644 (file)
--- a/abook.h
+++ b/abook.h
@@ -26,6 +26,8 @@ int           strncasecmp (const char *, const char *, size_t);
 #define DIR_IN_HOME    ".abook"
 #define DATAFILE       "addressbook"
 
+#define RCFILE         "abookrc"
+
 /*
  * some "abookwide" useful macros
  */
index 43ab31a0fe7d45323a6d06c6834e334c9a9aace2..f5d05ca69662ced96589f565702da2d8a77191ed 100644 (file)
@@ -120,9 +120,8 @@ abook_readline(WINDOW *w, int y, int x, char *s, int limit, bool use_completion)
        
        ret = readline(NULL);
 
-       if(rl_cancelled) {
-               if(ret)
-                       free(ret);
+       if(rl_cancelled && ret) {
+               free(ret);
                ret = NULL;
        }
 
diff --git a/conff.c b/conff.c
deleted file mode 100644 (file)
index 80e9c5f..0000000
--- a/conff.c
+++ /dev/null
@@ -1,208 +0,0 @@
-
-/*
- *
- * $Id$
- *
- * Copyright (C) Jaakko Heinonen
- *
- * 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include "misc.h"
-#ifdef HAVE_CONFIG_H
-#      include "config.h"
-#endif
-#include "conff.h"
-
-#ifndef DEBUG
-#      define NDEBUG   1
-#else
-#      undef NDEBUG
-#endif
-
-#include <assert.h>
-
-#ifdef _AIX
-int strcasecmp (const char *, const char *);
-int strncasecmp (const char *, const char *, size_t);
-#endif
-
-#define COMMENT_CHAR   '#'
-
-static void
-conff_free_node(struct conff_node *node)
-{
-       free(node -> value);
-       free(node -> key);
-       free(node);
-}
-
-/*
- * conff_add_key
- *
- * returns 0 if the key was successfully added
- */
-
-int
-conff_add_key(struct conff_node **ptr, char *key, char *value, int flags)
-{
-       struct conff_node *new_item, *next = NULL;
-       int replace = 0;
-
-       assert(key != NULL && value != NULL);
-
-       for(; *ptr; ptr = &( (*ptr) -> next) ) 
-               if(!strcasecmp(key, (*ptr) -> key ) ) {
-                       if (flags & REPLACE_KEY) {
-                               replace = 1;
-                               break;
-                       } else
-                               return 1;
-               }
-       
-       if( (new_item = (struct conff_node *)malloc(sizeof(struct conff_node)))
-                       == NULL )
-               return 5;
-
-       if(replace) { 
-               next = (*ptr) -> next;
-               conff_free_node(*ptr);
-       }
-
-       new_item -> key = strdup(key);
-       new_item -> value = strdup(value);
-       new_item -> next = next;
-
-       *ptr = new_item;
-
-       return 0;
-}
-
-char *
-conff_get_value(struct conff_node *node, char *key)
-{
-
-       assert(key != NULL);
-       
-       for(; node ; node = node -> next) {
-               if(!strcasecmp(node -> key, key))
-                       return node -> value;
-       }
-
-       return NULL; /* not found */
-}
-
-void
-conff_free_nodes(struct conff_node *node)
-{
-       if(node != NULL) {
-               conff_free_nodes( node -> next );
-               conff_free_node( node );
-       }
-}
-
-#ifdef DEBUG
-void
-print_values(struct conff_node *node)
-{
-        for(;node; node = node -> next)
-               fprintf(stderr, "%s - %s\n", node -> key, node -> value);
-}
-#endif
-
-void
-conff_remove_key(struct conff_node **node, char *key)
-{
-       assert(key != NULL);
-       
-       for(; *node; node = &((*node) -> next) ) {
-               if(!strcasecmp(key, (*node) -> key ) ) {
-                       struct conff_node *tmp = *node;
-                       *node = (*node) -> next;
-                       conff_free_node(tmp);
-                       return;
-               }
-       }
-}
-
-int
-conff_save_file(struct conff_node *node, char *filename)
-{
-       FILE *out;
-
-       assert(filename != NULL);
-
-       if (!(out = fopen(filename, "w")))
-               return -1;
-
-       for(; node; node = node -> next)
-               fprintf(out, "%s=%s\n", node -> key, node -> value);
-
-       fputc('\n', out);
-       fclose(out);
-
-       return 0;
-}
-
-int
-conff_load_file(struct conff_node **node, char *filename, int flags)
-{
-       FILE *in;
-       char *line = NULL, *tmp;
-       int i = 0;
-
-       assert(filename != NULL);
-
-       if (!(in = fopen(filename, "r")))
-               return -1;
-
-       for(;;) {
-               i++;
-
-               line = getaline(in);
-               if( feof(in) )
-                       break;
-               if(!line)
-                       continue;
-
-               strtrim(line);
-
-               if(*line == '\n' || *line == '\0' || *line == COMMENT_CHAR) {
-                       free(line);
-                       continue;
-               }
-
-               if ( (tmp = strchr(line, '=') )) {
-                       *tmp++ = 0;
-                       conff_add_key(node, strtrim(line), strtrim(tmp), flags);
-               } else {
-/*                      fprintf(stderr, "parse error2,line #%d\n",i);*/
-                       fclose(in);
-                       free(line);
-                       return i;
-               }
-               free(line);
-       }
-
-       free(line);
-       fclose(in);
-
-       return 0;
-}
-
diff --git a/conff.h b/conff.h
deleted file mode 100644 (file)
index 26963c9..0000000
--- a/conff.h
+++ /dev/null
@@ -1,54 +0,0 @@
-
-/*
- *
- *  $Id$
- *
- *  Copyright (C) Jaakko Heinonen
- *
- *  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 2 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, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CONFF_H
-#define _CONFF_H
-
-#include <stdlib.h>
-
-
-struct conff_node
-{
-       char *key, *value;
-
-       struct conff_node *next;
-};
-
-
-int            conff_add_key(struct conff_node **ptr, char *key,
-               char *value, int flags);
-char           *conff_get_value(struct conff_node *node, char *key);
-#ifdef DEBUG
-void           print_values(struct conff_node *root);
-#endif
-void           conff_free_nodes(struct conff_node *node);
-void           conff_remove_key(struct conff_node **node, char *key);
-int            conff_save_file(struct conff_node *node, char *filename);
-int            conff_load_file(struct conff_node **node,
-               char *filename, int flags);
-char           *strtrim(char *);
-
-
-#define DONT_REPLACE_KEY       0
-#define REPLACE_KEY            1
-
-#endif
index 8b22602e03b6a2a60121904a6cf2ae05f2fb22ad..70e5a1ccfb00942e076ca2797fc8e0eb1be18072 100644 (file)
@@ -13,6 +13,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include "abook.h"
+#include <assert.h>
 #include "database.h"
 #include "list.h"
 #include "misc.h"
@@ -318,21 +319,14 @@ remove_selected_items()
 char *
 get_surname(char *s)
 {
-       int i, a;
-       int len = strlen(s);
-       char *name = strdup(s);
+       char *p = s + strlen(s);
 
-       for( a = 0, i = len - 1; i >= 0; i--, a++ ) {
-               name[a] = s[i];
-               if(name[a] == ' ')
-                       break;
-       }
-
-       name[ a ] = 0;
+       assert(s != NULL);
 
-       revstr(name);
+       while(p > s && *(p - 1) != ' ')
+               p--;
 
-       return name;
+       return strdup(p);
 }
 
 static int
@@ -401,13 +395,13 @@ find_item(char *str, int start, int search_fields[])
                return -2; /* error */
 
        findstr = strdup(str);
-       findstr = strupper(findstr);
+       findstr = strlower(findstr);
 
        e.item = start - 1; /* must be "real start" - 1 */
        db_enumerate_items(e) {
                for( i = 0; search_fields[i] >= 0; i++ ) {
                        tmp = safe_strdup(database[e.item][search_fields[i]]);
-                       if( tmp && strstr(strupper(tmp), findstr) ) {
+                       if( tmp && strstr(strlower(tmp), findstr) ) {
                                ret = e.item;
                                goto out;
                        }
diff --git a/edit.c b/edit.c
index 9403975263bc1520a48031cc81eb0f1b2e943d9b..d8e3278065bff4922588d90ac446958e0f22e53d 100644 (file)
--- a/edit.c
+++ b/edit.c
@@ -182,6 +182,21 @@ editor_print_data(int tab, int item)
        }
 }
 
+/*
+ * function: change_field
+ *
+ * parameters:
+ *  (char *msg)
+ *   message to display as a prompt
+ *  (char **field)
+ *   a pointer to a pointer which will point a new string. if the latter
+ *   pointer != NULL it will be freed (if user doesn't cancel)
+ *
+ * returns (int)
+ *  a nonzero value if user has cancelled and zero if user has typed a
+ *  valid string
+ */
+
 static int
 change_field(char *msg, char **field)
 {
@@ -246,12 +261,9 @@ edit_emails(char c, int item)
        split_emailstr(item, emails);
        field = strdup(emails[email_num]);
 
-       if(change_field("E-mail: ", &field)) {
-#ifdef DEBUG
-               fprintf(stderr, "change_field = TRUE\n");
-#endif
-               return;
-       }
+       if(change_field("E-mail: ", &field))
+               return; /* user cancelled ( C-g ) */
+
        if(field) {
                strncpy(emails[email_num], field, MAX_EMAIL_LEN);
                fix_email_str(emails[email_num]);
index d98ad117e3e1406b3a8148691d530586cd74d944..08f49b069b538d962257b8857a4946643ab11923 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -783,11 +783,12 @@ ldif_export_database(FILE *out, struct db_enumerator e)
 static void            html_export_write_head(FILE *out, int extra_column);
 static void            html_export_write_tail(FILE *out);
 
+extern int extra_column;
+
 static int
 html_export_database(FILE *out, struct db_enumerator e)
 {
        char tmp[MAX_EMAILSTR_LEN];
-       int extra_column = options_get_int("extra_column");
 
        if( items < 1 )
                return 2;
@@ -1398,7 +1399,7 @@ text_export_database(FILE * out, struct db_enumerator e)
        char emails[MAX_EMAILS][MAX_EMAIL_LEN];
        int j;
        char *realname = get_real_name();
-       char *style = options_get_str("address_style");
+       char *style = opt_get_str(STR_ADDRESS_STYLE);
 
        fprintf(out,
                "-----------------------------------------\n%s's address book\n"
diff --git a/list.c b/list.c
index 5bb6753a4d7be745bd82e6cc565427e629c68cd3..d349209582f31f44df74ccae33045a623b8d8dfc 100644 (file)
--- a/list.c
+++ b/list.c
@@ -35,14 +35,14 @@ extern struct abook_field abook_fields[];
 WINDOW *list = NULL;
 
 static int
-init_extra_field(char *option_name)
+init_extra_field(enum str_opts option)
 {
        int i, ret = -1;
        char *option_str;
 
        assert(option_name != NULL);
        
-       option_str = options_get_str(option_name);
+       option_str = opt_get_str(option);
 
        if(option_str && *option_str) {
                for(i = 0; i < ITEM_FIELDS; i++) {
@@ -69,8 +69,8 @@ init_list()
         * init extra_column and extra alternative
         */
 
-       extra_column = init_extra_field("extra_column");
-       extra_alternative = init_extra_field("extra_alternative");
+       extra_column = init_extra_field(STR_EXTRA_COLUMN);
+       extra_alternative = init_extra_field(STR_EXTRA_ALTERNATIVE);
 }
 
 void
@@ -131,7 +131,7 @@ print_list_line(int i, int line, int highlight)
                mvwaddch(list, line, 0, '*' );
        
        mvwaddnstr(list, line, NAMEPOS, database[i][NAME], NAMELEN);
-       if( options_get_int( "show_all_emails"  ) )
+       if( opt_get_bool(BOOL_SHOW_ALL_EMAILS) )
                mvwaddnstr(list, line, EMAILPOS, database[i][EMAIL],
                                real_emaillen);
        else {
diff --git a/list.h b/list.h
index d6389791fc4477c0012fdaf841c4771a9cd9aa71..cdffe73903e4acc193eb7274e35b817b14abe9fc 100644 (file)
--- a/list.h
+++ b/list.h
@@ -36,8 +36,8 @@ enum {
 #define LIST_COLS      COLS
 
 #define NAMEPOS                2
-#define EMAILPOS        options_get_int("emailpos")
-#define EXTRAPOS       options_get_int("extrapos")
+#define EMAILPOS        opt_get_int(INT_EMAILPOS)
+#define EXTRAPOS       opt_get_int(INT_EXTRAPOS)
 
 #define NAMELEN                (EMAILPOS-NAMEPOS -1)
 #define EMAILLEN        (EXTRAPOS-EMAILPOS -1)
diff --git a/misc.c b/misc.c
index 7bf2f8fc1380f9a6b6c55f2059725c2da0afb6b2..fa67f0c99a644942f26c2b43af43ca3f85282370 100644 (file)
--- a/misc.c
+++ b/misc.c
 
 #include <assert.h>
 
-char *
-revstr(char *str)
-{
-       char *s, *s2;
-
-       assert(str != NULL);
-
-       s = s2 = strdup(str);
-
-       while( *str )
-               str++;
-
-       while( *s )
-               *--str = *s++;
-
-       free(s2);
-       return str;
-}
-
-char *
-strupper(char *str)
-{
-       char *tmp = str;
-
-       assert(str != NULL);
-
-       while( ( *str = toupper( *str ) ) )
-               str++;
-       
-       return tmp;
-}
-
 char *
 strlower(char *str)
 {
index ad0671161abf79e7da0f50fa23c3d1eb2b42c6ec..82aae49cef02ae9566945f4559608d54e061a2e4 100644 (file)
--- a/options.c
+++ b/options.c
  * by JH <jheinonen@users.sourceforge.net>
  *
  * Copyright (C) Jaakko Heinonen
+ *
  */
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
-#include "abook_curses.h"
-#include "abook.h"
+#include <ctype.h>
+#include <assert.h>
 #include "options.h"
-#ifdef HAVE_CONFIG_H
-#      include "config.h"
+#include "abook.h"
+#include "misc.h"
+
+#ifndef FALSE
+#      define FALSE    0
+#endif
+#ifndef TRUE
+#      define TRUE     1
 #endif
 
-struct conff_node *abook_config;
+#define UL     (unsigned long)
 
-static int     rcfile_exist();
-static void    default_options();
+/*
+ * option types
+ */
 
-extern char *rcfile;
+enum opt_type {
+       OT_BOOL,
+       OT_STR,
+       OT_INT
+};
 
-static char *
-abook_opt_conff_get_val(char *key)
+struct option {
+       char *option;
+       enum opt_type type;
+       unsigned int data;
+       unsigned long init;
+};
+
+static struct option abook_vars[] = {
+       { "autosave", OT_BOOL, BOOL_AUTOSAVE, TRUE },
+
+       { "show_all_emails", OT_BOOL, BOOL_SHOW_ALL_EMAILS, TRUE },
+       { "emailpos", OT_INT, INT_EMAILPOS, 25 },
+       { "extra_column", OT_STR, STR_EXTRA_COLUMN, UL "phone" },
+       { "extra_alternative", OT_STR, STR_EXTRA_ALTERNATIVE, UL "-1" },
+       { "extrapos", OT_INT, INT_EXTRAPOS, 65 },
+
+       { "mutt_command", OT_STR, STR_MUTT_COMMAND, UL "mutt" },
+       { "mutt_return_all_emails", OT_BOOL, BOOL_MUTT_RETURN_ALL_EMAILS,
+               TRUE },
+       
+       { "print_command", OT_STR, STR_PRINT_COMMAND, UL "lpr" },
+
+       { "www_command", OT_STR, STR_WWW_COMMAND, UL "lynx" },
+       
+       { "address_style", OT_STR, STR_ADDRESS_STYLE, UL "eu" },
+
+       { "use_ascii_only", OT_BOOL, BOOL_USE_ASCII_ONLY, FALSE },
+
+       { NULL }
+};
+
+static unsigned char bool_opts[BOOL_MAX];
+static int int_opts[INT_MAX];
+static char *str_opts[STR_MAX];
+
+static void
+set_int(enum int_opts opt, int value)
 {
-       int tried;
-       char *value = NULL;
+       assert(opt >= 0 && opt < INT_MAX);
 
+       int_opts[opt] = value;
+}
 
-       for(tried = 0; tried < 2; ) {
-               if( ( value = conff_get_value(abook_config, key) )
-                               == 0 ) {
-                       tried ++;
-                       default_options(); /* try with defaults */
-               } else
-                       return value;
-       }
-       return NULL;
+static void
+set_bool(enum bool_opts opt, bool value)
+{
+       assert(opt >= 0 && opt < BOOL_MAX);
+
+       bool_opts[opt] = value;
+}
+
+static void
+set_str(enum str_opts opt, char *value)
+{
+       assert(opt >= 0 && opt < STR_MAX);
+
+       if(str_opts[opt])
+               free(str_opts[opt]);
+
+       str_opts[opt] = strdup(value);
 }
 
 int
-options_get_int(char *key)
+opt_get_int(enum int_opts opt)
 {
-       char *value;
-       int ret;
-       
-       if( ( value = abook_opt_conff_get_val(key) )
-                       == NULL)
-               return 1;
+       assert(opt >= 0 && opt < INT_MAX);
 
-       if( !strcasecmp(value, "true") )
-               ret = 1;
-       else
-       if( !strcasecmp(value, "false") )
-               ret = 0;
-       else
-               ret = safe_atoi(value);
-       
-       return ret;
+       return int_opts[opt];
 }
-       
+
+bool
+opt_get_bool(enum bool_opts opt)
+{
+       assert(opt >= 0 && opt < STR_MAX);
+
+       return bool_opts[opt];
+}
+
 char *
-options_get_str(char *key)
+opt_get_str(enum str_opts opt)
 {
-       return abook_opt_conff_get_val(key); 
+       assert(opt >= 0 && opt < STR_MAX);
+
+       return str_opts[opt];
 }
-               
+
+static void
+restore_default(struct option *p)
+{
+       switch(p -> type) {
+               case OT_BOOL:
+                       set_bool(p -> data, (bool)p -> init);
+                       break;
+               case OT_INT:
+                       set_int(p -> data, (int)p -> init);
+                       break;
+               case OT_STR:
+                       if(p -> init)
+                               set_str(p -> data, (char *) p -> init);
+                       break;
+               default:
+                       assert(0);
+       }
+}
+
 void
-init_options()
+init_opts()
 {
-       abook_config = NULL;
+       int i;
 
-       if( rcfile_exist() )
-               load_options();
-       else
-               default_options();
+       for(i = 0; abook_vars[i].option; i++)
+               restore_default(&abook_vars[i]);
 }
 
+void
+free_opts()
+{
+       int i;
 
-#if 1
-extern bool alternative_rcfile;
-#endif
+       /*
+        * only strings need to be freed
+        */
+       for(i = 0; i < STR_MAX; i++) {
+               free(str_opts[i]);
+               str_opts[i] = NULL;
+       }
+}
 
-void
-close_config()
+/*
+ * file parsing
+ */
+
+static void
+opt_line_remove_comments(char *p)
 {
-#if 1
-       if(!alternative_rcfile)
-               save_options();
-#endif
+       bool in_quote = FALSE;
+       bool escape = FALSE;
+
+       assert(p != NULL);
+
+       for(; *p; p++) {
+               switch(*p) {
+                       case '\"':
+                               if(!escape) {
+                                       in_quote = !in_quote;
+                                       escape = FALSE;
+                               }
+                               break;
+                       case '\\':
+                               escape = TRUE;
+                               break;
+                       case '#':
+                               if(!in_quote) {
+                                       *p = 0;
+                                       return;
+                               }
+                       default:
+                               escape = FALSE;
+               }
+       }
+}
+
+static char *
+get_token_start(char *p)
+{
+       assert(p);
+       
+       for(; ISSPACE(*p); p++);
 
-       conff_free_nodes(abook_config);
+       return p;
 }
 
-static int
-rcfile_exist()
+static char *
+get_token_end(char *p)
 {
-       return ( (0 == access(SYSWIDE_RCFILE, F_OK)) ||
-                       (0 == access(rcfile, F_OK)) );
+       assert(p);
+
+       for(p = get_token_start(p); *p; p++) {
+               if(ISSPACE(*p)) {
+                       break;
+               }
+       }
+
+       return p;
 }
 
-void
-load_options()
+static char *
+opt_set_set_option(char *var, char *p, struct option *opt)
 {
-       int ret;
+       int len;
        
-        if( (ret = conff_load_file(&abook_config, rcfile,
-                               REPLACE_KEY)) > 0) {
-               fprintf(stderr, "%s: parse error at line %d\n", rcfile, ret);
-               exit(1);
+       strtrim(p);
+
+       len = strlen(p);
+
+       if(p[len - 1] == '\"' && *p == '\"') {
+               if(len < 3)
+                       return "invalid value";
+               p[len - 1] = 0;
+               p++;
        }
 
-       if( (ret = conff_load_file(&abook_config, SYSWIDE_RCFILE,
-                                       DONT_REPLACE_KEY )) > 0) {
-               fprintf(stderr, "%s: parse error at line %d\n",
-                               SYSWIDE_RCFILE, ret);
-               exit(1);
+       switch(opt -> type) {
+               case OT_STR:
+                       set_str(opt -> data, p);
+                       break;
+               case OT_INT:
+                       set_int(opt -> data, safe_atoi(p));
+                       break;
+               case OT_BOOL:
+                       if(!strcasecmp(p, "true") && !strcasecmp(p, "on"))
+                               set_bool(opt -> data, TRUE);
+                       else if(!strcasecmp(p, "false") &&
+                                       !strcasecmp(p, "off"))
+                               set_bool(opt -> data, FALSE);
+                       else
+                               return "invalid value";
+                       break;
        }
+       
+       return NULL;
 }
 
-#if 1
-void
-save_options()
+static char *
+opt_parse_set(char *p)
 {
-       if( rcfile_exist() ) /* don't overwrite existing config */
-               return;
+       char *var;
+       int i;
 
-       conff_save_file(abook_config, rcfile);
+       var = get_token_start(p);
+       if((p = strchr(var, '=')))
+               *p++ = 0;
+       else
+               return "invalid value assignment";
+       
+       strtrim(var);
+
+       for(i = 0;abook_vars[i].option; i++)
+               if(!strcmp(abook_vars[i].option, var))
+                       return opt_set_set_option(var, p, &abook_vars[i]);
+       
+       return "unknown option";
 }
-#endif
 
-static void
-options_add_key(char *key, char *value)
+
+static struct {
+       char *token;
+       char * (*func) (char *line);
+} opt_parsers[] = {
+       { "set", opt_parse_set },
+       { NULL }
+};
+
+static bool
+opt_parse_line(char *line, int n, char *fn)
 {
-       const int flags = DONT_REPLACE_KEY;
+       int i;
+       char *p;
+       char *err = NULL;
+       
+       assert(line && fn);
+
+       line = get_token_start(line);
+       p = get_token_end(line);
+       *p++ = 0;
+
+       if(!*line)
+               return FALSE;
 
-       conff_add_key(&abook_config, key, value, flags);
+       strtrim(line);
+       strtrim(p);
+
+       for(i = 0; opt_parsers[i].token; i++)
+               if(!strcmp(opt_parsers[i].token, line)) {
+                       if(!(err = opt_parsers[i].func(p)))
+                               return FALSE;
+                       break;
+               }
+       
+       fprintf(stderr, "%s: parse error at line %d: ", fn, n);
+       if(err)
+               fprintf(stderr, "%s\n", err);
+       else
+               fprintf(stderr, "unknown token %s\n", line);
+
+       return TRUE;
 }
 
-static void
-default_options()
+int
+load_opts(char *filename)
 {
-       options_add_key("autosave", "true");
-
-       options_add_key("show_all_emails", "true");
-       options_add_key("emailpos", "25");
-       options_add_key("extra_column", "phone");
-       options_add_key("extra_alternative", "-1");
-       options_add_key("extrapos", "65");
+       FILE *in;
+       char *line = NULL;
+       int n;
+       bool err = FALSE;
+       
+       if((in = fopen(filename, "r")) == NULL)
+               return -1;
 
-       options_add_key("mutt_command", "mutt");
-       options_add_key("mutt_return_all_emails", "true");
+       
+       for(n = 1;!feof(in); n++) {
+               line = getaline(in);
 
-       options_add_key("print_command", "lpr");
+               if(feof(in))
+                       break;
 
-       options_add_key("filesel_sort", "false");
+               if(line && *line) {
+                       opt_line_remove_comments(line);
+                       if(*line)
+                               err = opt_parse_line(line, n, filename);
+               }
 
-       options_add_key("www_command", "lynx");
+               my_free(line);
+       }
 
-       options_add_key("address_style", "eu");
+       free(line);
 
-       options_add_key("use_ascii_only", "false");
+       if(err) {
+               printf("Press any key to continue...\n");
+               fgetc(stdin);
+       }
+       
+       return err;
 }
+
index e45831447a320a99c9424b0f10f9b7b3ab451611..13e97098ed7c05ae97b3a0f07c1273312e0ac000 100644 (file)
--- a/options.h
+++ b/options.h
@@ -1,16 +1,55 @@
 #ifndef _OPTIONS_H
 #define _OPTIONS_H
 
-#define RCFILE         "abookrc"
-#define SYSWIDE_RCFILE "/etc/abookrc"
+#if 0
+typedef int bool;
+#else
+#      include <abook_curses.h> /* bool */
+#endif
+
+/*
+ * bool options
+ */
+
+
+enum bool_opts {
+       BOOL_AUTOSAVE,
+       BOOL_SHOW_ALL_EMAILS,
+       BOOL_MUTT_RETURN_ALL_EMAILS,
+       BOOL_USE_ASCII_ONLY,
+       BOOL_MAX
+};
+
+/*
+ * int options
+ */
+
+enum int_opts {
+       INT_EMAILPOS,
+       INT_EXTRAPOS,
+       INT_MAX
+};
+
+/*
+ * string options
+ */
+
+enum str_opts {
+       STR_EXTRA_COLUMN,
+       STR_EXTRA_ALTERNATIVE,
+       STR_MUTT_COMMAND,
+       STR_PRINT_COMMAND,
+       STR_WWW_COMMAND,
+       STR_ADDRESS_STYLE,
+       STR_MAX
+};
 
-#include "conff.h"
 
-int    options_get_int(char *key);
-char   *options_get_str(char *key);
-void   init_options();
-void   close_config();
-void   load_options();
-void   save_options();
+int            opt_get_int(enum int_opts opt);
+bool           opt_get_bool(enum bool_opts opt);
+char *         opt_get_str(enum str_opts opt);
+void           init_opts();
+void           free_opts();
+int            load_opts(char *filename);
 
 #endif
diff --git a/ui.c b/ui.c
index a7d1a5428322aa11503a484486f8c3685af7aecc..ceb61dbd45fcab29d2edd834a6a6bb25f7b7264d 100644 (file)
--- a/ui.c
+++ b/ui.c
@@ -538,7 +538,7 @@ void
 ui_print_database()
 {
        FILE *handle;
-       char *command = options_get_str("print_command");
+       char *command = opt_get_str(STR_PRINT_COMMAND);
        int mode;
 
        if( list_is_empty() )
@@ -586,7 +586,7 @@ ui_open_datafile()
                return;
        }
 
-       if( options_get_int("autosave") )
+       if( opt_get_bool(BOOL_AUTOSAVE) )
                save_database();
        else if(statusline_ask_boolean("Save current database", FALSE))
                save_database();
diff --git a/ui.h b/ui.h
index 33107f8dabbf28d5319a43801c309c804cc3548c..5cdd87357412ee2b2c9bb7151b6ecdc65359ed9c 100644 (file)
--- a/ui.h
+++ b/ui.h
@@ -35,7 +35,7 @@ void          ui_open_datafile();
 
 #include "options.h" /* needed for options_get_int */
 
-#define UI_HLINE_CHAR          options_get_int("use_ascii_only") ? \
+#define UI_HLINE_CHAR          opt_get_bool(BOOL_USE_ASCII_ONLY) ? \
                                        '-' : ACS_HLINE
 
 #endif