From 50f72ab6a11e25dbf9431c06adb3f7f16315befe Mon Sep 17 00:00:00 2001 From: hiro Date: Thu, 30 Nov 2017 02:40:07 +0000 Subject: 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 --- ChangeLog | 6 +++ libsylph/utils.c | 8 +++- src/exportcsv.c | 109 +++++++++++++++++++++++++++---------------------------- 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; } -- cgit v1.2.3