diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2007-04-11 04:55:33 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2007-04-11 04:55:33 +0000 |
commit | ae89f3a0a68c3b407127ec50caf06f7730e1932d (patch) | |
tree | 41a107d398964297636ccf323a3128bce9ca663c | |
parent | c50e22097bdcee524604a3c8d4a7639d1af2904c (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-- | ChangeLog | 5 | ||||
-rw-r--r-- | ChangeLog.ja | 6 | ||||
-rw-r--r-- | libsylph/utils.c | 75 | ||||
-rw-r--r-- | libsylph/utils.h | 3 | ||||
-rw-r--r-- | src/importcsv.c | 4 |
5 files changed, 89 insertions, 4 deletions
@@ -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; |