2002-xx-xx
+ - options.c rewritten (new mutt style rc file support)
- added a spec file for rpm support
- bugfixes
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
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
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 =
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)
- new file format (xml?)
- new configuration system (maybe not yet in 0.5)
- custom views, keybindings
+ - update man pages
{
set_filenames();
check_abook_directory();
- init_options();
+ init_opts();
+ load_opts(rcfile);
signal(SIGKILL, quit_abook_sig);
signal(SIGTERM, quit_abook_sig);
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);
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();
quit_mutt_query(int status)
{
close_database();
- close_config();
+ free_opts();
exit(status);
}
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],
init_mutt_query()
{
set_filenames();
- init_options();
+ init_opts();
+ load_opts(rcfile);
if( load_database(datafile) ) {
printf("Cannot open database\n");
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;
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;
#endif
set_filenames();
- init_options();
+ init_opts();
+ load_opts(rcfile);
switch( import_file(srcformat, srcfile) ) {
case -1:
}
close_database();
- close_config();
+ free_opts();
exit(ret);
}
{
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
#define DIR_IN_HOME ".abook"
#define DATAFILE "addressbook"
+#define RCFILE "abookrc"
+
/*
* some "abookwide" useful macros
*/
ret = readline(NULL);
- if(rl_cancelled) {
- if(ret)
- free(ret);
+ if(rl_cancelled && ret) {
+ free(ret);
ret = NULL;
}
+++ /dev/null
-
-/*
- *
- * $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;
-}
-
+++ /dev/null
-
-/*
- *
- * $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
#include <unistd.h>
#include <fcntl.h>
#include "abook.h"
+#include <assert.h>
#include "database.h"
#include "list.h"
#include "misc.h"
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
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;
}
}
}
+/*
+ * 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)
{
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]);
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;
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"
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++) {
* 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
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 {
#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)
#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)
{
* 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;
}
+
#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
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() )
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();
#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