Don't call g_set_error() unless the GError pointer is non-NULL. This

2005-04-27  Tor Lillqvist  <tml@novell.com>

	* glib/gconvert.c (open_converter, g_convert_with_iconv): Don't
	call g_set_error() unless the GError pointer is non-NULL. This
	avoids infinite recursion problems in certain rare situations on
	Windows, when g_locale_from_utf8() is called from
	_glib_get_locale_dir() after the change below. It's the
	_glib_gettext() calls to translate error messages that are
	parameters to g_set_error() that cause the recursion, not
	g_set_error() itself.

	* glib/gwin32.c (g_win32_locale_filename_from_utf8): New
	function. Converts a filename to the system codepage, and if a
	straight conversion isn't possible (because the filename contains
	characters not in the system codepage), try looking up the
	filename (which should refer to an existing file for this to
	succeed) with short (8.3) pathname components.

	* glib/gutils.c (_glib_get_locale_dir): No need to cache the
	result, this function is normally called only once. Return the
	path to the locale directory in system codepage, not UTF-8. The
	path is passed to bindtextdomain(), which doesn't use UTF-8 file
	names. Use g_win32_locale_filename_from_utf8(). (#301772)

	Don't do run-time lookup of message catalog directory on
	Cygwin. Cygwin is supposed to look and feel like Unix, and on Unix
	we use paths fixed at configure time.
This commit is contained in:
Tor Lillqvist 2005-04-27 09:50:09 +00:00 committed by Tor Lillqvist
parent 810e3f1605
commit dc11b4370f
8 changed files with 226 additions and 27 deletions

View File

@ -1,3 +1,31 @@
2005-04-27 Tor Lillqvist <tml@novell.com>
* glib/gconvert.c (open_converter, g_convert_with_iconv): Don't
call g_set_error() unless the GError pointer is non-NULL. This
avoids infinite recursion problems in certain rare situations on
Windows, when g_locale_from_utf8() is called from
_glib_get_locale_dir() after the change below. It's the
_glib_gettext() calls to translate error messages that are
parameters to g_set_error() that cause the recursion, not
g_set_error() itself.
* glib/gwin32.c (g_win32_locale_filename_from_utf8): New
function. Converts a filename to the system codepage, and if a
straight conversion isn't possible (because the filename contains
characters not in the system codepage), try looking up the
filename (which should refer to an existing file for this to
succeed) with short (8.3) pathname components.
* glib/gutils.c (_glib_get_locale_dir): No need to cache the
result, this function is normally called only once. Return the
path to the locale directory in system codepage, not UTF-8. The
path is passed to bindtextdomain(), which doesn't use UTF-8 file
names. Use g_win32_locale_filename_from_utf8(). (#301772)
Don't do run-time lookup of message catalog directory on
Cygwin. Cygwin is supposed to look and feel like Unix, and on Unix
we use paths fixed at configure time.
2005-04-19 Tor Lillqvist <tml@novell.com>
* glib/gutils.h: Minor comment improvement.

View File

@ -1,3 +1,31 @@
2005-04-27 Tor Lillqvist <tml@novell.com>
* glib/gconvert.c (open_converter, g_convert_with_iconv): Don't
call g_set_error() unless the GError pointer is non-NULL. This
avoids infinite recursion problems in certain rare situations on
Windows, when g_locale_from_utf8() is called from
_glib_get_locale_dir() after the change below. It's the
_glib_gettext() calls to translate error messages that are
parameters to g_set_error() that cause the recursion, not
g_set_error() itself.
* glib/gwin32.c (g_win32_locale_filename_from_utf8): New
function. Converts a filename to the system codepage, and if a
straight conversion isn't possible (because the filename contains
characters not in the system codepage), try looking up the
filename (which should refer to an existing file for this to
succeed) with short (8.3) pathname components.
* glib/gutils.c (_glib_get_locale_dir): No need to cache the
result, this function is normally called only once. Return the
path to the locale directory in system codepage, not UTF-8. The
path is passed to bindtextdomain(), which doesn't use UTF-8 file
names. Use g_win32_locale_filename_from_utf8(). (#301772)
Don't do run-time lookup of message catalog directory on
Cygwin. Cygwin is supposed to look and feel like Unix, and on Unix
we use paths fixed at configure time.
2005-04-19 Tor Lillqvist <tml@novell.com>
* glib/gutils.h: Minor comment improvement.

View File

@ -1,3 +1,31 @@
2005-04-27 Tor Lillqvist <tml@novell.com>
* glib/gconvert.c (open_converter, g_convert_with_iconv): Don't
call g_set_error() unless the GError pointer is non-NULL. This
avoids infinite recursion problems in certain rare situations on
Windows, when g_locale_from_utf8() is called from
_glib_get_locale_dir() after the change below. It's the
_glib_gettext() calls to translate error messages that are
parameters to g_set_error() that cause the recursion, not
g_set_error() itself.
* glib/gwin32.c (g_win32_locale_filename_from_utf8): New
function. Converts a filename to the system codepage, and if a
straight conversion isn't possible (because the filename contains
characters not in the system codepage), try looking up the
filename (which should refer to an existing file for this to
succeed) with short (8.3) pathname components.
* glib/gutils.c (_glib_get_locale_dir): No need to cache the
result, this function is normally called only once. Return the
path to the locale directory in system codepage, not UTF-8. The
path is passed to bindtextdomain(), which doesn't use UTF-8 file
names. Use g_win32_locale_filename_from_utf8(). (#301772)
Don't do run-time lookup of message catalog directory on
Cygwin. Cygwin is supposed to look and feel like Unix, and on Unix
we use paths fixed at configure time.
2005-04-19 Tor Lillqvist <tml@novell.com>
* glib/gutils.h: Minor comment improvement.

View File

@ -1,3 +1,31 @@
2005-04-27 Tor Lillqvist <tml@novell.com>
* glib/gconvert.c (open_converter, g_convert_with_iconv): Don't
call g_set_error() unless the GError pointer is non-NULL. This
avoids infinite recursion problems in certain rare situations on
Windows, when g_locale_from_utf8() is called from
_glib_get_locale_dir() after the change below. It's the
_glib_gettext() calls to translate error messages that are
parameters to g_set_error() that cause the recursion, not
g_set_error() itself.
* glib/gwin32.c (g_win32_locale_filename_from_utf8): New
function. Converts a filename to the system codepage, and if a
straight conversion isn't possible (because the filename contains
characters not in the system codepage), try looking up the
filename (which should refer to an existing file for this to
succeed) with short (8.3) pathname components.
* glib/gutils.c (_glib_get_locale_dir): No need to cache the
result, this function is normally called only once. Return the
path to the locale directory in system codepage, not UTF-8. The
path is passed to bindtextdomain(), which doesn't use UTF-8 file
names. Use g_win32_locale_filename_from_utf8(). (#301772)
Don't do run-time lookup of message catalog directory on
Cygwin. Cygwin is supposed to look and feel like Unix, and on Unix
we use paths fixed at configure time.
2005-04-19 Tor Lillqvist <tml@novell.com>
* glib/gutils.h: Minor comment improvement.

View File

@ -399,14 +399,17 @@ open_converter (const gchar *to_codeset,
G_UNLOCK (iconv_cache_lock);
/* Something went wrong. */
if (errno == EINVAL)
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
_("Conversion from character set '%s' to '%s' is not supported"),
from_codeset, to_codeset);
else
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
_("Could not open converter from '%s' to '%s'"),
from_codeset, to_codeset);
if (error)
{
if (errno == EINVAL)
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
_("Conversion from character set '%s' to '%s' is not supported"),
from_codeset, to_codeset);
else
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
_("Could not open converter from '%s' to '%s'"),
from_codeset, to_codeset);
}
return cd;
}
@ -610,14 +613,16 @@ g_convert_with_iconv (const gchar *str,
goto again;
}
case EILSEQ:
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
_("Invalid byte sequence in conversion input"));
if (error)
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
_("Invalid byte sequence in conversion input"));
have_error = TRUE;
break;
default:
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
_("Error during conversion: %s"),
g_strerror (errno));
if (error)
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
_("Error during conversion: %s"),
g_strerror (errno));
have_error = TRUE;
break;
}
@ -633,8 +638,9 @@ g_convert_with_iconv (const gchar *str,
{
if (!have_error)
{
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
_("Partial character sequence at end of input"));
if (error)
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
_("Partial character sequence at end of input"));
have_error = TRUE;
}
}
@ -1122,7 +1128,7 @@ g_get_filename_charsets (G_CONST_RETURN gchar ***filename_charsets)
gboolean
g_get_filename_charsets (G_CONST_RETURN gchar ***filename_charsets)
{
static gchar *charsets[] = {
static const gchar *charsets[] = {
"UTF-8",
NULL
};
@ -1190,8 +1196,9 @@ _g_convert_thread_init (void)
* @error: location to store the error occuring, or %NULL to ignore
* errors. Any of the errors in #GConvertError may occur.
*
* Converts a string which is in the encoding used by GLib for filenames
* into a UTF-8 string.
* Converts a string which is in the encoding used by GLib for
* filenames into a UTF-8 string. Note that on Windows GLib uses UTF-8
* for filenames.
*
* Return value: The converted string, or %NULL on an error.
**/
@ -1253,7 +1260,8 @@ g_filename_to_utf8 (const gchar *opsysstring,
* @error: location to store the error occuring, or %NULL to ignore
* errors. Any of the errors in #GConvertError may occur.
*
* Converts a string from UTF-8 to the encoding used for filenames.
* Converts a string from UTF-8 to the encoding GLib uses for
* filenames. Note that on Windows GLib uses UTF-8 for filenames.
*
* Return value: The converted string, or %NULL on an error.
**/

View File

@ -2781,23 +2781,46 @@ _g_utils_thread_init (void)
#include <libintl.h>
#ifdef G_PLATFORM_WIN32
#ifdef G_OS_WIN32
/**
* _glib_get_locale_dir:
*
* Return the path to the lib\locale subfolder of the GLib
* installation folder. The path is in the system codepage. We have to
* use system codepage as bindtextdomain() doesn't have a UTF-8
* interface.
*/
static const gchar *
_glib_get_locale_dir (void)
{
static const gchar *cache = NULL;
if (cache == NULL)
cache = g_win32_get_package_installation_subdirectory
(GETTEXT_PACKAGE, dll_name, "lib\\locale");
gchar *dir, *cp_dir;
gchar *retval = NULL;
return cache;
dir = g_win32_get_package_installation_directory (GETTEXT_PACKAGE, dll_name);
cp_dir = g_win32_locale_filename_from_utf8 (dir);
g_free (dir);
if (cp_dir)
{
/* Don't use g_build_filename() on pathnames in the system
* codepage. In CJK locales cp_dir might end with a double-byte
* character whose trailing byte is a backslash.
*/
retval = g_strconcat (cp_dir, "\\lib\\locale", NULL);
g_free (cp_dir);
}
if (retval)
return retval;
else
return g_strdup ("");
}
#undef GLIB_LOCALE_DIR
#define GLIB_LOCALE_DIR _glib_get_locale_dir ()
#endif /* G_PLATFORM_WIN32 */
#endif /* G_OS_WIN32 */
G_CONST_RETURN gchar *
_glib_gettext (const gchar *str)

View File

@ -1223,7 +1223,7 @@ get_package_directory_from_module (gchar *module_name)
* @dll_name was %NULL.
*
* If both @package and @dll_name are %NULL, the directory from where
* the main executable of the process was loaded is uses instead in
* the main executable of the process was loaded is used instead in
* the same way as above.
*
* Returns: a string containing the installation directory for
@ -1467,5 +1467,59 @@ g_win32_get_windows_version (void)
return windows_version;
}
/**
* g_win32_locale_filename_from_utf8:
*
* @utf8filename: a UTF-8 encoded filename.
*
* Convertes a filename from UTF-8 to the system codepage.
*
* On NT-based Windows, on NTFS file systems, file names are in
* Unicode. It is quite possible that Unicode file names contain
* characters not representable in the system codepage. (For instance,
* Greek or Cyrillic characters on Western European or US Windows
* installations, or various less common CJK characters on CJK Windows
* installations.)
*
* In such a case, and if the filename refers to an existing file, and
* the file system stores alternate short (8.3) names for directory
* entries, the short form of the filename is returned. Note that the
* "short" name might in fact be longer than the Unicode name. If no
* system codepage name for the file is possible, NULL is returned.
*
* The return value is dynamically allocated and should be freed when
* no longer used.
*
* Return value: The converted filename, or %NULL on conversion
* failure and lack of short names.
*
* Since: 2.7
*/
gchar *
g_win32_locale_filename_from_utf8 (const gchar *utf8filename)
{
gchar *retval = g_locale_from_utf8 (utf8filename, -1, NULL, NULL, NULL);
if (retval == NULL && G_WIN32_HAVE_WIDECHAR_API ())
{
/* Conversion failed, so convert to wide chars, check if there
* is a 8.3 version, and use that.
*/
wchar_t *wname = g_utf8_to_utf16 (utf8filename, -1, NULL, NULL, NULL);
if (wname != NULL)
{
wchar_t wshortname[MAX_PATH + 1];
if (GetShortPathNameW (wname, wshortname, G_N_ELEMENTS (wshortname)))
{
gchar *tem = g_utf16_to_utf8 (wshortname, -1, NULL, NULL, NULL);
retval = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL);
g_free (tem);
}
g_free (wname);
}
}
return retval;
}
#define __G_WIN32_C__
#include "galiasdef.c"

View File

@ -91,6 +91,8 @@ gchar* g_win32_get_package_installation_subdirectory (gchar *package,
guint g_win32_get_windows_version (void);
gchar* g_win32_locale_filename_from_utf8 (const gchar *utf8filename);
#define G_WIN32_IS_NT_BASED() (g_win32_get_windows_version () < 0x80000000)
#define G_WIN32_HAVE_WIDECHAR_API() (G_WIN32_IS_NT_BASED ())