1a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* -*- buffer-read-only: t -*- vi: set ro: */
2a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Determine a canonical name for the current locale's character encoding.
4a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
5a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   Copyright (C) 2000-2006, 2008-2009 Free Software Foundation, Inc.
6a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
7a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   This program is free software; you can redistribute it and/or modify
8a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   it under the terms of the GNU General Public License as published by
9a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   the Free Software Foundation; either version 3, or (at your option)
10a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   any later version.
11a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
12a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   This program is distributed in the hope that it will be useful,
13a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   but WITHOUT ANY WARRANTY; without even the implied warranty of
14a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   GNU General Public License for more details.
16a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
17a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   You should have received a copy of the GNU General Public License along
18a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   with this program; if not, write to the Free Software Foundation,
19a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
20a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
21a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Written by Bruno Haible <bruno@clisp.org>.  */
22a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
23a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#include <config.h>
24a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
25a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Specification.  */
26a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#include "localcharset.h"
27a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
28a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#include <stddef.h>
29a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#include <stdio.h>
30a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#include <string.h>
31a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#include <stdlib.h>
32a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
33a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET
34a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define DARWIN7 /* Darwin 7 or newer, i.e. MacOS X 10.3 or newer */
35a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
36a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
37a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if defined _WIN32 || defined __WIN32__
38a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define WIN32_NATIVE
39a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
40a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
41a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if defined __EMX__
42a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Assume EMX program runs on OS/2, even if compiled under DOS.  */
43a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifndef OS2
44a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#  define OS2
45a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif
46a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
47a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
48a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if !defined WIN32_NATIVE
49a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# if HAVE_LANGINFO_CODESET
50a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#  include <langinfo.h>
51a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# else
52a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#  if 0 /* see comment below */
53a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#   include <locale.h>
54a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#  endif
55a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif
56a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifdef __CYGWIN__
57a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#  define WIN32_LEAN_AND_MEAN
58a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#  include <windows.h>
59a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif
60a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#elif defined WIN32_NATIVE
61a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define WIN32_LEAN_AND_MEAN
62a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include <windows.h>
63a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
64a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if defined OS2
65a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define INCL_DOS
66a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include <os2.h>
67a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
68a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
69a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if ENABLE_RELOCATABLE
70a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include "relocatable.h"
71a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#else
72a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define relocate(pathname) (pathname)
73a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
74a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
75a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Get LIBDIR.  */
76a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#ifndef LIBDIR
77a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include "configmake.h"
78a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
79a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
80a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
81a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  /* Win32, Cygwin, OS/2, DOS */
82a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define ISSLASH(C) ((C) == '/' || (C) == '\\')
83a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
84a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
85a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#ifndef DIRECTORY_SEPARATOR
86a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define DIRECTORY_SEPARATOR '/'
87a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
88a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
89a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#ifndef ISSLASH
90a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
91a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
92a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
93a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if HAVE_DECL_GETC_UNLOCKED
94a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# undef getc
95a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define getc getc_unlocked
96a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
97a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
98a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* The following static variable is declared 'volatile' to avoid a
99a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   possible multithread problem in the function get_charset_aliases. If we
100a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   are running in a threaded environment, and if two threads initialize
101a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   'charset_aliases' simultaneously, both will produce the same value,
102a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   and everything will be ok if the two assignments to 'charset_aliases'
103a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   are atomic. But I don't know what will happen if the two assignments mix.  */
104a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if __STDC__ != 1
105a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define volatile /* empty */
106a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
107a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Pointer to the contents of the charset.alias file, if it has already been
108a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   read, else NULL.  Its format is:
109a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0'  */
110a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerstatic const char * volatile charset_aliases;
111a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
112a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Return a pointer to the contents of the charset.alias file.  */
113a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerstatic const char *
114a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerget_charset_aliases (void)
115a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner{
116a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  const char *cp;
117a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
118a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  cp = charset_aliases;
119a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  if (cp == NULL)
120a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    {
121a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__)
122a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      FILE *fp;
123a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      const char *dir;
124a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      const char *base = "charset.alias";
125a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      char *file_name;
126a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
127a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      /* Make it possible to override the charset.alias location.  This is
128a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	 necessary for running the testsuite before "make install".  */
129a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      dir = getenv ("CHARSETALIASDIR");
130a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      if (dir == NULL || dir[0] == '\0')
131a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	dir = relocate (LIBDIR);
132a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
133a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      /* Concatenate dir and base into freshly allocated file_name.  */
134a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      {
135a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	size_t dir_len = strlen (dir);
136a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	size_t base_len = strlen (base);
137a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1]));
138a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	file_name = (char *) malloc (dir_len + add_slash + base_len + 1);
139a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	if (file_name != NULL)
140a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  {
141a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    memcpy (file_name, dir, dir_len);
142a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    if (add_slash)
143a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      file_name[dir_len] = DIRECTORY_SEPARATOR;
144a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    memcpy (file_name + dir_len + add_slash, base, base_len + 1);
145a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  }
146a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      }
147a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
148a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL)
149a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	/* Out of memory or file not found, treat it as empty.  */
150a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	cp = "";
151a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      else
152a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	{
153a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  /* Parse the file's contents.  */
154a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  char *res_ptr = NULL;
155a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  size_t res_size = 0;
156a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
157a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  for (;;)
158a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    {
159a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      int c;
160a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      char buf1[50+1];
161a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      char buf2[50+1];
162a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      size_t l1, l2;
163a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      char *old_res_ptr;
164a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
165a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      c = getc (fp);
166a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      if (c == EOF)
167a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		break;
168a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      if (c == '\n' || c == ' ' || c == '\t')
169a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		continue;
170a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      if (c == '#')
171a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		{
172a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  /* Skip comment, to end of line.  */
173a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  do
174a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		    c = getc (fp);
175a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  while (!(c == EOF || c == '\n'));
176a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  if (c == EOF)
177a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		    break;
178a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  continue;
179a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		}
180a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      ungetc (c, fp);
181a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      if (fscanf (fp, "%50s %50s", buf1, buf2) < 2)
182a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		break;
183a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      l1 = strlen (buf1);
184a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      l2 = strlen (buf2);
185a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      old_res_ptr = res_ptr;
186a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      if (res_size == 0)
187a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		{
188a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  res_size = l1 + 1 + l2 + 1;
189a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  res_ptr = (char *) malloc (res_size + 1);
190a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		}
191a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      else
192a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		{
193a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  res_size += l1 + 1 + l2 + 1;
194a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  res_ptr = (char *) realloc (res_ptr, res_size + 1);
195a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		}
196a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      if (res_ptr == NULL)
197a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		{
198a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  /* Out of memory. */
199a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  res_size = 0;
200a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  if (old_res_ptr != NULL)
201a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		    free (old_res_ptr);
202a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  break;
203a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		}
204a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1);
205a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      strcpy (res_ptr + res_size - (l2 + 1), buf2);
206a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    }
207a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  fclose (fp);
208a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  if (res_size == 0)
209a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    cp = "";
210a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  else
211a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    {
212a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      *(res_ptr + res_size) = '\0';
213a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      cp = res_ptr;
214a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    }
215a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	}
216a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
217a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      if (file_name != NULL)
218a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	free (file_name);
219a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
220a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#else
221a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
222a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# if defined DARWIN7
223a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      /* To avoid the trouble of installing a file that is shared by many
224a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	 GNU packages -- many packaging systems have problems with this --,
225a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	 simply inline the aliases here.  */
226a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      cp = "ISO8859-1" "\0" "ISO-8859-1" "\0"
227a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-2" "\0" "ISO-8859-2" "\0"
228a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-4" "\0" "ISO-8859-4" "\0"
229a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-5" "\0" "ISO-8859-5" "\0"
230a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-7" "\0" "ISO-8859-7" "\0"
231a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-9" "\0" "ISO-8859-9" "\0"
232a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-13" "\0" "ISO-8859-13" "\0"
233a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-15" "\0" "ISO-8859-15" "\0"
234a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "KOI8-R" "\0" "KOI8-R" "\0"
235a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "KOI8-U" "\0" "KOI8-U" "\0"
236a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP866" "\0" "CP866" "\0"
237a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP949" "\0" "CP949" "\0"
238a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP1131" "\0" "CP1131" "\0"
239a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP1251" "\0" "CP1251" "\0"
240a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "eucCN" "\0" "GB2312" "\0"
241a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "GB2312" "\0" "GB2312" "\0"
242a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "eucJP" "\0" "EUC-JP" "\0"
243a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "eucKR" "\0" "EUC-KR" "\0"
244a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "Big5" "\0" "BIG5" "\0"
245a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "Big5HKSCS" "\0" "BIG5-HKSCS" "\0"
246a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "GBK" "\0" "GBK" "\0"
247a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "GB18030" "\0" "GB18030" "\0"
248a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "SJIS" "\0" "SHIFT_JIS" "\0"
249a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ARMSCII-8" "\0" "ARMSCII-8" "\0"
250a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "PT154" "\0" "PT154" "\0"
251a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	 /*"ISCII-DEV" "\0" "?" "\0"*/
252a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "*" "\0" "UTF-8" "\0";
253a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif
254a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
255a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# if defined VMS
256a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      /* To avoid the troubles of an extra file charset.alias_vms in the
257a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	 sources of many GNU packages, simply inline the aliases here.  */
258a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      /* The list of encodings is taken from the OpenVMS 7.3-1 documentation
259a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	 "Compaq C Run-Time Library Reference Manual for OpenVMS systems"
260a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	 section 10.7 "Handling Different Character Sets".  */
261a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      cp = "ISO8859-1" "\0" "ISO-8859-1" "\0"
262a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-2" "\0" "ISO-8859-2" "\0"
263a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-5" "\0" "ISO-8859-5" "\0"
264a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-7" "\0" "ISO-8859-7" "\0"
265a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-8" "\0" "ISO-8859-8" "\0"
266a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "ISO8859-9" "\0" "ISO-8859-9" "\0"
267a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   /* Japanese */
268a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "eucJP" "\0" "EUC-JP" "\0"
269a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "SJIS" "\0" "SHIFT_JIS" "\0"
270a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "DECKANJI" "\0" "DEC-KANJI" "\0"
271a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "SDECKANJI" "\0" "EUC-JP" "\0"
272a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   /* Chinese */
273a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "eucTW" "\0" "EUC-TW" "\0"
274a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "DECHANYU" "\0" "DEC-HANYU" "\0"
275a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "DECHANZI" "\0" "GB2312" "\0"
276a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   /* Korean */
277a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "DECKOREAN" "\0" "EUC-KR" "\0";
278a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif
279a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
280a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# if defined WIN32_NATIVE || defined __CYGWIN__
281a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      /* To avoid the troubles of installing a separate file in the same
282a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	 directory as the DLL and of retrieving the DLL's directory at
283a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	 runtime, simply inline the aliases here.  */
284a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
285a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      cp = "CP936" "\0" "GBK" "\0"
286a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP1361" "\0" "JOHAB" "\0"
287a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP20127" "\0" "ASCII" "\0"
288a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP20866" "\0" "KOI8-R" "\0"
289a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP20936" "\0" "GB2312" "\0"
290a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP21866" "\0" "KOI8-RU" "\0"
291a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP28591" "\0" "ISO-8859-1" "\0"
292a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP28592" "\0" "ISO-8859-2" "\0"
293a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP28593" "\0" "ISO-8859-3" "\0"
294a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP28594" "\0" "ISO-8859-4" "\0"
295a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP28595" "\0" "ISO-8859-5" "\0"
296a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP28596" "\0" "ISO-8859-6" "\0"
297a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP28597" "\0" "ISO-8859-7" "\0"
298a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP28598" "\0" "ISO-8859-8" "\0"
299a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP28599" "\0" "ISO-8859-9" "\0"
300a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP28605" "\0" "ISO-8859-15" "\0"
301a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP38598" "\0" "ISO-8859-8" "\0"
302a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP51932" "\0" "EUC-JP" "\0"
303a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP51936" "\0" "GB2312" "\0"
304a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP51949" "\0" "EUC-KR" "\0"
305a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP51950" "\0" "EUC-TW" "\0"
306a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP54936" "\0" "GB18030" "\0"
307a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	   "CP65001" "\0" "UTF-8" "\0";
308a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif
309a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
310a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
311a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      charset_aliases = cp;
312a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    }
313a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
314a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  return cp;
315a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner}
316a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
317a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Determine the current locale's character encoding, and canonicalize it
318a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   into one of the canonical names listed in config.charset.
319a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   The result must not be freed; it is statically allocated.
320a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   If the canonical name cannot be determined, the result is a non-canonical
321a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner   name.  */
322a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
323a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#ifdef STATIC
324a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' TurnerSTATIC
325a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
326a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerconst char *
327a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerlocale_charset (void)
328a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner{
329a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  const char *codeset;
330a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  const char *aliases;
331a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
332a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if !(defined WIN32_NATIVE || defined OS2)
333a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
334a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# if HAVE_LANGINFO_CODESET
335a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
336a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  /* Most systems support nl_langinfo (CODESET) nowadays.  */
337a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  codeset = nl_langinfo (CODESET);
338a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
339a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#  ifdef __CYGWIN__
340a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  /* Cygwin 2006 does not have locales.  nl_langinfo (CODESET) always
341a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner     returns "US-ASCII".  As long as this is not fixed, return the suffix
342a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner     of the locale name from the environment variables (if present) or
343a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner     the codepage as a number.  */
344a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0)
345a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    {
346a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      const char *locale;
347a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      static char buf[2 + 10 + 1];
348a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
349a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      locale = getenv ("LC_ALL");
350a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      if (locale == NULL || locale[0] == '\0')
351a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	{
352a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  locale = getenv ("LC_CTYPE");
353a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  if (locale == NULL || locale[0] == '\0')
354a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    locale = getenv ("LANG");
355a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	}
356a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      if (locale != NULL && locale[0] != '\0')
357a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	{
358a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  /* If the locale name contains an encoding after the dot, return
359a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	     it.  */
360a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  const char *dot = strchr (locale, '.');
361a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
362a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  if (dot != NULL)
363a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    {
364a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      const char *modifier;
365a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
366a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      dot++;
367a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      /* Look for the possible @... trailer and remove it, if any.  */
368a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      modifier = strchr (dot, '@');
369a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      if (modifier == NULL)
370a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		return dot;
371a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      if (modifier - dot < sizeof (buf))
372a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		{
373a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  memcpy (buf, dot, modifier - dot);
374a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  buf [modifier - dot] = '\0';
375a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		  return buf;
376a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner		}
377a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    }
378a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	}
379a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
380a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      /* Woe32 has a function returning the locale's codepage as a number.  */
381a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      sprintf (buf, "CP%u", GetACP ());
382a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      codeset = buf;
383a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    }
384a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#  endif
385a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
386a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# else
387a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
388a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  /* On old systems which lack it, use setlocale or getenv.  */
389a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  const char *locale = NULL;
390a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
391a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  /* But most old systems don't have a complete set of locales.  Some
392a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner     (like SunOS 4 or DJGPP) have only the C locale.  Therefore we don't
393a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner     use setlocale here; it would return "C" when it doesn't support the
394a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner     locale name the user has set.  */
395a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#  if 0
396a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  locale = setlocale (LC_CTYPE, NULL);
397a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#  endif
398a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  if (locale == NULL || locale[0] == '\0')
399a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    {
400a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      locale = getenv ("LC_ALL");
401a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      if (locale == NULL || locale[0] == '\0')
402a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	{
403a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  locale = getenv ("LC_CTYPE");
404a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  if (locale == NULL || locale[0] == '\0')
405a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    locale = getenv ("LANG");
406a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	}
407a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    }
408a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
409a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  /* On some old systems, one used to set locale = "iso8859_1". On others,
410a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner     you set it to "language_COUNTRY.charset". In any case, we resolve it
411a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner     through the charset.alias file.  */
412a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  codeset = locale;
413a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
414a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif
415a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
416a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#elif defined WIN32_NATIVE
417a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
418a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  static char buf[2 + 10 + 1];
419a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
420a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  /* Woe32 has a function returning the locale's codepage as a number.  */
421a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  sprintf (buf, "CP%u", GetACP ());
422a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  codeset = buf;
423a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
424a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#elif defined OS2
425a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
426a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  const char *locale;
427a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  static char buf[2 + 10 + 1];
428a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  ULONG cp[3];
429a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  ULONG cplen;
430a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
431a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  /* Allow user to override the codeset, as set in the operating system,
432a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner     with standard language environment variables.  */
433a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  locale = getenv ("LC_ALL");
434a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  if (locale == NULL || locale[0] == '\0')
435a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    {
436a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      locale = getenv ("LC_CTYPE");
437a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      if (locale == NULL || locale[0] == '\0')
438a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	locale = getenv ("LANG");
439a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    }
440a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  if (locale != NULL && locale[0] != '\0')
441a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    {
442a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      /* If the locale name contains an encoding after the dot, return it.  */
443a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      const char *dot = strchr (locale, '.');
444a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
445a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      if (dot != NULL)
446a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	{
447a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  const char *modifier;
448a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
449a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  dot++;
450a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  /* Look for the possible @... trailer and remove it, if any.  */
451a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  modifier = strchr (dot, '@');
452a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  if (modifier == NULL)
453a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    return dot;
454a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  if (modifier - dot < sizeof (buf))
455a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    {
456a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      memcpy (buf, dot, modifier - dot);
457a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      buf [modifier - dot] = '\0';
458a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	      return buf;
459a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	    }
460a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	}
461a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
462a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      /* Resolve through the charset.alias file.  */
463a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      codeset = locale;
464a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    }
465a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  else
466a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    {
467a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      /* OS/2 has a function returning the locale's codepage as a number.  */
468a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      if (DosQueryCp (sizeof (cp), cp, &cplen))
469a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	codeset = "";
470a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      else
471a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	{
472a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  sprintf (buf, "CP%u", cp[0]);
473a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	  codeset = buf;
474a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	}
475a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    }
476a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
477a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif
478a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
479a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  if (codeset == NULL)
480a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    /* The canonical name cannot be determined.  */
481a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    codeset = "";
482a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
483a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  /* Resolve alias. */
484a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  for (aliases = get_charset_aliases ();
485a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner       *aliases != '\0';
486a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner       aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
487a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    if (strcmp (codeset, aliases) == 0
488a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	|| (aliases[0] == '*' && aliases[1] == '\0'))
489a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      {
490a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	codeset = aliases + strlen (aliases) + 1;
491a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner	break;
492a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner      }
493a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
494a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  /* Don't return an empty string.  GNU libc and GNU libiconv interpret
495a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner     the empty string as denoting "the locale's character encoding",
496a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner     thus GNU libiconv would call this function a second time.  */
497a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  if (codeset[0] == '\0')
498a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner    codeset = "ASCII";
499a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner
500a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner  return codeset;
501a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner}
502