X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Flocalcharset.c;h=936d93d84caa2c8d12fa5db130d69d75d2c468a8;hb=aaea9d07f672ec45a4687a5e99c3994ef41d4491;hp=86f7ed1b2e09ba35cfad1de6e47ccc7155352952;hpb=8f36ae9ded052371bd995708ab1f587db5c0f3bc;p=gnulib.git diff --git a/lib/localcharset.c b/lib/localcharset.c index 86f7ed1b2..936d93d84 100644 --- a/lib/localcharset.c +++ b/lib/localcharset.c @@ -37,18 +37,31 @@ # include #endif -#if HAVE_LANGINFO_CODESET -# include -#else -# if HAVE_SETLOCALE -# include +#if defined _WIN32 || defined __WIN32__ +# undef WIN32 /* avoid warning on mingw32 */ +# define WIN32 +#endif + +#ifndef WIN32 +# if HAVE_LANGINFO_CODESET +# include +# else +# if HAVE_SETLOCALE +# include +# endif # endif +#else /* WIN32 */ +# define WIN32_LEAN_AND_MEAN +# include #endif -#include "path-concat.h" +#ifndef DIRECTORY_SEPARATOR +# define DIRECTORY_SEPARATOR '/' +#endif -char *xmalloc (); -char *xrealloc (); +#ifndef ISSLASH +# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) +#endif /* The following static variable is declared 'volatile' to avoid a possible multithread problem in the function get_charset_aliases. If we @@ -70,8 +83,26 @@ get_charset_aliases () cp = charset_aliases; if (cp == NULL) { +#ifndef WIN32 FILE *fp; - char *file_name = path_concat (LIBDIR, "charset.alias", NULL); + const char *dir = LIBDIR; + const char *base = "charset.alias"; + char *file_name; + + /* Concatenate dir and base into freshly allocated file_name. */ + { + size_t dir_len = strlen (dir); + size_t base_len = strlen (base); + int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); + file_name = (char *) malloc (dir_len + add_slash + base_len + 1); + if (file_name != NULL) + { + memcpy (file_name, dir, dir_len); + if (add_slash) + file_name[dir_len] = DIRECTORY_SEPARATOR; + memcpy (file_name + dir_len + add_slash, base, base_len + 1); + } + } if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL) /* Out of memory or file not found, treat it as empty. */ @@ -111,12 +142,18 @@ get_charset_aliases () if (res_size == 0) { res_size = l1 + 1 + l2 + 1; - res_ptr = xmalloc (res_size + 1); + res_ptr = malloc (res_size + 1); } else { res_size += l1 + 1 + l2 + 1; - res_ptr = xrealloc (res_ptr, res_size + 1); + res_ptr = realloc (res_ptr, res_size + 1); + } + if (res_ptr == NULL) + { + /* Out of memory. */ + res_size = 0; + break; } strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); strcpy (res_ptr + res_size - (l2 + 1), buf2); @@ -131,8 +168,20 @@ get_charset_aliases () } } + if (file_name != NULL) + free (file_name); + +#else /* WIN32 */ + + /* To avoid the troubles of installing a separate file in the same + directory as the DLL and of retrieving the DLL's directory at + runtime, simply inline the aliases here. */ + + cp = "CP936" "\0" "GBK" "\0" + "CP1361" "\0" "JOHAB" "\0"; +#endif + charset_aliases = cp; - free (file_name); } return cp; @@ -153,26 +202,28 @@ locale_charset () const char *codeset; const char *aliases; -#if HAVE_LANGINFO_CODESET +#ifndef WIN32 + +# if HAVE_LANGINFO_CODESET /* Most systems support nl_langinfo (CODESET) nowadays. */ codeset = nl_langinfo (CODESET); -#else +# else /* On old systems which lack it, use setlocale and getenv. */ const char *locale = NULL; -# if HAVE_SETLOCALE +# if HAVE_SETLOCALE locale = setlocale (LC_CTYPE, NULL); -# endif - if (locale == NULL) +# endif + if (locale == NULL || locale[0] == '\0') { locale = getenv ("LC_ALL"); - if (locale == NULL) + if (locale == NULL || locale[0] == '\0') { locale = getenv ("LC_CTYPE"); - if (locale == NULL) + if (locale == NULL || locale[0] == '\0') locale = getenv ("LANG"); } } @@ -182,9 +233,19 @@ locale_charset () through the charset.alias file. */ codeset = locale; +# endif + +#else /* WIN32 */ + + static char buf[2 + 10 + 1]; + + /* Win32 has a function returning the locale's codepage as a number. */ + sprintf (buf, "CP%u", GetACP ()); + codeset = buf; + #endif - if (codeset != NULL) + if (codeset != NULL && codeset[0] != '\0') { /* Resolve alias. */ for (aliases = get_charset_aliases ();