]> git.deb.at Git - pkg/abook.git/commitdiff
Merged csv import filter
authorJaakko Heinonen <jheinonen@users.sourceforge.net>
Sun, 19 Aug 2001 10:40:01 +0000 (10:40 +0000)
committerJaakko Heinonen <jheinonen@users.sourceforge.net>
Sun, 19 Aug 2001 10:40:01 +0000 (10:40 +0000)
AUTHORS
ChangeLog
THANKS
abook.c
filter.c

diff --git a/AUTHORS b/AUTHORS
index 8111da0acb08e89e834a33006940cf1f137ecf6b..588c3bcc87c48ea8d612d04c7cc11445b25cfdb5 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -15,3 +15,7 @@ Josua Groeger         <fractalus@gmx.net>
 
 Matt Kraai             <kraai@alumni.carnegiemellon.edu>
  - patches
+
+Koenraad Heijlen       <vipie@ulyssis.org>
+ - csv import filter
+ - fixes
index 139cc988032d15b787340847501baaa0eb787f6c..f6aa9d79d8f95aff35388bd2bfde0374e9576290 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
 0.4.14
+ - added csv import filter
+ - csv export filter fix
  - minor html filter update
  - fixed a minor memory leak in pine import filter
+ - fixes
 
 0.4.13
  - major code reorganization (phase 1)
diff --git a/THANKS b/THANKS
index 9153b4c4e4b7a4d949c06caea83788e6d4cc1e20..6a04e234f813aed26d8ada6b8aa98300a3e24a30 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -10,6 +10,5 @@ R. Shohn Trojacek     <snazzle@galvani.tamu.edu>
 ?                      <antirez@invece.org>
 Shao Zhang             <shao@cia.com.au>
 Gustavo Niemeyer       <gustavo@niemeyer.net>
-Koenraad Heijlen       <vipie@ulyssis.org>
 
 See also AUTHORS
diff --git a/abook.c b/abook.c
index b79fcae0b2fad72537bcb29bd681f7f0dd9bdfdd..dd2757751bcaa5a94cd7b01cc225352c365c041c 100644 (file)
--- a/abook.c
+++ b/abook.c
@@ -417,11 +417,13 @@ convert(char *srcformat, char *srcfile, char *dstformat, char *dstfile)
        strlower(srcformat);
        strlower(dstformat);
 
+#ifndef DEBUG
        if( !strcmp(srcformat, dstformat) ) {
                printf( "input and output formats are the same\n"
                        "exiting...\n");
                exit(1);
        }
+#endif
 
        set_filenames();
        init_options();
index a4399399b168d267d47b4ed18374c501b77afc8a..83a14b8af228e9dba4364b983c9049675363cbd5 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -21,6 +21,7 @@
 #include "list.h"
 #include "misc.h"
 #include "options.h"
+#include <assert.h>
 
 extern int items;
 extern list_item *database;
@@ -37,6 +38,7 @@ extern struct abook_field abook_fields[];
 static int      ldif_parse_file(FILE *handle);
 static int     mutt_parse_file(FILE *in);
 static int     pine_parse_file(FILE *in);
+static int     csv_parse_file(FILE *in);
 
 /*
  * export filter prototypes
@@ -61,6 +63,7 @@ struct abook_input_filter i_filters[] = {
        { "ldif", "ldif / Netscape addressbook", ldif_parse_file },
        { "mutt", "mutt alias (beta)", mutt_parse_file },
        { "pine", "pine addressbook", pine_parse_file },
+       { "csv", "comma separated values", csv_parse_file },
        { "\0", NULL, NULL }
 };
 
@@ -1013,6 +1016,173 @@ pine_export_database(FILE *out, struct db_enumerator e)
  */
 
 
+/*
+ * csv import filter
+ */
+
+/* FIXME
+ * these files should be parsed according to a certain
+ * lay out, or the default if layout is not given, at 
+ * the moment only default is done...
+ */ 
+
+#define CSV_COMMENT_CHAR       '#'
+
+static int csv_conv_table[] = {
+       NAME,
+       EMAIL,
+       PHONE,
+       NOTES,
+       NICK
+};
+
+static void
+csv_convert_emails(char *s)
+{
+       int i;
+       char *tmp;
+
+       if( s == NULL )
+               return;
+
+       for(i=1; ( tmp = strchr(s, ',') ) != NULL ; i++, s = tmp + 1 )
+               if( i > MAX_EMAILS - 1 ) {
+                       *tmp = 0;
+                       break;  
+               }
+
+}
+
+static char *
+csv_remove_quotes(char *s)
+{
+       char *copy, *trimmed;
+       int len;
+       
+       copy = trimmed = strdup(s);
+       strtrim(trimmed);
+       
+       len = strlen(trimmed);
+       if(trimmed[len - 1] == '\"' && *trimmed == '\"') {
+               if(len < 3) {
+                       my_free(copy);
+                       return NULL;
+               }
+               trimmed[len - 1] = 0;
+               trimmed++;
+               trimmed = strdup(trimmed);
+               free(copy);
+               return trimmed;
+       }
+
+       my_free(copy);
+       return strdup(s);
+}
+
+static void
+csv_store_field(list_item item, char *s, int field)
+{
+       char *newstr = NULL;
+
+       if(!s || !*s)
+               return;
+
+       if( !(newstr = csv_remove_quotes(s)) )
+               return;
+
+       if(field < (sizeof(csv_conv_table) / sizeof(*csv_conv_table))
+                       && csv_conv_table[field] >= 0) {
+               item[csv_conv_table[field]] = newstr;
+       }
+}
+
+static int
+csv_is_valid_quote_end(char *p)
+{
+       if(*p != '\"')
+               return FALSE;
+
+       for(p++; *p; p++) {
+               if(*p == ',')
+                       return TRUE;
+               else if(!ISSPACE(*p))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+static int
+csv_is_valid_quote_start(char *p)
+{
+       for(; *p; p++) {
+               if(*p == '\"')
+                       return TRUE;
+               else if(!ISSPACE(*p))
+                       return FALSE;
+       }
+
+       return FALSE;
+}
+
+static void
+csv_parse_line(char *line)
+{
+       char *p, *start;
+       int field;
+       int in_quote = FALSE;
+       list_item item;
+
+       memset(item, 0, sizeof(item));
+
+       for(p = start = line, field = 0; *p; p++) {
+               if(!in_quote) {
+                       if ( (((p - start) / sizeof (char)) < 2 ) &&
+                               csv_is_valid_quote_start(p) )
+                               in_quote = TRUE;
+               } else {
+                       if(csv_is_valid_quote_end(p))
+                               in_quote = FALSE;
+               }
+
+               if( *p == ',' && !in_quote) {
+                       *p = 0;
+                       csv_store_field(item, start, field);
+                       field++;
+                       start = p + 1;
+               }
+       }
+       /*
+        * store last field
+        */
+       csv_store_field(item, start, field);
+
+       csv_convert_emails(item[EMAIL]);
+       add_item2database(item);
+}
+
+
+static int
+csv_parse_file(FILE *in)
+{
+       char *line = NULL;
+
+       while(!feof(in)) {
+               line = getaline(in);
+
+               if(line && *line && *line != CSV_COMMENT_CHAR)
+                       csv_parse_line(line);
+
+               my_free(line);
+       }
+
+       return 0;
+}
+
+/*
+ * end of csv import filter
+ */
+
 /*
  * csv addressbook export filter
  */
@@ -1026,12 +1196,16 @@ csv_export_database(FILE *out, struct db_enumerator e)
                EMAIL,
                PHONE,
                NOTES,
+               NICK,
                -1
        };
 
        db_enumerate_items(e) {
                for(j = 0; csv_export_fields[j] >= 0; j++) {
-                       fprintf(out, strchr(safe_str(database[e.item][csv_export_fields[j]]), ',') ?
+                       fprintf(out,(
+               strchr(safe_str(database[e.item][csv_export_fields[j]]), ',') ||
+               strchr(safe_str(database[e.item][csv_export_fields[j]]), '\"')
+                       ) ?
                                "\"%s\"" : "%s",
                                safe_str(database[e.item][csv_export_fields[j]])
                                );