00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef HAVE_CONFIG_H
00023 # include <config.h>
00024 #endif
00025
00026 #if HAVE_STDDEF_H
00027 # include <stddef.h>
00028 #endif
00029
00030 #include <stdio.h>
00031 #if HAVE_STRING_H
00032 # include <string.h>
00033 #else
00034 # include <strings.h>
00035 #endif
00036 #if HAVE_STDLIB_H
00037 # include <stdlib.h>
00038 #endif
00039
00040 #if defined _WIN32 || defined __WIN32__
00041 # undef WIN32
00042 # define WIN32
00043 #endif
00044
00045 #if defined __EMX__
00046
00047 # define OS2
00048 #endif
00049
00050 #if !defined WIN32
00051 # if HAVE_LANGINFO_CODESET
00052 # include <langinfo.h>
00053 # else
00054 # if HAVE_SETLOCALE
00055 # include <locale.h>
00056 # endif
00057 # endif
00058 #elif defined WIN32
00059 # define WIN32_LEAN_AND_MEAN
00060 # include <windows.h>
00061 #endif
00062 #if defined OS2
00063 # define INCL_DOS
00064 # include <os2.h>
00065 #endif
00066
00067 #if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
00068
00069 # define ISSLASH(C) ((C) == '/' || (C) == '\\')
00070 #endif
00071
00072 #ifndef DIRECTORY_SEPARATOR
00073 # define DIRECTORY_SEPARATOR '/'
00074 #endif
00075
00076 #ifndef ISSLASH
00077 # define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
00078 #endif
00079
00080 #ifdef HAVE_GETC_UNLOCKED
00081 # undef getc
00082 # define getc getc_unlocked
00083 #endif
00084
00085
00086
00087
00088
00089
00090
00091 #if __STDC__ != 1
00092 # define volatile
00093 #endif
00094
00095
00096
00097 static const char * volatile charset_aliases;
00098
00099
00100 static const char *
00101 get_charset_aliases ()
00102 {
00103 const char *cp;
00104
00105 cp = charset_aliases;
00106 if (cp == NULL)
00107 {
00108 #if !defined WIN32
00109 FILE *fp;
00110 const char *dir = LIBDIR;
00111 const char *base = "charset.alias";
00112 char *file_name;
00113
00114
00115 {
00116 size_t dir_len = strlen (dir);
00117 size_t base_len = strlen (base);
00118 int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1]));
00119 file_name = (char *) malloc (dir_len + add_slash + base_len + 1);
00120 if (file_name != NULL)
00121 {
00122 memcpy (file_name, dir, dir_len);
00123 if (add_slash)
00124 file_name[dir_len] = DIRECTORY_SEPARATOR;
00125 memcpy (file_name + dir_len + add_slash, base, base_len + 1);
00126 }
00127 }
00128
00129 if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL)
00130
00131 cp = "";
00132 else
00133 {
00134
00135 int c;
00136 char buf1[50+1];
00137 char buf2[50+1];
00138 char *res_ptr = NULL;
00139 size_t res_size = 0;
00140 size_t l1, l2;
00141
00142 for (;;)
00143 {
00144 c = getc (fp);
00145 if (c == EOF)
00146 break;
00147 if (c == '\n' || c == ' ' || c == '\t')
00148 continue;
00149 if (c == '#')
00150 {
00151
00152 do
00153 c = getc (fp);
00154 while (!(c == EOF || c == '\n'));
00155 if (c == EOF)
00156 break;
00157 continue;
00158 }
00159 ungetc (c, fp);
00160 if (fscanf (fp, "%50s %50s", buf1, buf2) < 2)
00161 break;
00162 l1 = strlen (buf1);
00163 l2 = strlen (buf2);
00164 if (res_size == 0)
00165 {
00166 res_size = l1 + 1 + l2 + 1;
00167 res_ptr = (char *) malloc (res_size + 1);
00168 }
00169 else
00170 {
00171 res_size += l1 + 1 + l2 + 1;
00172 res_ptr = (char *) realloc (res_ptr, res_size + 1);
00173 }
00174 if (res_ptr == NULL)
00175 {
00176
00177 res_size = 0;
00178 break;
00179 }
00180 strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1);
00181 strcpy (res_ptr + res_size - (l2 + 1), buf2);
00182 }
00183 fclose (fp);
00184 if (res_size == 0)
00185 cp = "";
00186 else
00187 {
00188 *(res_ptr + res_size) = '\0';
00189 cp = res_ptr;
00190 }
00191 }
00192
00193 if (file_name != NULL)
00194 free (file_name);
00195
00196 #else
00197
00198
00199
00200
00201
00202 # if defined WIN32
00203 cp = "CP936" "\0" "GBK" "\0"
00204 "CP1361" "\0" "JOHAB" "\0";
00205 # endif
00206 #endif
00207
00208 charset_aliases = cp;
00209 }
00210
00211 return cp;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220 #ifdef STATIC
00221 STATIC
00222 #endif
00223 const char *
00224 locale_charset ()
00225 {
00226 const char *codeset;
00227 const char *aliases;
00228
00229 #if !(defined WIN32 || defined OS2)
00230
00231 # if HAVE_LANGINFO_CODESET
00232
00233
00234 codeset = nl_langinfo (CODESET);
00235
00236 # else
00237
00238
00239 const char *locale = NULL;
00240
00241
00242
00243
00244
00245 # if HAVE_SETLOCALE && 0
00246 locale = setlocale (LC_CTYPE, NULL);
00247 # endif
00248 if (locale == NULL || locale[0] == '\0')
00249 {
00250 locale = getenv ("LC_ALL");
00251 if (locale == NULL || locale[0] == '\0')
00252 {
00253 locale = getenv ("LC_CTYPE");
00254 if (locale == NULL || locale[0] == '\0')
00255 locale = getenv ("LANG");
00256 }
00257 }
00258
00259
00260
00261
00262 codeset = locale;
00263
00264 # endif
00265
00266 #elif defined WIN32
00267
00268 static char buf[2 + 10 + 1];
00269
00270
00271 sprintf (buf, "CP%u", GetACP ());
00272 codeset = buf;
00273
00274 #elif defined OS2
00275
00276 const char *locale;
00277 static char buf[2 + 10 + 1];
00278 ULONG cp[3];
00279 ULONG cplen;
00280
00281
00282
00283 locale = getenv ("LC_ALL");
00284 if (locale == NULL || locale[0] == '\0')
00285 {
00286 locale = getenv ("LC_CTYPE");
00287 if (locale == NULL || locale[0] == '\0')
00288 locale = getenv ("LANG");
00289 }
00290 if (locale != NULL && locale[0] != '\0')
00291 {
00292
00293 const char *dot = strchr (locale, '.');
00294
00295 if (dot != NULL)
00296 {
00297 const char *modifier;
00298
00299 dot++;
00300
00301 modifier = strchr (dot, '@');
00302 if (modifier == NULL)
00303 return dot;
00304 if (modifier - dot < sizeof (buf))
00305 {
00306 memcpy (buf, dot, modifier - dot);
00307 buf [modifier - dot] = '\0';
00308 return buf;
00309 }
00310 }
00311
00312
00313 codeset = locale;
00314 }
00315 else
00316 {
00317
00318 if (DosQueryCp (sizeof (cp), cp, &cplen))
00319 codeset = "";
00320 else
00321 {
00322 sprintf (buf, "CP%u", cp[0]);
00323 codeset = buf;
00324 }
00325 }
00326
00327 #endif
00328
00329 if (codeset == NULL)
00330
00331 codeset = "";
00332
00333
00334 for (aliases = get_charset_aliases ();
00335 *aliases != '\0';
00336 aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
00337 if (strcmp (codeset, aliases) == 0
00338 || (aliases[0] == '*' && aliases[1] == '\0'))
00339 {
00340 codeset = aliases + strlen (aliases) + 1;
00341 break;
00342 }
00343
00344 return codeset;
00345 }