]> git.deb.at Git - pkg/abook.git/commitdiff
Support for dynamic views.
authorCedric Duval <cedricduval@free.fr>
Tue, 25 Oct 2005 23:27:24 +0000 (23:27 +0000)
committerCedric Duval <cedricduval@free.fr>
Tue, 25 Oct 2005 23:27:24 +0000 (23:27 +0000)
* Two new configuration commands: 'field' and 'view'.
* A new configuration variable: 'preserve_fields'.
* In absence of user configuration, abook behaves and displays mostly like
  previous releases.
* More abstraction for database access. db_field_get(), db_field_put(), etc.
* Functions for handling lists of strings (abook_list)
* Functions for conversting abook_lists to CSV and vice-versa.
* Arbitrary number of email addresses internally. Still limited to 9 for
  practical reasons with the UI.
* Up to 35 fields per view.
* Escape as a modifier key in the editor.
* Addresses can be rolled both directions (esc-r).
* Fixed html produced by export filter.
* Updated abookrc man page and sample.abookrc accordingly.

25 files changed:
Makefile.am
Makefile.in
abook.c
abook.h
abookrc.5
aclocal.m4
configure
database.c
database.h
edit.c
edit.h
filter.c
help.h
list.c
list.h
misc.c
misc.h
options.c
options.h
po/POTFILES.in
sample.abookrc
ui.c
ui.h
views.c [new file with mode: 0644]
views.h [new file with mode: 0644]

index 304d60840ae736d2c0b9f45c98e7fa7329ee3182..7d87a599a1685331975826d1442787d7dd547cb3 100644 (file)
@@ -1,20 +1,22 @@
 
 bin_PROGRAMS = abook
 
-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 gettext.c abook_rl.c mbswidth.c \
-               xmalloc.c \
-               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 gettext.h abook_rl.h mbswidth.h \
-               xmalloc.h
+abook_SOURCES = abook.c abook_rl.c database.c edit.c \
+               filter.c getname.c getopt.c getopt1.c gettext.c \
+               ldif.c list.c mbswidth.c misc.c options.c \
+               ui.c views.c xmalloc.c \
+               \
+               abook.h abook_curses.h abook_rl.h database.h edit.h \
+               filter.h getname.h getopt.h gettext.h \
+               help.h list.h ldif.h mbswidth.h misc.h options.h \
+               ui.h views.h xmalloc.h
 
 EXTRA_DIST = config.rpath  ANNOUNCE BUGS FAQ abook.1 abookrc.5 sample.abookrc \
                abook.spec contrib doc/HOWTO.translating_abook
 
 abook_LDADD = @LIBINTL@
 
+
 install-data-local:
        $(mkinstalldirs) $(DESTDIR)$(mandir)/man1 $(DESTDIR)$(mandir)/man5
        $(INSTALL_DATA) $(srcdir)/abook.1 $(DESTDIR)$(mandir)/man1/
index cd747713d31f8be535ec397aa042459dacb6d3c1..40fa7dd396f40210c1672e4a9b59fb3ea538d99b 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004  Free Software Foundation, Inc.
+# 2003, 2004, 2005  Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -73,13 +73,14 @@ CONFIG_CLEAN_FILES = abook.spec intl/Makefile
 am__installdirs = "$(DESTDIR)$(bindir)"
 binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(bin_PROGRAMS)
-am_abook_OBJECTS = abook.$(OBJEXT) database.$(OBJEXT) filter.$(OBJEXT) \
-       list.$(OBJEXT) misc.$(OBJEXT) options.$(OBJEXT) edit.$(OBJEXT) \
-       ldif.$(OBJEXT) ui.$(OBJEXT) getname.$(OBJEXT) getopt.$(OBJEXT) \
-       getopt1.$(OBJEXT) gettext.$(OBJEXT) abook_rl.$(OBJEXT) \
-       mbswidth.$(OBJEXT) xmalloc.$(OBJEXT)
+am_abook_OBJECTS = abook.$(OBJEXT) abook_rl.$(OBJEXT) \
+       database.$(OBJEXT) edit.$(OBJEXT) filter.$(OBJEXT) \
+       getname.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \
+       gettext.$(OBJEXT) ldif.$(OBJEXT) list.$(OBJEXT) \
+       mbswidth.$(OBJEXT) misc.$(OBJEXT) options.$(OBJEXT) \
+       ui.$(OBJEXT) views.$(OBJEXT) xmalloc.$(OBJEXT)
 abook_OBJECTS = $(am_abook_OBJECTS)
-abook_LDADD = $(LDADD)
+abook_DEPENDENCIES =
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -178,6 +179,8 @@ SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 U = @U@
+USE_INCLUDED_INTL_H_FALSE = @USE_INCLUDED_INTL_H_FALSE@
+USE_INCLUDED_INTL_H_TRUE = @USE_INCLUDED_INTL_H_TRUE@
 USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
@@ -221,20 +224,23 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
-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 gettext.c abook_rl.c mbswidth.c \
-               xmalloc.c \
-               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 gettext.h abook_rl.h mbswidth.h \
-               xmalloc.h
+abook_SOURCES = abook.c abook_rl.c database.c edit.c \
+               filter.c getname.c getopt.c getopt1.c gettext.c \
+               ldif.c list.c mbswidth.c misc.c options.c \
+               ui.c views.c xmalloc.c \
+               \
+               abook.h abook_curses.h abook_rl.h database.h edit.h \
+               filter.h getname.h getopt.h gettext.h \
+               help.h list.h ldif.h mbswidth.h misc.h options.h \
+               ui.h views.h xmalloc.h
 
 EXTRA_DIST = config.rpath  ANNOUNCE BUGS FAQ abook.1 abookrc.5 sample.abookrc \
                abook.spec contrib doc/HOWTO.translating_abook
 
+abook_LDADD = @LIBINTL@
 SUBDIRS = intl po
 ACLOCAL_AMFLAGS = -I m4
+@USE_INCLUDED_INTL_H_TRUE@AM_CPPFLAGS = -Iintl
 all: config.h
        $(MAKE) $(AM_MAKEFLAGS) all-recursive
 
@@ -342,6 +348,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/views.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmalloc.Po@am__quote@
 
 .c.o:
@@ -366,7 +373,13 @@ uninstall-info-am:
 #     (which will cause the Makefiles to be regenerated when you run `make');
 # (2) otherwise, pass the desired values on the `make' command line.
 $(RECURSIVE_TARGETS):
-       @set fnord $$MAKEFLAGS; amf=$$2; \
+       @failcom='exit 1'; \
+       for f in x $$MAKEFLAGS; do \
+         case $$f in \
+           *=* | --[!k]*);; \
+           *k*) failcom='fail=yes';; \
+         esac; \
+       done; \
        dot_seen=no; \
        target=`echo $@ | sed s/-recursive//`; \
        list='$(SUBDIRS)'; for subdir in $$list; do \
@@ -378,7 +391,7 @@ $(RECURSIVE_TARGETS):
            local_target="$$target"; \
          fi; \
          (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
-          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+         || eval $$failcom; \
        done; \
        if test "$$dot_seen" = "no"; then \
          $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
@@ -386,7 +399,13 @@ $(RECURSIVE_TARGETS):
 
 mostlyclean-recursive clean-recursive distclean-recursive \
 maintainer-clean-recursive:
-       @set fnord $$MAKEFLAGS; amf=$$2; \
+       @failcom='exit 1'; \
+       for f in x $$MAKEFLAGS; do \
+         case $$f in \
+           *=* | --[!k]*);; \
+           *k*) failcom='fail=yes';; \
+         esac; \
+       done; \
        dot_seen=no; \
        case "$@" in \
          distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
@@ -407,7 +426,7 @@ maintainer-clean-recursive:
            local_target="$$target"; \
          fi; \
          (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
-          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+         || eval $$failcom; \
        done && test -z "$$fail"
 tags-recursive:
        list='$(SUBDIRS)'; for subdir in $$list; do \
diff --git a/abook.c b/abook.c
index afd3eaebcc4c17201629d2e3de02f5cd05a00081..ae69a029987b5874aa55d7c9f44adb8d61d7fde5 100644 (file)
--- a/abook.c
+++ b/abook.c
@@ -33,6 +33,7 @@
 #include "options.h"
 #include "getname.h"
 #include "getopt.h"
+#include "views.h"
 #include "xmalloc.h"
 
 static void             init_abook();
@@ -52,6 +53,7 @@ static char *rcfile = NULL;
 bool alternative_datafile = FALSE;
 bool alternative_rcfile = FALSE;
 
+
 static int
 datafile_writeable()
 {
@@ -126,6 +128,7 @@ init_abook()
                printf(_("Press enter to continue...\n"));
                fgetc(stdin);
        }
+       init_default_views();
 
        signal(SIGTERM, quit_abook_sig);
 
@@ -190,6 +193,8 @@ main(int argc, char **argv)
 
        xmalloc_set_error_handler(xmalloc_error_handler);
 
+       prepare_database_internals();
+
        parse_command_line(argc, argv);
 
        init_abook();
@@ -375,7 +380,7 @@ parse_command_line(int argc, char **argv)
                }
        }
 
-       if (optind < argc) {
+       if(optind < argc) {
                fprintf(stderr, _("%s: unrecognized arguments on command line\n"),
                                argv[0]);
                exit(EXIT_FAILURE);
@@ -427,7 +432,6 @@ show_usage()
  * end of CLI
  */
 
-extern list_item *database;
 
 static void
 quit_mutt_query(int status)
@@ -441,19 +445,18 @@ quit_mutt_query(int status)
 static void
 muttq_print_item(FILE *file, int item)
 {
-       char emails[MAX_EMAILS][MAX_EMAIL_LEN];
-       int i;
-
-       split_emailstr(item, 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],
-                               database[item][NAME],
-                               database[item][NOTES] == NULL ? " " :
-                                       database[item][NOTES]
+       abook_list *emails, *e;
+
+       emails = csv_to_abook_list(db_email_get(item));
+
+       for(e = emails; e; e = e->next) {
+               fprintf(file, "%s\t%s\t%s\n", e->data, db_name_get(item),
+                               !db_fget(item, NOTES) ?" " :db_fget(item, NOTES)
                                );
+               if(!opt_get_bool(BOOL_MUTT_RETURN_ALL_EMAILS))
+                       break;
+       }
+       abook_list_free(&emails);
 }
 
 static void
@@ -503,11 +506,11 @@ make_mailstr(int item)
 {
        char email[MAX_EMAIL_LEN];
        char *ret;
-       char *name = strdup_printf("\"%s\"", database[item][NAME]);
+       char *name = strdup_printf("\"%s\"", db_name_get(item));
 
        get_first_email(email, item);
 
-       ret = *database[item][EMAIL] ?
+       ret = *db_email_get(item) ?
                strdup_printf("%s <%s>", name, email) :
                xstrdup(name);
 
@@ -577,10 +580,10 @@ launch_wwwbrowser(int item)
        if( !is_valid_item(item) )
                return;
 
-       if( database[item][URL] )
+       if(db_fget(item, URL))
                cmd = strdup_printf("%s '%s'",
                                opt_get_str(STR_WWW_COMMAND),
-                               safe_str(database[item][URL]));
+                               safe_str(db_fget(item, URL)));
        else
                return;
 
@@ -632,6 +635,7 @@ convert(char *srcformat, char *srcfile, char *dstformat, char *dstfile)
        set_filenames();
        init_opts();
        load_opts(rcfile);
+       init_standard_fields();
 
        switch(import_file(srcformat, srcfile)) {
                case -1:
@@ -752,10 +756,11 @@ add_email_add_item(int quiet, char *name, char *email)
                fclose(in);
        }
 
-       memset(item, 0, sizeof(item));
-       item[NAME] = xstrdup(name);
-       item[EMAIL] = xstrdup(email);
+       item = item_create();
+       item_fput(item, NAME, xstrdup(name));
+       item_fput(item, EMAIL, xstrdup(email));
        add_item2database(item);
+       item_free(&item);
 
        return 1;
 }
diff --git a/abook.h b/abook.h
index 564caf39b946725839cab05b5e7fa0600b3f906a..fc6c1bbc0486d6e54f5e62a01fbdc5248c25f45a 100644 (file)
--- a/abook.h
+++ b/abook.h
@@ -49,6 +49,8 @@ int           strncasecmp (const char *, const char *, size_t);
 
 #define ISSPACE(c)     isspace((unsigned char)c)
 
+#define SKIPWS(c)      while(*(c) && ISSPACE(*(c))) c++
+
 #ifndef DEBUG
 #      define NDEBUG   1
 #else
index 0602c98eaf8b8e47991c4d8c4591c1f349f3da35..7c24bafb728f4fcc640dd63c87d14cdd02997708 100644 (file)
--- a/abookrc.5
+++ b/abookrc.5
@@ -1,4 +1,4 @@
-.TH ABOOKRC 5 "Jun 4, 2003"
+.TH ABOOKRC 5 "Oct 25, 2005"
 .nh
 .SH NAME
 \fB$HOME/.abook/abookrc\fP \- configuration file for abook address book program
@@ -27,12 +27,61 @@ Comments in
 .B abookrc
 are on lines beginning with '#'.
 
+.SH COMMANDS
+
+.TP
+\fBset\fP \fIoption\fP = \fIvalue\fP
+
+.TP
+\fBfield\fP \fIidentifier\fP = \fIhuman_readable_name\fP [ , \fItype\fP ]
+Defines a new custom field. \fItype\fP can be one of 'string' (default)
+, 'emails', 'list', or 'day'.
+
+.TP
+\fBview\fP \fIview name\fP = \fIfield1\fP [ , \fIfield2\fP, ... ]
+Defines a view/tab, with \fIfieldN\fP being the identifier of a field
+declared with the \fBfield\fP command, or the identifier of a standard field.
+.IP
+Standard fields:
+.br
+       name, email,
+.br
+       address, address2, city, state, zip, country,
+.br
+       phone, workphone, fax, mobile,
+.br
+       nick, url, notes, anniversary
+.IP
+Note: if you don't define any view, abook will use a default display based
+on the above standard fields.
+
+
 .SH VARIABLES
 
 .TP
 \fBautosave\fP=[true|false]
 Defines whether the addressbook is automatically saved on exit. Default is true.
 
+.TP
+\fBpreserve_fields\fP=[all|standard|none]
+Specifies how fields not declared with the \fBfield\fP command nor in a view
+should be preserved while loading an abook database.
+.RS
+.TP
+.B all
+preserve any completely unknown field.
+.TP
+.B standard
+only preserve the standard fields (see a list in the
+  description of the \fBview\fP command) and the legacy
+  'custom[1-5]' fields.
+.TP
+.B none
+discards any unknown field.
+.IP
+Default is \fIstandard\fP.
+.RE
+
 .TP
 \fBshow_all_emails\fP=[true|false]
 Defines whether all email addresses for a contact are shown in the main list view. Default is true
@@ -44,7 +93,7 @@ Defines the screen column on the main list where the email address is to begin.
 .TP
 \fBextra_column\fP=field
 Defines the field to display in the extra (third) column on the main list. Default is "phone" (Home Phone).
-.br
+.IP
 \fIfield\fP can be any of the following:
 .br
 -1                     disabled
@@ -113,6 +162,21 @@ Defines if the cursor is visible in main display. Default is false.
 # sample abook configuration file
 #
 
+# Declare a few custom fields
+field pager = Pager
+field address_lines = Address, list
+field birthday = Birthday, day
+
+# Define how fields should be displayed in tabs
+view CONTACT = name, email
+view ADDRESS = address_lines, city, state, zip, country
+view PHONE = phone, workphone, pager, mobile, fax
+view OTHER = url, birthday
+
+
+# Preserve any unknown field while loading an abook database
+set preserve_fields=all
+
 # Automatically save database on exit
 set autosave=true
 
@@ -171,8 +235,9 @@ set show_cursor=false
 .SH SEE ALSO
 .BR abook (1).
 .br
-.SH AUTHOR
-This manual page was written by Alan Ford <alan@whirlnet.co.uk>.
+.SH AUTHORS
+This manual page was written by Alan Ford <alan@whirlnet.co.uk> and
+expanded by Cedric Duval <cedricduval@free.fr>.
 
 .br
 .B abook
index a7b70a741083102f7fc77eaf09c5142ce765e586..d646da6b10845fc76bf60e64285f02e19c8d3506 100644 (file)
@@ -1,7 +1,7 @@
-# generated automatically by aclocal 1.9.3 -*- Autoconf -*-
+# generated automatically by aclocal 1.9.5 -*- Autoconf -*-
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-# Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005  Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
-#                                                        -*- Autoconf -*-
-# Copyright (C) 2002, 2003  Free Software Foundation, Inc.
-# Generated from amversion.in; do not edit by hand.
-
-# 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, 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
+# Copyright (C) 2002, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
 # AM_AUTOMAKE_VERSION(VERSION)
 # ----------------------------
@@ -40,26 +28,15 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
 # Call AM_AUTOMAKE_VERSION so it can be traced.
 # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-        [AM_AUTOMAKE_VERSION([1.9.3])])
-
-# AM_AUX_DIR_EXPAND
-
-# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+        [AM_AUTOMAKE_VERSION([1.9.5])])
 
-# 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, or (at your option)
-# any later version.
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# 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.
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
 # $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
@@ -106,26 +83,16 @@ AC_PREREQ([2.50])dnl
 am_aux_dir=`cd $ac_aux_dir && pwd`
 ])
 
-# AM_CONDITIONAL                                              -*- Autoconf -*-
+# AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
-
-# 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, 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.
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
-# serial 6
+# serial 7
 
 # AM_CONDITIONAL(NAME, SHELL-CONDITION)
 # -------------------------------------
@@ -149,26 +116,15 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# serial 7                                             -*- Autoconf -*-
 
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
 # Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
-# 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, 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.
-
+# serial 8
 
 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
 # written in clear, in which case automake, when reading aclocal.m4,
@@ -177,7 +133,6 @@ fi])])
 # CC etc. in the Makefile, will ask for an AC_PROG_CC use...
 
 
-
 # _AM_DEPENDENCIES(NAME)
 # ----------------------
 # See how the compiler implements dependency checking.
@@ -317,27 +272,16 @@ AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
 AC_SUBST([AMDEPBACKSLASH])
 ])
 
-# Generate code to set up dependency tracking.   -*- Autoconf -*-
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
-#   Free Software Foundation, Inc.
-
-# 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, or (at your option)
-# any later version.
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# 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.
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
-#serial 2
+#serial 3
 
 # _AM_OUTPUT_DEPENDENCY_COMMANDS
 # ------------------------------
@@ -396,54 +340,31 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
 ])
 
-# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
-
-# 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, 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.
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
-# serial 7
+# serial 8
 
 # AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
 AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
 
-# Do all the work for Automake.                            -*- Autoconf -*-
-
-# This macro actually does too much some checks are only needed if
-# your package does certain things.  But this isn't really a big deal.
+# Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
 # Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
-# 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, 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.
+# serial 12
 
-# serial 11
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
 
 # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
 # AM_INIT_AUTOMAKE([OPTIONS])
@@ -545,51 +466,27 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
 
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
 # AM_PROG_INSTALL_SH
 # ------------------
 # Define $install_sh.
-
-# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-
-# 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, 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.
-
 AC_DEFUN([AM_PROG_INSTALL_SH],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 install_sh=${install_sh-"$am_aux_dir/install-sh"}
 AC_SUBST(install_sh)])
 
-#                                                          -*- Autoconf -*-
-# Copyright (C) 2003  Free Software Foundation, Inc.
-
-# 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, 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.
+# Copyright (C) 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
-# serial 1
+# serial 2
 
 # Check whether the underlying file-system supports filenames
 # with a leading dot.  For instance MS-DOS doesn't.
@@ -604,26 +501,15 @@ fi
 rmdir .tst 2>/dev/null
 AC_SUBST([am__leading_dot])])
 
-# Check to see how 'make' treats includes.     -*- Autoconf -*-
+# Check to see how 'make' treats includes.                 -*- Autoconf -*-
 
-# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
-
-# 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, 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.
+# Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
-# serial 2
+# serial 3
 
 # AM_MAKE_INCLUDE()
 # -----------------
@@ -667,27 +553,16 @@ AC_MSG_RESULT([$_am_result])
 rm -f confinc confmf
 ])
 
-#  -*- Autoconf -*-
-
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
-
-# 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, 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.
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
-# serial 3
+# serial 4
 
 # AM_MISSING_PROG(NAME, PROGRAM)
 # ------------------------------
@@ -713,27 +588,16 @@ else
 fi
 ])
 
+# Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
 # AM_PROG_MKDIR_P
 # ---------------
 # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
-
-# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
-
-# 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, 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.
-
+#
 # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
 # created by `make install' are always world readable, even if the
 # installer happens to have an overly restrictive umask (e.g. 077).
@@ -787,26 +651,15 @@ else
 fi
 AC_SUBST([mkdir_p])])
 
-# Helper functions for option handling.                    -*- Autoconf -*-
+# Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001, 2002, 2003  Free Software Foundation, Inc.
-
-# 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, 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.
+# Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
-# serial 2
+# serial 3
 
 # _AM_MANGLE_OPTION(NAME)
 # -----------------------
@@ -831,26 +684,14 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-
-# Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003
+# Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005
 # Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
-# 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, 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.
-
-# serial 3
+# serial 4
 
 AC_DEFUN([AM_C_PROTOTYPES],
 [AC_REQUIRE([AC_C_PROTOTYPES])
@@ -868,28 +709,16 @@ AC_SUBST(ANSI2KNR)dnl
 
 AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES])
 
-#
-# Check to make sure that the build environment is sane.
-#
-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
-
-# 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, or (at your option)
-# any later version.
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# 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.
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
-# serial 3
+# serial 4
 
 # AM_SANITY_CHECK
 # ---------------
@@ -932,25 +761,14 @@ Check your system clock])
 fi
 AC_MSG_RESULT(yes)])
 
-# AM_PROG_INSTALL_STRIP
-
-# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-
-# 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, 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.
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
+# AM_PROG_INSTALL_STRIP
+# ---------------------
 # One issue with vendor `install' (even GNU) is that you can't
 # specify the program used to strip binaries.  This is especially
 # annoying in cross-compiling environments, where the build's strip
@@ -973,25 +791,13 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004  Free Software Foundation, Inc.
-
-# 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, 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.
-
-# serial 1
+# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
+# serial 2
 
 # _AM_PROG_TAR(FORMAT)
 # --------------------
index b5bc7ce48554b1cb0ab2226ddc23dc8fd127d9e9..30612e6eec7d28e37ba7c1844e6f9fd49c2b4c21 100755 (executable)
--- a/configure
+++ b/configure
@@ -309,7 +309,7 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os CPP EGREP GLIBC2 RANLIB ac_ct_RANLIB ALLOCA GLIBC21 INTL_MACOSX_LIBS HAVE_POSIX_PRINTF HAVE_ASPRINTF HAVE_SNPRINTF HAVE_WPRINTF LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB localedir U ANSI2KNR LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os CPP EGREP GLIBC2 RANLIB ac_ct_RANLIB ALLOCA GLIBC21 INTL_MACOSX_LIBS HAVE_POSIX_PRINTF HAVE_ASPRINTF HAVE_SNPRINTF HAVE_WPRINTF LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB localedir USE_INCLUDED_INTL_H_TRUE USE_INCLUDED_INTL_H_FALSE U ANSI2KNR LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -968,7 +968,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd $ac_popdir
+    cd "$ac_popdir"
   done
 fi
 
@@ -2700,8 +2700,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2759,8 +2758,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2876,8 +2874,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2931,8 +2928,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2977,8 +2973,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3022,8 +3017,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3632,8 +3626,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3687,8 +3680,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3753,8 +3745,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3961,8 +3952,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4023,8 +4013,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4084,8 +4073,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4164,8 +4152,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4230,8 +4217,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4296,8 +4282,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4361,8 +4346,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4432,8 +4416,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4496,8 +4479,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4559,8 +4541,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4622,8 +4603,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4685,8 +4665,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4758,8 +4737,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4908,8 +4886,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4990,8 +4967,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5132,8 +5108,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5271,8 +5246,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5456,8 +5430,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5832,8 +5805,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5918,8 +5890,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5988,8 +5959,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6057,8 +6027,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6227,8 +6196,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6268,8 +6236,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6325,8 +6292,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6366,8 +6332,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6431,8 +6396,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6459,10 +6423,8 @@ case $ac_lo in
 esac
 else
   if test "$cross_compiling" = yes; then
-  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
+  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
+echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
    { (exit 1); exit 1; }; }
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -6555,8 +6517,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6596,8 +6557,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6653,8 +6613,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6694,8 +6653,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6759,8 +6717,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6787,10 +6744,8 @@ case $ac_lo in
 esac
 else
   if test "$cross_compiling" = yes; then
-  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
+  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
+echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
    { (exit 1); exit 1; }; }
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -6883,8 +6838,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6924,8 +6878,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6981,8 +6934,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -7022,8 +6974,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -7087,8 +7038,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -7115,10 +7065,8 @@ case $ac_lo in
 esac
 else
   if test "$cross_compiling" = yes; then
-  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
+  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
+echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
    { (exit 1); exit 1; }; }
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -7211,8 +7159,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -7289,8 +7236,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -7440,8 +7386,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -7507,8 +7452,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -8131,8 +8075,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -8210,8 +8153,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -8420,8 +8362,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -8488,8 +8429,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -8557,8 +8497,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -8627,8 +8566,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -8696,8 +8634,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -8765,8 +8702,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -8890,8 +8826,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -8941,8 +8876,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -9032,8 +8966,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -9098,8 +9031,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -9163,8 +9095,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -9309,8 +9240,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -9376,8 +9306,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -9496,8 +9425,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -9942,8 +9870,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -9997,8 +9924,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -10217,6 +10143,17 @@ _ACEOF
 
 
 
+
+if test x$USE_INCLUDED_LIBINTL = xyes; then
+  USE_INCLUDED_INTL_H_TRUE=
+  USE_INCLUDED_INTL_H_FALSE='#'
+else
+  USE_INCLUDED_INTL_H_TRUE='#'
+  USE_INCLUDED_INTL_H_FALSE=
+fi
+
+
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -10584,8 +10521,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -10643,8 +10579,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -10760,8 +10695,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -10815,8 +10749,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -10861,8 +10794,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -10906,8 +10838,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -11093,8 +11024,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -11148,8 +11078,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -11243,8 +11172,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -11394,8 +11322,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -11548,8 +11475,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -11718,8 +11644,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -11864,8 +11789,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -12111,8 +12035,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -12176,8 +12099,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -12368,8 +12290,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -12435,8 +12356,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -12507,8 +12427,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -12597,8 +12516,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -12662,8 +12580,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -12819,8 +12736,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -12884,8 +12800,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13067,8 +12982,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13136,8 +13050,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13206,8 +13119,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13278,8 +13190,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13401,8 +13312,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13471,8 +13381,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13549,8 +13458,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13612,8 +13520,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13666,8 +13573,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13710,8 +13616,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13813,8 +13718,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -13893,8 +13797,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -14047,8 +13950,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -14113,8 +14015,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -14318,8 +14219,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -14422,8 +14322,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -14585,6 +14484,13 @@ echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
+if test -z "${USE_INCLUDED_INTL_H_TRUE}" && test -z "${USE_INCLUDED_INTL_H_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"USE_INCLUDED_INTL_H\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_INCLUDED_INTL_H\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
 if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
   { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
@@ -15215,6 +15121,8 @@ s,@LIBINTL@,$LIBINTL,;t t
 s,@LTLIBINTL@,$LTLIBINTL,;t t
 s,@POSUB@,$POSUB,;t t
 s,@localedir@,$localedir,;t t
+s,@USE_INCLUDED_INTL_H_TRUE@,$USE_INCLUDED_INTL_H_TRUE,;t t
+s,@USE_INCLUDED_INTL_H_FALSE@,$USE_INCLUDED_INTL_H_FALSE,;t t
 s,@U@,$U,;t t
 s,@ANSI2KNR@,$ANSI2KNR,;t t
 s,@LIBOBJS@,$LIBOBJS,;t t
@@ -15385,11 +15293,6 @@ esac
   *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
   esac
 
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -15428,6 +15331,12 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 092f56351911766aa44cda62e0116d785ef91454..893cb9902cd5dd8456394007b9108e8b4a9d38c9 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <fcntl.h>
-#include "abook.h"
 #include <assert.h>
+#ifdef HAVE_CONFIG_H
+#      include "config.h"
+#endif
+#include "abook.h"
 #include "database.h"
 #include "gettext.h"
 #include "list.h"
 #include "misc.h"
-#include "options.h"
-#include "filter.h"
 #include "xmalloc.h"
-#ifdef HAVE_CONFIG_H
-#      include "config.h"
-#endif
 
-list_item *database = NULL;
+abook_field_list *fields_list = NULL;
+int fields_count = 0;
 
+list_item *database = NULL;
 int items = 0;
 
-#define INITIAL_LIST_CAPACITY  30
+#define ITEM_SIZE (fields_count * sizeof(char *))
 
+#define INITIAL_LIST_CAPACITY  30
 static int list_capacity = 0;
 
+int standard_fields_indexed[ITEM_FIELDS];
+
+/*
+ * notes about adding predefined "standard" fields:
+ *     - leave alone "name" and "email"
+ *     - reorganize the field numbers in database.h
+ */
+abook_field standard_fields[] = {
+       {"name",        N_("Name"),             FIELD_STRING}, /* NAME */
+       {"email",       N_("E-mail addresses"), FIELD_EMAILS}, /* EMAIL */
+       {"address",     N_("Address"),          FIELD_STRING}, /* ADDRESS */
+       {"address2",    N_("Address2"),         FIELD_STRING}, /* ADDRESS2 */
+       {"city",        N_("City"),             FIELD_STRING}, /* CITY */
+       {"state",       N_("State/Province"),   FIELD_STRING}, /* STATE */
+       {"zip",         N_("ZIP/Postal Code"),  FIELD_STRING}, /* ZIP */
+       {"country",     N_("Country"),          FIELD_STRING}, /* COUNTRY */
+       {"phone",       N_("Home Phone"),       FIELD_STRING}, /* PHONE */
+       {"workphone",   N_("Work Phone"),       FIELD_STRING}, /* WORKPHONE */
+       {"fax",         N_("Fax"),              FIELD_STRING}, /* FAX */
+       {"mobile",      N_("Mobile"),           FIELD_STRING}, /* MOBILEPHONE */
+       {"nick",        N_("Nickname/Alias"),   FIELD_STRING}, /* NICK */
+       {"url",         N_("URL"),              FIELD_STRING}, /* URL */
+       {"notes",       N_("Notes"),            FIELD_STRING}, /* NOTES */
+       {"anniversary", N_("Anniversary day"),  FIELD_DAY},    /* ANNIVERSARY */
+       {0} /* ITEM_FIELDS */
+};
+
+
 extern int first_list_item;
 extern int curitem;
 extern char *selected;
-
 extern char *datafile;
 
+
+
+static abook_field *
+declare_standard_field(int i)
+{
+       abook_field *f = xmalloc(sizeof(abook_field));
+
+       f = memcpy(f, &standard_fields[i], sizeof(abook_field));
+       f->name = xstrdup(gettext(f->name));
+
+       add_field(&fields_list, f);
+
+       assert(standard_fields_indexed[i] == -1);
+       standard_fields_indexed[i] = fields_count++;
+
+       return f;
+}
+
+abook_field *
+find_standard_field(char *key, int do_declare)
+{
+       int i;
+
+       for(i = 0; standard_fields[i].key; i++)
+               if(0 == strcmp(standard_fields[i].key, key))
+                       goto found;
+
+       return NULL;
+
+found:
+       return do_declare ? declare_standard_field(i) : &standard_fields[i];
+}
+
+/* Search for a field. Use the list of declared fields if no list specified. */
+abook_field *
+real_find_field(char *key, abook_field_list *list, int *number)
+{
+       abook_field_list *cur;
+       int i;
+
+       for(cur = (list ? list : fields_list), i = 0; cur; cur = cur->next, i++)
+               if(0 == strcmp(cur->field->key, key)) {
+                       if(number)
+                               *number = i;
+                       return cur->field;
+               }
+
+       if(number)
+               *number = -1;
+
+       return NULL;
+}
+
+void
+get_field_keyname(int i, char **key, char **name)
+{
+       abook_field_list *cur = fields_list;
+       int j;
+
+       assert(i < fields_count);
+
+       for(j = 0; i >= 0 && j < i; j++, cur = cur->next)
+               ;
+
+       if(key)
+               *key = (i < 0) ? NULL : cur->field->key;
+       if(name)
+               *name = (i < 0) ? NULL : cur->field->name;
+}
+
+void
+add_field(abook_field_list **list, abook_field *f)
+{
+       abook_field_list *tmp;
+
+       for(tmp = *list; tmp && tmp->next; tmp = tmp->next)
+               ;
+
+       if(tmp) {
+               tmp->next = xmalloc(sizeof(abook_field_list));
+               tmp = tmp->next;
+       } else
+               *list = tmp = xmalloc(sizeof(abook_field_list));
+
+       tmp->field = f;
+       tmp->next = NULL;
+}
+
+char *
+declare_new_field(char *key, char *name, char *type, int accept_standard)
+{
+       abook_field *f;
+
+       if(find_declared_field(key))
+               return _("field already defined");
+
+       if(find_standard_field(key, accept_standard))
+               return accept_standard ? NULL /* ok, added */ :
+                       _("standard field does not need to be declared");
+
+       f = xmalloc(sizeof(abook_field));
+       f->key = xstrdup(key);
+       f->name = xstrdup(name);
+
+       if(!*type || (0 == strcasecmp("string", type)))
+               f->type = FIELD_STRING;
+       else if(0 == strcasecmp("emails", type))
+               f->type = FIELD_EMAILS;
+       else if(0 == strcasecmp("list", type))
+               f->type = FIELD_LIST;
+       else if(0 == strcasecmp("day", type))
+               f->type = FIELD_DAY;
+       else
+               return _("unknown type");
+
+       add_field(&fields_list, f);
+       fields_count++;
+
+       return NULL;
+}
+
 /*
- * field definitions
+ * Declare a new field while database is already loaded
+ * making it grow accordingly
  */
+static void
+declare_unknown_field(char *key)
+{
+       int i;
 
-#include "edit.h"
+       declare_new_field(key, key, "string",
+                       1 /* accept to declare "standard" fields */);
+
+       if(!database)
+               return;
+
+       for(i = 0; i < fields_count; i++)
+               if(database[i])
+                       database[i] = xrealloc(database[i], ITEM_SIZE);
+}
 
 /*
- * notes about adding fields:
- *     - do not change any fields in TAB_CONTACT
- *     - do not add fields to contact tab
- *     - 6 fields per tab is maximum
- *     - reorganize the field numbers in database.h
+ * Declare "standard" fields, thus preserving them while parsing a database,
+ * even if they won't be displayed.
  */
+void
+init_standard_fields()
+{
+       int i;
 
-struct abook_field abook_fields[ITEM_FIELDS] = {
-       {N_("Name"),    "name",         TAB_CONTACT},/* NAME */
-       {N_("E-mails"), "email",        TAB_CONTACT},/* EMAIL */
-       {N_("Address"), "address",      TAB_ADDRESS},/* ADDRESS */
-       {N_("Address2"),        "address2",     TAB_ADDRESS},/* ADDRESS2 */
-       {N_("City"),    "city",         TAB_ADDRESS},/* CITY */
-       {N_("State/Province"),"state",  TAB_ADDRESS},/* STATE */
-       {N_("ZIP/Postal Code"),"zip",   TAB_ADDRESS},/* ZIP */
-       {N_("Country"), "country",      TAB_ADDRESS},/* COUNTRY */
-       {N_("Home Phone"),      "phone",        TAB_PHONE},/* PHONE */
-       {N_("Work Phone"),      "workphone",    TAB_PHONE},/* WORKPHONE */
-       {N_("Fax"),             "fax",          TAB_PHONE},/* FAX */
-       {N_("Mobile"),  "mobile",       TAB_PHONE},/* MOBILEPHONE */
-       {N_("Nickname/Alias"), "nick",      TAB_OTHER},/* NICK */
-       {N_("URL"),             "url",          TAB_OTHER},/* URL */
-       {N_("Notes"),   "notes",        TAB_OTHER},/* NOTES */
-       {N_("Custom1"), "custom1",      TAB_CUSTOM},/* CUSTOM1 */
-       {N_("Custom2"), "custom2",      TAB_CUSTOM},/* CUSTOM2 */
-       {N_("Custom3"), "custom3",      TAB_CUSTOM},/* CUSTOM3 */
-       {N_("Custom4"), "custom4",      TAB_CUSTOM},/* CUSTOM4 */
-       {N_("Custom5"), "custom5",      TAB_CUSTOM},/* CUSTOM5 */
-};
-
+       for(i = 0; standard_fields[i].key; i++)
+               if(standard_fields_indexed[i] == -1)
+                       declare_standard_field(i);
+}
 
-int
-find_field(const char *field)
+/* Some initializations - Must be called _before_ load_opts() */
+void
+prepare_database_internals()
 {
        int i;
 
        for(i = 0; i < ITEM_FIELDS; i++)
-               if( !strcmp(abook_fields[i].key, field) )
-                       return i;
+               standard_fields_indexed[i] = -1;
 
-       return -1;
+       /* the only two mandatory fields */
+       declare_standard_field(NAME);
+       declare_standard_field(EMAIL);
 }
 
 int
@@ -94,50 +240,57 @@ parse_database(FILE *in)
 {
         char *line = NULL;
        char *tmp;
-       int sec=0, i;
-       list_item item;
+       int sec=0, field;
+       list_item item;
 
-       memset(&item, 0, sizeof(item));
+       item = item_create();
 
        for(;;) {
                line = getaline(in);
                if(feof(in)) {
-                       if(item[NAME] && sec)
+                       if(item[field_id(NAME)] && sec) {
                                add_item2database(item);
-                       else
-                               free_list_item(item);
+                       } else {
+                               item_empty(item);
+                       }
                        break;
                }
 
                if(!*line || *line == '\n' || *line == '#') {
                        goto next;
                } else if(*line == '[') {
-                       if( item[NAME] && sec )
+                       if(item[field_id(NAME)] && sec ) {
                                add_item2database(item);
-                       else
-                               free_list_item(item);
-                       memset(&item, 0, sizeof(item));
+                       } else {
+                               item_empty(item);
+                       }
                        sec = 1;
+                       memset(item, 0, ITEM_SIZE);
                        if(!(tmp = strchr(line, ']')))
                                sec = 0; /*incorrect section lines are skipped*/
                } else if((tmp = strchr(line, '=') ) && sec) {
                        *tmp++ = '\0';
-                       for(i = 0; i < ITEM_FIELDS; i++)
-                               if(!strcmp(abook_fields[i].key, line)) {
-                                       item[i] = xstrdup(tmp);
-                                       goto next;
-                               }
+                       find_field_number(line, &field);
+                       if(field != -1) {
+                               item[field] = xstrdup(tmp);
+                               goto next;
+                       } else if(!strcasecmp(opt_get_str(STR_PRESERVE_FIELDS),
+                                               "all")){
+                               declare_unknown_field(line);
+                               item = xrealloc(item, ITEM_SIZE);
+                               item[fields_count - 1] = xstrdup(tmp);
+                               goto next;
+                       }
                }
 next:
                xfree(line);
        }
 
        xfree(line);
+       item_free(&item);
        return 0;
 }
 
-
-
 int
 load_database(char *filename)
 {
@@ -159,6 +312,7 @@ write_database(FILE *out, struct db_enumerator e)
 {
        int j;
        int i = 0;
+       abook_field_list *cur;
 
        fprintf(out,
                "# abook addressbook file\n\n"
@@ -170,14 +324,16 @@ write_database(FILE *out, struct db_enumerator e)
 
        db_enumerate_items(e) {
                fprintf(out, "[%d]\n", i);
-               for(j = 0; j < ITEM_FIELDS; j++) {
+
+               for(cur = fields_list, j = 0; cur; cur = cur->next, j++) {
                        if( database[e.item][j] != NULL &&
                                        *database[e.item][j] )
                                fprintf(out, "%s=%s\n",
-                                       abook_fields[j].key,
+                                       cur->field->key,
                                        database[e.item][j]
                                        );
                }
+
                fputc('\n', out);
                i++;
        }
@@ -209,18 +365,9 @@ save_database()
 }
 
 static void
-free_item(int item)
+db_free_item(int item)
 {
-       free_list_item(database[item]);
-}
-
-void
-free_list_item(list_item item)
-{
-       int i;
-
-       for(i=0; i<ITEM_FIELDS; i++)
-               xfree(item[i]);
+       item_empty(database[item]);
 }
 
 void
@@ -228,10 +375,10 @@ close_database()
 {
        int i;
 
-       for(i=0; i < items; i++)
-               free_item(i);
+       for(i=0; i <= LAST_ITEM; i++)
+               db_free_item(i);
 
-       free(database);
+       xfree(database);
        free(selected);
 
        database = NULL;
@@ -242,27 +389,46 @@ close_database()
        list_capacity = 0;
 }
 
-#define _MAX_FIELD_LEN(X)      (X == EMAIL ? MAX_EMAILSTR_LEN:MAX_FIELD_LEN)
 
 static void
 validate_item(list_item item)
 {
-       int i;
+       abook_field_list *f;
+       int i, max_field_len;
        char *tmp;
 
-       if(item[EMAIL] == NULL)
-               item[EMAIL] = xstrdup("");
+       for(f = fields_list, i = 0; f; f = f->next, i++) {
+               max_field_len = 0;
+
+               switch(f->field->type) {
+                       case FIELD_EMAILS:
+                               max_field_len = MAX_EMAILSTR_LEN;
+                               if(item[i] == NULL)
+                                       item[i] = xstrdup("");
+                               break;
+                       case FIELD_LIST:
+                               /* TODO quote string if it contains commas */
+                               break;
+                       case FIELD_STRING:
+                               max_field_len = MAX_FIELD_LEN;
+                               break;
+                       case FIELD_DAY:
+                               break;
+                       default:
+                               assert(0);
+               }
 
-       for(i=0; i<ITEM_FIELDS; i++)
-               if( item[i] && ((int)strlen(item[i]) > _MAX_FIELD_LEN(i) ) ) {
+               if(max_field_len && item[i] &&
+                               ((int)strlen(item[i]) > max_field_len)) {
+                       /* truncate field */
                        tmp = item[i];
-                       item[i][_MAX_FIELD_LEN(i)-1] = 0;
+                       item[i][max_field_len - 1] = 0;
                        item[i] = xstrdup(item[i]);
                        free(tmp);
                }
+       }
 }
 
-
 static void
 adjust_list_capacity()
 {
@@ -275,15 +441,20 @@ adjust_list_capacity()
        else
                return;
 
-       database = xrealloc(database, sizeof(list_item) * list_capacity);
+       if(database)
+               database = xrealloc(database,sizeof(list_item) * list_capacity);
+       else /* allocate memory _and_ initialize pointers to NULL */
+               database = xmalloc0(sizeof(list_item) * list_capacity);
+
        selected = xrealloc(selected, list_capacity);
 }
 
 int
 add_item2database(list_item item)
 {
-       if(item[NAME] == NULL || ! *item[NAME]) {
-               free_list_item(item);
+       /* 'name' field is mandatory */
+       if((item[field_id(NAME)] == NULL) || ! *item[field_id(NAME)]) {
+               item_empty(item);
                return 1;
        }
 
@@ -293,10 +464,13 @@ add_item2database(list_item item)
        validate_item(item);
 
        selected[LAST_ITEM] = 0;
-       itemcpy(database[LAST_ITEM], item);
+
+       database[LAST_ITEM] = item_create();
+        item_copy(database[LAST_ITEM], item);
 
        return 0;
 }
+       
 
 void
 remove_selected_items()
@@ -311,11 +485,12 @@ remove_selected_items()
 
        for(j = LAST_ITEM; j >= 0; j--) {
                if(selected[j]) {
-                       free_item(j); /* added for .4 data_s_ */
+                       db_free_item(j); /* added for .4 data_s_ */
                        for(i = j; i < LAST_ITEM; i++) {
-                               itemcpy(database[i], database[i + 1]);
+                               item_copy(database[i], database[i + 1]);
                                selected[i] = selected[i + 1];
                        }
+                       item_free(&database[LAST_ITEM]);
                        items--;
                }
        }
@@ -344,18 +519,20 @@ get_surname(char *s)
 static int
 surnamecmp(const void *i1, const void *i2)
 {
-       int ret;
-       list_item a,b;
-       char *s1, *s2;
+       int ret, idx = field_id(NAME);
+       char *n1, *n2, *s1, *s2;
 
-       itemcpy(a, i1);
-       itemcpy(b, i2);
+       if(idx == 0)
+               return 0; /* no 'name' field */
 
-       s1 = get_surname(a[NAME]);
-       s2 = get_surname(b[NAME]);
+       n1 = (*(list_item *)i1)[idx];
+       n2 = (*(list_item *)i2)[idx];
+       
+       s1 = get_surname(n1);
+       s2 = get_surname(n2);
 
        if( !(ret = safe_strcoll(s1, s2)) )
-               ret = safe_strcoll(a[NAME], b[NAME]);
+               ret = safe_strcoll(n1, n2);
 
        free(s1);
        free(s2);
@@ -368,45 +545,34 @@ static int sort_field = -1;
 static int
 namecmp(const void *i1, const void *i2)
 {
-       list_item a, b;
+       char *n1, *n2;
 
-       assert(sort_field >= 0 && sort_field <= LAST_FIELD);
+       assert(sort_field >= 0 && sort_field < fields_count);
 
-       itemcpy(a, i1);
-       itemcpy(b, i2);
+       n1 = (*(list_item *)i1)[sort_field];
+       n2 = (*(list_item *)i2)[sort_field];
 
-       return safe_strcoll(a[sort_field], b[sort_field]);
-}
-
-static int
-name2field(char *name)
-{
-       int i, ret = -1;
-
-       for(i = 0; i < ITEM_FIELDS; i++) {
-               if(!strcasecmp(name, abook_fields[i].key)) {
-                       ret = i;
-                       break;
-               }
-       }
-
-       return ret;
+       return safe_strcoll(n1, n2);
 }
 
 void
-sort_by_field(int field)
+sort_by_field(char *name)
 {
+       int field;
+
        select_none();
 
-       assert(field <= LAST_FIELD);
+       name = (name == NULL) ? opt_get_str(STR_SORT_FIELD) : name;
+       find_field_number(name, &field);
 
        if(field < 0) {
-               field = name2field(opt_get_str(STR_SORT_FIELD));
-               if(field < 0) {
+               if(name == opt_get_str(STR_SORT_FIELD))
                        statusline_msg(_("Invalid field value defined "
                                "in configuration"));
-                       return;
-               }
+               else
+                       statusline_msg(_("Invalid field value for sorting"));
+
+               return;
        }
 
        sort_field = field;
@@ -426,10 +592,11 @@ sort_surname()
        refresh_screen();
 }
 
+/* TODO implement a search based on more sophisticated patterns */
 int
 find_item(char *str, int start, int search_fields[])
 {
-       int i;
+       int i, id;
        char *findstr = NULL;
        char *tmp = NULL;
        int ret = -1; /* not found */
@@ -444,9 +611,11 @@ find_item(char *str, int start, int search_fields[])
        e.item = start - 1; /* must be "real start" - 1 */
        db_enumerate_items(e) {
                for(i = 0; search_fields[i] >= 0; i++) {
-                       if(database[e.item][search_fields[i]] == NULL)
+                       if((id = field_id(search_fields[i])) == -1)
+                               continue;
+                       if(database[e.item][id] == NULL)
                                continue;
-                       tmp = xstrdup(database[e.item][search_fields[i]]);
+                       tmp = xstrdup(database[e.item][id]);
                        if( tmp && strstr(strlower(tmp), findstr) ) {
                                ret = e.item;
                                goto out;
@@ -461,7 +630,6 @@ out:
        return ret;
 }
 
-
 int
 is_selected(int item)
 {
@@ -474,6 +642,7 @@ is_valid_item(int item)
        return item <= LAST_ITEM && item >= 0;
 }
 
+
 int
 real_db_enumerate_items(struct db_enumerator e)
 {
@@ -486,7 +655,7 @@ real_db_enumerate_items(struct db_enumerator e)
                        break;
 #endif
                case ENUM_SELECTED:
-                       for(i = item; i < items; i++) {
+                       for(i = item; i <= LAST_ITEM; i++) {
                                if(is_selected(i)) {
                                        item = i;
                                        goto out;
@@ -516,46 +685,123 @@ init_db_enumerator(int mode)
        return e;
 }
 
-static int
-assign_fieldname(const char *name, int i)
+
+list_item
+item_create()
+{
+       return xmalloc0(ITEM_SIZE);
+}
+
+void
+item_free(list_item *item)
+{
+       assert(item);
+
+       xfree(*item);
+}
+
+void
+item_empty(list_item item)
+{      int i;
+
+       assert(item);
+
+       for(i = 0; i < fields_count; i++)
+               if(item[i])
+                       xfree(item[i]);
+
+}
+
+void
+item_copy(list_item dest, list_item src)
+{
+       memmove(dest, src, ITEM_SIZE);
+}
+
+void
+item_duplicate(list_item dest, list_item src)
 {
-       char *s;
+       int i;
 
-       assert(name);
-       assert(i >= 0 && i < ITEM_FIELDS);
+       for(i = 0; i < fields_count; i++)
+               dest[i] = src[i] ? xstrdup(src[i]) : NULL;
+}
 
-       if(strcasecmp(abook_fields[i].name, name)) { /* name differs */
-               /*
-                * check if we are overwriting statically allocated default
-                */
-               if(strcasecmp(abook_fields[i].name, abook_fields[i].key))
-                       xfree(abook_fields[i].name);
+/* 
+ * Things like item[field_id(NICK)] should never be used, since besides NAME
+ * and EMAIL, none of the standard fields can be assumed to be existing.
+ *
+ * Prefer the functions item_fput(), item_fget(), db_fput() and db_fget()
+ * to access fields in items and database.
+ */
 
-               s = xmalloc_inc(MAX_FIELDNAME_LEN, 1);
-               snprintf(s, MAX_FIELDNAME_LEN, "%s", name);
-               abook_fields[i].name = s;
+/* quick lookup by "standard" field number */
+inline int
+field_id(int i)
+{
+       assert((i >= 0) && (i < ITEM_FIELDS));
+       return standard_fields_indexed[i];
+}
+
+int
+item_fput(list_item item, int i, char *val)
+{
+       int id = field_id(i);
+
+       if(id != -1) {
+               item[id] = val;
+               return 1;
        }
 
        return 0;
 }
 
+char *
+item_fget(list_item item, int i)
+{
+       int id = field_id(i);
+
+       if(id != -1)
+               return item[id];
+       else
+               return NULL;
+}
+
 int
-change_custom_field_name(const char *name, int n)
+real_db_field_put(int item, int i, int std, char *val)
 {
-       int i;
-       char keyname[21];
+       int id;
 
-       assert(name);
+       assert(database[item]);
 
-       snprintf(keyname, sizeof(keyname), "custom%d", n);
+       id = std ? field_id(i) : i;
 
-       for(i = CUSTOM_MIN; i <= CUSTOM_MAX; i++) {
-               if(!strcasecmp(abook_fields[i].key, keyname)) {
-                       assign_fieldname(name, i);
-                       return i;
-               }
+       if(id != -1) {
+               database[item][id] = val;
+               return 1;
        }
 
-       return -1;
+       return 0;
+}
+
+char *
+real_db_field_get(int item, int i, int std)
+{
+       int id;
+
+       assert(database[item]);
+
+       id = std ? field_id(i) : i;
+
+       if(id != -1)
+               return database[item][id];
+       else
+               return NULL;
+}
+
+list_item
+db_item_get(int i)
+{
+       return database[i];
 }
 
index 87228851df824051ad20fe6ea8bc1e37f67e2324..bd86d975a9cce5460d07aa181e22a72c417b2c27 100644 (file)
@@ -1,14 +1,13 @@
 #ifndef _DATABASE_H
 #define _DATABASE_H
 
-
-#define MAX_EMAILS             4
+#define MAX_LIST_ITEMS         9
 #define MAX_EMAIL_LEN          80
-#define MAX_EMAILSTR_LEN       (MAX_EMAILS*MAX_EMAIL_LEN + MAX_EMAILS + 1)
+#define MAX_EMAILSTR_LEN       (MAX_LIST_ITEMS * (MAX_EMAIL_LEN + 1) + 1)
 #define MAX_FIELD_LEN          81
 
 enum {
-       NAME,
+       NAME = 0, /* important */
        EMAIL,
        ADDRESS,
         ADDRESS2,
@@ -23,27 +22,28 @@ enum {
        NICK,
        URL,
        NOTES,
-       CUSTOM1,
-       CUSTOM2,
-       CUSTOM3,
-       CUSTOM4,
-       CUSTOM5,
+       ANNIVERSARY,
        ITEM_FIELDS /* this is the last */
 };
 
-#define LAST_FIELD             (ITEM_FIELDS - 1)
-
-#define CUSTOM_MIN             CUSTOM1
-#define CUSTOM_MAX             CUSTOM5
+typedef struct {
+       char *key;
+       char *name;
+       int type;
+} abook_field;
 
-typedef char *list_item[ITEM_FIELDS];
+typedef struct abook_field_list_t {
+       abook_field *field;
+       struct abook_field_list_t *next;
+} abook_field_list;
 
-#define        MAX_FIELDNAME_LEN       21
+typedef char **list_item;
 
-struct abook_field {
-       char *name;
-       char *key;
-       int tab;
+enum {
+       FIELD_STRING = 1,
+       FIELD_EMAILS,
+       FIELD_LIST,
+       FIELD_DAY,
 };
 
 enum {
@@ -56,48 +56,88 @@ struct db_enumerator {
        int mode; /* warning: read only */
 };
 
-int            find_field(const char *field);
-int            parse_database(FILE *in);
-int            write_database(FILE *out, struct db_enumerator e);
-int            load_database(char *filename);
-int            save_database();
-void           close_database();
-int            add_item2database(list_item item);
-void           free_list_item(list_item item);
-void           remove_selected_items();
-void           sort_surname();
-void           sort_by_field(int field);
-char           *get_surname(char *s);
-int            find_item(char *str, int start, int search_fields[]);
-int            is_selected(int item);
-int            is_valid_item(int item);
-
-int            real_db_enumerate_items(struct db_enumerator e);
-struct db_enumerator   init_db_enumerator(int mode);
-int            change_custom_field_name(const char *name, int n);
-
-#define LAST_ITEM      (items - 1)
-
-#define itemcpy(dest, src)     memmove(dest, src, sizeof(list_item))
-
-#define split_emailstr(item, emails) do {\
-       int _i,_j,_k,len; \
-       memset(&emails, 0, sizeof(emails) ); \
-       len = strlen(database[item][EMAIL]); \
-       for( _i=0,_j=0, _k=0; _i < len && _j < MAX_EMAILS; _i++ ) { \
-               if( database[item][EMAIL][_i] ==',' ) { \
-                       _j++; \
-                       _k = 0; \
-               } else \
-                       if( _k < MAX_EMAIL_LEN -1 ) \
-                               emails[_j][_k++] = database[item][EMAIL][_i]; \
-       } \
-} while(0)
-
-#define have_multiple_emails(item) \
-       strchr(database[item][EMAIL], ',')
 
+/*
+ * Field operations
+ */
+inline int field_id(int i);
+abook_field *find_standard_field(char *key, int do_declare);
+abook_field *real_find_field(char *key, abook_field_list *list, int *nb);
+#define find_field(key, list)          real_find_field(key, list, NULL)
+#define find_field_number(key, pt_nb)  real_find_field(key, NULL, pt_nb)
+#define find_declared_field(key)       find_field(key,NULL)
+void get_field_keyname(int i, char **key, char **name);
+void add_field(abook_field_list **list, abook_field *f);
+char *declare_new_field(char *key, char *name, char *type, int accept_standard);
+void init_standard_fields();
+
+/*
+ * Various database operations
+ */
+void prepare_database_internals();
+int parse_database(FILE *in);
+int load_database(char *filename);
+int write_database(FILE *out, struct db_enumerator e);
+int save_database();
+void remove_selected_items();
+void sort_surname();
+void sort_by_field(char *field);
+void close_database();
+int add_item2database(list_item item);
+char *get_surname(char *s);
+int find_item(char *str, int start, int search_fields[]);
+int is_selected(int item);
+int is_valid_item(int item);
+
+int real_db_enumerate_items(struct db_enumerator e);
+struct db_enumerator init_db_enumerator(int mode);
 #define db_enumerate_items(e) \
        while( -1 != (e.item = real_db_enumerate_items(e)))
 
-#endif
+/*
+ * item manipulation
+ */
+list_item item_create();
+void item_empty(list_item item);
+void item_free(list_item *item);
+void item_copy(list_item dest, list_item src);
+void item_duplicate(list_item dest, list_item src);
+
+int item_fput(list_item item, int i, char *val);
+char *item_fget(list_item item, int i);
+
+/*
+ * database field read
+ */
+char *real_db_field_get(int item, int i, int std);
+#define db_fget(item, i)               real_db_field_get(item, i, 1)
+#define db_fget_byid(item, i)          real_db_field_get(item, i, 0)
+#define db_name_get(item)              db_fget(item, NAME)
+#define db_email_get(item)             db_fget(item, EMAIL)
+
+/*
+ * database field write
+ */
+int real_db_field_put(int item, int i, int std, char *val);
+#define db_fput(item, i, val) \
+                       real_db_field_put(item, i, 1, val)
+#define db_fput_byid(item, i, val) \
+                       real_db_field_put(item, i, 0, val)
+
+/*
+ * database item read
+ */
+list_item db_item_get(int i);
+
+
+/*
+ * Various macros
+ */
+
+#define LAST_ITEM (items - 1)
+
+#define have_multiple_emails(item) \
+       strchr(db_email_get(item), ',')
+
+#endif /* _DATABASE_H */
+
diff --git a/edit.c b/edit.c
index 47c288686775c07dc89645a3ab5106bd0345edc8..f5e05845e8022e1abc94f20e4845815a5aa0c8d9 100644 (file)
--- a/edit.c
+++ b/edit.c
@@ -9,6 +9,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <ctype.h>
 #include <assert.h>
 #include "abook_curses.h"
 #include "ui.h"
@@ -18,6 +19,7 @@
 #include "list.h"
 #include "edit.h"
 #include "misc.h"
+#include "views.h"
 #include "xmalloc.h"
 #ifdef HAVE_CONFIG_H
 #      include "config.h"
  * some extern variables
  */
 
-extern struct abook_field abook_fields[];
 
-extern list_item *database;
 extern int curitem;
+extern int views_count;
 extern int items;
 
 WINDOW *editw;
 
+
 static void
 editor_tab(const int tab)
 {
        int i, j;
        int x_pos = 2; /* current x pos */
-       static char *tab_names[] = {
-               N_("CONTACT"),
-               N_("ADDRESS"),
-               N_(" PHONE "),
-               N_(" OTHER "),
-               N_("CUSTOM ")
-       };
+       char *tab_name;
 
        mvwhline(editw, TABLINE + 1, 0, UI_HLINE_CHAR, EDITW_COLS);
 
-       for(i = 0; i < TABS; i++) {
-               int width = strwidth(gettext(tab_names[i])) + 5;
+       for(i = 0; i < views_count; i++) {
+               view_info(i, &tab_name, NULL);
+               int width = strwidth(tab_name) + 5;
 
                if(x_pos + width + 1 > EDITW_COLS) {
                        statusline_msg(_("Tab name too wide for screen"));
+                       /* Disabling this field */
+                       /* TODO should be recomputed on window resize */
+                       views_count--;
                        break;
                }
 
@@ -63,7 +63,7 @@ editor_tab(const int tab)
 
                mvwaddch(editw,  TABLINE, x_pos,  UI_ULCORNER_CHAR);
                mvwaddch(editw,  TABLINE, x_pos + 1,  UI_LBOXLINE_CHAR);
-               mvwaddstr(editw, TABLINE, x_pos + 2,  gettext(tab_names[i]));
+               mvwaddstr(editw, TABLINE, x_pos + 2,  tab_name);
                mvwaddch(editw,  TABLINE, x_pos + width - 3, UI_RBOXLINE_CHAR);
                mvwaddch(editw,  TABLINE, x_pos + width - 2, UI_URCORNER_CHAR);
 
@@ -84,34 +84,30 @@ get_first_email(char *str, int item)
 {
        char *tmp;
 
-       if(database[item][EMAIL] == NULL) {
+       if(!db_email_get(item)) {
                *str = 0;
                return;
        }
 
-       strncpy(str, database[item][EMAIL], MAX_EMAIL_LEN);
+       strncpy(str, db_email_get(item), MAX_EMAIL_LEN);
        if( (tmp = strchr(str, ',')) )
                *tmp = 0;
        else
-               str[MAX_EMAIL_LEN-1] = 0;
+               str[MAX_EMAIL_LEN - 1] = 0;
 }
 
 static void
-roll_emails(int item)
+roll_emails(int item, enum rotate_dir dir)
 {
-       char tmp[MAX_EMAILSTR_LEN];
-       char *p;
-
-       strcpy(tmp, database[item][EMAIL]);
+       abook_list *emails = csv_to_abook_list(db_email_get(item));
 
-       if( !(p = strchr(tmp, ',')) )
+       if(!emails)
                return;
-       else
-               *p = 0;
 
-       strcpy(database[item][EMAIL], p+1);
-       strcat(database[item][EMAIL], ",");
-       strcat(database[item][EMAIL], tmp);
+       free(db_email_get(item));
+       abook_list_rotate(&emails, dir);
+       db_fput(item, EMAIL, abook_list_to_csv(emails));
+       abook_list_free(&emails);
 }
 
 static void
@@ -119,6 +115,7 @@ init_editor()
 {
        clear();
        editw = newwin(EDITW_LINES, EDITW_COLS, EDITW_TOP, EDITW_X);
+       notimeout(editw, TRUE); /* handling of escape key */
 
        refresh_statusline();
 }
@@ -132,47 +129,39 @@ enum {
 static int
 edit_undo(int item, int mode)
 {
-       int i;
-       static list_item *backup = NULL;
+       static list_item backup = NULL;
        static int backed_up_item = -1;
 
        switch(mode) {
                case CLEAR_UNDO:
                        if(backup) {
-                               free_list_item(backup[0]);
-                               xfree(backup);
+                               item_empty(backup);
+                               item_free(&backup);
                        }
                        break;
                case BACKUP_ITEM:
                        if(backup) {
-                               free_list_item(backup[0]);
-                               xfree(backup);
+                               item_empty(backup);
+                               item_free(&backup);
                        }
-                       backup = xmalloc(sizeof(list_item));
-                       for(i = 0; i < ITEM_FIELDS; i++)
-                               if(database[item][i] == NULL)
-                                       backup[0][i] = NULL;
-                               else
-                                       backup[0][i] =
-                                               xstrdup(database[item][i]);
+                       backup = item_create();
+                       item_duplicate(backup, db_item_get(item));
                        backed_up_item = item;
                        break;
                case RESTORE_ITEM:
                        if(backup) {
-                               free_list_item(database[backed_up_item]);
-                               itemcpy(database[backed_up_item], backup[0]);
-                               xfree(backup);
+                               item_empty(db_item_get(backed_up_item));
+                               item_copy(db_item_get(backed_up_item), backup);
+                               item_free(&backup);
                                return backed_up_item;
                        }
                        break;
                default:
                        assert(0);
        }
-
        return item;
 }
 
-
 static void
 close_editor()
 {
@@ -192,15 +181,14 @@ print_editor_header(int item)
 
        get_first_email(email, item);
 
-       if(*database[item][EMAIL])
+       if(*db_email_get(item))
                snprintf(header, EDITW_COLS, "%s <%s>",
-                               database[item][NAME],
+                               db_name_get(item),
                                email);
        else
-               snprintf(header, EDITW_COLS, "%s", database[item][NAME]);
+               snprintf(header, EDITW_COLS, "%s", db_name_get(item));
 
-       mvwaddstr(editw, 0, (EDITW_COLS - strwidth(header)) / 2,
-                       header);
+       mvwaddstr(editw, 0, (EDITW_COLS - strwidth(header)) / 2, header);
 
        free(header);
 }
@@ -208,29 +196,14 @@ print_editor_header(int item)
 static void
 editor_print_data(int tab, int item)
 {
-       int i, j;
+       int j = 1, nb;
        int y, x;
+       abook_field_list *cur;
+       char *str;
 
-       for(i = 0, j = 1; i < ITEM_FIELDS; i++) {
-               if(abook_fields[i].tab != tab)
-                       continue;
+       view_info(tab, NULL, &cur);
 
-               if(i == EMAIL) { /* special field */
-                       int k;
-                       char emails[MAX_EMAILS][MAX_EMAIL_LEN];
-                       split_emailstr(item, emails);
-                       getyx(editw, y, x);
-                       mvwaddstr(editw, y+1, FIELDS_START_X,
-                                       _("E-mail addresses:"));
-                       for(k = 0; k < MAX_EMAILS; k++) {
-                               getyx(editw, y, x);
-                               mvwprintw(editw, y+1, FIELDS_START_X,
-                               "%c -", '2' + k);
-                               mvwprintw(editw, y +1, TAB_COLON_POS,
-                                               ": %s", emails[k]);
-                       }
-                       continue;
-               }
+       for(; cur; cur = cur->next) {
 
                if(j > 1) {
                        getyx(editw, y, x);
@@ -238,12 +211,43 @@ editor_print_data(int tab, int item)
                } else
                        y = FIELDS_START_Y;
 
-               mvwprintw(editw, y, FIELDS_START_X, "%d - %s",
-                               j,
-                               gettext(abook_fields[i].name));
+               mvwprintw(editw, y, FIELDS_START_X, "%c - ",
+                               (j < 10) ? '0' + j : 'A' + j - 10);
+               mvwaddnstr(editw, y, FIELDS_START_X + 4, cur->field->name,
+                               bytes2width(cur->field->name,
+                                       FIELDNAME_MAX_WIDTH));
                mvwaddch(editw, y, TAB_COLON_POS, ':');
-               mvwaddstr(editw, y, TAB_COLON_POS + 2,
-                               safe_str(database[item][i]));
+
+               if((cur->field->type == FIELD_EMAILS) ||
+                               (cur->field->type == FIELD_LIST)) {
+                       abook_list *emails, *e;
+                       
+                       find_field_number(cur->field->key, &nb);
+                       emails = csv_to_abook_list(db_fget_byid(item, nb));
+
+                       for(e = emails; e; e = e->next) {
+                               getyx(editw, y, x);
+                               mvwaddnstr(editw, y + 1, TAB_COLON_POS + 2,
+                                               e->data,
+                                               bytes2width(e->data,
+                                                       FIELD_MAX_WIDTH));
+                               mvwaddch(editw, y + 1, TAB_COLON_POS,
+                                               UI_VLINE_CHAR);
+                       }
+                       if(emails) {
+                               mvwaddch(editw, y + 2, TAB_COLON_POS,
+                                               UI_LLCORNER_CHAR);
+                               mvwhline(editw, y + 2, TAB_COLON_POS + 1,
+                                               UI_HLINE_CHAR,
+                                               EDITW_COLS - TAB_COLON_POS - 2);
+                       }
+                       abook_list_free(&emails);
+               } else {
+                       find_field_number(cur->field->key, &nb);
+                       str = safe_str(db_fget_byid(item, nb));
+                       mvwaddnstr(editw, y, TAB_COLON_POS + 2, str,
+                               bytes2width(str, FIELD_MAX_WIDTH));
+               }
 
                j++;
        }
@@ -258,22 +262,19 @@ editor_print_data(int tab, int item)
  *  (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)
+ *  (size_t max_len)
+ *   maximum length of field to read from user
  *
  * 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)
+change_field(char *msg, char **field, int max_len)
 {
-       int max_len = MAX_FIELD_LEN;
        char *old;
        int ret = 0;
 
-       if(!strncmp("E-mail", msg, 6))
-               max_len = MAX_EMAIL_LEN;
-
        old = *field;
 
        *field = ui_readline(msg, old, max_len - 1, 0);
@@ -293,13 +294,14 @@ change_field(char *msg, char **field)
        return ret;
 }
 
-static void
-change_name_field(char **field)
+static int
+change_name_field(char *msg, char **field, int max_len)
 {
        char *tmp;
+       int ret;
 
        tmp = xstrdup(*field);
-       change_field("Name: ", field);
+       ret = change_field(msg, field, max_len);
 
        if(*field == NULL || ! **field) {
                xfree(*field);
@@ -307,6 +309,8 @@ change_name_field(char **field)
        }
 
        xfree(tmp);
+
+       return ret;
 }
 
 static void
@@ -317,83 +321,133 @@ fix_email_str(char *str)
 }
 
 static void
-edit_emails(char c, int item)
+edit_list(int item, int nb, int isemail)
 {
-       char *field;
-       char emails[MAX_EMAILS][MAX_EMAIL_LEN];
-       char tmp[MAX_EMAILSTR_LEN] = "";
-       int i, len;
-       int email_num = c - '2';
+       char *field, *msg, *keys;
+       abook_list *list, *e;
+       int choice = 1, elem_count;
+
+       list = csv_to_abook_list(db_fget_byid(item, nb));
+
+       for(e = list, elem_count = 0; e; e = e->next, elem_count++)
+               ;
+
+       if(elem_count) {
+               keys = xstrndup(S_("keybindings_new_123456789|n123456789"),
+                               elem_count + 1);
+               msg = strdup_printf(_("Choose %s to modify (<1>%s%c%s%s."),
+                               isemail ? _("email") : _("item"),
+                               (elem_count > 1) ? "-<" : "",
+                               (elem_count > 1) ?  '0' + elem_count : ')',
+                               (elem_count > 1) ? ">)" : "",
+                               (elem_count < MAX_LIST_ITEMS) ?
+                                       _(" or <n>ew") : ""
+                               );
+               choice = statusline_askchoice(
+                               msg,
+                               keys,
+                               (elem_count < MAX_LIST_ITEMS) ? 1 : 2
+                               );
+               free(keys);
+               free(msg);
+       }
 
-       split_emailstr(item, emails);
-       field = xstrdup(emails[email_num]);
+       if(choice == 0)
+               return;
 
-       if(change_field("E-mail: ", &field))
-               return; /* user cancelled ( C-g ) */
+       field = (choice > 1) ?
+               xstrdup(abook_list_get(list, choice - 2)->data) :
+               NULL;
 
-       if(field) {
-               strncpy(emails[email_num], field, MAX_EMAIL_LEN);
-               fix_email_str(emails[email_num]);
-       } else
-               *emails[email_num] = 0;
+       if(change_field(isemail ? _("E-mail: ") : _("Item: "),
+                               &field, MAX_EMAIL_LEN))
+               return; /* user cancelled ( C-g ) */
 
-       xfree(database[item][EMAIL]);
+       /* TODO if list item contains commas, sjould use quotes instead */
+       if(field)
+               fix_email_str(field);
 
-       for(i = 0; i < MAX_EMAILS; i++) {
-               if( *emails[i] ) {
-                       strcat(tmp, emails[i]);
-                       strcat(tmp, ",");
-               }
-       }
+       if(choice == 1)
+               abook_list_append(&list, field);
+       else
+               abook_list_replace(&list, choice - 2, field);
 
-       len = strlen(tmp);
-       if(tmp[len -1] == ',')
-               tmp[len-1] =0;
+       if(field)
+               xfree(field);
 
-       database[item][EMAIL] = xstrdup(tmp);
+       field = abook_list_to_csv(list);
+       db_fput_byid(item, nb, field ? field : xstrdup(""));
+       abook_list_free(&list);
 }
 
+
+/* input range: 1-9A-Z
+ * output range: 0-34 */
 static int
-edit_field(int tab, char c, int item)
+key_to_field_number(char c)
 {
-       int i, j;
-       int n = c - '1' + 1;
-       char *str;
+       int n = c - '1';
+       if(n >= 0 && n < 9)
+               return n;
 
-       if(n < 1 || n > MAX_TAB_FIELDS)
-               return 0;
+       n = c - 'A' + 9;
+       if(n > 8 && n < 35)
+               return n;
 
-       edit_undo(item, BACKUP_ITEM);
+       return -1;
+}
 
-       if(tab == TAB_CONTACT) {
-               switch(c) {
-                       case '1': change_name_field(&database[item][NAME]);
-                                 break;
-                       case '2':
-                       case '3':
-                       case '4':
-                       case '5': edit_emails(c, item); break;
-                       default: return 0;
-               }
-               return 1;
-       }
+static void
+edit_field(int tab, char c, int item_number)
+{
+       int i = 0, number, idx;
+       char *msg;
+       abook_field_list *f;
+       list_item item;
 
-       for(i = 0, j = 0; i< ITEM_FIELDS; i++) {
-               if(abook_fields[i].tab == tab)
-                       j++;
-               if(j==n)
-                       break;
-       }
+       if((number = key_to_field_number(c)) < 0)
+               return;
+
+       edit_undo(item_number, BACKUP_ITEM);
 
-       if(j != n)
-               return 0;
+       view_info(tab, NULL, &f);
 
-       str = strdup_printf("%s: ", gettext(abook_fields[i].name));
-       change_field(str, &database[item][i]);
+       while(1) {
+               if(!f)
+                       return;
+
+               if(i == number)
+                       break;
 
-       free(str);
+               f = f->next;
+               i++;
+       }
 
-       return 1;
+       find_field_number(f->field->key, &idx);
+       
+       switch(f->field->type) {
+               case FIELD_STRING:
+                       msg = strdup_printf("%s: ", f->field->name);
+                       item = db_item_get(item_number);
+                       if(strcmp(f->field->key, "name") == 0)
+                               change_name_field(msg,&item[idx],MAX_FIELD_LEN);
+                       else
+                               change_field(msg,&item[idx],MAX_FIELD_LEN);
+                       free(msg);
+                       break;
+               case FIELD_LIST:
+                       edit_list(item_number, idx, 0);
+                       break;
+               case FIELD_EMAILS:
+                       edit_list(item_number, idx, 1);
+                       break;
+               case FIELD_DAY:
+                       statusline_msg(_("sorry, input for this field type is "
+                                               "not yet implemented"));
+                       return;
+               default:
+                       assert(0);
+       }
 }
 
 static int
@@ -413,31 +467,44 @@ edit_loop(int item)
        refresh();
        wrefresh(editw);
 
-       switch((c = getch())) {
-               case 'c': tab = TAB_CONTACT; break;
-               case 'a': tab = TAB_ADDRESS; break;
-               case 'p': tab = TAB_PHONE; break;
-               case 'o': tab = TAB_OTHER; break;
-               case 'C': tab = TAB_CUSTOM; break;
+       c = getch();
+       if(c == '\033') {
+               statusline_addstr("ESC-");
+               c = getch();
+               clear_statusline();
+
+               /* Escaped bindings */
+               switch(c) {
+                       case 'r': roll_emails(item, ROTATE_RIGHT); break;
+                       default: break;
+               }
+
+               return item;
+       }
+
+       /* No uppercase nor numeric key should be used in this menu,
+        * as they are reserved for field selection */
+       switch(c) {
                case 'h':
-               case KEY_LEFT: tab = tab == 0 ? MAX_TAB : tab - 1;
+               case KEY_LEFT: tab = tab == 0 ? views_count - 1 : tab - 1;
                               break;
                case 'l':
-               case KEY_RIGHT: tab = tab == MAX_TAB ? 0 : tab + 1;
+               case KEY_RIGHT: tab = tab == views_count - 1 ? 0 : tab + 1;
                                break;
                case KEY_UP:
                case '<':
-               case 'k': if(is_valid_item(item-1)) item--; break;
+               case 'k': if(is_valid_item(item - 1)) item--; break;
                case KEY_DOWN:
                case '>':
                case 'j': if(is_valid_item(item + 1)) item++; break;
-               case 'r': roll_emails(item); break;
+               case 'r': roll_emails(item, ROTATE_LEFT); break;
                case '?': display_help(HELP_EDITOR); break;
                case 'u': item = edit_undo(item, RESTORE_ITEM); break;
                case 'm': launch_mutt(item); clearok(stdscr, 1); break;
                case 'v': launch_wwwbrowser(item); clearok(stdscr, 1); break;
                case 12 : clearok(stdscr, 1); break; /* ^L (refresh screen) */
-               default:  return edit_field(tab, c, item) ? item : -1;
+               case 'q': return -1;
+               default: edit_field(tab, c, item);
        }
 
        return item;
@@ -465,18 +532,17 @@ void
 add_item()
 {
        char *field = NULL;
-       list_item item;
+       list_item item = item_create();
 
-       change_field("Name: ", &field);
+       change_field("Name: ", &field, MAX_FIELD_LEN);
 
        if( field == NULL )
                return;
 
-       memset(item, 0, sizeof(item));
-
-       item[NAME] = field;
+       item_fput(item, NAME, field);
 
        add_item2database(item);
+       item_free(&item);
 
        curitem = LAST_ITEM;
 
diff --git a/edit.h b/edit.h
index e9ac9202b4aa2c7051cc52c6bef445524ef9776a..aa521411823a0b652ba910ae25fe5223a3a6c600 100644 (file)
--- a/edit.h
+++ b/edit.h
@@ -10,26 +10,15 @@ void                add_item();
 #define EDITW_TOP      2
 #define EDITW_X                3
 
-#define EDITOR_HELPLINE        N_("?:help c:contact a:address p:phone o:other")
+#define EDITOR_HELPLINE        N_("?:help q:quit editor")
 
 #define TABLINE                1
 
-#define MAX_TAB_FIELDS 7
-
 #define TAB_COLON_POS  28
+#define FIELDNAME_MAX_WIDTH    20
+#define FIELD_MAX_WIDTH        (EDITW_COLS - TAB_COLON_POS - FIELDS_START_X - 2)
+
 #define FIELDS_START_Y 4
 #define FIELDS_START_X 4
 
-enum {
-       TAB_CONTACT,
-       TAB_ADDRESS,
-       TAB_PHONE,
-       TAB_OTHER,
-       TAB_CUSTOM
-};
-
-#define MAX_TAB                TAB_CUSTOM
-
-#define TABS           (MAX_TAB+1)
-
 #endif
index 62394ca0cf2c1b05fca28541c600b3b1b99e4603..0020fc201fd43158a7c3dd00d72ca5403d3c7fab 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -28,8 +28,8 @@
 #include <assert.h>
 
 extern int items;
-extern list_item *database;
-extern struct abook_field abook_fields[];
+extern abook_field_list *fields_list;
+extern int fields_count;
 
 /*
  * function declarations
@@ -281,7 +281,7 @@ import_file(char filtname[FILTNAME_LEN], char *filename)
  * export
  */
 
-static int             e_write_file(char *filename,
+static int e_write_file(char *filename,
                int (*func) (FILE *in, struct db_enumerator e), int mode);
 
 static void
@@ -531,10 +531,10 @@ ldif_read_line(FILE *in)
 static void
 ldif_add_item(ldif_item li)
 {
-       list_item abook_item;
+       list_item item;
        int i;
 
-       memset(abook_item, 0, sizeof(abook_item));
+       item = item_create();
 
        if(!li[LDIF_ITEM_FIELDS -1])
                goto bail_out;
@@ -542,14 +542,15 @@ ldif_add_item(ldif_item li)
 
        for(i=0; i < LDIF_ITEM_FIELDS; i++) {
                if(ldif_conv_table[i] >= 0 && li[i] && *li[i])
-                       abook_item[ldif_conv_table[i]] = xstrdup(li[i]);
+                       item_fput(item,ldif_conv_table[i],xstrdup(li[i]));
        }
 
-       add_item2database(abook_item);
+       add_item2database(item);
 
 bail_out:
        for(i=0; i < LDIF_ITEM_FIELDS; i++)
                xfree(li[i]);
+       item_free(&item);
 
 }
 
@@ -568,9 +569,11 @@ ldif_convert(ldif_item item, char *type, char *value)
                        if(i == LDIF_ITEM_FIELDS - 1) /* this is a dirty hack */
                                if(safe_strcmp("person", value))
                                        break;
-                       if(item[i])
-                               xfree(item[i]);
-                       item[i] = xstrdup(value);
+
+                       if(item_fget(item, i))
+                               free(item_fget(item, i));
+
+                       item_fput(item, i, xstrdup(value));
                }
        }
 }
@@ -638,8 +641,7 @@ mutt_read_line(FILE *in, char **alias, char **rest)
        if( !(line = ptr = getaline(in)) )
                return 1; /* error / EOF */
 
-       while( ISSPACE(*ptr) )
-               ptr++;
+       SKIPWS(ptr);
 
        if(strncmp("alias", ptr, 5)) {
                free(line);
@@ -648,8 +650,7 @@ mutt_read_line(FILE *in, char **alias, char **rest)
 
        ptr += 5;
 
-       while( ISSPACE(*ptr) )
-               ptr++;
+       SKIPWS(ptr);
 
        tmp = ptr;
 
@@ -658,13 +659,13 @@ mutt_read_line(FILE *in, char **alias, char **rest)
 
        alias_len = (size_t)(ptr - tmp);
 
-       *alias = xmalloc_inc(alias_len, 1);
+       if(alias)
+               *alias = xmalloc_inc(alias_len, 1);
 
        strncpy(*alias, tmp, alias_len);
        *(*alias + alias_len) = 0;
 
-       while(ISSPACE(*ptr))
-               ptr++;
+       SKIPWS(ptr);
 
        *rest = xstrdup(ptr);
 
@@ -695,7 +696,7 @@ mutt_fix_quoting(char *p)
 static void
 mutt_parse_email(list_item item)
 {
-       char *line = item[NAME];
+       char *line = item_fget(item, NAME);
        char *tmp;
        char *name, *email;
 #if 0
@@ -709,11 +710,12 @@ mutt_parse_email(list_item item)
        free(tmp);
 
        if(name)
-               item[NAME] = name;
+               item_fput(item, NAME, name);
        else
                return;
+
        if(email)
-               item[EMAIL] = email;
+               item_fput(item, EMAIL, email);
        else
                return;
 
@@ -742,22 +744,25 @@ mutt_parse_email(list_item item)
 static int
 mutt_parse_file(FILE *in)
 {
-       list_item item;
+       list_item item = item_create();
 
        for(;;) {
-               memset(item, 0, sizeof(item));
+               memset(item, 0, fields_count * sizeof(char *));
 
-               if(!mutt_read_line(in, &item[NICK],
-                               &item[NAME]) )
+               if(!mutt_read_line(in,
+                                       (field_id(NICK) != -1) ?
+                                       &item[field_id(NICK)] : NULL,
+                                       &item[field_id(NAME)]))
                        mutt_parse_email(item);
 
                if(feof(in)) {
-                       free_list_item(item);
+                       item_empty(item);
                        break;
                }
 
                add_item2database(item);
        }
+       item_free(&item);
 
        return 0;
 }
@@ -795,7 +800,8 @@ ldif_export_database(FILE *out, struct db_enumerator e)
                int j;
                get_first_email(email, e.item);
 
-               tmp = strdup_printf("cn=%s,mail=%s", database[e.item][NAME], email);
+               tmp = strdup_printf("cn=%s,mail=%s",db_name_get(e.item),email);
+
                ldif_fput_type_and_value(out, "dn", tmp);
                free(tmp);
 
@@ -804,10 +810,11 @@ ldif_export_database(FILE *out, struct db_enumerator e)
                                if(ldif_conv_table[j] == EMAIL)
                                        ldif_fput_type_and_value(out,
                                                ldif_field_names[j], email);
-                               else if(database[e.item][ldif_conv_table[j]])
+                               else if(db_fget(e.item,ldif_conv_table[j]))
                                        ldif_fput_type_and_value(out,
                                                ldif_field_names[j],
-                                               database[e.item][ldif_conv_table[j]]);
+                                               db_fget(e.item,
+                                                       ldif_conv_table[j]));
                        }
                }
 
@@ -829,34 +836,33 @@ 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;
 
        if(items < 1)
                return 2;
 
-       extra_column = (extra_column > 2 && extra_column < ITEM_FIELDS) ?
-               extra_column : PHONE;
-
+       extra_column = init_extra_field(STR_EXTRA_COLUMN);
        html_export_write_head(out, extra_column);
 
        db_enumerate_items(e) {
                get_first_email(tmp, e.item);
                if (*tmp)
-                   fprintf(out, "<tr>\n<td><a href=\"mailto:%s\">%s</a>\n",
+                   fprintf(out, "<tr>\n<td>"
+                                   "<a href=\"mailto:%s\">%s</a>"
+                                   "</td>\n",
                            tmp,
-                           database[e.item][NAME] );
+                           db_name_get(e.item));
                else
-                   fprintf(out, "<tr>\n<td>%s\n",
-                           database[e.item][NAME] );
+                   fprintf(out, "<tr>\n<td>%s</td>\n", db_name_get(e.item));
 
-               fprintf(out, "<td>%s\n<td>%s\n",
-                               database[e.item][EMAIL],
-                               safe_str(database[e.item][extra_column]) );
+               fprintf(out, "<td>%s</td>\n", db_email_get(e.item));
+               if(extra_column >= 0)
+                       fprintf(out, "<td>%s</td>\n",
+                               safe_str(db_fget_byid(e.item, extra_column)));
                fprintf(out, "</tr>\n\n");
        }
 
@@ -865,21 +871,25 @@ html_export_database(FILE *out, struct db_enumerator e)
        return 0;
 }
 
-
 static void
 html_export_write_head(FILE *out, int extra_column)
 {
-       char *realname = get_real_name();
+       char *realname = get_real_name(), *extra_column_name = NULL;
 
        fprintf(out, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
-       fprintf(out, "<html>\n<head>\n <title>%s's addressbook</title>", realname );
+       fprintf(out, "<html>\n<head>\n <title>%s's addressbook</title>",
+                       realname );
        fprintf(out, "\n</head>\n<body>\n");
        fprintf(out, "\n<h2>%s's addressbook</h2>\n", realname );
        fprintf(out, "<br><br>\n\n");
 
        fprintf(out, "<table border=\"1\" align=\"center\">\n");
-       fprintf(out, "\n<tr><th>Name<th>E-mail address(es)<th>%s</tr>\n\n",
-                       abook_fields[extra_column].name);
+       fprintf(out, "\n<tr><th>Name</th><th>E-mail address(es)</th>");
+       if(extra_column >= 0) {
+               get_field_keyname(extra_column, NULL, &extra_column_name);
+               fprintf(out, "<th>%s</th>", safe_str(extra_column_name));
+       }
+       fprintf(out, "</tr>\n\n");
 
        free(realname);
 }
@@ -927,7 +937,7 @@ pine_convert_emails(char *s)
                *tmp=0;
 
        for(i = 1; ( tmp = strchr(s, ',') ) != NULL ; i++, s = tmp + 1)
-               if(i > MAX_EMAILS - 1) {
+               if(i > MAX_LIST_ITEMS - 1) {
                        *tmp = 0;
                        break;
                }
@@ -944,7 +954,7 @@ pine_parse_buf(char *buf)
        int i, len, last;
        int pine_conv_table[]= {NICK, NAME, EMAIL, -1, NOTES};
 
-       memset(&item, 0, sizeof(item));
+       item = item_create();
 
        for(i=0, last=0; !last ; i++) {
                if( !(end = strchr(start, '\t')) )
@@ -958,13 +968,15 @@ pine_parse_buf(char *buf)
                        strncpy(tmp, start, len);
                        tmp[len] = 0;
                        if(*tmp)
-                               item[pine_conv_table[i]] = xstrdup(tmp);
+                               item_fput(item, pine_conv_table[i],
+                                               xstrdup(tmp));
                }
                start = end + 1;
        }
 
-       pine_convert_emails(item[EMAIL]);
+       pine_convert_emails(item_fget(item, EMAIL));
        add_item2database(item);
+       item_free(&item);
 }
 
 
@@ -1027,10 +1039,10 @@ pine_export_database(FILE *out, struct db_enumerator e)
        db_enumerate_items(e) {
                fprintf(out, have_multiple_emails(e.item) ?
                                "%s\t%s\t(%s)\t\t%s\n" : "%s\t%s\t%s\t\t%s\n",
-                               safe_str(database[e.item][NICK]),
-                               safe_str(database[e.item][NAME]),
-                               safe_str(database[e.item][EMAIL]),
-                               safe_str(database[e.item][NOTES])
+                               safe_str(db_fget(e.item, NICK)),
+                               safe_str(db_name_get(e.item)),
+                               safe_str(db_email_get(e.item)),
+                               safe_str(db_fget(e.item, NOTES))
                                );
        }
 
@@ -1080,11 +1092,7 @@ static int allcsv_conv_table[] = {
        NICK,
        URL,
        NOTES,
-       CUSTOM1,
-       CUSTOM2,
-       CUSTOM3,
-       CUSTOM4,
-       CUSTOM5,
+       ANNIVERSARY
 };
 
 static int palmcsv_conv_table[] = {
@@ -1102,11 +1110,7 @@ static int palmcsv_conv_table[] = {
        STATE,
        ZIP,
        COUNTRY,
-       CUSTOM1,
-       CUSTOM2,
-       CUSTOM3,
-       CUSTOM4,
-       CUSTOM5,
+       ANNIVERSARY,
 };
 
 static void
@@ -1119,7 +1123,7 @@ csv_convert_emails(char *s)
                return;
 
        for(i = 1; ( tmp = strchr(s, ',') ) != NULL ; i++, s = tmp + 1)
-               if(i > MAX_EMAILS - 1) {
+               if(i > MAX_LIST_ITEMS - 1) {
                        *tmp = 0;
                        break;
                }
@@ -1156,7 +1160,7 @@ static int
 csv_field_to_item(int *table_base, size_t table_size, int field)
 {
        if(field < table_size)
-               return table_base[field];
+               return field_id(table_base[field]);
 
        return -1;
 }
@@ -1225,7 +1229,7 @@ csv_parse_line(char *line, int *table_base, size_t table_size)
        bool in_quote = FALSE;
        list_item item;
 
-       memset(item, 0, sizeof(item));
+       item = item_create();
 
        for(p = start = line, field = 0; *p; p++) {
                if(in_quote) {
@@ -1239,10 +1243,8 @@ csv_parse_line(char *line, int *table_base, size_t table_size)
 
                if(*p == ',' && !in_quote) {
                        *p = 0;
-                       csv_field_to_item(table_base, table_size, field);
                        csv_store_item(item,
-                               csv_field_to_item(table_base,
-                                                       table_size, field),
+                               csv_field_to_item(table_base,table_size,field),
                                start);
                        field++;
                        start = p + 1;
@@ -1254,8 +1256,9 @@ csv_parse_line(char *line, int *table_base, size_t table_size)
        csv_store_item(item, csv_field_to_item(table_base, table_size, field),
                start);
 
-       csv_convert_emails(item[EMAIL]);
+       csv_convert_emails(item_fget(item, EMAIL));
        add_item2database(item);
+       item_free(&item);
 }
 
 static int
@@ -1324,13 +1327,13 @@ csv_export_common(FILE *out, struct db_enumerator e,
                                        (*special_func)(out, e.item, fields[i]);
                        } else
                                /*fprintf(out,(
-                       strchr(safe_str(database[e.item][fields[i]]), ',') ||
-                       strchr(safe_str(database[e.item][fields[i]]), '\"')) ?
+                       strchr(safe_str(database[e.item][field_idx(fields[i])]), ',') ||
+                       strchr(safe_str(database[e.item][field_idx(fields[i])]), '\"')) ?
                                "\"%s\"" : "%s",
-                               safe_str(database[e.item][fields[i]])
+                               safe_str(database[e.item][field_idx(fields[i])])
                                );*/
                                fprintf(out, "\"%s\"",
-                                       safe_str(database[e.item][fields[i]]));
+                                       safe_str(db_fget(e.item,fields[i])));
 
                        if(fields[i + 1] != CSV_LAST)
                                fputc(',', out);
@@ -1381,11 +1384,7 @@ allcsv_export_database(FILE *out, struct db_enumerator e)
                NICK,
                URL,
                NOTES,
-               CUSTOM1,
-               CUSTOM2,
-               CUSTOM3,
-               CUSTOM4,
-               CUSTOM5,
+               ANNIVERSARY,
                CSV_LAST
        };
 
@@ -1405,11 +1404,7 @@ allcsv_export_database(FILE *out, struct db_enumerator e)
        fprintf(out, "\"NICK\",");
        fprintf(out, "\"URL\",");
        fprintf(out, "\"NOTES\",");
-       fprintf(out, "\"CUSTOM1\",");
-       fprintf(out, "\"CUSTOM2\",");
-       fprintf(out, "\"CUSTOM3\",");
-       fprintf(out, "\"CUSTOM4\",");
-       fprintf(out, "\"CUSTOM5\"\n");
+       fprintf(out, "\"ANNIVERSARY\"\n");
 
        csv_export_common(out, e, allcsv_export_fields, NULL);
 
@@ -1448,7 +1443,7 @@ palm_csv_handle_specials(FILE *out, int item, int field)
 {
        switch(field) {
                case PALM_CSV_NAME:
-                       palm_split_and_write_name(out, database[item][NAME]);
+                       palm_split_and_write_name(out, db_name_get(item));
                        break;
                case PALM_CSV_CAT:
                        fprintf(out, "\"abook\"");
@@ -1504,59 +1499,65 @@ palm_export_database(FILE *out, struct db_enumerator e)
 static int
 gcrd_export_database(FILE *out, struct db_enumerator e)
 {
-       char emails[MAX_EMAILS][MAX_EMAIL_LEN];
        int j;
        char *name;
+       abook_list *emails, *em;
 
        db_enumerate_items(e) {
                fprintf(out, "BEGIN:VCARD\nFN:%s\n",
-                               safe_str(database[e.item][NAME]));
+                               safe_str(db_name_get(e.item)));
 
-               name = get_surname(database[e.item][NAME]);
-               for( j = strlen(database[e.item][NAME]) - 1; j >= 0; j-- ) {
-                       if(database[e.item][NAME][j] == ' ')
+               name = get_surname(db_name_get(e.item));
+               for( j = strlen(db_name_get(e.item)) - 1; j >= 0; j-- ) {
+                       if((db_name_get(e.item))[j] == ' ')
                                break;
                }
                fprintf(out, "N:%s;%.*s\n",
                        safe_str(name),
                        j,
-                       safe_str(database[e.item][NAME])
+                       safe_str(db_name_get(e.item))
                        );
 
                free(name);
 
-               if ( database[e.item][ADDRESS] )
+               if(db_fget(e.item, ADDRESS))
                        fprintf(out, "ADR:;;%s;%s;%s;%s;%s;%s\n",
-                               safe_str(database[e.item][ADDRESS]),
-                               safe_str(database[e.item][ADDRESS2]),
-                               safe_str(database[e.item][CITY]),
-                               safe_str(database[e.item][STATE]),
-                               safe_str(database[e.item][ZIP]),
-                               safe_str(database[e.item][COUNTRY])
+                               safe_str(db_fget(e.item, ADDRESS)),
+                               safe_str(db_fget(e.item, ADDRESS2)),
+                               safe_str(db_fget(e.item, CITY)),
+                               safe_str(db_fget(e.item, STATE)),
+                               safe_str(db_fget(e.item, ZIP)),
+                               safe_str(db_fget(e.item, COUNTRY))
                                );
 
-               if (database[e.item][PHONE])
-                       fprintf(out, "TEL;HOME:%s\n", database[e.item][PHONE]);
-               if (database[e.item][WORKPHONE])
-                       fprintf(out, "TEL;WORK:%s\n", database[e.item][WORKPHONE]);
-               if (database[e.item][FAX])
-                       fprintf(out, "TEL;FAX:%s\n", database[e.item][FAX]);
-               if (database[e.item][MOBILEPHONE])
-                       fprintf(out, "TEL;CELL:%s\n", database[e.item][MOBILEPHONE]);
-
-               if ( database[e.item][EMAIL] ) {
-                       split_emailstr(e.item, emails);
-                       for(j=0; j < MAX_EMAILS ; j++) {
-                               if ( *emails[j] )
-                                       fprintf(out, "EMAIL;INTERNET:%s\n",
-                                               emails[j]);
-                       }
+               if(db_fget(e.item, PHONE))
+                       fprintf(out, "TEL;HOME:%s\n",
+                                       db_fget(e.item, PHONE));
+               if(db_fget(e.item, WORKPHONE))
+                       fprintf(out, "TEL;WORK:%s\n",
+                                       db_fget(e.item, WORKPHONE));
+               if(db_fget(e.item, FAX))
+                       fprintf(out, "TEL;FAX:%s\n",
+                                       db_fget(e.item, FAX));
+               if(db_fget(e.item, MOBILEPHONE))
+                       fprintf(out, "TEL;CELL:%s\n",
+                                       db_fget(e.item, MOBILEPHONE));
+
+               if(*db_email_get(e.item)) {
+                       emails = csv_to_abook_list(db_email_get(e.item));
+
+                       for(em = emails; em; em = em->next)
+                               fprintf(out, "EMAIL;INTERNET:%s\n", em->data);
+
+                       abook_list_free(&emails);
                }
 
-               if ( database[e.item][NOTES] )
-                       fprintf(out, "NOTE:%s\n", database[e.item][NOTES]);
-               if (database[e.item][URL])
-                       fprintf(out, "URL:%s\n",  database[e.item][URL]);
+               if(db_fget(e.item, NOTES))
+                       fprintf(out, "NOTE:%s\n",
+                                       db_fget(e.item, NOTES));
+               if(db_fget(e.item, URL))
+                       fprintf(out, "URL:%s\n",
+                                       db_fget(e.item, URL));
 
                fprintf(out, "END:VCARD\n\n");
 
@@ -1579,10 +1580,10 @@ mutt_alias_genalias(int i)
 {
        char *tmp, *pos;
 
-       if(database[i][NICK])
-               return xstrdup(database[i][NICK]);
+       if(db_fget(i, NICK))
+               return xstrdup(db_fget(i, NICK));
 
-       tmp = xstrdup(database[i][NAME]);
+       tmp = xstrdup(db_name_get(i));
 
        if( ( pos = strchr(tmp, ' ') ) )
                *pos = 0;
@@ -1600,11 +1601,10 @@ mutt_alias_export(FILE *out, struct db_enumerator e)
 
        db_enumerate_items(e) {
                alias = mutt_alias_genalias(e.item);
-
                get_first_email(email, e.item);
                fprintf(out, *email ? "alias %s %s <%s>\n": "alias %s %s%s\n",
                                alias,
-                               database[e.item][NAME],
+                               db_name_get(e.item),
                                email);
                xfree(alias);
        }
@@ -1624,29 +1624,29 @@ mutt_alias_export(FILE *out, struct db_enumerator e)
 
 static void
 text_write_address_us(FILE *out, int i) {
-       fprintf(out, "\n%s", database[i][ADDRESS]);
+       fprintf(out, "\n%s", db_fget(i, ADDRESS));
 
-       if (database[i][ADDRESS2])
-               fprintf(out, "\n%s", database[i][ADDRESS2]);
+       if(db_fget(i, ADDRESS2))
+               fprintf(out, "\n%s", db_fget(i, ADDRESS2));
 
-       if (database[i][CITY])
-               fprintf(out, "\n%s", database[i][CITY]);
+       if(db_fget(i, CITY))
+               fprintf(out, "\n%s", db_fget(i, CITY));
 
-       if (database[i][STATE] || database[i][ZIP]) {
+       if(db_fget(i, STATE) || db_fget(i, ZIP)) {
                fputc('\n', out);
 
-               if(database[i][STATE]) {
-                       fprintf(out, "%s", database[i][STATE]);
-                       if(database[i][ZIP])
+               if(db_fget(i, STATE)) {
+                       fprintf(out, "%s", db_fget(i, STATE));
+                       if(db_fget(i, ZIP))
                                fputc(' ', out);
                }
 
-               if(database[i][ZIP])
-                       fprintf(out, "%s", database[i][ZIP]);
+               if(db_fget(i, ZIP))
+                       fprintf(out, "%s", db_fget(i, ZIP));
        }
 
-       if (database[i][COUNTRY])
-               fprintf(out, "\n%s", database[i][COUNTRY]);
+       if(db_fget(i, COUNTRY))
+               fprintf(out, "\n%s", db_fget(i, COUNTRY));
 }
 
 
@@ -1654,44 +1654,43 @@ static void
 text_write_address_uk(FILE *out, int i) {
        int j;
 
-       for (j = ADDRESS; j <= COUNTRY; j++)
-               if (database[i][j])
-                       fprintf(out, "\n%s", database[i][j]);
+       for(j = ADDRESS; j <= COUNTRY; j++)
+               if(db_fget(i, j))
+                       fprintf(out, "\n%s", db_fget(i, j));
 }
 
 static void
 text_write_address_eu(FILE *out, int i) {
-       fprintf(out, "\n%s", database[i][ADDRESS]);
+       fprintf(out, "\n%s", db_fget(i, ADDRESS));
 
-       if (database[i][ADDRESS2])
-               fprintf(out, "\n%s", database[i][ADDRESS2]);
+       if(db_fget(i, ADDRESS2))
+               fprintf(out, "\n%s", db_fget(i, ADDRESS2));
 
-       if (database[i][ZIP] || database[i][CITY]) {
+       if(db_fget(i, ZIP) || db_fget(i, CITY)) {
                fputc('\n', out);
 
-               if(database[i][ZIP]) {
-                       fprintf(out, "%s", database[i][ZIP]);
-                       if(database[i][CITY])
+               if(db_fget(i, ZIP)) {
+                       fprintf(out, "%s", db_fget(i, ZIP));
+                       if(db_fget(i, CITY))
                                fputc(' ', out);
                }
 
-               if(database[i][CITY])
-                       fprintf(out, "%s", database[i][CITY]);
+               fprintf(out, "%s", safe_str(db_fget(i, CITY)));
        }
 
-       if (database[i][STATE])
-               fprintf(out, "\n%s", database[i][STATE]);
+       if(db_fget(i, STATE))
+               fprintf(out, "\n%s", db_fget(i, STATE));
 
-       if (database[i][COUNTRY])
-               fprintf(out, "\n%s", database[i][COUNTRY]);
+       if(db_fget(i, COUNTRY))
+               fprintf(out, "\n%s", db_fget(i, COUNTRY));
 }
 
 static int
 text_export_database(FILE * out, struct db_enumerator e)
 {
-       char emails[MAX_EMAILS][MAX_EMAIL_LEN];
+       abook_list *emails, *em;
        int j;
-       char *realname = get_real_name();
+       char *realname = get_real_name(), *str = NULL;
        char *style = opt_get_str(STR_ADDRESS_STYLE);
 
        fprintf(out,
@@ -1703,23 +1702,25 @@ text_export_database(FILE * out, struct db_enumerator e)
        db_enumerate_items(e) {
                fprintf(out,
                        "-----------------------------------------\n\n");
-               fprintf(out, "%s", database[e.item][NAME]);
-               if (database[e.item][NICK] && *database[e.item][NICK])
-                       fprintf(out, "\n(%s)", database[e.item][NICK]);
+               fprintf(out, "%s", db_name_get(e.item));
+               if(db_fget(e.item, NICK) && *db_fget(e.item, NICK))
+                       fprintf(out, "\n(%s)", db_fget(e.item, NICK));
                fprintf(out, "\n");
 
-               if (*database[e.item][EMAIL]) {
+               if(*db_email_get(e.item)) {
+                       emails = csv_to_abook_list(db_email_get(e.item));
+
                        fprintf(out, "\n");
-                       split_emailstr(e.item, emails);
-                       for (j = 0; j < MAX_EMAILS; j++)
-                               if (*emails[j])
-                                       fprintf(out, "%s\n", emails[j]);
+                       for(em = emails; em; em = em->next)
+                               fprintf(out, "%s\n", em->data);
+
+                       abook_list_free(&emails);
                }
                /* Print address */
-               if (database[e.item][ADDRESS]) {
-                       if (!safe_strcmp(style, "us"))  /* US like */
+               if(db_fget(e.item, ADDRESS)) {
+                       if(!safe_strcmp(style, "us"))   /* US like */
                                text_write_address_us(out, e.item);
-                       else if (!safe_strcmp(style, "uk"))     /* UK like */
+                       else if(!safe_strcmp(style, "uk"))      /* UK like */
                                text_write_address_uk(out, e.item);
                        else    /* EU like */
                                text_write_address_eu(out, e.item);
@@ -1727,22 +1728,24 @@ text_export_database(FILE * out, struct db_enumerator e)
                        fprintf(out, "\n");
                }
 
-               if ((database[e.item][PHONE]) ||
-                       (database[e.item][WORKPHONE]) ||
-                       (database[e.item][FAX]) ||
-                       (database[e.item][MOBILEPHONE])) {
+               if((db_fget(e.item, PHONE)) ||
+                       (db_fget(e.item, WORKPHONE)) ||
+                       (db_fget(e.item, FAX)) ||
+                       (db_fget(e.item, MOBILEPHONE))) {
                        fprintf(out, "\n");
-                       for (j = PHONE; j <= MOBILEPHONE; j++)
-                               if (database[e.item][j])
-                                       fprintf(out, "%s: %s\n",
-                                               abook_fields[j].name,
-                                               database[e.item][j]);
+                       for(j = PHONE; j <= MOBILEPHONE; j++)
+                               if(db_fget(e.item, j)) {
+                                       get_field_keyname(field_id(j),
+                                                       NULL, &str);
+                                       fprintf(out, "%s: %s\n", str,
+                                               db_fget(e.item, j));
+                               }
                }
 
-               if (database[e.item][URL])
-                       fprintf(out, "\n%s\n", database[e.item][URL]);
-               if (database[e.item][NOTES])
-                       fprintf(out, "\n%s\n", database[e.item][NOTES]);
+               if(db_fget(e.item, URL))
+                       fprintf(out, "\n%s\n", db_fget(e.item, URL));
+               if(db_fget(e.item, NOTES))
+                       fprintf(out, "\n%s\n", db_fget(e.item, NOTES));
 
                fprintf(out, "\n");
        }
@@ -1769,10 +1772,7 @@ elm_alias_export(FILE *out, struct db_enumerator e)
        db_enumerate_items(e) {
                alias = mutt_alias_genalias(e.item);
                get_first_email(email, e.item);
-               fprintf(out, "%s = %s = %s\n",
-                               alias,
-                               database[e.item][NAME],
-                               email);
+               fprintf(out, "%s = %s = %s\n",alias,db_name_get(e.item),email);
                xfree(alias);
        }
 
@@ -1793,16 +1793,16 @@ spruce_export_database (FILE *out, struct db_enumerator e)
 {
        char email[MAX_EMAIL_LEN];
 
-       fprintf (out, "# This is a generated file made by abook for the Spruce e-mail client.\n\n");
+       fprintf(out, "# This is a generated file made by abook for the Spruce e-mail client.\n\n");
 
        db_enumerate_items(e) {
-               if(strcmp (safe_str(database[e.item][EMAIL]), "")) {
+               if(strcmp(safe_str(db_email_get(e.item)), "")) {
                        get_first_email(email, e.item);
                        fprintf(out, "# Address %d\nName: %s\nEmail: %s\nMemo: %s\n\n",
                                        e.item,
-                                       database[e.item][NAME],
+                                       db_name_get(e.item),
                                        email,
-                                       safe_str(database[e.item][NOTES])
+                                       safe_str(db_fget(e.item, NOTES))
                                        );
                }
        }
@@ -1823,19 +1823,19 @@ spruce_export_database (FILE *out, struct db_enumerator e)
 static int
 wl_export_database(FILE *out, struct db_enumerator e)
 {
-       char emails[MAX_EMAILS][MAX_EMAIL_LEN];
+       abook_list *emails;
 
-       fprintf (out, "# Wanderlust address book written by %s\n\n", PACKAGE);
+       fprintf(out, "# Wanderlust address book written by %s\n\n", PACKAGE);
        db_enumerate_items(e) {
-               split_emailstr(e.item, emails);
-               if (**emails) {
+               if((emails = csv_to_abook_list(db_email_get(e.item))) != NULL) {
                        fprintf(out,
                                "%s\t\"%s\"\t\"%s\"\n",
-                               *emails,
-                               safe_str(database[e.item][NICK]),
-                               safe_str(database[e.item][NAME])
+                               emails->data,
+                               safe_str(db_fget(e.item, NICK)),
+                               safe_str(db_name_get(e.item))
                        );
                }
+               abook_list_free(&emails);
        }
 
        fprintf (out, "\n# End of address book file.\n");
diff --git a/help.h b/help.h
index 7de967ee1c115e59a0b8c192cc9db490507d14c5..e54e92ed5b6cde43f6677d85bd71228c2dd44729 100644 (file)
--- a/help.h
+++ b/help.h
@@ -52,14 +52,17 @@ NULL
 static char *editorhelp[] = {
 
 "\n",
-N_("   a,c,p,o,C/arrows/h,l    change tab\n"),
+N_("   arrows/h,l              change tab\n"),
 "\n",
-N_("   1 - 5                   edit fields\n"),
+N_("   q                       quit to main screen\n"),
+"\n",
+N_("   1 - 5 A - Z             edit fields\n"),
 "\n",
 N_("   k or <                  previous item\n"),
 N_("   j or >                  next item\n"),
 "\n",
-N_("   r                       roll e-mail addresses\n"),
+N_("   r                       roll e-mail addresses up\n"),
+N_("   ESC-r                   roll e-mail addresses down\n"),
 "\n",
 N_("   u                       undo\n"),
 "\n",
diff --git a/list.c b/list.c
index 00e149ad50b2ffc442a2769d01424ba41654fc2b..b1c6ebabada1be5e94c9c31f7b911081352220c0 100644 (file)
--- a/list.c
+++ b/list.c
@@ -20,8 +20,6 @@
 #include "options.h"
 #include "xmalloc.h"
 
-#define MIN_EXTRA_COLUMN       ADDRESS /* 2 */
-#define MAX_EXTRA_COLUMN       LAST_FIELD
 
 int curitem = -1;
 int first_list_item = -1;
@@ -31,29 +29,24 @@ int extra_column = -1;
 int extra_alternative = -1;
 
 extern int items;
-extern list_item *database;
-extern struct abook_field abook_fields[];
+extern abook_field_list *fields_list;
 
 static WINDOW *list = NULL;
 
-static int
+
+int
 init_extra_field(enum str_opts option)
 {
-       int i, ret = -1;
+       int ret = -1;
        char *option_str;
 
        option_str = opt_get_str(option);
 
        if(option_str && *option_str) {
-               for(i = 0; i < ITEM_FIELDS; i++) {
-                       if(!strcasecmp(option_str, abook_fields[i].key)) {
-                               ret = i;
-                               break;
-                       }
-               }
-               if(ret < MIN_EXTRA_COLUMN || ret > MAX_EXTRA_COLUMN) {
+               find_field_number(option_str, &ret);
+
+               if(!strcmp(option_str, "name") || !strcmp(option_str, "email"))
                        ret = -1;
-               }
        }
 
        return ret;
@@ -135,41 +128,47 @@ print_list_line(int i, int line, int highlight)
        if(selected[i])
                mvwaddch(list, line, 0, '*' );
 
-       mvwaddnstr(list, line, NAMEPOS, database[i][NAME],
-               bytes2width(database[i][NAME], NAMELEN));
+       mvwaddnstr(list, line, NAMEPOS, db_name_get(i),
+               bytes2width(db_name_get(i), NAMELEN));
+
        if(opt_get_bool(BOOL_SHOW_ALL_EMAILS))
-               mvwaddnstr(list, line, EMAILPOS, database[i][EMAIL],
-                               bytes2width(database[i][EMAIL], real_emaillen));
+               mvwaddnstr(list, line, EMAILPOS, db_email_get(i),
+                               bytes2width(db_email_get(i), real_emaillen));
        else {
                get_first_email(tmp, i);
                mvwaddnstr(list, line, EMAILPOS, tmp,
-                       bytes2width(tmp, real_emaillen));
+                               bytes2width(tmp, real_emaillen));
        }
 
-       if(extra < 0 || !database[i][extra])
+       if(extra < 0 || !db_fget_byid(i, extra))
                extra = extra_alternative;
        if(extra >= 0)
                mvwaddnstr(list, line, EXTRAPOS,
-                       safe_str(database[i][extra]),
-                       bytes2width(safe_str(database[i][extra]), EXTRALEN));
+                       safe_str(db_fget_byid(i, extra)),
+                       bytes2width(safe_str(db_fget_byid(i, extra)),
+                       EXTRALEN));
 
        scrollok(list, TRUE);
        if(highlight)
                wstandend(list);
 }
 
-
 void
 list_headerline()
 {
+       char *str = NULL;
+
 #if defined(A_BOLD) && defined(A_NORMAL)
        attrset(A_BOLD);
 #endif
-       mvaddstr(2, NAMEPOS, gettext(abook_fields[NAME].name));
-       mvaddstr(2, EMAILPOS, gettext(abook_fields[EMAIL].name));
-       if(extra_column > 0)
-               mvaddnstr(2, EXTRAPOS, gettext(abook_fields[extra_column].name),
-                               COLS-EXTRAPOS);
+
+       mvaddstr(2, NAMEPOS, find_field("name", NULL)->name);
+       mvaddstr(2, EMAILPOS, find_field("email", NULL)->name);
+       if(extra_column > 0) {
+               get_field_keyname(extra_column, NULL, &str);
+               mvaddnstr(2, EXTRAPOS, str, COLS - EXTRAPOS);
+       }
+
 #if defined(A_BOLD) && defined(A_NORMAL)
        attrset(A_NORMAL);
 #endif
@@ -243,25 +242,31 @@ move_curitem(int direction)
         if( curitem < 0 || curitem > LAST_ITEM )
                 return;
 
-        itemcpy(tmp, database[curitem]);
-
-        switch(direction) {
-                case MOVE_ITEM_UP:
-                        if( curitem < 1 )
-                                return;
-                        itemcpy(database[curitem], database[curitem - 1]);
-                        itemcpy(database[curitem-1], tmp);
-                        scroll_up();
-                        break;
-
-                case MOVE_ITEM_DOWN:
-                        if( curitem >= LAST_ITEM )
-                                return;
-                        itemcpy(database[curitem], database[curitem + 1]);
-                        itemcpy(database[curitem+1], tmp);
-                        scroll_down();
-                        break;
-        }
+       tmp = item_create();
+       item_copy(tmp, db_item_get(curitem));
+
+       switch(direction) {
+               case MOVE_ITEM_UP:
+                       if( curitem < 1 )
+                               goto out_move;
+                       item_copy(db_item_get(curitem),
+                                       db_item_get(curitem - 1));
+                       item_copy(db_item_get(curitem-1), tmp);
+                       scroll_up();
+                       break;
+
+               case MOVE_ITEM_DOWN:
+                       if( curitem >= LAST_ITEM )
+                               goto out_move;
+                       item_copy(db_item_get(curitem),
+                                       db_item_get(curitem + 1));
+                       item_copy(db_item_get(curitem + 1), tmp);
+                       scroll_down();
+                       break;
+       }
+
+out_move:
+       item_free(&tmp);
 }
 
 void
@@ -282,7 +287,6 @@ goto_end()
        refresh_list();
 }
 
-
 void
 highlight_line(WINDOW *win, int line)
 {
@@ -349,18 +353,18 @@ list_is_empty()
 int
 duplicate_item()
 {
-       int i;
        list_item item;
-
+       
        if(curitem < 0)
                return 1;
 
-       for(i = 0; i < ITEM_FIELDS; i++)
-               item[i] = database[curitem][i] ? xstrdup(database[curitem][i]) :
-                       NULL;
-
-       if(add_item2database(item))
+       item = item_create();
+       item_duplicate(item, db_item_get(curitem));
+       if(add_item2database(item)) {
+               item_free(&item);
                return 1;
+       }
+       item_free(&item);
 
        curitem = LAST_ITEM;
        refresh_list();
diff --git a/list.h b/list.h
index ac8377f1228e734ffdd2ee9bfacc95e630604da5..16a2dd9899cc54c5065bf364e3cb3bb0cc307fd9 100644 (file)
--- a/list.h
+++ b/list.h
@@ -4,6 +4,7 @@
 #include "ui.h"
 
 void           init_list();
+int            init_extra_field(enum str_opts option);
 void           close_list();
 void            refresh_list();
 void           print_list_line(int i, int line, int highlight);
@@ -40,9 +41,9 @@ enum {
 #define EMAILPOS        opt_get_int(INT_EMAILPOS)
 #define EXTRAPOS       opt_get_int(INT_EXTRAPOS)
 
-#define NAMELEN                (EMAILPOS-NAMEPOS -1)
-#define EMAILLEN        (EXTRAPOS-EMAILPOS -1)
-#define EXTRALEN       (COLS-EXTRAPOS)
+#define NAMELEN                (EMAILPOS - NAMEPOS - 1)
+#define EMAILLEN        (EXTRAPOS - EMAILPOS - 1)
+#define EXTRALEN       (COLS - EXTRAPOS)
 
 #define LAST_LIST_ITEM ( first_list_item + LIST_LINES - 1 )
 
diff --git a/misc.c b/misc.c
index 22ebc800ef941cab85154079e42be606c7a2efb1..01bdd545095073254211065d076f4930a9b11b3f 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -19,6 +19,7 @@
 #      include "config.h"
 #endif
 #include <mbswidth.h>
+#include "abook.h"
 #include "misc.h"
 #include "xmalloc.h"
 
@@ -1076,3 +1077,189 @@ int main (void)
 #endif /* SNPRINTF_TEST */
 
 #endif /* !HAVE_SNPRINTF */
+
+
+
+
+/*
+ * List handling functions
+ */
+
+void
+abook_list_append(abook_list **list, char *str)
+{
+       abook_list *tmp;
+
+       if(!str)
+               return;
+
+       for(tmp = *list; tmp && tmp->next; tmp = tmp->next)
+               ;
+
+       if(tmp) {
+               tmp->next = xmalloc(sizeof(abook_list));
+               tmp = tmp->next;
+       } else
+               tmp = *list = xmalloc(sizeof(abook_list));
+
+       tmp->data = xstrdup(str);
+       tmp->next = NULL;
+}
+
+void
+abook_list_free(abook_list **list)
+{
+       abook_list *prev = NULL, *tmp = *list;
+
+       if(!list)
+               return;
+
+       while(tmp) {
+               xfree(tmp->data);
+               prev = tmp;
+               tmp = tmp->next;
+               xfree(prev);
+       }
+
+       *list = NULL;
+}
+
+abook_list *
+csv_to_abook_list(char *str)
+{
+       char *start, *p = str, *end;
+       abook_list *list = NULL;
+
+       if(!str)
+               return NULL;
+
+       SKIPWS(p);
+       start = end = p;
+
+       while(*p) {
+               if(!strchr(", ", *p)) {
+                       end = ++p;
+                       continue;
+               }
+
+               if((*p == ',') && (end - start)) {
+                       abook_list_append(&list, xstrndup(start, end - start));
+                       p++;
+                       SKIPWS(p);
+                       start = end = p;
+                       continue;
+               }
+
+               p++;
+       }
+       if(end - start)
+               abook_list_append(&list, xstrndup(start, end - start));
+
+       return list;
+}
+
+char *
+abook_list_to_csv(abook_list *list)
+{
+       abook_list *tmp;
+       char *res = NULL;
+
+       for(tmp = list; tmp; tmp = tmp->next) {
+               if(tmp == list)
+                       res = xstrdup(tmp->data);
+               else {
+                       res = xrealloc(res, strlen(res)+strlen(tmp->data)+2);
+                       strcat(res, ",");
+                       strcat(res, tmp->data);
+               }
+       }
+
+       return res;
+}
+
+void
+abook_list_rotate(abook_list **list, enum rotate_dir dir)
+{
+       abook_list *tmp = *list;
+
+       if(!tmp || !tmp->next)
+               return;
+
+       switch(dir) {
+               case ROTATE_LEFT:
+                       for(; tmp && tmp->next; tmp = tmp->next)
+                               ;
+
+                       tmp->next = *list;
+                       tmp = *list;
+                       *list = (*list)->next;
+                       tmp->next = NULL;
+                       break;
+               case ROTATE_RIGHT:
+                       for(; tmp && tmp->next && tmp->next->next;
+                                       tmp = tmp->next)
+                               ;
+
+                       tmp->next->next = *list;
+                       *list = tmp->next;
+                       tmp->next = NULL;
+                       break;
+               default:
+                       assert(0);
+       }
+}
+
+/* if str == NULL, deleting the list element */
+void
+abook_list_replace(abook_list **list, int index, char *str)
+{
+       abook_list *cur, *prev;
+       int i = 0;
+
+       cur = prev = *list;
+
+       if((index == 0) && !str) {
+               *list = cur->next;
+               free(cur->data);
+               free(cur);
+               return;
+       }
+       
+       while(1) {
+               if(!cur)
+                       return;
+
+               if(i == index)
+                       break;
+
+               prev = cur;
+               cur = cur->next;
+               i++;
+       }
+
+       if(str) {
+               free(cur->data);
+               cur->data = xstrdup(str);
+       } else {
+               prev->next = cur->next;
+               free(cur->data);
+               free(cur);
+       }
+}
+
+abook_list *
+abook_list_get(abook_list *list, int index)
+{
+       int i = 0;
+
+       while(1) {
+               if(!list)
+                       return NULL;
+
+               if(i == index)
+                       return list;
+
+               i++;
+               list = list->next;
+       }
+}
diff --git a/misc.h b/misc.h
index b40a4a1af9ca435186389e469292811af6ded909..d01691bdc60e51848618dbdcb3950590d117cff7 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -1,6 +1,16 @@
 #ifndef _MISC_H
 #define _MISC_H
 
+typedef struct abook_list_t {
+       char *data;
+       struct abook_list_t *next;
+} abook_list;
+
+enum rotate_dir {
+       ROTATE_LEFT,
+       ROTATE_RIGHT
+};
+
 char           *revstr(char *str);
 char           *strupper(char *str);
 char           *strlower(char *str);
@@ -20,6 +30,16 @@ int          strwidth(const char *s);
 int            bytes2width(const char *s, int width);
 
 
+void           abook_list_append(abook_list **list, char *str);
+void           abook_list_free(abook_list **list);
+char           *abook_list_to_csv(abook_list *list);
+abook_list     *csv_to_abook_list(char *str);
+void           abook_list_rotate(abook_list **list, enum rotate_dir dir);
+void           abook_list_replace(abook_list **list, int index, char *str);
+abook_list     *abook_list_get(abook_list *list, int index);
+#define        abook_list_delete(list, index) abook_list_replace(list, index, NULL)
+
+
 #ifdef HAVE_CONFIG_H
 #      include "config.h"
 #endif
@@ -34,3 +54,6 @@ int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
 #endif
 
 #endif
+
+
+
index 0783173a1293131c90d733ddef1effa28e07528d..a370a30ddd1c7cdb749e2ffd541c562de7db8f98 100644 (file)
--- a/options.c
+++ b/options.c
@@ -17,6 +17,7 @@
 #include "abook.h"
 #include "gettext.h"
 #include "misc.h"
+#include "views.h"
 #include "xmalloc.h"
 
 #ifndef FALSE
@@ -67,6 +68,7 @@ static struct option abook_vars[] = {
        { "use_ascii_only", OT_BOOL, BOOL_USE_ASCII_ONLY, FALSE },
 
        { "add_email_prevent_duplicates", OT_BOOL, BOOL_ADD_EMAIL_PREVENT_DUPLICATES, FALSE },
+       { "preserve_fields", OT_STR, STR_PRESERVE_FIELDS, UL "standard" },
        { "sort_field", OT_STR, STR_SORT_FIELD, UL "nick" },
        { "show_cursor", OT_BOOL, BOOL_SHOW_CURSOR, FALSE },
 
@@ -206,28 +208,78 @@ opt_line_remove_comments(char *p)
        }
 }
 
-void
-find_token_start(buffer *b)
+/* After calling,
+ * - b->data points to the found token, or NULL is end of parsing
+ * - b->ptr  points to the begining of next token
+ *
+ * If the TOKEN_ALLOC option is used, the original string is not mangled
+ * and memory is allocated for the token.
+ */
+static char *
+get_token(buffer *b, int options)
 {
+       char quote = 0, c;
+       char *end = NULL;
+
        assert(b);
 
-       for(; ISSPACE(*b -> ptr); b -> ptr ++);
-}
+       SKIPWS(b->ptr);
+       if(*b->ptr && strchr("\"'", *b->ptr))
+               quote = *(b->ptr++);
+       b->data = b->ptr;
 
-void
-find_token_end(buffer *b)
-{
-       assert(b);
+       while(1) {
+               if(!(c = *b->ptr)) {
+                       end = b->ptr;
+                       break;
+               }
 
-       for(find_token_start(b); *(b -> ptr); b -> ptr ++) {
-               if(ISSPACE(*(b -> ptr))) {
+               if(!quote && (
+                               ISSPACE(c) ||
+                               ((options & TOKEN_EQUAL) && (c == '=')) ||
+                               ((options & TOKEN_COMMA) && (c == ',')))
+                               ) {
+                       end = b->ptr;
+                       break;
+               } else if(c == quote) {
+                       quote = 0;
+                       end = b->ptr++;
                        break;
                }
+
+               b->ptr++;
+       }
+
+       if(quote)
+               return _("quote mismatch");
+
+       if(options & (TOKEN_EQUAL | TOKEN_COMMA))
+               SKIPWS(b->ptr); /* whitespaces can precede the sign */
+
+       if((options & TOKEN_EQUAL) && (*b->ptr != '='))
+               return _("no assignment character found");
+
+       if((options & TOKEN_COMMA) && *b->ptr && (*b->ptr != ','))
+               return _("error in comma separated list");
+
+       if(b->ptr == b->data) {
+               b->data = NULL;
+               return NULL; /* no error, just end of parsing */
        }
+
+       if(options & TOKEN_ALLOC) /* freeing is the caller's responsibility */
+               b->data = xstrndup(b->data, end - b->data);
+       else
+               *end = 0;
+
+       b->ptr++; /* advance to next token */
+       SKIPWS(b->ptr);
+
+       return NULL;
 }
 
 static char *
-opt_set_set_option(char *var, char *p, struct option *opt)
+opt_set_set_option(char *p, struct option *opt)
 {
        int len;
 
@@ -266,59 +318,139 @@ opt_set_set_option(char *var, char *p, struct option *opt)
 }
 
 static char *
-opt_parse_set(buffer *b)
+opt_set_option(char *var, char *p)
 {
        int i;
-       char *p;
 
-       find_token_start(b);
-       if((p = strchr(b -> ptr, '=')))
-               *p++ = 0;
-       else
-               return _("invalid value assignment");
+       for(i = 0; abook_vars[i].option; i++)
+               if(!strcmp(abook_vars[i].option, var))
+                       return opt_set_set_option(p, &abook_vars[i]);
 
-       strtrim(b -> ptr);
+       return _("unknown option");
+}
 
-       for(i = 0;abook_vars[i].option; i++)
-               if(!strcmp(abook_vars[i].option, b -> ptr))
-                       return opt_set_set_option(b -> ptr, p, &abook_vars[i]);
+static int
+check_options()
+{
+       char *str;
+       int err = 0;
 
-       return _("unknown option");
+       str = opt_get_str(STR_PRESERVE_FIELDS);
+       if(strcasecmp(str, "all") && strcasecmp(str, "none") &&
+                       strcasecmp(str, "standard")) {
+               fprintf(stderr, _("valid values for the 'preserve_fields' "
+                                       "option are 'all', 'standard' "
+                                       "(default), and 'none'\n"));
+               restore_default(&abook_vars[STR_PRESERVE_FIELDS]);
+               err++;
+       }
+       str = opt_get_str(STR_ADDRESS_STYLE);
+       if(strcasecmp(str, "eu") && strcasecmp(str, "uk") &&
+                       strcasecmp(str, "us")) {
+               fprintf(stderr, _("valid values for the 'address_style' "
+                                       "option are 'eu' (default), 'uk', "
+                                       "and 'us'\n"));
+               restore_default(&abook_vars[STR_ADDRESS_STYLE]);
+               err++;
+       }
+
+       return err;
 }
 
-#include "database.h" /* needed for change_custom_field_name */
+/*
+ * syntax: set <option> = <value>
+ */
+static char *
+opt_parse_set(buffer *b)
+{
+       char *var, *err;
+
+       if((err = get_token(b, TOKEN_EQUAL)))
+               return err;
+
+       if((var = b->data) == NULL)
+               return _("invalid value assignment");
+
+       return opt_set_option(var, b->ptr);
+}
 
 static char *
 opt_parse_customfield(buffer *b)
 {
-       char *p, num[5];
-       int n;
-       size_t len;
+       return _("customfield: obsolete command - please use the "
+                       "'field' and 'view' commands instead");
+}
+
+#include "views.h" /* needed for add_field_to_view */
+
+/*
+ * syntax: view <tab name> = <field1> [ , <field2>, ... ]
+ */
+static char *
+opt_parse_view(buffer *b)
+{
+       char *err, *view;
+
+       if((err = get_token(b, TOKEN_EQUAL)))
+               return err;
+
+       if((view = b->data) == NULL)
+               return _("no view name provided");
+
+       while(1) {
+               if((err = get_token(b, TOKEN_COMMA)))
+                       return err;
 
-       find_token_start(b);
-       p = b -> ptr;
-       find_token_end(b);
+               if(b->data == NULL)
+                       break;
+
+               if((err = add_field_to_view(view, b->data)))
+                       return err;
+       }
+
+       return NULL;
+}
 
-       memset(num, 0, sizeof(num));
+#include "database.h" /* needed for declare_new_field */
 
-       len = (b -> ptr - p);
-       strncpy(num, p, min(sizeof(num) - 1, len));
-       n = safe_atoi(num);
+/*
+ * syntax: field <identifier> = <human readable name> [ , <type> ]
+ */
+static char *
+opt_parse_field(buffer *b)
+{
+       char *err, *field, *name;
 
-       find_token_start(b);
+       if((err = get_token(b, TOKEN_EQUAL)))
+               return err;
 
-       if(change_custom_field_name(b->ptr, n) == -1)
-               return _("invalid custom field number");
+       if((field = b->data) == NULL)
+               return _("no field identifier provided");
+
+       if((err = get_token(b, TOKEN_COMMA)))
+               return err;
+
+       if((name = b->data) == NULL)
+               return _("no field name provided");
+
+       if((err = declare_new_field(field,
+                                       name,
+                                       b->ptr,
+                                       0 /* reject "standard" fields */)))
+               return err;
 
        return NULL;
 }
 
+
 static struct {
        char *token;
        char * (*func) (buffer *line);
 } opt_parsers[] = {
        { "set", opt_parse_set },
-       { "customfield", opt_parse_customfield },
+       { "customfield", opt_parse_customfield }, /* obsolete */
+       { "view", opt_parse_view },
+       { "field", opt_parse_field },
        { NULL }
 };
 
@@ -334,12 +466,12 @@ opt_parse_line(char *line, int n, char *fn)
 
        b.ptr = line;
 
-       find_token_start(&b);
-       b.data = b.ptr;
-       find_token_end(&b);
-       *b.ptr++ = 0;
+       if((err = get_token(&b, 0))) {
+               fprintf(stderr, "%s\n", err);
+               return FALSE;
+       }
 
-       if(!*line)
+       if(b.data == NULL)
                return FALSE;
 
        strtrim(b.data);
@@ -375,7 +507,6 @@ load_opts(char *filename)
        if((in = fopen(filename, "r")) == NULL)
                return -1;
 
-
        for(n = 1;!feof(in); n++) {
                line = getaline(in);
 
@@ -394,6 +525,11 @@ load_opts(char *filename)
 
        free(line);
 
+       /* post-initialization */
+       err += check_options();
+       if(!strcasecmp(opt_get_str(STR_PRESERVE_FIELDS), "standard"))
+               init_standard_fields();
+
        return err;
 }
 
index 73b300cdf59cbcaffeb48e8f2ecf44de9f67d05e..c1e02ec8cb6a690975178fcd58583b0efb638463 100644 (file)
--- a/options.h
+++ b/options.h
@@ -8,9 +8,16 @@ typedef int bool;
 #endif
 
 /*
- * bool options
+ * token parsing options
  */
 
+#define TOKEN_ALLOC (1<<1) /* allocate memory for the token */
+#define TOKEN_EQUAL (1<<2) /* left hand value of assignment */
+#define TOKEN_COMMA (1<<3) /* comma is a separator */
+
+/*
+ * bool options
+ */
 
 enum bool_opts {
        BOOL_AUTOSAVE,
@@ -43,6 +50,7 @@ enum str_opts {
        STR_PRINT_COMMAND,
        STR_WWW_COMMAND,
        STR_ADDRESS_STYLE,
+       STR_PRESERVE_FIELDS,
        STR_SORT_FIELD,
        STR_MAX
 };
index d88f435ea6751d076a80fd598d66c7f6454a3f7a..b23c8f5160fd90286c995d829ff2ec1b7f9d8378 100644 (file)
@@ -9,3 +9,4 @@ help.h
 list.c
 options.c
 ui.c
+views.c
index 086235f8185bc465ca628cbb2c676b609c19f3b9..315192d13dbc3db7678394b10e8caa80ae10a42c 100644 (file)
@@ -1,9 +1,75 @@
 # sample abook configuration file
 # see abookrc(5) for detailed explanation
 
+##
+##  Commands
+## ==========
+
+
+#  Setting a variable
+# --------------------
+#
+# syntax: set <option> = <value>
+# 
+# See below for the list of available variables.
+
+
+#  Defining a new custom field
+# -----------------------------
+#
+# syntax: field <identifier> = <human readable name> [ , <type> ]
+#
+# with <type> being one of 'string' (default), 'emails', 'list', or 'day'
+#
+# Example of field definitions:
+field pager = Pager
+field address_lines = Address, list
+field birthday = Birthday, day
+
+
+#  Defining a view/tab
+# ---------------------
+#
+# view <view name> = <field1> [ , <field2>, ... ]
+#
+# with <fieldN> being the identifier of a field declared with the 'field'
+# command, or the identifier of a standard field.
+#
+# Standard fields:
+#    name, email,
+#    address, address2, city, state, zip, country,
+#    phone, workphone, fax, mobile,
+#    nick, url, notes, anniversary
+#
+# Note: if you don't define any view, abook will use a default display based
+#       on the above standard fields.
+#
+# Example of views:
+view CONTACT = name, email
+view ADDRESS = address_lines, city, state, zip, country
+view PHONE = phone, workphone, pager, mobile, fax
+view OTHER = url, birthday
+
+
+
+##
+##  Variables
+## ===========
+
 # Automatically save database on exit
 set autosave=true
 
+# Specify how fields not declared with the 'field' command nor
+# in a view should be preserved while loading an abook database.
+#
+# It must be one of 'all', 'standard' (default), or 'none'.
+#   * 'all': preserve any completely unknown field.
+#   * 'standard': only preserve the standard fields (see a list in the
+#                 description of the 'view' command) and the legacy
+#                 'custom[1-5]' fields.
+#   * 'none': discards any unknown field.
+set preserve_fields=standard
+
 # Show all email addresses in list
 set show_all_emails=true
 
@@ -55,11 +121,3 @@ set sort_field=nick
 # show cursor in main display
 set show_cursor=false
 
-# custom fields
-
-#customfield 1 Name1
-#customfield 2 Name2
-#customfield 3 Name3
-#customfield 4 Name4
-#customfield 5 Name5
-
diff --git a/ui.c b/ui.c
index 20ec8feed48ecade9f964364e8815fefeb4a7064..7c71eb977a38af73aaf926f92fec68255b198aa7 100644 (file)
--- a/ui.c
+++ b/ui.c
@@ -38,7 +38,8 @@
  * external variables
  */
 
-extern int items, curitem;
+extern int curitem;
+extern int items;
 extern char *datafile;
 
 extern bool alternative_datafile;
@@ -281,7 +282,7 @@ statusline_askchoice(const char *msg, const char *choices, short dflt)
        char *s;
        int ch;
 
-       assert((dflt < 0) || (dflt > strlen(choices)));
+       assert((dflt >= 0) && (dflt <= strlen(choices)));
 
        if(dflt) {
                s = strdup_printf("%s [%c]", msg, choices[dflt - 1]);
@@ -491,9 +492,9 @@ get_commands()
 
                        case 'o': ui_open_datafile();   break;
 
-                       case 's': sort_by_field(NAME);  break;
+                       case 's': sort_by_field("name");break;
                        case 'S': sort_surname();       break;
-                       case 'F': sort_by_field(-1);    break;
+                       case 'F': sort_by_field(NULL);  break;
 
                        case '/': ui_find(0);           break;
                        case '\\': ui_find(1);          break;
@@ -584,7 +585,6 @@ ui_find(int next)
        }
 }
 
-
 void
 ui_print_number_of_items()
 {
diff --git a/ui.h b/ui.h
index 7e1b8a8cda6008d8882236bc2d2ad0e447f346a6..ebffcd8d9112f0c3fdfa696cc664889bb5dc11b7 100644 (file)
--- a/ui.h
+++ b/ui.h
@@ -38,6 +38,8 @@ void          ui_open_datafile();
 
 #define UI_HLINE_CHAR          opt_get_bool(BOOL_USE_ASCII_ONLY) ? \
                                        '-' : ACS_HLINE
+#define UI_VLINE_CHAR          opt_get_bool(BOOL_USE_ASCII_ONLY) ? \
+                                       '|' : ACS_VLINE
 #define UI_TEE_CHAR            opt_get_bool(BOOL_USE_ASCII_ONLY) ? \
                                        '-' : ACS_BTEE
 #define UI_LBOXLINE_CHAR       opt_get_bool(BOOL_USE_ASCII_ONLY) ? \
diff --git a/views.c b/views.c
new file mode 100644 (file)
index 0000000..bd773d8
--- /dev/null
+++ b/views.c
@@ -0,0 +1,170 @@
+/*
+ * $Id$
+ *
+ * by Cedric Duval <cedricduval@free.fr>
+ *
+ * Copyright (C) Cedric Duval
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#ifdef HAVE_CONFIG_H
+#      include "config.h"
+#endif
+#include "gettext.h"
+#include "misc.h"
+#include "options.h"
+#include "views.h"
+#include "xmalloc.h"
+
+
+abook_view *abook_views = NULL;
+int views_count = 0;
+
+
+extern abook_field standard_fields[];
+
+
+static abook_view *
+find_view(char *name)
+{
+       abook_view *cur = abook_views;
+
+       for(; cur; cur = cur->next)
+               if(0 == strcasecmp(cur->name, name))
+                       return cur;
+
+       return NULL;
+}
+
+static abook_view *
+create_view(char *name) {
+       abook_view *v;
+
+       for(v = abook_views; v && v->next; v = v->next)
+               ;
+
+       if(v) {
+               v->next = xmalloc(sizeof(abook_view));
+               v = v->next;            
+       } else
+               abook_views = v = xmalloc(sizeof(abook_view));
+
+       v->name = xstrdup(name);
+       v->fields = NULL;
+       v->next = NULL;
+
+       views_count++;
+
+       return v;
+}
+
+static int
+fields_in_view(abook_view *view)
+{
+       int nb;
+       abook_field_list *f;
+
+       for(nb = 0, f = view->fields; f; f = f->next, nb++)
+               ;
+
+       return nb;
+}
+
+char *
+add_field_to_view(char *viewname, char *field)
+{
+       abook_view *v;
+       abook_field *f;
+
+       if(
+                       !(f = find_declared_field(field)) &&
+                       !(f = find_standard_field(field, 1 /*do_declare*/))
+               )
+               return _("undeclared field");
+       
+       if((v = find_view(viewname)) == NULL)
+               v = create_view(viewname);
+       else if(fields_in_view(v) == MAX_VIEW_FIELDS)
+               return _("maximal number of fields per view reached");
+
+       if(v->fields && (find_field(field, v->fields)))
+               return _("field already in this view");
+
+       add_field(&v->fields, f);
+       
+       return NULL;
+}
+
+void
+view_info(int number, char **name, abook_field_list **fields)
+{      int i = 0;
+       abook_view *cur = abook_views;
+
+       assert((number < views_count) && (number >= 0));
+       
+       while(i++ != number)
+               cur = cur->next;
+
+       if(fields)
+               *fields = cur->fields;
+
+       if(name)
+               *name = cur->name;
+}
+
+#define MAX_DEFAULT_FIELDS_PER_VIEW 6
+
+void
+init_default_views()
+{
+       char *str;
+       int i, j, add_custom_fields, add_custom_view = 0;
+       
+       add_custom_fields =
+               !strcasecmp(opt_get_str(STR_PRESERVE_FIELDS), "standard");
+
+       /* if the user has configured views, no need to provide defaults */
+       if(abook_views)
+               goto out;
+       add_custom_view = 1;
+
+       struct {
+               char *name;
+               int fields[MAX_DEFAULT_FIELDS_PER_VIEW + 1];
+       } default_views[] = {
+               { N_("CONTACT"), {NAME, EMAIL, -1} },
+               { N_("ADDRESS"),
+                       { ADDRESS, ADDRESS2, CITY, STATE, ZIP, COUNTRY, -1 } },
+               { N_("PHONE"), { PHONE, WORKPHONE, FAX, MOBILEPHONE, -1 } },
+               { N_("OTHER"), { NICK, URL, NOTES, -1 } },
+               { 0 }
+       };
+
+       for(i = 0; default_views[i].name; i++) {
+               for(j = 0; j < MAX_DEFAULT_FIELDS_PER_VIEW; j++) {
+                       if(default_views[i].fields[j] == -1)
+                               break;
+                       str = standard_fields[default_views[i].fields[j]].key;
+                       add_field_to_view(default_views[i].name, str);
+               }
+       }
+out:
+
+#define init_view(view, key, name) do { \
+       if(add_custom_fields || add_custom_view) \
+               declare_new_field(key, name, "string", \
+                               0 /*"standard" field already declared above*/);\
+       if(add_custom_view) \
+               add_field_to_view(view, key); \
+} while(0);
+
+       init_view(_("CUSTOM"), "custom1", _("Custom1"));
+       init_view(_("CUSTOM"), "custom2", _("Custom2"));
+       init_view(_("CUSTOM"), "custom3", _("Custom3"));
+       init_view(_("CUSTOM"), "custom4", _("Custom4"));
+       init_view(_("CUSTOM"), "custom5", _("Custom5"));
+}
diff --git a/views.h b/views.h
new file mode 100644 (file)
index 0000000..0a899ff
--- /dev/null
+++ b/views.h
@@ -0,0 +1,18 @@
+#ifndef _VIEWS_H
+#define _VIEWS_H
+
+#include "database.h"
+
+#define MAX_VIEW_FIELDS 35 /* keybindings for modifying a field: 1-9A-Z */
+
+typedef struct abook_view_t {
+       char *name;
+       abook_field_list *fields;
+       struct abook_view_t *next;
+} abook_view;
+
+char *add_field_to_view(char *tabname, char *field);
+void view_info(int number, char **name, abook_field_list **fields);
+void init_default_views();
+
+#endif /* _VIEWS_H */