diff options
Diffstat (limited to 'lib/localcharset.c')
-rw-r--r-- | lib/localcharset.c | 81 |
1 files changed, 61 insertions, 20 deletions
diff --git a/lib/localcharset.c b/lib/localcharset.c index d03ab79d0..cd44ca658 100644 --- a/lib/localcharset.c +++ b/lib/localcharset.c @@ -25,23 +25,13 @@ /* Specification. */ #include "localcharset.h" -#if HAVE_STDDEF_H -# include <stddef.h> -#endif - +#include <stddef.h> #include <stdio.h> -#if HAVE_STRING_H -# include <string.h> -#else -# include <strings.h> -#endif -#if HAVE_STDLIB_H -# include <stdlib.h> -#endif +#include <string.h> +#include <stdlib.h> #if defined _WIN32 || defined __WIN32__ -# undef WIN32 /* avoid warning on mingw32 */ -# define WIN32 +# define WIN32_NATIVE #endif #if defined __EMX__ @@ -49,7 +39,7 @@ # define OS2 #endif -#if !defined WIN32 +#if !defined WIN32_NATIVE # if HAVE_LANGINFO_CODESET # include <langinfo.h> # else @@ -57,7 +47,11 @@ # include <locale.h> # endif # endif -#elif defined WIN32 +# ifdef __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +# endif +#elif defined WIN32_NATIVE # define WIN32_LEAN_AND_MEAN # include <windows.h> #endif @@ -113,7 +107,7 @@ get_charset_aliases (void) cp = charset_aliases; if (cp == NULL) { -#if !(defined VMS || defined WIN32) +#if !(defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) FILE *fp; const char *dir; const char *base = "charset.alias"; @@ -239,7 +233,7 @@ get_charset_aliases (void) "DECKOREAN" "\0" "EUC-KR" "\0"; # endif -# if defined WIN32 +# if defined WIN32_NATIVE || defined __CYGWIN__ /* 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. */ @@ -291,13 +285,60 @@ locale_charset (void) const char *codeset; const char *aliases; -#if !(defined WIN32 || defined OS2) +#if !(defined WIN32_NATIVE || defined OS2) # if HAVE_LANGINFO_CODESET /* Most systems support nl_langinfo (CODESET) nowadays. */ codeset = nl_langinfo (CODESET); +# ifdef __CYGWIN__ + /* Cygwin 2006 does not have locales. nl_langinfo (CODESET) always + returns "US-ASCII". As long as this is not fixed, return the suffix + of the locale name from the environment variables (if present) or + the codepage as a number. */ + if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0) + { + const char *locale; + static char buf[2 + 10 + 1]; + + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + if (locale != NULL && locale[0] != '\0') + { + /* If the locale name contains an encoding after the dot, return + it. */ + const char *dot = strchr (locale, '.'); + + if (dot != NULL) + { + const char *modifier; + + dot++; + /* Look for the possible @... trailer and remove it, if any. */ + modifier = strchr (dot, '@'); + if (modifier == NULL) + return dot; + if (modifier - dot < sizeof (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + } + + /* Woe32 has a function returning the locale's codepage as a number. */ + sprintf (buf, "CP%u", GetACP ()); + codeset = buf; + } +# endif + # else /* On old systems which lack it, use setlocale or getenv. */ @@ -328,7 +369,7 @@ locale_charset (void) # endif -#elif defined WIN32 +#elif defined WIN32_NATIVE static char buf[2 + 10 + 1]; |