/* Determine a canonical name for the current locale's character encoding.
- Copyright (C) 2000-2001 Free Software Foundation, Inc.
+ Copyright (C) 2000-2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published
# define WIN32
#endif
-#ifndef WIN32
+#if defined __EMX__
+/* Assume EMX program runs on OS/2, even if compiled under DOS. */
+# define OS2
+#endif
+
+#if !defined WIN32
# if HAVE_LANGINFO_CODESET
# include <langinfo.h>
# else
# include <locale.h>
# endif
# endif
-#else /* WIN32 */
+#elif defined WIN32
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
+#if defined OS2
+# define INCL_DOS
+# include <os2.h>
+#endif
+
+#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
+ /* Win32, OS/2, DOS */
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+#endif
#ifndef DIRECTORY_SEPARATOR
# define DIRECTORY_SEPARATOR '/'
# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
#endif
+#ifdef HAVE_GETC_UNLOCKED
+# undef getc
+# define getc getc_unlocked
+#endif
+
/* The following static variable is declared 'volatile' to avoid a
possible multithread problem in the function get_charset_aliases. If we
are running in a threaded environment, and if two threads initialize
cp = charset_aliases;
if (cp == NULL)
{
-#ifndef WIN32
+#if !defined WIN32
FILE *fp;
const char *dir = LIBDIR;
const char *base = "charset.alias";
continue;
}
ungetc (c, fp);
- if (fscanf(fp, "%50s %50s", buf1, buf2) < 2)
+ if (fscanf (fp, "%50s %50s", buf1, buf2) < 2)
break;
l1 = strlen (buf1);
l2 = strlen (buf2);
if (res_size == 0)
{
res_size = l1 + 1 + l2 + 1;
- res_ptr = malloc (res_size + 1);
+ res_ptr = (char *) malloc (res_size + 1);
}
else
{
res_size += l1 + 1 + l2 + 1;
- res_ptr = realloc (res_ptr, res_size + 1);
+ res_ptr = (char *) realloc (res_ptr, res_size + 1);
}
if (res_ptr == NULL)
{
if (file_name != NULL)
free (file_name);
-#else /* WIN32 */
+#else
/* 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. */
+# if defined WIN32
cp = "CP936" "\0" "GBK" "\0"
"CP1361" "\0" "JOHAB" "\0";
+# endif
#endif
charset_aliases = cp;
const char *codeset;
const char *aliases;
-#ifndef WIN32
+#if !(defined WIN32 || defined OS2)
# if HAVE_LANGINFO_CODESET
# endif
-#else /* WIN32 */
+#elif defined WIN32
static char buf[2 + 10 + 1];
sprintf (buf, "CP%u", GetACP ());
codeset = buf;
+#elif defined OS2
+
+ const char *locale;
+ static char buf[2 + 10 + 1];
+ ULONG cp[3];
+ ULONG cplen;
+
+ /* Allow user to override the codeset, as set in the operating system,
+ with standard language environment variables. */
+ 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;
+ }
+ }
+
+ /* Resolve through the charset.alias file. */
+ codeset = locale;
+ }
+ else
+ {
+ /* OS/2 has a function returning the locale's codepage as a number. */
+ if (DosQueryCp (sizeof (cp), cp, &cplen))
+ codeset = "";
+ else
+ {
+ sprintf (buf, "CP%u", cp[0]);
+ codeset = buf;
+ }
+ }
+
#endif
if (codeset == NULL)