* mu-util.[ch]: add mu_util_locale_is_utf8, handle invalid utf8 string more gracefully

This commit is contained in:
Dirk-Jan C. Binnema 2011-06-01 21:52:58 +03:00
parent 8b7d0f9b06
commit 7019bd9b86
2 changed files with 36 additions and 7 deletions

View File

@ -51,6 +51,8 @@
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <errno.h> #include <errno.h>
#include <langinfo.h>
static char* static char*
do_wordexp (const char *path) do_wordexp (const char *path)
{ {
@ -117,7 +119,9 @@ char*
mu_util_create_tmpdir (void) mu_util_create_tmpdir (void)
{ {
gchar *dirname; gchar *dirname;
dirname = g_strdup_printf ("%s%cmu-%d%c%x", g_get_tmp_dir(),
dirname = g_strdup_printf ("%s%cmu-%d%c%x",
g_get_tmp_dir(),
G_DIR_SEPARATOR, G_DIR_SEPARATOR,
getuid(), getuid(),
G_DIR_SEPARATOR, G_DIR_SEPARATOR,
@ -151,7 +155,7 @@ mu_util_init_system (void)
/* without setlocale, non-ascii cmdline params (like search /* without setlocale, non-ascii cmdline params (like search
* terms) won't work */ * terms) won't work */
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
/* on FreeBSD, it seems g_slice_new and friends lead to /* on FreeBSD, it seems g_slice_new and friends lead to
* segfaults. So we shut if off */ * segfaults. So we shut if off */
#ifdef __FreeBSD__ #ifdef __FreeBSD__
@ -370,27 +374,45 @@ mu_util_get_dtype_with_lstat (const char *path)
} }
gboolean
mu_util_locale_is_utf8 (void)
{
const gchar *dummy;
static int is_utf8 = -1;
if (G_UNLIKELY(is_utf8 == -1))
is_utf8 = g_get_charset(&dummy) ? 1 : 0;
return is_utf8 ? TRUE : FALSE;
}
gboolean gboolean
mu_util_fputs_encoded (const char *str, FILE *stream) mu_util_fputs_encoded (const char *str, FILE *stream)
{ {
char *conv; char *conv;
const char *dummy;
int rv; int rv;
g_return_val_if_fail (str, FALSE); g_return_val_if_fail (str, FALSE);
g_return_val_if_fail (stream, FALSE); g_return_val_if_fail (stream, FALSE);
/* g_get_charset return TRUE when the locale is UTF8 */ /* g_get_charset return TRUE when the locale is UTF8 */
if (g_get_charset(&dummy)) if (mu_util_locale_is_utf8())
rv = fputs (str, stream); rv = fputs (str, stream);
else { /* charset is _not_ utf8, so we actually have to else { /* charset is _not_ utf8, so we actually have to
* convert it..*/ * convert it..*/
GError *err; GError *err;
unsigned bytes;
err = NULL; err = NULL;
conv = g_locale_from_utf8 (str, -1, NULL, NULL, &err);
conv = g_locale_from_utf8 (str, -1, &bytes, NULL, &err);
if (err) { if (err) {
g_printerr ("conversion failed: %s", err->message); /* conversion failed; this happens because is
* some cases GMime may gives us non-UTF-8
* string from e.g. wrongly encoded
* message-subjects; if so, we escape the
* string */
g_free (conv);
conv = g_strescape (str, NULL);
g_error_free (err); g_error_free (err);
return FALSE; return FALSE;
} }

View File

@ -135,6 +135,13 @@ int mu_util_create_writeable_fd (const char* path, mode_t mode,
gboolean mu_util_is_local_file (const char* path); gboolean mu_util_is_local_file (const char* path);
/**
* is the current locale utf-8 compatible?
*
* @return TRUE if it's utf8 compatible, FALSE otherwise
*/
gboolean mu_util_locale_is_utf8 (void) G_GNUC_CONST;
/** /**
* write a string (assumed to be in utf8-format) to a stream, * write a string (assumed to be in utf8-format) to a stream,
* converted to the current locale * converted to the current locale