예제 #1
0
파일: localcharset.c 프로젝트: WndSks/msys
STATIC
#endif
const char *
locale_charset ()
{
  const char *codeset;
  const char *aliases;

#ifndef WIN32

# if HAVE_LANGINFO_CODESET

  /* Most systems support nl_langinfo (CODESET) nowadays.  */
  codeset = nl_langinfo (CODESET);

# else

  /* On old systems which lack it, use setlocale or getenv.  */
  const char *locale = NULL;

  /* But most old systems don't have a complete set of locales.  Some
     (like SunOS 4 or DJGPP) have only the C locale.  Therefore we don't
     use setlocale here; it would return "C" when it doesn't support the
     locale name the user has set.  */
#  if HAVE_SETLOCALE && 0
  locale = setlocale (LC_CTYPE, NULL);
#  endif
  if (locale == NULL || locale[0] == '\0')
    {
      locale = getenv ("LC_ALL");
      if (locale == NULL || locale[0] == '\0')
	{
	  locale = getenv ("LC_CTYPE");
	  if (locale == NULL || locale[0] == '\0')
	    locale = getenv ("LANG");
	}
    }

  /* On some old systems, one used to set locale = "iso8859_1". On others,
     you set it to "language_COUNTRY.charset". In any case, we resolve it
     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)
    /* The canonical name cannot be determined.  */
    codeset = "";

  /* Resolve alias. */
  for (aliases = get_charset_aliases ();
       *aliases != '\0';
       aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
    if (strcmp (codeset, aliases) == 0
	|| (aliases[0] == '*' && aliases[1] == '\0'))
      {
	codeset = aliases + strlen (aliases) + 1;
	break;
      }

  return codeset;
}
예제 #2
0
STATIC
#endif
const char *
locale_charset (void)
{
  const char *codeset;
  const char *aliases;

#if !(defined WINDOWS_NATIVE || defined OS2)

# if HAVE_LANGINFO_CODESET

  /* Most systems support nl_langinfo (CODESET) nowadays.  */
  codeset = nl_langinfo (CODESET);

#  ifdef __CYGWIN__
  /* Cygwin < 1.7 does not have locales.  nl_langinfo (CODESET) always
     returns "US-ASCII".  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:
         GetACP().  This encoding is used by Cygwin, unless the user has set
         the environment variable CYGWIN=codepage:oem (which very few people
         do).
         Output directed to console windows needs to be converted (to
         GetOEMCP() if the console is using a raster font, or to
         GetConsoleOutputCP() if it is using a TrueType font).  Cygwin does
         this conversion transparently (see winsup/cygwin/fhandler_console.cc),
         converting to GetConsoleOutputCP().  This leads to correct results,
         except when SetConsoleOutputCP has been called and a raster font is
         in use.  */
      sprintf (buf, "CP%u", GetACP ());
      codeset = buf;
    }
#  endif

# else

  /* On old systems which lack it, use setlocale or getenv.  */
  const char *locale = NULL;

  /* But most old systems don't have a complete set of locales.  Some
     (like SunOS 4 or DJGPP) have only the C locale.  Therefore we don't
     use setlocale here; it would return "C" when it doesn't support the
     locale name the user has set.  */
#  if 0
  locale = setlocale (LC_CTYPE, NULL);
#  endif
  if (locale == NULL || locale[0] == '\0')
    {
      locale = getenv ("LC_ALL");
      if (locale == NULL || locale[0] == '\0')
        {
          locale = getenv ("LC_CTYPE");
          if (locale == NULL || locale[0] == '\0')
            locale = getenv ("LANG");
        }
    }

  /* On some old systems, one used to set locale = "iso8859_1". On others,
     you set it to "language_COUNTRY.charset". In any case, we resolve it
     through the charset.alias file.  */
  codeset = locale;

# endif

#elif defined WINDOWS_NATIVE

  static char buf[2 + 10 + 1];

  /* Woe32 has a function returning the locale's codepage as a number:
     GetACP().
     When the output goes to a console window, it needs to be provided in
     GetOEMCP() encoding if the console is using a raster font, or in
     GetConsoleOutputCP() encoding if it is using a TrueType font.
     But in GUI programs and for output sent to files and pipes, GetACP()
     encoding is the best bet.  */
  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)
    /* The canonical name cannot be determined.  */
    codeset = "";

  /* Resolve alias. */
  for (aliases = get_charset_aliases ();
       *aliases != '\0';
       aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
    if (strcmp (codeset, aliases) == 0
        || (aliases[0] == '*' && aliases[1] == '\0'))
      {
        codeset = aliases + strlen (aliases) + 1;
        break;
      }

  /* Don't return an empty string.  GNU libc and GNU libiconv interpret
     the empty string as denoting "the locale's character encoding",
     thus GNU libiconv would call this function a second time.  */
  if (codeset[0] == '\0')
    codeset = "ASCII";

  return codeset;
}
예제 #3
0
STATIC
#endif
const char *
locale_charset (void)
{
  const char *codeset;
  const char *aliases;

  /* Force output encoding, particularly useful for redirected output on win32
     where charset detection fails when no actual console is attached. */
  const char *forced_encoding = getenv("GETTEXTIOENCODING");
  if (forced_encoding)
      return forced_encoding;

#if !(defined WINDOWS_NATIVE || defined OS2)

# if HAVE_LANGINFO_CODESET

  /* Most systems support nl_langinfo (CODESET) nowadays.  */
  codeset = nl_langinfo (CODESET);

#  ifdef __CYGWIN__
  /* Cygwin < 1.7 does not have locales.  nl_langinfo (CODESET) always
     returns "US-ASCII".  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;
                }
            }
        }

      /* The Windows API has a function returning the locale's codepage as a
         number: GetACP().  This encoding is used by Cygwin, unless the user
         has set the environment variable CYGWIN=codepage:oem (which very few
         people do).
         Output directed to console windows needs to be converted (to
         GetOEMCP() if the console is using a raster font, or to
         GetConsoleOutputCP() if it is using a TrueType font).  Cygwin does
         this conversion transparently (see winsup/cygwin/fhandler_console.cc),
         converting to GetConsoleOutputCP().  This leads to correct results,
         except when SetConsoleOutputCP has been called and a raster font is
         in use.  */
      sprintf (buf, "CP%u", GetACP ());
      codeset = buf;
    }
#  endif

# else

  /* On old systems which lack it, use setlocale or getenv.  */
  const char *locale = NULL;

  /* But most old systems don't have a complete set of locales.  Some
     (like SunOS 4 or DJGPP) have only the C locale.  Therefore we don't
     use setlocale here; it would return "C" when it doesn't support the
     locale name the user has set.  */
#  if 0
  locale = setlocale (LC_CTYPE, NULL);
#  endif
  if (locale == NULL || locale[0] == '\0')
    {
      locale = getenv ("LC_ALL");
      if (locale == NULL || locale[0] == '\0')
        {
          locale = getenv ("LC_CTYPE");
          if (locale == NULL || locale[0] == '\0')
            locale = getenv ("LANG");
        }
    }

  /* On some old systems, one used to set locale = "iso8859_1". On others,
     you set it to "language_COUNTRY.charset". In any case, we resolve it
     through the charset.alias file.  */
  codeset = locale;

# endif

#elif defined WINDOWS_NATIVE

  static char buf[2 + 10 + 1];

  /* The Windows API has a function returning the locale's codepage as
     a number, but the value doesn't change according to what the
     'setlocale' call specified.  So we use it as a last resort, in
     case the string returned by 'setlocale' doesn't specify the
     codepage.  */
  char *current_locale = setlocale (LC_ALL, NULL);
  char *pdot;

  /* If they set different locales for different categories,
     'setlocale' will return a semi-colon separated list of locale
     values.  To make sure we use the correct one, we choose LC_CTYPE.  */
  if (strchr (current_locale, ';'))
    current_locale = setlocale (LC_CTYPE, NULL);

  pdot = strrchr (current_locale, '.');
  if (pdot)
    sprintf (buf, "CP%s", pdot + 1);
  else
    {
      /* The Windows API has a function returning the locale's codepage as a
        number: GetACP().
        When the output goes to a console window, it needs to be provided in
        GetOEMCP() encoding if the console is using a raster font, or in
        GetConsoleOutputCP() encoding if it is using a TrueType font.
        But in GUI programs and for output sent to files and pipes, GetACP()
        encoding is the best bet.  */
      sprintf (buf, "CP%u", GetACP ());
    }
  codeset = buf;

#elif defined OS2

  const char *locale;
  static char buf[2 + 10 + 1];
  ULONG cp[3];
  ULONG cplen;

  codeset = NULL;

  /* 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;
            }
        }

      /* For the POSIX locale, don't use the system's codepage.  */
      if (strcmp (locale, "C") == 0 || strcmp (locale, "POSIX") == 0)
        codeset = "";
    }

  if (codeset == NULL)
    {
      /* 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)
    /* The canonical name cannot be determined.  */
    codeset = "";

  /* Resolve alias. */
  for (aliases = get_charset_aliases ();
       *aliases != '\0';
       aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
    if (strcmp (codeset, aliases) == 0
        || (aliases[0] == '*' && aliases[1] == '\0'))
      {
        codeset = aliases + strlen (aliases) + 1;
        break;
      }

  /* Don't return an empty string.  GNU libc and GNU libiconv interpret
     the empty string as denoting "the locale's character encoding",
     thus GNU libiconv would call this function a second time.  */
  if (codeset[0] == '\0')
    codeset = "ASCII";

#ifdef DARWIN7
  /* Mac OS X sets MB_CUR_MAX to 1 when LC_ALL=C, and "UTF-8"
     (the default codeset) does not work when MB_CUR_MAX is 1.  */
  if (strcmp (codeset, "UTF-8") == 0 && MB_CUR_MAX_L (uselocale (NULL)) <= 1)
    codeset = "ASCII";
#endif

  return codeset;
}
예제 #4
0
STATIC
#endif
const char *
locale_charset (void)
{
  const char *codeset;
  const char *aliases;

#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.  */
  const char *locale = NULL;

  /* But most old systems don't have a complete set of locales.  Some
     (like SunOS 4 or DJGPP) have only the C locale.  Therefore we don't
     use setlocale here; it would return "C" when it doesn't support the
     locale name the user has set.  */
#  if 0
  locale = setlocale (LC_CTYPE, NULL);
#  endif
  if (locale == NULL || locale[0] == '\0')
    {
      locale = getenv ("LC_ALL");
      if (locale == NULL || locale[0] == '\0')
	{
	  locale = getenv ("LC_CTYPE");
	  if (locale == NULL || locale[0] == '\0')
	    locale = getenv ("LANG");
	}
    }

  /* On some old systems, one used to set locale = "iso8859_1". On others,
     you set it to "language_COUNTRY.charset". In any case, we resolve it
     through the charset.alias file.  */
  codeset = locale;

# endif

#elif defined WIN32_NATIVE

  //static char buf[2 + 10 + 1];

  /* Woe32 has a function returning the locale's codepage as a number.  */
  //sprintf (buf, "CP%u", GetACP ());
  codeset = "CP20127";

#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)
    /* The canonical name cannot be determined.  */
    codeset = "";

  /* Resolve alias. */
  for (aliases = get_charset_aliases ();
       *aliases != '\0';
       aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
    if (strcmp (codeset, aliases) == 0
	|| (aliases[0] == '*' && aliases[1] == '\0'))
      {
	codeset = aliases + strlen (aliases) + 1;
	break;
      }

  /* Don't return an empty string.  GNU libc and GNU libiconv interpret
     the empty string as denoting "the locale's character encoding",
     thus GNU libiconv would call this function a second time.  */
  if (codeset[0] == '\0')
    codeset = "ASCII";

  return codeset;
}
예제 #5
0
STATIC
#endif
const char *
locale_charset ()
{
  const char *codeset;
  const char *aliases;

#if !(defined WIN32 || defined OS2)

# if HAVE_LANGINFO_CODESET

  
  codeset = nl_langinfo (CODESET);

# else

  
  const char *locale = NULL;

#  if HAVE_SETLOCALE && 0
  locale = setlocale (LC_CTYPE, NULL);
#  endif
  if (locale == NULL || locale[0] == '\0')
    {
      locale = getenv ("LC_ALL");
      if (locale == NULL || locale[0] == '\0')
	{
	  locale = getenv ("LC_CTYPE");
	  if (locale == NULL || locale[0] == '\0')
	    locale = getenv ("LANG");
	}
    }

  codeset = locale;

# endif

#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;

  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')
    {
      
      const char *dot = strchr (locale, '.');

      if (dot != NULL)
	{
	  const char *modifier;

	  dot++;
	  
	  modifier = strchr (dot, '@');
	  if (modifier == NULL)
	    return dot;
	  if (modifier - dot < sizeof (buf))
	    {
	      memcpy (buf, dot, modifier - dot);
	      buf [modifier - dot] = '\0';
	      return buf;
	    }
	}

      
      codeset = locale;
    }
  else
    {
      
      if (DosQueryCp (sizeof (cp), cp, &cplen))
	codeset = "";
      else
	{
	  sprintf (buf, "CP%u", cp[0]);
	  codeset = buf;
	}
    }

#endif

  if (codeset == NULL)
    
    codeset = "";

  
  for (aliases = get_charset_aliases ();
       *aliases != '\0';
       aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
    if (strcmp (codeset, aliases) == 0
	|| (aliases[0] == '*' && aliases[1] == '\0'))
      {
	codeset = aliases + strlen (aliases) + 1;
	break;
      }

  if (codeset[0] == '\0')
    codeset = "ASCII";

  return codeset;
}
예제 #6
0
STATIC
#endif
const char *
locale_charset ()
{
  const char *codeset;
  const char *aliases;

#ifndef WIN32

# if HAVE_LANGINFO_CODESET

  /* Most systems support nl_langinfo (CODESET) nowadays.  */
  codeset = nl_langinfo (CODESET);

# else

  /* On old systems which lack it, use setlocale and getenv.  */
  const char *locale = NULL;

#  if HAVE_SETLOCALE
  locale = setlocale (LC_CTYPE, NULL);
#  endif
  if (locale == NULL || locale[0] == '\0')
    {
      locale = getenv ("LC_ALL");
      if (locale == NULL || locale[0] == '\0')
	{
	  locale = getenv ("LC_CTYPE");
	  if (locale == NULL || locale[0] == '\0')
	    locale = getenv ("LANG");
	}
    }

  /* On some old systems, one used to set locale = "iso8859_1". On others,
     you set it to "language_COUNTRY.charset". In any case, we resolve it
     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 && codeset[0] != '\0')
    {
      /* Resolve alias. */
      for (aliases = get_charset_aliases ();
	   *aliases != '\0';
	   aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
	if (!strcmp (codeset, aliases))
	  {
	    codeset = aliases + strlen (aliases) + 1;
	    break;
	  }
    }

  return codeset;
}
예제 #7
0
STATIC
#endif /* STATIC */
const char *
locale_charset(void)
{
  const char *codeset;
  const char *aliases;

#if !(defined WINDOWS_NATIVE || defined OS2)
# if HAVE_LANGINFO_CODESET && defined(HAVE_NL_LANGINFO)
  /* Most systems support nl_langinfo(CODESET) nowadays.  */
  codeset = nl_langinfo(CODESET);

#  ifdef __CYGWIN__
  /* Cygwin < 1.7 does not have locales.  nl_langinfo(CODESET) always
   * returns "US-ASCII".  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)]; /* why not just 13? */

      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, then 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;
			  }
		  }
	  }

      /* The Windows API has a function returning the locale's codepage as a
       * number: GetACP().  This encoding is used by Cygwin, unless the user
       * has set the environment variable CYGWIN=codepage:oem (which very few
       * people do).
       * Output directed to console windows needs to be converted (to
       * GetOEMCP() if the console is using a raster font, or to
       * GetConsoleOutputCP() if it is using a TrueType font).  Cygwin does
       * this conversion transparently (see winsup/cygwin/fhandler_console.cc),
       * converting to GetConsoleOutputCP().  This leads to correct results,
       * except when SetConsoleOutputCP has been called and a raster font is
       * in use.  */
      sprintf(buf, "CP%u", GetACP());
      codeset = buf;
  }
#  endif /* __CYGWIN__ */
# else /* !HAVE_LANGINFO_CODESET || !HAVE_NL_LANGINFO: */
  /* On old systems which lack it, use setlocale or getenv.  */
  const char *locale = NULL;

  /* But most old systems do NOT have a complete set of locales. Some
   * (like SunOS 4 or DJGPP) have only the C locale. Therefore we do NOT
   * use setlocale here; it would return "C" when it does NOT support the
   * locale name the user has set. */
  /* (I tried to make the ifdef here more closely follow the comment; to return
   * to the original behavior, change the "|| 0" to "&& 0") */
#  if (defined(LC_CTYPE) && defined(HAVE_SETLOCALE) && !defined(__DJGPP__) && !defined(__sun)) || 0
#   if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#    warning "using setlocale() in an instance where it may still be incomplete"
#   endif /* __GNUC__ && !__STRICT_ANSI__ */
  locale = setlocale(LC_CTYPE, NULL);
#  endif /* (LC_CTYPE && HAVE_SETLOCALE && !__DJGPP__ && !__sun) || 0 */
  if ((locale == NULL) || (locale[0] == '\0')) {
      locale = getenv("LC_ALL");
      if ((locale == NULL) || (locale[0] == '\0')) {
          locale = getenv("LC_CTYPE");
          if ((locale == NULL) || (locale[0] == '\0')) {
			  locale = getenv("LANG");
		  }
	  }
  }

  /* On some old systems, one used to set locale = "iso8859_1". On others,
   * you set it to "language_COUNTRY.charset". In any case, we resolve it
   * through the charset.alias file.  */
  codeset = locale;

# endif /* HAVE_LANGINFO_CODESET && HAVE_NL_LANGINFO */
#elif defined WINDOWS_NATIVE
  static char buf[(2 + 10 + 1)];

  /* The Windows API has a function returning the locale's codepage as a
   * number: GetACP().
   * When the output goes to a console window, it needs to be provided in
   * GetOEMCP() encoding if the console is using a raster font, or in
   * GetConsoleOutputCP() encoding if it is using a TrueType font.
   * But in GUI programs and for output sent to files and pipes, GetACP()
   * encoding is the best bet.  */
  sprintf(buf, "CP%u", GetACP());
  codeset = buf;
  /* ...and that should be all we need on Windows! */
#elif defined OS2
  /* things are a little more complicated on 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, so
	   * use it here: */
      if (DosQueryCp(sizeof(cp), cp, &cplen)) {
		  codeset = "";
      } else {
          sprintf(buf, "CP%u", cp[0]);
          codeset = buf;
	  }
  }
  /* end OS2-specific code */
#endif /* !(WINDOWS_NATIVE || OS2) */
  /* back to code generic to all platforms: */
  if (codeset == NULL) {
	  /* If we are here, then the canonical name cannot be determined. */
	  codeset = "";
  }

  /* Resolve alias: */
  for ((aliases = get_charset_aliases());
       (*aliases != '\0');
       (aliases += (strlen(aliases) + 1)), (aliases += (strlen(aliases) + 1))) {
	  if ((strcmp(codeset, aliases) == 0)
		  || ((aliases[0] == '*') && (aliases[1] == '\0'))) {
		  codeset = (aliases + strlen(aliases) + 1);
		  break;
	  }
  }

  /* Do NOT return an empty string. GNU libc and GNU libiconv interpret
   * the empty string as denoting "the locale's character encoding",
   * thus GNU libiconv would call this function a second time.  */
  if (codeset[0] == '\0') {
	  codeset = "ASCII";
  }

  return codeset;
}