version 1.1, 2012/02/21 22:57:48
|
version 1.1.1.2, 2012/05/29 09:29:42
|
Line 1
|
Line 1
|
/* Determine a canonical name for the current locale's character encoding. |
/* Determine a canonical name for the current locale's character encoding. |
|
|
Copyright (C) 2000-2006, 2008-2009 Free Software Foundation, Inc. | Copyright (C) 2000-2006, 2008-2010 Free Software Foundation, Inc. |
|
|
This program is free software; you can redistribute it and/or modify it |
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 |
under the terms of the GNU Library General Public License as published |
Line 24
|
Line 24
|
/* Specification. */ |
/* Specification. */ |
#include "localcharset.h" |
#include "localcharset.h" |
|
|
|
#include <fcntl.h> |
#include <stddef.h> |
#include <stddef.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <string.h> |
#include <string.h> |
Line 45
|
Line 46
|
#endif |
#endif |
|
|
#if !defined WIN32_NATIVE |
#if !defined WIN32_NATIVE |
|
# include <unistd.h> |
# if HAVE_LANGINFO_CODESET |
# if HAVE_LANGINFO_CODESET |
# include <langinfo.h> |
# include <langinfo.h> |
# else |
# else |
Line 76
|
Line 78
|
# include "configmake.h" |
# include "configmake.h" |
#endif |
#endif |
|
|
|
/* Define O_NOFOLLOW to 0 on platforms where it does not exist. */ |
|
#ifndef O_NOFOLLOW |
|
# define O_NOFOLLOW 0 |
|
#endif |
|
|
#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ |
#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ |
/* Win32, Cygwin, OS/2, DOS */ |
/* Win32, Cygwin, OS/2, DOS */ |
# define ISSLASH(C) ((C) == '/' || (C) == '\\') |
# define ISSLASH(C) ((C) == '/' || (C) == '\\') |
Line 118 get_charset_aliases (void)
|
Line 125 get_charset_aliases (void)
|
if (cp == NULL) |
if (cp == NULL) |
{ |
{ |
#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) |
#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) |
FILE *fp; |
|
const char *dir; |
const char *dir; |
const char *base = "charset.alias"; |
const char *base = "charset.alias"; |
char *file_name; |
char *file_name; |
|
|
/* Make it possible to override the charset.alias location. This is |
/* Make it possible to override the charset.alias location. This is |
necessary for running the testsuite before "make install". */ | necessary for running the testsuite before "make install". */ |
dir = getenv ("CHARSETALIASDIR"); |
dir = getenv ("CHARSETALIASDIR"); |
if (dir == NULL || dir[0] == '\0') |
if (dir == NULL || dir[0] == '\0') |
dir = relocate (LIBDIR); | dir = relocate (LIBDIR); |
|
|
/* Concatenate dir and base into freshly allocated file_name. */ |
/* Concatenate dir and base into freshly allocated file_name. */ |
{ |
{ |
size_t dir_len = strlen (dir); | size_t dir_len = strlen (dir); |
size_t base_len = strlen (base); | size_t base_len = strlen (base); |
int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); | int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); |
file_name = (char *) malloc (dir_len + add_slash + base_len + 1); | file_name = (char *) malloc (dir_len + add_slash + base_len + 1); |
if (file_name != NULL) | if (file_name != NULL) |
{ | { |
memcpy (file_name, dir, dir_len); | memcpy (file_name, dir, dir_len); |
if (add_slash) | if (add_slash) |
file_name[dir_len] = DIRECTORY_SEPARATOR; | file_name[dir_len] = DIRECTORY_SEPARATOR; |
memcpy (file_name + dir_len + add_slash, base, base_len + 1); | memcpy (file_name + dir_len + add_slash, base, base_len + 1); |
} | } |
} |
} |
|
|
if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL) | if (file_name == NULL) |
/* Out of memory or file not found, treat it as empty. */ | /* Out of memory. Treat the file as empty. */ |
cp = ""; | cp = ""; |
else |
else |
{ | { |
/* Parse the file's contents. */ | int fd; |
char *res_ptr = NULL; | |
size_t res_size = 0; | |
|
|
for (;;) | /* Open the file. Reject symbolic links on platforms that support |
{ | O_NOFOLLOW. This is a security feature. Without it, an attacker |
int c; | could retrieve parts of the contents (namely, the tail of the |
char buf1[50+1]; | first line that starts with "* ") of an arbitrary file by placing |
char buf2[50+1]; | a symbolic link to that file under the name "charset.alias" in |
size_t l1, l2; | some writable directory and defining the environment variable |
char *old_res_ptr; | CHARSETALIASDIR to point to that directory. */ |
| fd = open (file_name, |
| O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0)); |
| if (fd < 0) |
| /* File not found. Treat it as empty. */ |
| cp = ""; |
| else |
| { |
| FILE *fp; |
|
|
c = getc (fp); | fp = fdopen (fd, "r"); |
if (c == EOF) | if (fp == NULL) |
break; | { |
if (c == '\n' || c == ' ' || c == '\t') | /* Out of memory. Treat the file as empty. */ |
continue; | close (fd); |
if (c == '#') | cp = ""; |
{ | } |
/* Skip comment, to end of line. */ | else |
do | { |
c = getc (fp); | /* Parse the file's contents. */ |
while (!(c == EOF || c == '\n')); | char *res_ptr = NULL; |
if (c == EOF) | size_t res_size = 0; |
break; | |
continue; | |
} | |
ungetc (c, fp); | |
if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) | |
break; | |
l1 = strlen (buf1); | |
l2 = strlen (buf2); | |
old_res_ptr = res_ptr; | |
if (res_size == 0) | |
{ | |
res_size = l1 + 1 + l2 + 1; | |
res_ptr = (char *) malloc (res_size + 1); | |
} | |
else | |
{ | |
res_size += l1 + 1 + l2 + 1; | |
res_ptr = (char *) realloc (res_ptr, res_size + 1); | |
} | |
if (res_ptr == NULL) | |
{ | |
/* Out of memory. */ | |
res_size = 0; | |
if (old_res_ptr != NULL) | |
free (old_res_ptr); | |
break; | |
} | |
strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); | |
strcpy (res_ptr + res_size - (l2 + 1), buf2); | |
} | |
fclose (fp); | |
if (res_size == 0) | |
cp = ""; | |
else | |
{ | |
*(res_ptr + res_size) = '\0'; | |
cp = res_ptr; | |
} | |
} | |
|
|
if (file_name != NULL) | for (;;) |
free (file_name); | { |
| int c; |
| char buf1[50+1]; |
| char buf2[50+1]; |
| size_t l1, l2; |
| char *old_res_ptr; |
|
|
|
c = getc (fp); |
|
if (c == EOF) |
|
break; |
|
if (c == '\n' || c == ' ' || c == '\t') |
|
continue; |
|
if (c == '#') |
|
{ |
|
/* Skip comment, to end of line. */ |
|
do |
|
c = getc (fp); |
|
while (!(c == EOF || c == '\n')); |
|
if (c == EOF) |
|
break; |
|
continue; |
|
} |
|
ungetc (c, fp); |
|
if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) |
|
break; |
|
l1 = strlen (buf1); |
|
l2 = strlen (buf2); |
|
old_res_ptr = res_ptr; |
|
if (res_size == 0) |
|
{ |
|
res_size = l1 + 1 + l2 + 1; |
|
res_ptr = (char *) malloc (res_size + 1); |
|
} |
|
else |
|
{ |
|
res_size += l1 + 1 + l2 + 1; |
|
res_ptr = (char *) realloc (res_ptr, res_size + 1); |
|
} |
|
if (res_ptr == NULL) |
|
{ |
|
/* Out of memory. */ |
|
res_size = 0; |
|
free (old_res_ptr); |
|
break; |
|
} |
|
strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); |
|
strcpy (res_ptr + res_size - (l2 + 1), buf2); |
|
} |
|
fclose (fp); |
|
if (res_size == 0) |
|
cp = ""; |
|
else |
|
{ |
|
*(res_ptr + res_size) = '\0'; |
|
cp = res_ptr; |
|
} |
|
} |
|
} |
|
|
|
free (file_name); |
|
} |
|
|
#else |
#else |
|
|
# if defined DARWIN7 |
# if defined DARWIN7 |
/* To avoid the trouble of installing a file that is shared by many |
/* To avoid the trouble of installing a file that is shared by many |
GNU packages -- many packaging systems have problems with this --, | GNU packages -- many packaging systems have problems with this --, |
simply inline the aliases here. */ | simply inline the aliases here. */ |
cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" |
cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" |
"ISO8859-2" "\0" "ISO-8859-2" "\0" | "ISO8859-2" "\0" "ISO-8859-2" "\0" |
"ISO8859-4" "\0" "ISO-8859-4" "\0" | "ISO8859-4" "\0" "ISO-8859-4" "\0" |
"ISO8859-5" "\0" "ISO-8859-5" "\0" | "ISO8859-5" "\0" "ISO-8859-5" "\0" |
"ISO8859-7" "\0" "ISO-8859-7" "\0" | "ISO8859-7" "\0" "ISO-8859-7" "\0" |
"ISO8859-9" "\0" "ISO-8859-9" "\0" | "ISO8859-9" "\0" "ISO-8859-9" "\0" |
"ISO8859-13" "\0" "ISO-8859-13" "\0" | "ISO8859-13" "\0" "ISO-8859-13" "\0" |
"ISO8859-15" "\0" "ISO-8859-15" "\0" | "ISO8859-15" "\0" "ISO-8859-15" "\0" |
"KOI8-R" "\0" "KOI8-R" "\0" | "KOI8-R" "\0" "KOI8-R" "\0" |
"KOI8-U" "\0" "KOI8-U" "\0" | "KOI8-U" "\0" "KOI8-U" "\0" |
"CP866" "\0" "CP866" "\0" | "CP866" "\0" "CP866" "\0" |
"CP949" "\0" "CP949" "\0" | "CP949" "\0" "CP949" "\0" |
"CP1131" "\0" "CP1131" "\0" | "CP1131" "\0" "CP1131" "\0" |
"CP1251" "\0" "CP1251" "\0" | "CP1251" "\0" "CP1251" "\0" |
"eucCN" "\0" "GB2312" "\0" | "eucCN" "\0" "GB2312" "\0" |
"GB2312" "\0" "GB2312" "\0" | "GB2312" "\0" "GB2312" "\0" |
"eucJP" "\0" "EUC-JP" "\0" | "eucJP" "\0" "EUC-JP" "\0" |
"eucKR" "\0" "EUC-KR" "\0" | "eucKR" "\0" "EUC-KR" "\0" |
"Big5" "\0" "BIG5" "\0" | "Big5" "\0" "BIG5" "\0" |
"Big5HKSCS" "\0" "BIG5-HKSCS" "\0" | "Big5HKSCS" "\0" "BIG5-HKSCS" "\0" |
"GBK" "\0" "GBK" "\0" | "GBK" "\0" "GBK" "\0" |
"GB18030" "\0" "GB18030" "\0" | "GB18030" "\0" "GB18030" "\0" |
"SJIS" "\0" "SHIFT_JIS" "\0" | "SJIS" "\0" "SHIFT_JIS" "\0" |
"ARMSCII-8" "\0" "ARMSCII-8" "\0" | "ARMSCII-8" "\0" "ARMSCII-8" "\0" |
"PT154" "\0" "PT154" "\0" | "PT154" "\0" "PT154" "\0" |
/*"ISCII-DEV" "\0" "?" "\0"*/ | /*"ISCII-DEV" "\0" "?" "\0"*/ |
"*" "\0" "UTF-8" "\0"; | "*" "\0" "UTF-8" "\0"; |
# endif |
# endif |
|
|
# if defined VMS |
# if defined VMS |
/* To avoid the troubles of an extra file charset.alias_vms in the |
/* To avoid the troubles of an extra file charset.alias_vms in the |
sources of many GNU packages, simply inline the aliases here. */ | sources of many GNU packages, simply inline the aliases here. */ |
/* The list of encodings is taken from the OpenVMS 7.3-1 documentation |
/* The list of encodings is taken from the OpenVMS 7.3-1 documentation |
"Compaq C Run-Time Library Reference Manual for OpenVMS systems" | "Compaq C Run-Time Library Reference Manual for OpenVMS systems" |
section 10.7 "Handling Different Character Sets". */ | section 10.7 "Handling Different Character Sets". */ |
cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" |
cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" |
"ISO8859-2" "\0" "ISO-8859-2" "\0" | "ISO8859-2" "\0" "ISO-8859-2" "\0" |
"ISO8859-5" "\0" "ISO-8859-5" "\0" | "ISO8859-5" "\0" "ISO-8859-5" "\0" |
"ISO8859-7" "\0" "ISO-8859-7" "\0" | "ISO8859-7" "\0" "ISO-8859-7" "\0" |
"ISO8859-8" "\0" "ISO-8859-8" "\0" | "ISO8859-8" "\0" "ISO-8859-8" "\0" |
"ISO8859-9" "\0" "ISO-8859-9" "\0" | "ISO8859-9" "\0" "ISO-8859-9" "\0" |
/* Japanese */ | /* Japanese */ |
"eucJP" "\0" "EUC-JP" "\0" | "eucJP" "\0" "EUC-JP" "\0" |
"SJIS" "\0" "SHIFT_JIS" "\0" | "SJIS" "\0" "SHIFT_JIS" "\0" |
"DECKANJI" "\0" "DEC-KANJI" "\0" | "DECKANJI" "\0" "DEC-KANJI" "\0" |
"SDECKANJI" "\0" "EUC-JP" "\0" | "SDECKANJI" "\0" "EUC-JP" "\0" |
/* Chinese */ | /* Chinese */ |
"eucTW" "\0" "EUC-TW" "\0" | "eucTW" "\0" "EUC-TW" "\0" |
"DECHANYU" "\0" "DEC-HANYU" "\0" | "DECHANYU" "\0" "DEC-HANYU" "\0" |
"DECHANZI" "\0" "GB2312" "\0" | "DECHANZI" "\0" "GB2312" "\0" |
/* Korean */ | /* Korean */ |
"DECKOREAN" "\0" "EUC-KR" "\0"; | "DECKOREAN" "\0" "EUC-KR" "\0"; |
# endif |
# endif |
|
|
# if defined WIN32_NATIVE || defined __CYGWIN__ |
# if defined WIN32_NATIVE || defined __CYGWIN__ |
/* To avoid the troubles of installing a separate file in the same |
/* To avoid the troubles of installing a separate file in the same |
directory as the DLL and of retrieving the DLL's directory at | directory as the DLL and of retrieving the DLL's directory at |
runtime, simply inline the aliases here. */ | runtime, simply inline the aliases here. */ |
|
|
cp = "CP936" "\0" "GBK" "\0" |
cp = "CP936" "\0" "GBK" "\0" |
"CP1361" "\0" "JOHAB" "\0" | "CP1361" "\0" "JOHAB" "\0" |
"CP20127" "\0" "ASCII" "\0" | "CP20127" "\0" "ASCII" "\0" |
"CP20866" "\0" "KOI8-R" "\0" | "CP20866" "\0" "KOI8-R" "\0" |
"CP20936" "\0" "GB2312" "\0" | "CP20936" "\0" "GB2312" "\0" |
"CP21866" "\0" "KOI8-RU" "\0" | "CP21866" "\0" "KOI8-RU" "\0" |
"CP28591" "\0" "ISO-8859-1" "\0" | "CP28591" "\0" "ISO-8859-1" "\0" |
"CP28592" "\0" "ISO-8859-2" "\0" | "CP28592" "\0" "ISO-8859-2" "\0" |
"CP28593" "\0" "ISO-8859-3" "\0" | "CP28593" "\0" "ISO-8859-3" "\0" |
"CP28594" "\0" "ISO-8859-4" "\0" | "CP28594" "\0" "ISO-8859-4" "\0" |
"CP28595" "\0" "ISO-8859-5" "\0" | "CP28595" "\0" "ISO-8859-5" "\0" |
"CP28596" "\0" "ISO-8859-6" "\0" | "CP28596" "\0" "ISO-8859-6" "\0" |
"CP28597" "\0" "ISO-8859-7" "\0" | "CP28597" "\0" "ISO-8859-7" "\0" |
"CP28598" "\0" "ISO-8859-8" "\0" | "CP28598" "\0" "ISO-8859-8" "\0" |
"CP28599" "\0" "ISO-8859-9" "\0" | "CP28599" "\0" "ISO-8859-9" "\0" |
"CP28605" "\0" "ISO-8859-15" "\0" | "CP28605" "\0" "ISO-8859-15" "\0" |
"CP38598" "\0" "ISO-8859-8" "\0" | "CP38598" "\0" "ISO-8859-8" "\0" |
"CP51932" "\0" "EUC-JP" "\0" | "CP51932" "\0" "EUC-JP" "\0" |
"CP51936" "\0" "GB2312" "\0" | "CP51936" "\0" "GB2312" "\0" |
"CP51949" "\0" "EUC-KR" "\0" | "CP51949" "\0" "EUC-KR" "\0" |
"CP51950" "\0" "EUC-TW" "\0" | "CP51950" "\0" "EUC-TW" "\0" |
"CP54936" "\0" "GB18030" "\0" | "CP54936" "\0" "GB18030" "\0" |
"CP65001" "\0" "UTF-8" "\0"; | "CP65001" "\0" "UTF-8" "\0"; |
# endif |
# endif |
#endif |
#endif |
|
|
Line 336 locale_charset (void)
|
Line 369 locale_charset (void)
|
codeset = nl_langinfo (CODESET); |
codeset = nl_langinfo (CODESET); |
|
|
# ifdef __CYGWIN__ |
# ifdef __CYGWIN__ |
/* Cygwin 2006 does not have locales. nl_langinfo (CODESET) always | /* Cygwin < 1.7 does not have locales. nl_langinfo (CODESET) always |
returns "US-ASCII". As long as this is not fixed, return the suffix | returns "US-ASCII". Return the suffix of the locale name from the |
of the locale name from the environment variables (if present) or | environment variables (if present) or the codepage as a number. */ |
the codepage as a number. */ | |
if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0) |
if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0) |
{ |
{ |
const char *locale; |
const char *locale; |
Line 347 locale_charset (void)
|
Line 379 locale_charset (void)
|
|
|
locale = getenv ("LC_ALL"); |
locale = getenv ("LC_ALL"); |
if (locale == NULL || locale[0] == '\0') |
if (locale == NULL || locale[0] == '\0') |
{ | { |
locale = getenv ("LC_CTYPE"); | locale = getenv ("LC_CTYPE"); |
if (locale == NULL || locale[0] == '\0') | if (locale == NULL || locale[0] == '\0') |
locale = getenv ("LANG"); | locale = getenv ("LANG"); |
} | } |
if (locale != NULL && locale[0] != '\0') |
if (locale != NULL && locale[0] != '\0') |
{ | { |
/* If the locale name contains an encoding after the dot, return | /* If the locale name contains an encoding after the dot, return |
it. */ | it. */ |
const char *dot = strchr (locale, '.'); | const char *dot = strchr (locale, '.'); |
|
|
if (dot != NULL) | if (dot != NULL) |
{ | { |
const char *modifier; | const char *modifier; |
|
|
dot++; | dot++; |
/* Look for the possible @... trailer and remove it, if any. */ | /* Look for the possible @... trailer and remove it, if any. */ |
modifier = strchr (dot, '@'); | modifier = strchr (dot, '@'); |
if (modifier == NULL) | if (modifier == NULL) |
return dot; | return dot; |
if (modifier - dot < sizeof (buf)) | if (modifier - dot < sizeof (buf)) |
{ | { |
memcpy (buf, dot, modifier - dot); | memcpy (buf, dot, modifier - dot); |
buf [modifier - dot] = '\0'; | buf [modifier - dot] = '\0'; |
return buf; | return buf; |
} | } |
} | } |
} | } |
|
|
/* Woe32 has a function returning the locale's codepage as a number. */ | /* 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 ()); |
sprintf (buf, "CP%u", GetACP ()); |
codeset = buf; |
codeset = buf; |
} |
} |
Line 398 locale_charset (void)
|
Line 440 locale_charset (void)
|
{ |
{ |
locale = getenv ("LC_ALL"); |
locale = getenv ("LC_ALL"); |
if (locale == NULL || locale[0] == '\0') |
if (locale == NULL || locale[0] == '\0') |
{ | { |
locale = getenv ("LC_CTYPE"); | locale = getenv ("LC_CTYPE"); |
if (locale == NULL || locale[0] == '\0') | if (locale == NULL || locale[0] == '\0') |
locale = getenv ("LANG"); | locale = getenv ("LANG"); |
} | } |
} |
} |
|
|
/* On some old systems, one used to set locale = "iso8859_1". On others, |
/* On some old systems, one used to set locale = "iso8859_1". On others, |
Line 416 locale_charset (void)
|
Line 458 locale_charset (void)
|
|
|
static char buf[2 + 10 + 1]; |
static char buf[2 + 10 + 1]; |
|
|
/* Woe32 has a function returning the locale's codepage as a number. */ | /* 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 ()); |
sprintf (buf, "CP%u", GetACP ()); |
codeset = buf; |
codeset = buf; |
|
|
Line 434 locale_charset (void)
|
Line 482 locale_charset (void)
|
{ |
{ |
locale = getenv ("LC_CTYPE"); |
locale = getenv ("LC_CTYPE"); |
if (locale == NULL || locale[0] == '\0') |
if (locale == NULL || locale[0] == '\0') |
locale = getenv ("LANG"); | locale = getenv ("LANG"); |
} |
} |
if (locale != NULL && locale[0] != '\0') |
if (locale != NULL && locale[0] != '\0') |
{ |
{ |
Line 442 locale_charset (void)
|
Line 490 locale_charset (void)
|
const char *dot = strchr (locale, '.'); |
const char *dot = strchr (locale, '.'); |
|
|
if (dot != NULL) |
if (dot != NULL) |
{ | { |
const char *modifier; | const char *modifier; |
|
|
dot++; | dot++; |
/* Look for the possible @... trailer and remove it, if any. */ | /* Look for the possible @... trailer and remove it, if any. */ |
modifier = strchr (dot, '@'); | modifier = strchr (dot, '@'); |
if (modifier == NULL) | if (modifier == NULL) |
return dot; | return dot; |
if (modifier - dot < sizeof (buf)) | if (modifier - dot < sizeof (buf)) |
{ | { |
memcpy (buf, dot, modifier - dot); | memcpy (buf, dot, modifier - dot); |
buf [modifier - dot] = '\0'; | buf [modifier - dot] = '\0'; |
return buf; | return buf; |
} | } |
} | } |
|
|
/* Resolve through the charset.alias file. */ |
/* Resolve through the charset.alias file. */ |
codeset = locale; |
codeset = locale; |
Line 465 locale_charset (void)
|
Line 513 locale_charset (void)
|
{ |
{ |
/* OS/2 has a function returning the locale's codepage as a number. */ |
/* OS/2 has a function returning the locale's codepage as a number. */ |
if (DosQueryCp (sizeof (cp), cp, &cplen)) |
if (DosQueryCp (sizeof (cp), cp, &cplen)) |
codeset = ""; | codeset = ""; |
else |
else |
{ | { |
sprintf (buf, "CP%u", cp[0]); | sprintf (buf, "CP%u", cp[0]); |
codeset = buf; | codeset = buf; |
} | } |
} |
} |
|
|
#endif |
#endif |
Line 484 locale_charset (void)
|
Line 532 locale_charset (void)
|
*aliases != '\0'; |
*aliases != '\0'; |
aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) |
aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) |
if (strcmp (codeset, aliases) == 0 |
if (strcmp (codeset, aliases) == 0 |
|| (aliases[0] == '*' && aliases[1] == '\0')) | || (aliases[0] == '*' && aliases[1] == '\0')) |
{ |
{ |
codeset = aliases + strlen (aliases) + 1; | codeset = aliases + strlen (aliases) + 1; |
break; | break; |
} |
} |
|
|
/* Don't return an empty string. GNU libc and GNU libiconv interpret |
/* Don't return an empty string. GNU libc and GNU libiconv interpret |