aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2007-04-11 04:55:33 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2007-04-11 04:55:33 +0000
commitae89f3a0a68c3b407127ec50caf06f7730e1932d (patch)
tree41a107d398964297636ccf323a3128bce9ca663c
parentc50e22097bdcee524604a3c8d4a7639d1af2904c (diff)
properly process CSV with double quotations.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@1616 ee746299-78ed-0310-b773-934348b2243d
-rw-r--r--ChangeLog5
-rw-r--r--ChangeLog.ja6
-rw-r--r--libsylph/utils.c75
-rw-r--r--libsylph/utils.h3
-rw-r--r--src/importcsv.c4
5 files changed, 89 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 866e423f..f4e76a1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2007-04-11
+ * libsylph/utils.[ch]: strsplit_csv(): added.
+ * src/importcsv.c: properly process CSV with double quotations.
+
+2007-04-11
+
* src/addressbook.c: set focus row after import.
2007-04-11
diff --git a/ChangeLog.ja b/ChangeLog.ja
index a6d03bb2..ff6c2d8b 100644
--- a/ChangeLog.ja
+++ b/ChangeLog.ja
@@ -1,5 +1,11 @@
2007-04-11
+ * libsylph/utils.[ch]: strsplit_csv(): 追加。
+ * src/importcsv.c: ダブルクォート付きの CSV を適切に処理するように
+ した。
+
+2007-04-11
+
* src/addressbook.c: インポートの後フォーカス行をセットするようにした。
2007-04-11
diff --git a/libsylph/utils.c b/libsylph/utils.c
index c80809fb..c5c3a9d8 100644
--- a/libsylph/utils.c
+++ b/libsylph/utils.c
@@ -1020,7 +1020,7 @@ GList *add_history(GList *list, const gchar *str)
last = g_list_last(list);
if (last) {
g_free(last->data);
- g_list_remove(list, last->data);
+ list = g_list_remove(list, last->data);
}
}
@@ -1355,7 +1355,6 @@ gchar **strsplit_parenthesis(const gchar *str, gchar op, gchar cl,
str_array = g_new(gchar*, n);
i = n - 1;
-
str_array[i--] = NULL;
for (slist = string_list; slist; slist = slist->next)
str_array[i--] = slist->data;
@@ -1415,7 +1414,79 @@ gchar **strsplit_with_quote(const gchar *str, const gchar *delim,
str_array = g_new(gchar*, n);
i = n - 1;
+ str_array[i--] = NULL;
+ for (slist = string_list; slist; slist = slist->next)
+ str_array[i--] = slist->data;
+
+ g_slist_free(string_list);
+
+ return str_array;
+}
+
+gchar **strsplit_csv(const gchar *str, gchar delim, gint max_tokens)
+{
+ GSList *string_list = NULL, *slist;
+ gchar **str_array, *s, *new_str;
+ gchar *tmp, *tmpp, *p;
+ guint i, n = 1, len;
+
+ g_return_val_if_fail(str != NULL, NULL);
+
+ if (max_tokens < 1)
+ max_tokens = G_MAXINT;
+
+ s = strchr_with_skip_quote(str, '"', delim);
+ if (s) {
+ do {
+ len = s - str;
+ tmpp = tmp = g_strndup(str, len);
+
+ if (tmp[0] == '"' && tmp[len - 1] == tmp[0]) {
+ tmp[len - 1] = '\0';
+ ++tmpp;
+ p = new_str = g_malloc(len - 1);
+ while (*tmpp) {
+ if (*tmpp == '"' && *(tmpp + 1) == '"')
+ ++tmpp;
+ *p++ = *tmpp++;
+ }
+ *p = '\0';
+ g_free(tmp);
+ } else
+ new_str = tmp;
+ string_list = g_slist_prepend(string_list, new_str);
+ n++;
+ str = s + 1;
+ s = strchr_with_skip_quote(str, '"', delim);
+ } while (--max_tokens && s);
+ }
+
+ if (*str) {
+ len = strlen(str);
+ tmpp = tmp = g_strdup(str);
+
+ if (tmp[0] == '"' && tmp[len - 1] == tmp[0]) {
+ tmp[len - 1] = '\0';
+ ++tmpp;
+ p = new_str = g_malloc(len - 1);
+ while (*tmpp) {
+ if (*tmpp == '"' && *(tmpp + 1) == '"')
+ ++tmpp;
+ *p++ = *tmpp++;
+ }
+ *p = '\0';
+ g_free(tmp);
+ } else
+ new_str = tmp;
+
+ string_list = g_slist_prepend(string_list, new_str);
+ n++;
+ }
+
+ str_array = g_new(gchar*, n);
+
+ i = n - 1;
str_array[i--] = NULL;
for (slist = string_list; slist; slist = slist->next)
str_array[i--] = slist->data;
diff --git a/libsylph/utils.h b/libsylph/utils.h
index 62664077..fe0b585b 100644
--- a/libsylph/utils.h
+++ b/libsylph/utils.h
@@ -337,6 +337,9 @@ gchar **strsplit_parenthesis (const gchar *str,
gchar **strsplit_with_quote (const gchar *str,
const gchar *delim,
gint max_tokens);
+gchar **strsplit_csv (const gchar *str,
+ gchar delim,
+ gint max_tokens);
gchar *get_abbrev_newsgroup_name (const gchar *group,
gint len);
diff --git a/src/importcsv.c b/src/importcsv.c
index b9884737..b93f6928 100644
--- a/src/importcsv.c
+++ b/src/importcsv.c
@@ -207,7 +207,7 @@ static gboolean imp_csv_load_fields( gchar *sFile ) {
str = g_strdup(buf);
else
str = conv_localetodisp(buf, NULL);
- strv = g_strsplit(str, ",", 0);
+ strv = strsplit_csv(str, ',', 0);
fields_len = sizeof(imp_csv_attrib) / sizeof(imp_csv_attrib[0]);
while (strv[data_len])
++data_len;
@@ -381,7 +381,7 @@ static gint imp_csv_import_data( gchar *csvFile, AddressCache *cache ) {
str = g_strdup(buf);
else
str = conv_localetodisp(buf, NULL);
- strv = g_strsplit(str, ",", 0);
+ strv = strsplit_csv(str, ',', 0);
while (strv[cols])
++cols;