[easytag] Refactor filename_from_display()
- From: David King <davidk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [easytag] Refactor filename_from_display()
- Date: Thu, 14 Jan 2016 08:20:24 +0000 (UTC)
commit b23a3bb3fcb612b86c1c40372db6bc9125037a01
Author: David King <amigadave amigadave com>
Date: Tue Jan 12 17:34:44 2016 +0000
Refactor filename_from_display()
Validate that the supplied string is UTF-8 with g_return_val_if_fail().
Use g_filename_from_utf8() before attempting any other conversions.
Avoid leaking a GError if there are conversion failures. Use
g_get_filename_charsets() to query the filename encoding.
src/charset.c | 114 ++++++++++++++++++++++++++++++++++++---------------------
1 files changed, 72 insertions(+), 42 deletions(-)
---
diff --git a/src/charset.c b/src/charset.c
index 6eab881..8c764f5 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -430,36 +430,47 @@ convert_string_1 (const gchar *string, gssize length, const gchar *from_codeset,
}
/*
- * Convert a string from UTF-8 to the filename system encoding.
- * - conversion OK : returns the string in filename system encoding (new allocated)
- * - conversion KO : display error message + returns nothing!
+ * filename_from_display:
+ * @string: a UTF-8 string
+ *
+ * Convert a string from UTF-8 to the filesystem encoding.
+ *
+ * Returns: a newly-allocated filename in the GLib filename encoding on
+ * success, or an escaped ASCII string on error
*/
-gchar *filename_from_display (const gchar *string)
+gchar *
+filename_from_display (const gchar *string)
{
GError *error = NULL;
gchar *ret = NULL;
- const gchar *char_encoding = NULL;
- //const gchar *filename_encoding = NULL;
+ const gchar **filename_encodings;
g_return_val_if_fail (string != NULL, NULL);
+ g_return_val_if_fail (g_utf8_validate (string, -1, NULL), NULL);
- // Get system encoding from LANG if found (ex : fr_FR.UTF-8 => UTF-8)
- if (get_locale())
- char_encoding = strchr(get_locale(), '.');
+ ret = g_filename_from_utf8 (string, -1, NULL, NULL, &error);
- if (char_encoding)
- char_encoding = char_encoding+1; // Skip the '.'
- if (char_encoding)
+ if (!ret)
+ {
+ g_debug ("Error while converting filename from display to GLib encoding: %s",
+ error->message);
+ g_clear_error (&error);
+ }
+ else
+ {
+ return ret;
+ }
+
+ /* If the target encoding is not UTF-8, try the user-chosen alternative. */
+ if (!g_get_filename_charsets (&filename_encodings))
{
EtRenameEncoding enc_option = g_settings_get_enum (MainSettings,
"rename-encoding");
- error = NULL;
switch (enc_option)
{
case ET_RENAME_ENCODING_TRY_ALTERNATIVE:
- ret = g_convert (string, -1, char_encoding, "UTF-8", NULL,
- NULL, &error);
+ /* Already called g_filename_from_utf8(). */
break;
case ET_RENAME_ENCODING_TRANSLITERATE:
{
@@ -470,8 +481,17 @@ gchar *filename_from_display (const gchar *string)
* it can be approximated through one or several similarly
* looking characters.
*/
- gchar *enc = g_strconcat (char_encoding, "//TRANSLIT", NULL);
+ /* TODO: Use g_str_to_ascii() in GLib 2.40. */
+ gchar *enc = g_strconcat (*filename_encodings, "//TRANSLIT", NULL);
ret = g_convert (string, -1, enc, "UTF-8", NULL, NULL, &error);
+
+ if (!ret)
+ {
+ g_debug ("Error while converting filename from display to transliterated encoding '%s':
%s",
+ enc, error->message);
+ g_clear_error (&error);
+ }
+
g_free (enc);
break;
}
@@ -482,8 +502,16 @@ gchar *filename_from_display (const gchar *string)
* that cannot be represented in the target character set will
* be silently discarded.
*/
- gchar *enc = g_strconcat (char_encoding, "//IGNORE", NULL);
+ gchar *enc = g_strconcat (*filename_encodings, "//IGNORE", NULL);
ret = g_convert (string, -1, enc, "UTF-8", NULL, NULL, &error);
+
+ if (!ret)
+ {
+ g_debug ("Error while converting filename from display to encoding with ignored failures
'%s': %s",
+ enc, error->message);
+ g_clear_error (&error);
+ }
+
g_free (enc);
break;
}
@@ -492,52 +520,54 @@ gchar *filename_from_display (const gchar *string)
}
}
+ /* Try alternative encodings. */
if (!ret)
{
- // Get system encoding from locale in LANG if found (ex : fr_FR.UTF-8 => fr_FR => ISO-8859-1)
- char_encoding = get_encoding_from_locale(get_locale());
- if (char_encoding)
+ const gchar *legacy_encoding;
+
+ /* Guess the legacy (pre-Unicode) filesystem encoding from the locale.
+ * For example, fr_FR.UTF-8 => fr_FR => ISO-8859-1. */
+ legacy_encoding = get_encoding_from_locale (get_locale ());
+ ret = g_convert (string, -1, legacy_encoding, "UTF-8", NULL, NULL,
+ &error);
+
+ if (!ret)
{
- //g_print("> char_encoding: %s\n",char_encoding);
- error = NULL;
- ret = g_convert(string, -1, char_encoding, "UTF-8", NULL, NULL, &error);
+ g_debug ("Error while converting filename from display to legacy encoding '%s': %s",
+ legacy_encoding, error->message);
+ g_clear_error (&error);
}
}
if (!ret)
{
- // Failing that, try ISO-8859-1
- error = NULL;
- ret = g_convert(string, -1, "ISO-8859-1", "UTF-8", NULL, NULL, &error);
- }
+ /* Failing that, try ISO-8859-1. */
+ ret = g_convert (string, -1, "ISO-8859-1", "UTF-8", NULL, NULL,
+ &error);
- if (!ret)
- {
- if (g_utf8_validate(string, -1, NULL))
+ if (!ret)
{
- // String already in UTF-8
- ret = g_strdup(string);
+ g_debug ("Error while converting filename from display to ISO-8859-1: %s",
+ error->message);
+ g_clear_error (&error);
}
}
+ /* If all conversions fail, return an escaped version of the supplied UTF-8
+ * string. */
if (!ret)
{
- // Conversion KO!
- gchar *escaped_str = g_strescape(string, NULL);
+ gchar *escaped_str = g_strescape (string, NULL);
+
+ /* TODO: Improve error string. */
Log_Print (LOG_ERROR,
_("The UTF-8 string ā%sā could not be converted into filename encoding: %s"),
- escaped_str,
- error && error->message ? error->message : _("Invalid UTF-8"));
- g_clear_error(&error);
+ string, _("Invalid UTF-8"));
ret = escaped_str;
}
-#ifdef G_OS_WIN32
- //ET_Win32_Path_Replace_Backslashes (ret);
-#endif /* G_OS_WIN32 */
-
- return ret; // We need to catch errors (e.g. temp=NULL) in the real code
+ return ret;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]