aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2017-11-30 02:40:07 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2017-11-30 02:40:07 +0000
commit50f72ab6a11e25dbf9431c06adb3f7f16315befe (patch)
tree8a03904422826399eba812606a6f5cf2e5401f85
parentd85e720cb558df0206b93b6d956116b7d2754f44 (diff)
addressbook csv export: fixed double-quote escape and added header line.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@3587 ee746299-78ed-0310-b773-934348b2243d
-rw-r--r--ChangeLog6
-rw-r--r--libsylph/utils.c8
-rw-r--r--src/exportcsv.c109
3 files changed, 66 insertions, 57 deletions
diff --git a/ChangeLog b/ChangeLog
index 99944cfb..83a0e812 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2017-11-30
+
+ * libsylph/utils.c: strconcat_csv(): enclose fields in double quotes
+ if double quotes appear.
+ * src/exportcsv.c: code cleanup. Added header line.
+
2017-11-29
* libsylph/libsylph-0.def
diff --git a/libsylph/utils.c b/libsylph/utils.c
index a76d0a55..aabce066 100644
--- a/libsylph/utils.c
+++ b/libsylph/utils.c
@@ -1730,6 +1730,12 @@ gchar **strsplit_csv(const gchar *str, gchar delim, gint max_tokens)
return str_array;
}
+/* Concatenate multiple strings into a CSV (TSV) record.
+ * If delimiter characters or double-quotes appear in the string,
+ it is enclosed by double quotes.
+ * Double quote characters are escaped by another double quote.
+ * Strings must not include line breaks in this implementation.
+ */
gchar *strconcat_csv(gchar delim, const gchar *field1, ...)
{
va_list args;
@@ -1749,7 +1755,7 @@ gchar *strconcat_csv(gchar delim, const gchar *field1, ...)
if (count > 0)
g_string_append_c(csv, delim);
- if (delim != '\t' && strchr(s, delim) != NULL)
+ if (strchr(s, delim) != NULL || strchr(s, '"') != NULL)
add_quote = TRUE;
if (add_quote)
g_string_append_c(csv, '"');
diff --git a/src/exportcsv.c b/src/exportcsv.c
index aad78291..882bb4f2 100644
--- a/src/exportcsv.c
+++ b/src/exportcsv.c
@@ -106,6 +106,38 @@ static void exp_csv_message( void ) {
exp_csv_status_show( sMsg );
}
+static gint exp_csv_write_email_record( ItemPerson *person, ItemEMail *email, FILE *fp ) {
+ gchar *sName, *sAddress, *sAlias, *sNickName;
+ gchar *sFirstName, *sLastName;
+ gchar *sRemarks;
+ gchar *csv;
+
+ g_return_val_if_fail(person != NULL, MGU_BAD_ARGS);
+
+ sName = ADDRITEM_NAME(person) ? ADDRITEM_NAME(person) : "";
+ sFirstName = person->firstName ? person->firstName : "";
+ sLastName = person->lastName ? person->lastName : "";
+ sNickName = person->nickName ? person->nickName : "";
+
+ if (email) {
+ sAddress = email->address ? email->address : "";
+ sRemarks = email->remarks ? email->remarks : "";
+ sAlias = ADDRITEM_NAME(email) ? ADDRITEM_NAME(email) : "";
+ } else {
+ sAddress = "";
+ sRemarks = "";
+ sAlias = "";
+ }
+
+ csv = strconcat_csv(expcsv_dlg.delimiter, sFirstName, sLastName, sName, sNickName, sAddress, sRemarks, sAlias, NULL);
+ debug_print("%s\n", csv);
+ fputs(csv, fp);
+ fputc('\n', fp);
+ g_free(csv);
+
+ return MGU_SUCCESS;
+}
+
static gint exp_csv_export_folder_recursive( ItemFolder *itemFolder, FILE *fp ) {
GList *items;
GList *cur;
@@ -120,49 +152,24 @@ static gint exp_csv_export_folder_recursive( ItemFolder *itemFolder, FILE *fp )
ItemPerson *person;
ItemEMail *email;
GList *node;
- gchar *sName, *sAddress, *sAlias, *sNickName;
- gchar *sFirstName, *sLastName;
- gchar *sRemarks;
- gchar *csv;
person = (ItemPerson *)cur->data;
- if (!person)
+ if (!person) {
continue;
-
- sName = ADDRITEM_NAME(person) ? ADDRITEM_NAME(person) : "";
- sFirstName = person->firstName ? person->firstName : "";
- sLastName = person->lastName ? person->lastName : "";
- sNickName = person->nickName ? person->nickName : "";
+ }
node = person->listEMail;
if (!node) {
- sAddress = "";
- sRemarks = "";
- sAlias = "";
-
- csv = strconcat_csv(expcsv_dlg.delimiter, sFirstName, sLastName, sName, sNickName, sAddress, sRemarks, sAlias, NULL);
- debug_print("%s\n", csv);
- fputs(csv, fp);
- fputc('\n', fp);
- g_free(csv);
-
- count++;
+ if (exp_csv_write_email_record(person, NULL, fp) == MGU_SUCCESS) {
+ count++;
+ }
} else {
while (node) {
email = node->data;
node = g_list_next(node);
-
- sAddress = email->address ? email->address : "";
- sRemarks = email->remarks ? email->remarks : "";
- sAlias = ADDRITEM_NAME(email) ? ADDRITEM_NAME(email) : "";
-
- csv = strconcat_csv(expcsv_dlg.delimiter, sFirstName, sLastName, sName, sNickName, sAddress, sRemarks, sAlias, NULL);
- debug_print("%s\n", csv);
- fputs(csv, fp);
- fputc('\n', fp);
- g_free(csv);
-
- count++;
+ if (exp_csv_write_email_record(person, email, fp) == MGU_SUCCESS) {
+ count++;
+ }
}
}
}
@@ -186,6 +193,7 @@ static gint exp_csv_export_data( gchar *csvFile ) {
ItemGroup *itemGroup = NULL;
GList *items;
GList *cur;
+ gchar *csv;
gint count = 0;
g_return_val_if_fail(csvFile != NULL, MGU_BAD_ARGS);
@@ -210,7 +218,11 @@ static gint exp_csv_export_data( gchar *csvFile ) {
itemGroup = ADAPTER_GROUP(_exp_object_)->itemGroup;
}
- debug_print("%s,%s,%s,%s,%s,%s,%s\n", _("First Name"), _("Last Name"), _("Display Name"), _("Nick Name"), _("E-Mail Address"), _("Remarks"), _("Alias"));
+ csv = strconcat_csv(expcsv_dlg.delimiter, _("First Name"), _("Last Name"), _("Display Name"), _("Nick Name"), _("E-Mail Address"), _("Remarks"), _("Alias"), NULL);
+ debug_print("%s\n", csv);
+ fputs(csv, fp);
+ fputc('\n', fp);
+ g_free(csv);
if (itemFolder) {
exp_csv_export_folder_recursive(itemFolder, fp);
@@ -219,33 +231,18 @@ static gint exp_csv_export_data( gchar *csvFile ) {
for (cur = items; cur != NULL; cur = cur->next) {
ItemEMail *email = (ItemEMail *)cur->data;
ItemPerson *person;
- gchar *sName, *sAddress, *sAlias, *sNickName;
- gchar *sFirstName, *sLastName;
- gchar *sRemarks;
- gchar *csv;
- if (!email)
+ if (!email) {
continue;
+ }
person = (ItemPerson *)ADDRITEM_PARENT(email);
- if (!person)
+ if (!person) {
continue;
+ }
- sName = ADDRITEM_NAME(person) ? ADDRITEM_NAME(person) : "";
- sFirstName = person->firstName ? person->firstName : "";
- sLastName = person->lastName ? person->lastName : "";
- sNickName = person->nickName ? person->nickName : "";
-
- sAddress = email->address ? email->address : "";
- sRemarks = email->remarks ? email->remarks : "";
- sAlias = ADDRITEM_NAME(email) ? ADDRITEM_NAME(email) : "";
-
- csv = strconcat_csv(expcsv_dlg.delimiter, sFirstName, sLastName, sName, sNickName, sAddress, sRemarks, sAlias, NULL);
- debug_print("%s\n", csv);
- fputs(csv, fp);
- fputc('\n', fp);
- g_free(csv);
-
- count++;
+ if (exp_csv_write_email_record(person, email, fp) == MGU_SUCCESS) {
+ count++;
+ }
}
exportCount = count;
}