/* Character set conversion support for GDB.
- Copyright 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "charset.h"
#include "gdbcmd.h"
#include "gdb_assert.h"
+#include "gdb_obstack.h"
+#include "gdb_wait.h"
+#include "charset-list.h"
+#include "vec.h"
+#include "environ.h"
+#include "arch-utils.h"
#include <stddef.h>
#include "gdb_string.h"
#include <ctype.h>
-#ifdef HAVE_ICONV
-#include <iconv.h>
+#ifdef USE_WIN32API
+#include <windows.h>
#endif
-
\f
/* How GDB's character set support works
- GDB has two global settings:
+ GDB has three global settings:
- The `current host character set' is the character set GDB should
use in talking to the user, and which (hopefully) the user's
- terminal knows how to display properly.
+ terminal knows how to display properly. Most users should not
+ change this.
- The `current target character set' is the character set the
program being debugged uses.
+ - The `current target wide character set' is the wide character set
+ the program being debugged uses, that is, the encoding used for
+ wchar_t.
+
There are commands to set each of these, and mechanisms for
choosing reasonable default values. GDB has a global list of
character sets that it can use as its host or target character
characters the user enters in expressions (mostly host->target
conversions),
- and so on.
-
- Now, many of these operations are specific to a particular
- host/target character set pair. If GDB supports N character sets,
- there are N^2 possible pairs. This means that, the larger GDB's
- repertoire of character sets gets, the more expensive it gets to add
- new character sets.
-
- To make sure that GDB can do the right thing for every possible
- pairing of host and target character set, while still allowing
- GDB's repertoire to scale, we use a two-tiered approach:
-
- - We maintain a global table of "translations" --- groups of
- functions specific to a particular pair of character sets.
-
- - However, a translation can be incomplete: some functions can be
- omitted. Where there is not a translation to specify exactly
- what function to use, we provide reasonable defaults. The
- default behaviors try to use the "iconv" library functions, which
- support a wide range of character sets. However, even if iconv
- is not available, there are fallbacks to support trivial
- translations: when the host and target character sets are the
- same. */
+ and so on.
+
+ To avoid excessive code duplication and maintenance efforts,
+ GDB simply requires a capable iconv function. Users on platforms
+ without a suitable iconv can use the GNU iconv library. */
\f
-/* The character set and translation structures. */
-
-
-/* A character set GDB knows about. GDB only supports character sets
- with stateless encodings, in which every character is one byte
- long. */
-struct charset {
-
- /* A singly-linked list of all known charsets. */
- struct charset *next;
-
- /* The name of the character set. Comparisons on character set
- names are case-insensitive. */
- const char *name;
-
- /* Non-zero iff this character set can be used as a host character
- set. At present, GDB basically assumes that the host character
- set is a superset of ASCII. */
- int valid_host_charset;
-
- /* Pointers to charset-specific functions that depend only on a
- single character set, and data pointers to pass to them. */
- int (*host_char_print_literally) (void *baton,
- int host_char);
- void *host_char_print_literally_baton;
-
- int (*target_char_to_control_char) (void *baton,
- int target_char,
- int *target_ctrl_char);
- void *target_char_to_control_char_baton;
-};
-
-
-/* A translation from one character set to another. */
-struct translation {
-
- /* A singly-linked list of all known translations. */
- struct translation *next;
-
- /* This structure describes functions going from the FROM character
- set to the TO character set. Comparisons on character set names
- are case-insensitive. */
- const char *from, *to;
-
- /* Pointers to translation-specific functions, and data pointers to
- pass to them. These pointers can be zero, indicating that GDB
- should fall back on the default behavior. We hope the default
- behavior will be correct for many from/to pairs, reducing the
- number of translations that need to be registered explicitly. */
-
- /* TARGET_CHAR is in the `from' charset.
- Returns a string in the `to' charset. */
- const char *(*c_target_char_has_backslash_escape) (void *baton,
- int target_char);
- void *c_target_char_has_backslash_escape_baton;
-
- /* HOST_CHAR is in the `from' charset.
- TARGET_CHAR points to a char in the `to' charset. */
- int (*c_parse_backslash) (void *baton, int host_char, int *target_char);
- void *c_parse_backslash_baton;
-
- /* This is used for the host_char_to_target and target_char_to_host
- functions. */
- int (*convert_char) (void *baton, int from, int *to);
- void *convert_char_baton;
-};
-
-
-\f
-/* The global lists of character sets and translations. */
+#ifdef PHONY_ICONV
+/* Provide a phony iconv that does as little as possible. Also,
+ arrange for there to be a single available character set. */
-/* Character set names are always compared ignoring case. */
-static int
-strcmp_case_insensitive (const char *p, const char *q)
-{
- while (*p && *q && tolower (*p) == tolower (*q))
- p++, q++;
-
- return tolower (*p) - tolower (*q);
-}
-
-
-/* The global list of all the charsets GDB knows about. */
-static struct charset *all_charsets;
-
-
-static void
-register_charset (struct charset *cs)
-{
- struct charset **ptr;
-
- /* Put the new charset on the end, so that the list ends up in the
- same order as the registrations in the _initialize function. */
- for (ptr = &all_charsets; *ptr; ptr = &(*ptr)->next)
- ;
-
- cs->next = 0;
- *ptr = cs;
-}
-
+#undef GDB_DEFAULT_HOST_CHARSET
+#define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1"
+#define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1"
+#define GDB_DEFAULT_TARGET_WIDE_CHARSET "ISO-8859-1"
+#undef DEFAULT_CHARSET_NAMES
+#define DEFAULT_CHARSET_NAMES GDB_DEFAULT_HOST_CHARSET ,
+
+#undef iconv_t
+#define iconv_t int
+#undef iconv_open
+#undef iconv
+#undef iconv_close
+
+#undef ICONV_CONST
+#define ICONV_CONST const
+
+/* Some systems don't have EILSEQ, so we define it here, but not as
+ EINVAL, because callers of `iconv' want to distinguish EINVAL and
+ EILSEQ. This is what iconv.h from libiconv does as well. Note
+ that wchar.h may also define EILSEQ, so this needs to be after we
+ include wchar.h, which happens in defs.h through gdb_wchar.h. */
+#ifndef EILSEQ
+#define EILSEQ ENOENT
+#endif
-static struct charset *
-lookup_charset (const char *name)
+iconv_t
+iconv_open (const char *to, const char *from)
{
- struct charset *cs;
-
- for (cs = all_charsets; cs; cs = cs->next)
- if (! strcmp_case_insensitive (name, cs->name))
- return cs;
+ /* We allow conversions from UTF-32BE, wchar_t, and the host charset.
+ We allow conversions to wchar_t and the host charset. */
+ if (strcmp (from, "UTF-32BE") && strcmp (from, "wchar_t")
+ && strcmp (from, GDB_DEFAULT_HOST_CHARSET))
+ return -1;
+ if (strcmp (to, "wchar_t") && strcmp (to, GDB_DEFAULT_HOST_CHARSET))
+ return -1;
- return NULL;
+ /* Return 1 if we are converting from UTF-32BE, 0 otherwise. This is
+ used as a flag in calls to iconv. */
+ return !strcmp (from, "UTF-32BE");
}
-
-/* The global list of translations. */
-static struct translation *all_translations;
-
-
-static void
-register_translation (struct translation *t)
+int
+iconv_close (iconv_t arg)
{
- t->next = all_translations;
- all_translations = t;
+ return 0;
}
-
-static struct translation *
-lookup_translation (const char *from, const char *to)
+size_t
+iconv (iconv_t utf_flag, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
{
- struct translation *t;
+ if (utf_flag)
+ {
+ while (*inbytesleft >= 4)
+ {
+ size_t j;
+ unsigned long c = 0;
+
+ for (j = 0; j < 4; ++j)
+ {
+ c <<= 8;
+ c += (*inbuf)[j] & 0xff;
+ }
+
+ if (c >= 256)
+ {
+ errno = EILSEQ;
+ return -1;
+ }
+ **outbuf = c & 0xff;
+ ++*outbuf;
+ --*outbytesleft;
+
+ ++*inbuf;
+ *inbytesleft -= 4;
+ }
+ if (*inbytesleft < 4)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ }
+ else
+ {
+ /* In all other cases we simply copy input bytes to the
+ output. */
+ size_t amt = *inbytesleft;
+
+ if (amt > *outbytesleft)
+ amt = *outbytesleft;
+ memcpy (*outbuf, *inbuf, amt);
+ *inbuf += amt;
+ *outbuf += amt;
+ *inbytesleft -= amt;
+ *outbytesleft -= amt;
+ }
- for (t = all_translations; t; t = t->next)
- if (! strcmp_case_insensitive (from, t->from)
- && ! strcmp_case_insensitive (to, t->to))
- return t;
+ if (*inbytesleft)
+ {
+ errno = E2BIG;
+ return -1;
+ }
+ /* The number of non-reversible conversions -- but they were all
+ reversible. */
return 0;
}
-
-\f
-/* Constructing charsets. */
-
-/* Allocate, initialize and return a straightforward charset.
- Use this function, rather than creating the structures yourself,
- so that we can add new fields to the structure in the future without
- having to tweak all the old charset descriptions. */
-static struct charset *
-simple_charset (const char *name,
- int valid_host_charset,
- int (*host_char_print_literally) (void *baton, int host_char),
- void *host_char_print_literally_baton,
- int (*target_char_to_control_char) (void *baton,
- int target_char,
- int *target_ctrl_char),
- void *target_char_to_control_char_baton)
-{
- struct charset *cs = xmalloc (sizeof (*cs));
-
- memset (cs, 0, sizeof (*cs));
- cs->name = name;
- cs->valid_host_charset = valid_host_charset;
- cs->host_char_print_literally = host_char_print_literally;
- cs->host_char_print_literally_baton = host_char_print_literally_baton;
- cs->target_char_to_control_char = target_char_to_control_char;
- cs->target_char_to_control_char_baton = target_char_to_control_char_baton;
-
- return cs;
-}
+#endif
\f
-/* ASCII functions. */
+/* The global lists of character sets and translations. */
-static int
-ascii_print_literally (void *baton, int c)
-{
- c &= 0xff;
- return (0x20 <= c && c <= 0x7e);
-}
+#ifndef GDB_DEFAULT_TARGET_CHARSET
+#define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1"
+#endif
+#ifndef GDB_DEFAULT_TARGET_WIDE_CHARSET
+#define GDB_DEFAULT_TARGET_WIDE_CHARSET "UTF-32"
+#endif
-static int
-ascii_to_control (void *baton, int c, int *ctrl_char)
-{
- *ctrl_char = (c & 037);
- return 1;
+static const char *auto_host_charset_name = GDB_DEFAULT_HOST_CHARSET;
+static const char *host_charset_name = "auto";
+static void
+show_host_charset_name (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ if (!strcmp (value, "auto"))
+ fprintf_filtered (file,
+ _("The host character set is \"auto; currently %s\".\n"),
+ auto_host_charset_name);
+ else
+ fprintf_filtered (file, _("The host character set is \"%s\".\n"), value);
}
-\f
-/* ISO-8859 family functions. */
-
-
-static int
-iso_8859_print_literally (void *baton, int c)
-{
- c &= 0xff;
-
- return ((0x20 <= c && c <= 0x7e) /* ascii printables */
- || (! sevenbit_strings && 0xA0 <= c)); /* iso 8859 printables */
+static const char *target_charset_name = "auto";
+static void
+show_target_charset_name (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ if (!strcmp (value, "auto"))
+ fprintf_filtered (file,
+ _("The target character set is \"auto; "
+ "currently %s\".\n"),
+ gdbarch_auto_charset (get_current_arch ()));
+ else
+ fprintf_filtered (file, _("The target character set is \"%s\".\n"),
+ value);
}
-
-static int
-iso_8859_to_control (void *baton, int c, int *ctrl_char)
-{
- *ctrl_char = (c & 0200) | (c & 037);
- return 1;
+static const char *target_wide_charset_name = "auto";
+static void
+show_target_wide_charset_name (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ if (!strcmp (value, "auto"))
+ fprintf_filtered (file,
+ _("The target wide character set is \"auto; "
+ "currently %s\".\n"),
+ gdbarch_auto_wide_charset (get_current_arch ()));
+ else
+ fprintf_filtered (file, _("The target wide character set is \"%s\".\n"),
+ value);
}
-
-/* Construct an ISO-8859-like character set. */
-static struct charset *
-iso_8859_family_charset (const char *name)
+static const char *default_charset_names[] =
{
- return simple_charset (name, 1,
- iso_8859_print_literally, 0,
- iso_8859_to_control, 0);
-}
+ DEFAULT_CHARSET_NAMES
+ 0
+};
+static const char **charset_enum;
\f
-/* EBCDIC family functions. */
-
+/* If the target wide character set has big- or little-endian
+ variants, these are the corresponding names. */
+static const char *target_wide_charset_be_name;
+static const char *target_wide_charset_le_name;
-static int
-ebcdic_print_literally (void *baton, int c)
-{
- c &= 0xff;
-
- return (64 <= c && c <= 254);
-}
-
-
-static int
-ebcdic_to_control (void *baton, int c, int *ctrl_char)
-{
- /* There are no control character equivalents in EBCDIC. Use
- numeric escapes. */
- return 0;
-}
+/* The architecture for which the BE- and LE-names are valid. */
+static struct gdbarch *be_le_arch;
+/* A helper function which sets the target wide big- and little-endian
+ character set names, if possible. */
-/* Construct an EBCDIC-like character set. */
-static struct charset *
-ebcdic_family_charset (const char *name)
+static void
+set_be_le_names (struct gdbarch *gdbarch)
{
- return simple_charset (name, 0,
- ebcdic_print_literally, 0,
- ebcdic_to_control, 0);
-}
-
-
-
-
-\f
-/* Fallback functions using iconv. */
+ int i, len;
+ const char *target_wide;
-#if defined(HAVE_ICONV)
+ if (be_le_arch == gdbarch)
+ return;
+ be_le_arch = gdbarch;
-struct cached_iconv {
- struct charset *from, *to;
- iconv_t i;
-};
+ target_wide_charset_le_name = NULL;
+ target_wide_charset_be_name = NULL;
+ target_wide = target_wide_charset_name;
+ if (!strcmp (target_wide, "auto"))
+ target_wide = gdbarch_auto_wide_charset (gdbarch);
-/* Make sure the iconv cache *CI contains an iconv descriptor
- translating from FROM to TO. If it already does, fine; otherwise,
- close any existing descriptor, and open up a new one. On success,
- return zero; on failure, return -1 and set errno. */
-static int
-check_iconv_cache (struct cached_iconv *ci,
- struct charset *from,
- struct charset *to)
-{
- iconv_t i;
-
- /* Does the cached iconv descriptor match the conversion we're trying
- to do now? */
- if (ci->from == from
- && ci->to == to
- && ci->i != (iconv_t) 0)
- return 0;
-
- /* It doesn't. If we actually had any iconv descriptor open at
- all, close it now. */
- if (ci->i != (iconv_t) 0)
+ len = strlen (target_wide);
+ for (i = 0; charset_enum[i]; ++i)
{
- i = ci->i;
- ci->i = (iconv_t) 0;
-
- if (iconv_close (i) == -1)
- error ("Error closing `iconv' descriptor for "
- "`%s'-to-`%s' character conversion: %s",
- ci->from->name, ci->to->name, safe_strerror (errno));
+ if (strncmp (target_wide, charset_enum[i], len))
+ continue;
+ if ((charset_enum[i][len] == 'B'
+ || charset_enum[i][len] == 'L')
+ && charset_enum[i][len + 1] == 'E'
+ && charset_enum[i][len + 2] == '\0')
+ {
+ if (charset_enum[i][len] == 'B')
+ target_wide_charset_be_name = charset_enum[i];
+ else
+ target_wide_charset_le_name = charset_enum[i];
+ }
}
-
- /* Open a new iconv descriptor for the required conversion. */
- i = iconv_open (to->name, from->name);
- if (i == (iconv_t) -1)
- return -1;
-
- ci->i = i;
- ci->from = from;
- ci->to = to;
-
- return 0;
}
+/* 'Set charset', 'set host-charset', 'set target-charset', 'set
+ target-wide-charset', 'set charset' sfunc's. */
-/* Convert FROM_CHAR using the cached iconv conversion *CI. Return
- non-zero if the conversion was successful, zero otherwise. */
-static int
-cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char)
+static void
+validate (struct gdbarch *gdbarch)
{
- char from;
- ICONV_CONST char *from_ptr = &from;
- char to, *to_ptr = &to;
- size_t from_left = sizeof (from), to_left = sizeof (to);
+ iconv_t desc;
+ const char *host_cset = host_charset ();
+ const char *target_cset = target_charset (gdbarch);
+ const char *target_wide_cset = target_wide_charset_name;
- gdb_assert (ci->i != (iconv_t) 0);
+ if (!strcmp (target_wide_cset, "auto"))
+ target_wide_cset = gdbarch_auto_wide_charset (gdbarch);
- from = from_char;
- if (iconv (ci->i, &from_ptr, &from_left, &to_ptr, &to_left)
- == (size_t) -1)
- {
- /* These all suggest that the input or output character sets
- have multi-byte encodings of some characters, which means
- it's unsuitable for use as a GDB character set. We should
- never have selected it. */
- gdb_assert (errno != E2BIG && errno != EINVAL);
-
- /* This suggests a bug in the code managing *CI. */
- gdb_assert (errno != EBADF);
-
- /* This seems to mean that there is no equivalent character in
- the `to' character set. */
- if (errno == EILSEQ)
- return 0;
-
- /* Anything else is mysterious. */
- internal_error ("Error converting character `%d' from `%s' to `%s' "
- "character set: %s",
- from_char, ci->from->name, ci->to->name,
- safe_strerror (errno));
- }
+ desc = iconv_open (target_wide_cset, host_cset);
+ if (desc == (iconv_t) -1)
+ error ("Cannot convert between character sets `%s' and `%s'",
+ target_wide_cset, host_cset);
+ iconv_close (desc);
- /* If the pointers weren't advanced across the input, that also
- suggests something was wrong. */
- gdb_assert (from_left == 0 && to_left == 0);
+ desc = iconv_open (target_cset, host_cset);
+ if (desc == (iconv_t) -1)
+ error ("Cannot convert between character sets `%s' and `%s'",
+ target_cset, host_cset);
+ iconv_close (desc);
- *to_char = (unsigned char) to;
- return 1;
+ /* Clear the cache. */
+ be_le_arch = NULL;
}
-
+/* This is the sfunc for the 'set charset' command. */
static void
-register_iconv_charsets (void)
+set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c)
{
- /* Here we should check whether various character sets were
- recognized by the local iconv implementation.
-
- The first implementation registered a bunch of character sets
- recognized by iconv, but then we discovered that iconv on Solaris
- and iconv on GNU/Linux had no character sets in common. So we
- replaced them with the hard-coded tables that appear later in the
- file. */
+ /* CAREFUL: set the target charset here as well. */
+ target_charset_name = host_charset_name;
+ validate (get_current_arch ());
}
-#endif /* defined (HAVE_ICONV) */
-
-\f
-/* Fallback routines for systems without iconv. */
-
-#if ! defined (HAVE_ICONV)
-struct cached_iconv { char nothing; };
-
-static int
-check_iconv_cache (struct cached_iconv *ci,
- struct charset *from,
- struct charset *to)
+/* 'set host-charset' command sfunc. We need a wrapper here because
+ the function needs to have a specific signature. */
+static void
+set_host_charset_sfunc (char *charset, int from_tty,
+ struct cmd_list_element *c)
{
- errno = EINVAL;
- return -1;
+ validate (get_current_arch ());
}
-static int
-cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char)
+/* Wrapper for the 'set target-charset' command. */
+static void
+set_target_charset_sfunc (char *charset, int from_tty,
+ struct cmd_list_element *c)
{
- /* This function should never be called. */
- gdb_assert (0);
+ validate (get_current_arch ());
}
+/* Wrapper for the 'set target-wide-charset' command. */
static void
-register_iconv_charsets (void)
+set_target_wide_charset_sfunc (char *charset, int from_tty,
+ struct cmd_list_element *c)
{
+ validate (get_current_arch ());
}
-#endif /* ! defined(HAVE_ICONV) */
-
-\f
-/* Default trivial conversion functions. */
-
-static int
-identity_either_char_to_other (void *baton, int either_char, int *other_char)
+/* sfunc for the 'show charset' command. */
+static void
+show_charset (struct ui_file *file, int from_tty, struct cmd_list_element *c,
+ const char *name)
{
- *other_char = either_char;
- return 1;
+ show_host_charset_name (file, from_tty, c, host_charset_name);
+ show_target_charset_name (file, from_tty, c, target_charset_name);
+ show_target_wide_charset_name (file, from_tty, c, target_wide_charset_name);
}
-
\f
-/* Default non-trivial conversion functions. */
-
-
-static char backslashable[] = "abefnrtv";
-static char *backslashed[] = {"a", "b", "e", "f", "n", "r", "t", "v", "0"};
-static char represented[] = "\a\b\e\f\n\r\t\v";
-
-
-/* Translate TARGET_CHAR into the host character set, and see if it
- matches any of our standard escape sequences. */
-static const char *
-default_c_target_char_has_backslash_escape (void *baton, int target_char)
-{
- int host_char;
- const char *ix;
-
- /* If target_char has no equivalent in the host character set,
- assume it doesn't have a backslashed form. */
- if (! target_char_to_host (target_char, &host_char))
- return NULL;
+/* Accessor functions. */
- ix = strchr (represented, host_char);
- if (ix)
- return backslashed[ix - represented];
- else
- return NULL;
-}
-
-
-/* Translate the backslash the way we would in the host character set,
- and then try to translate that into the target character set. */
-static int
-default_c_parse_backslash (void *baton, int host_char, int *target_char)
+const char *
+host_charset (void)
{
- const char *ix;
-
- ix = strchr (backslashable, host_char);
-
- if (! ix)
- return 0;
- else
- return host_char_to_target (represented[ix - backslashable],
- target_char);
+ if (!strcmp (host_charset_name, "auto"))
+ return auto_host_charset_name;
+ return host_charset_name;
}
-
-/* Convert using a cached iconv descriptor. */
-static int
-iconv_convert (void *baton, int from_char, int *to_char)
+const char *
+target_charset (struct gdbarch *gdbarch)
{
- struct cached_iconv *ci = baton;
- return cached_iconv_convert (ci, from_char, to_char);
+ if (!strcmp (target_charset_name, "auto"))
+ return gdbarch_auto_charset (gdbarch);
+ return target_charset_name;
}
-
-\f
-/* Conversion tables. */
-
-
-/* I'd much rather fall back on iconv whenever possible. But the
- character set names you use with iconv aren't standardized at all,
- a lot of platforms have really meager character set coverage, etc.
- I wanted to have at least something we could use to exercise the
- test suite on all platforms.
-
- In the long run, we should have a configure-time process explore
- somehow which character sets the host platform supports, and some
- arrangement that allows GDB users to use platform-indepedent names
- for character sets. */
-
-
-/* We generated these tables using iconv on a GNU/Linux machine. */
-
-
-static int ascii_to_iso_8859_1_table[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 80 */
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 96 */
- 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 112 */
- 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 128 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */
-};
-
-
-static int ascii_to_ebcdic_us_table[] = {
- 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
- 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
- 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
- 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
- 215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109, /* 96 */
- 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
- 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */
-};
-
-
-static int ascii_to_ibm1047_table[] = {
- 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
- 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
- 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
- 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
- 215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109, /* 96 */
- 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
- 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */
-};
-
-
-static int iso_8859_1_to_ascii_table[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 80 */
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 96 */
- 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 112 */
- 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 128 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */
-};
-
-
-static int iso_8859_1_to_ebcdic_us_table[] = {
- 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
- 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
- 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
- 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
- 215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109, /* 96 */
- 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
- 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */
- 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27, /* 144 */
- 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62,255, /* 160 */
- -1, -1, 74, -1, -1, -1,106, -1, -1, -1, -1, -1, 95, -1, -1, -1, /* 176 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */
-};
-
-
-static int iso_8859_1_to_ibm1047_table[] = {
- 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
- 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
- 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
- 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
- 215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109, /* 96 */
- 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
- 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */
- 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27, /* 144 */
- 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62,255, /* 160 */
- 65,170, 74,177,159,178,106,181,187,180,154,138,176,202,175,188, /* 176 */
- 144,143,234,250,190,160,182,179,157,218,155,139,183,184,185,171, /* 192 */
- 100,101, 98,102, 99,103,158,104,116,113,114,115,120,117,118,119, /* 208 */
- 172,105,237,238,235,239,236,191,128,253,254,251,252,186,174, 89, /* 224 */
- 68, 69, 66, 70, 67, 71,156, 72, 84, 81, 82, 83, 88, 85, 86, 87, /* 240 */
- 140, 73,205,206,203,207,204,225,112,221,222,219,220,141,142,223 /* 256 */
-};
-
-
-static int ebcdic_us_to_ascii_table[] = {
- 0, 1, 2, 3, -1, 9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19, -1, -1, 8, -1, 24, 25, -1, -1, 28, 29, 30, 31, /* 32 */
- -1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1, 5, 6, 7, /* 48 */
- -1, -1, 22, -1, -1, -1, -1, 4, -1, -1, -1, -1, 20, 21, -1, 26, /* 64 */
- 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124, /* 80 */
- 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, -1, /* 96 */
- 45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63, /* 112 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */
- -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */
- -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */
- -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1, /* 176 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
- 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */
- 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */
- 92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1 /* 256 */
-};
-
-
-static int ebcdic_us_to_iso_8859_1_table[] = {
- 0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31, /* 32 */
- 128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7, /* 48 */
- 144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26, /* 64 */
- 32, -1, -1, -1, -1, -1, -1, -1, -1, -1,162, 46, 60, 40, 43,124, /* 80 */
- 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59,172, /* 96 */
- 45, 47, -1, -1, -1, -1, -1, -1, -1, -1,166, 44, 37, 95, 62, 63, /* 112 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */
- -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */
- -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */
- -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1, /* 176 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
- 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */
- 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */
- 92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,159 /* 256 */
-};
-
-
-static int ebcdic_us_to_ibm1047_table[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
- 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79, /* 80 */
- 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94,176, /* 96 */
- 96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111, /* 112 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127, /* 128 */
- -1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1, /* 144 */
- -1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1, /* 160 */
- -1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1, /* 176 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
- 192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1, /* 208 */
- 208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1, /* 224 */
- 224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1, /* 240 */
- 240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255 /* 256 */
-};
-
-
-static int ibm1047_to_ascii_table[] = {
- 0, 1, 2, 3, -1, 9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19, -1, -1, 8, -1, 24, 25, -1, -1, 28, 29, 30, 31, /* 32 */
- -1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1, 5, 6, 7, /* 48 */
- -1, -1, 22, -1, -1, -1, -1, 4, -1, -1, -1, -1, 20, 21, -1, 26, /* 64 */
- 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124, /* 80 */
- 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, 94, /* 96 */
- 45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63, /* 112 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */
- -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */
- -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */
- -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, 91, -1, -1, /* 176 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, /* 192 */
- 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */
- 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */
- 92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1 /* 256 */
-};
-
-
-static int ibm1047_to_iso_8859_1_table[] = {
- 0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31, /* 32 */
- 128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7, /* 48 */
- 144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26, /* 64 */
- 32,160,226,228,224,225,227,229,231,241,162, 46, 60, 40, 43,124, /* 80 */
- 38,233,234,235,232,237,238,239,236,223, 33, 36, 42, 41, 59, 94, /* 96 */
- 45, 47,194,196,192,193,195,197,199,209,166, 44, 37, 95, 62, 63, /* 112 */
- 248,201,202,203,200,205,206,207,204, 96, 58, 35, 64, 39, 61, 34, /* 128 */
- 216, 97, 98, 99,100,101,102,103,104,105,171,187,240,253,254,177, /* 144 */
- 176,106,107,108,109,110,111,112,113,114,170,186,230,184,198,164, /* 160 */
- 181,126,115,116,117,118,119,120,121,122,161,191,208, 91,222,174, /* 176 */
- 172,163,165,183,169,167,182,188,189,190,221,168,175, 93,180,215, /* 192 */
- 123, 65, 66, 67, 68, 69, 70, 71, 72, 73,173,244,246,242,243,245, /* 208 */
- 125, 74, 75, 76, 77, 78, 79, 80, 81, 82,185,251,252,249,250,255, /* 224 */
- 92,247, 83, 84, 85, 86, 87, 88, 89, 90,178,212,214,210,211,213, /* 240 */
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,179,219,220,217,218,159 /* 256 */
-};
-
-
-static int ibm1047_to_ebcdic_us_table[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
- 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79, /* 80 */
- 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94, -1, /* 96 */
- 96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111, /* 112 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127, /* 128 */
- -1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1, /* 144 */
- -1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1, /* 160 */
- -1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1, /* 176 */
- 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
- 192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1, /* 208 */
- 208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1, /* 224 */
- 224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1, /* 240 */
- 240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255 /* 256 */
-};
-
-
-static int
-table_convert_char (void *baton, int from, int *to)
+const char *
+target_wide_charset (struct gdbarch *gdbarch)
{
- int *table = (int *) baton;
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- if (0 <= from && from <= 255
- && table[from] != -1)
+ set_be_le_names (gdbarch);
+ if (byte_order == BFD_ENDIAN_BIG)
{
- *to = table[from];
- return 1;
+ if (target_wide_charset_be_name)
+ return target_wide_charset_be_name;
}
else
- return 0;
+ {
+ if (target_wide_charset_le_name)
+ return target_wide_charset_le_name;
+ }
+
+ if (!strcmp (target_wide_charset_name, "auto"))
+ return gdbarch_auto_wide_charset (gdbarch);
+
+ return target_wide_charset_name;
}
+\f
+/* Host character set management. For the time being, we assume that
+ the host character set is some superset of ASCII. */
-static struct translation *
-table_translation (const char *from, const char *to, int *table,
- const char *(*c_target_char_has_backslash_escape)
- (void *baton, int target_char),
- void *c_target_char_has_backslash_escape_baton,
- int (*c_parse_backslash) (void *baton,
- int host_char,
- int *target_char),
- void *c_parse_backslash_baton)
+char
+host_letter_to_control_character (char c)
{
- struct translation *t = xmalloc (sizeof (*t));
-
- memset (t, 0, sizeof (*t));
- t->from = from;
- t->to = to;
- t->c_target_char_has_backslash_escape = c_target_char_has_backslash_escape;
- t->c_target_char_has_backslash_escape_baton
- = c_target_char_has_backslash_escape_baton;
- t->c_parse_backslash = c_parse_backslash;
- t->c_parse_backslash_baton = c_parse_backslash_baton;
- t->convert_char = table_convert_char;
- t->convert_char_baton = (void *) table;
-
- return t;
+ if (c == '?')
+ return 0177;
+ return c & 0237;
}
+/* Convert a host character, C, to its hex value. C must already have
+ been validated using isxdigit. */
-static struct translation *
-simple_table_translation (const char *from, const char *to, int *table)
+int
+host_hex_value (char c)
{
- return table_translation (from, to, table, 0, 0, 0, 0);
+ if (isdigit (c))
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return 10 + c - 'a';
+ gdb_assert (c >= 'A' && c <= 'F');
+ return 10 + c - 'A';
}
-
\f
-/* Setting and retrieving the host and target charsets. */
-
-
-/* The current host and target character sets. */
-static struct charset *current_host_charset, *current_target_charset;
-
-/* The current functions and batons we should use for the functions in
- charset.h. */
-
-static const char *(*c_target_char_has_backslash_escape_func)
- (void *baton, int target_char);
-static void *c_target_char_has_backslash_escape_baton;
-
-static int (*c_parse_backslash_func) (void *baton,
- int host_char,
- int *target_char);
-static void *c_parse_backslash_baton;
-
-static int (*host_char_to_target_func) (void *baton,
- int host_char,
- int *target_char);
-static void *host_char_to_target_baton;
-
-static int (*target_char_to_host_func) (void *baton,
- int target_char,
- int *host_char);
-static void *target_char_to_host_baton;
-
-
-/* Cached iconv conversions, that might be useful to fallback
- routines. */
-static struct cached_iconv cached_iconv_host_to_target;
-static struct cached_iconv cached_iconv_target_to_host;
+/* Public character management functions. */
+/* A cleanup function which is run to close an iconv descriptor. */
-/* Set the host and target character sets to HOST and TARGET. */
static void
-set_host_and_target_charsets (struct charset *host, struct charset *target)
+cleanup_iconv (void *p)
{
- struct translation *h2t, *t2h;
+ iconv_t *descp = p;
+ iconv_close (*descp);
+}
- /* If they're not both initialized yet, then just do nothing for
- now. As soon as we're done running our initialize function,
- everything will be initialized. */
- if (! host || ! target)
+void
+convert_between_encodings (const char *from, const char *to,
+ const gdb_byte *bytes, unsigned int num_bytes,
+ int width, struct obstack *output,
+ enum transliterations translit)
+{
+ iconv_t desc;
+ struct cleanup *cleanups;
+ size_t inleft;
+ char *inp;
+ unsigned int space_request;
+
+ /* Often, the host and target charsets will be the same. */
+ if (!strcmp (from, to))
{
- current_host_charset = host;
- current_target_charset = target;
+ obstack_grow (output, bytes, num_bytes);
return;
}
- h2t = lookup_translation (host->name, target->name);
- t2h = lookup_translation (target->name, host->name);
-
- /* If the translations don't provide conversion functions, make sure
- iconv can back them up. Do this *before* modifying any state. */
- if (host != target)
- {
- if (! h2t || ! h2t->convert_char)
- {
- if (check_iconv_cache (&cached_iconv_host_to_target, host, target)
- < 0)
- error ("GDB can't convert from the `%s' character set to `%s'.",
- host->name, target->name);
- }
- if (! t2h || ! t2h->convert_char)
- {
- if (check_iconv_cache (&cached_iconv_target_to_host, target, host)
- < 0)
- error ("GDB can't convert from the `%s' character set to `%s'.",
- target->name, host->name);
- }
- }
-
- if (t2h && t2h->c_target_char_has_backslash_escape)
- {
- c_target_char_has_backslash_escape_func
- = t2h->c_target_char_has_backslash_escape;
- c_target_char_has_backslash_escape_baton
- = t2h->c_target_char_has_backslash_escape_baton;
- }
- else
- c_target_char_has_backslash_escape_func
- = default_c_target_char_has_backslash_escape;
+ desc = iconv_open (to, from);
+ if (desc == (iconv_t) -1)
+ perror_with_name ("Converting character sets");
+ cleanups = make_cleanup (cleanup_iconv, &desc);
- if (h2t && h2t->c_parse_backslash)
- {
- c_parse_backslash_func = h2t->c_parse_backslash;
- c_parse_backslash_baton = h2t->c_parse_backslash_baton;
- }
- else
- c_parse_backslash_func = default_c_parse_backslash;
+ inleft = num_bytes;
+ inp = (char *) bytes;
- if (h2t && h2t->convert_char)
- {
- host_char_to_target_func = h2t->convert_char;
- host_char_to_target_baton = h2t->convert_char_baton;
- }
- else if (host == target)
- host_char_to_target_func = identity_either_char_to_other;
- else
- {
- host_char_to_target_func = iconv_convert;
- host_char_to_target_baton = &cached_iconv_host_to_target;
- }
+ space_request = num_bytes;
- if (t2h && t2h->convert_char)
- {
- target_char_to_host_func = t2h->convert_char;
- target_char_to_host_baton = t2h->convert_char_baton;
- }
- else if (host == target)
- target_char_to_host_func = identity_either_char_to_other;
- else
+ while (inleft > 0)
{
- target_char_to_host_func = iconv_convert;
- target_char_to_host_baton = &cached_iconv_target_to_host;
+ char *outp;
+ size_t outleft, r;
+ int old_size;
+
+ old_size = obstack_object_size (output);
+ obstack_blank (output, space_request);
+
+ outp = obstack_base (output) + old_size;
+ outleft = space_request;
+
+ r = iconv (desc, (ICONV_CONST char **) &inp, &inleft, &outp, &outleft);
+
+ /* Now make sure that the object on the obstack only includes
+ bytes we have converted. */
+ obstack_blank (output, - (int) outleft);
+
+ if (r == (size_t) -1)
+ {
+ switch (errno)
+ {
+ case EILSEQ:
+ {
+ int i;
+
+ /* Invalid input sequence. */
+ if (translit == translit_none)
+ error (_("Could not convert character to `%s' character set"),
+ to);
+
+ /* We emit escape sequence for the bytes, skip them,
+ and try again. */
+ for (i = 0; i < width; ++i)
+ {
+ char octal[5];
+
+ sprintf (octal, "\\%.3o", *inp & 0xff);
+ obstack_grow_str (output, octal);
+
+ ++inp;
+ --inleft;
+ }
+ }
+ break;
+
+ case E2BIG:
+ /* We ran out of space in the output buffer. Make it
+ bigger next time around. */
+ space_request *= 2;
+ break;
+
+ case EINVAL:
+ /* Incomplete input sequence. FIXME: ought to report this
+ to the caller somehow. */
+ inleft = 0;
+ break;
+
+ default:
+ perror_with_name ("Internal error while converting character sets");
+ }
+ }
}
- current_host_charset = host;
- current_target_charset = target;
+ do_cleanups (cleanups);
}
+\f
-static struct charset *
-lookup_charset_or_error (const char *name)
+/* An iterator that returns host wchar_t's from a target string. */
+struct wchar_iterator
{
- struct charset *cs = lookup_charset (name);
-
- if (! cs)
- error ("GDB doesn't know of any character set named `%s'.", name);
+ /* The underlying iconv descriptor. */
+ iconv_t desc;
- return cs;
-}
-
+ /* The input string. This is updated as convert characters. */
+ char *input;
+ /* The number of bytes remaining in the input. */
+ size_t bytes;
-static void
-check_valid_host_charset (struct charset *cs)
-{
- if (! cs->valid_host_charset)
- error ("GDB can't use `%s' as its host character set.", cs->name);
-}
+ /* The width of an input character. */
+ size_t width;
+ /* The output buffer and its size. */
+ gdb_wchar_t *out;
+ size_t out_size;
+};
-void
-set_host_charset (const char *charset)
+/* Create a new iterator. */
+struct wchar_iterator *
+make_wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset,
+ size_t width)
{
- struct charset *cs = lookup_charset_or_error (charset);
- check_valid_host_charset (cs);
- set_host_and_target_charsets (cs, current_target_charset);
-}
-
+ struct wchar_iterator *result;
+ iconv_t desc;
-const char *
-host_charset (void)
-{
- return current_host_charset->name;
-}
+ desc = iconv_open (INTERMEDIATE_ENCODING, charset);
+ if (desc == (iconv_t) -1)
+ perror_with_name ("Converting character sets");
+ result = XNEW (struct wchar_iterator);
+ result->desc = desc;
+ result->input = (char *) input;
+ result->bytes = bytes;
+ result->width = width;
-void
-set_target_charset (const char *charset)
-{
- struct charset *cs = lookup_charset_or_error (charset);
+ result->out = XNEW (gdb_wchar_t);
+ result->out_size = 1;
- set_host_and_target_charsets (current_host_charset, cs);
+ return result;
}
-
-const char *
-target_charset (void)
+static void
+do_cleanup_iterator (void *p)
{
- return current_target_charset->name;
-}
+ struct wchar_iterator *iter = p;
-
-\f
-/* Public character management functions. */
-
-
-const char *
-c_target_char_has_backslash_escape (int target_char)
-{
- return ((*c_target_char_has_backslash_escape_func)
- (c_target_char_has_backslash_escape_baton, target_char));
+ iconv_close (iter->desc);
+ xfree (iter->out);
+ xfree (iter);
}
-
-int
-c_parse_backslash (int host_char, int *target_char)
+struct cleanup *
+make_cleanup_wchar_iterator (struct wchar_iterator *iter)
{
- return (*c_parse_backslash_func) (c_parse_backslash_baton,
- host_char, target_char);
+ return make_cleanup (do_cleanup_iterator, iter);
}
-
int
-host_char_print_literally (int host_char)
-{
- return ((*current_host_charset->host_char_print_literally)
- (current_host_charset->host_char_print_literally_baton,
- host_char));
+wchar_iterate (struct wchar_iterator *iter,
+ enum wchar_iterate_result *out_result,
+ gdb_wchar_t **out_chars,
+ const gdb_byte **ptr,
+ size_t *len)
+{
+ size_t out_request;
+
+ /* Try to convert some characters. At first we try to convert just
+ a single character. The reason for this is that iconv does not
+ necessarily update its outgoing arguments when it encounters an
+ invalid input sequence -- but we want to reliably report this to
+ our caller so it can emit an escape sequence. */
+ out_request = 1;
+ while (iter->bytes > 0)
+ {
+ char *outptr = (char *) &iter->out[0];
+ char *orig_inptr = iter->input;
+ size_t orig_in = iter->bytes;
+ size_t out_avail = out_request * sizeof (gdb_wchar_t);
+ size_t num;
+ size_t r = iconv (iter->desc,
+ (ICONV_CONST char **) &iter->input, &iter->bytes,
+ &outptr, &out_avail);
+
+ if (r == (size_t) -1)
+ {
+ switch (errno)
+ {
+ case EILSEQ:
+ /* Invalid input sequence. Skip it, and let the caller
+ know about it. */
+ *out_result = wchar_iterate_invalid;
+ *ptr = iter->input;
+ *len = iter->width;
+ iter->input += iter->width;
+ iter->bytes -= iter->width;
+ return 0;
+
+ case E2BIG:
+ /* We ran out of space. We still might have converted a
+ character; if so, return it. Otherwise, grow the
+ buffer and try again. */
+ if (out_avail < out_request * sizeof (gdb_wchar_t))
+ break;
+
+ ++out_request;
+ if (out_request > iter->out_size)
+ {
+ iter->out_size = out_request;
+ iter->out = xrealloc (iter->out,
+ out_request * sizeof (gdb_wchar_t));
+ }
+ continue;
+
+ case EINVAL:
+ /* Incomplete input sequence. Let the caller know, and
+ arrange for future calls to see EOF. */
+ *out_result = wchar_iterate_incomplete;
+ *ptr = iter->input;
+ *len = iter->bytes;
+ iter->bytes = 0;
+ return 0;
+
+ default:
+ perror_with_name ("Internal error while converting character sets");
+ }
+ }
+
+ /* We converted something. */
+ num = out_request - out_avail / sizeof (gdb_wchar_t);
+ *out_result = wchar_iterate_ok;
+ *out_chars = iter->out;
+ *ptr = orig_inptr;
+ *len = orig_in - iter->bytes;
+ return num;
+ }
+
+ /* Really done. */
+ *out_result = wchar_iterate_eof;
+ return -1;
}
+\f
+/* The charset.c module initialization function. */
-int
-target_char_to_control_char (int target_char, int *target_ctrl_char)
-{
- return ((*current_target_charset->target_char_to_control_char)
- (current_target_charset->target_char_to_control_char_baton,
- target_char, target_ctrl_char));
-}
+extern initialize_file_ftype _initialize_charset; /* -Wmissing-prototype */
+DEF_VEC_P (char_ptr);
-int
-host_char_to_target (int host_char, int *target_char)
-{
- return ((*host_char_to_target_func)
- (host_char_to_target_baton, host_char, target_char));
-}
+static VEC (char_ptr) *charsets;
+#ifdef PHONY_ICONV
-int
-target_char_to_host (int target_char, int *host_char)
+static void
+find_charset_names (void)
{
- return ((*target_char_to_host_func)
- (target_char_to_host_baton, target_char, host_char));
+ VEC_safe_push (char_ptr, charsets, GDB_DEFAULT_HOST_CHARSET);
+ VEC_safe_push (char_ptr, charsets, NULL);
}
+#else /* PHONY_ICONV */
-\f
-/* Commands. */
+/* Sometimes, libiconv redefines iconvlist as libiconvlist -- but
+ provides different symbols in the static and dynamic libraries.
+ So, configure may see libiconvlist but not iconvlist. But, calling
+ iconvlist is the right thing to do and will work. Hence we do a
+ check here but unconditionally call iconvlist below. */
+#if defined (HAVE_ICONVLIST) || defined (HAVE_LIBICONVLIST)
+/* A helper function that adds some character sets to the vector of
+ all character sets. This is a callback function for iconvlist. */
-/* List the valid character sets. If HOST_ONLY is non-zero, list only
- those character sets which can be used as GDB's host character set. */
-static void
-list_charsets (int host_only)
+static int
+add_one (unsigned int count, const char *const *names, void *data)
{
- struct charset *cs;
+ unsigned int i;
- printf_filtered ("Valid character sets are:\n");
+ for (i = 0; i < count; ++i)
+ VEC_safe_push (char_ptr, charsets, xstrdup (names[i]));
- for (cs = all_charsets; cs; cs = cs->next)
- if (host_only && cs->valid_host_charset)
- printf_filtered (" %s\n", cs->name);
- else
- printf_filtered (" %s %s\n",
- cs->name,
- cs->valid_host_charset ? "*" : " ");
-
- if (! host_only)
- printf_filtered ("* - can be used as a host character set\n");
+ return 0;
}
-
static void
-set_charset_command (char *arg, int from_tty)
+find_charset_names (void)
{
- if (! arg || arg[0] == '\0')
- list_charsets (0);
- else
- {
- struct charset *cs = lookup_charset_or_error (arg);
- check_valid_host_charset (cs);
- set_host_and_target_charsets (cs, cs);
- }
+ iconvlist (add_one, NULL);
+ VEC_safe_push (char_ptr, charsets, NULL);
}
+#else
-static void
-set_host_charset_command (char *arg, int from_tty)
+/* Return non-zero if LINE (output from iconv) should be ignored.
+ Older iconv programs (e.g. 2.2.2) include the human readable
+ introduction even when stdout is not a tty. Newer versions omit
+ the intro if stdout is not a tty. */
+
+static int
+ignore_line_p (const char *line)
{
- if (! arg || arg[0] == '\0')
- list_charsets (1);
- else
+ /* This table is used to filter the output. If this text appears
+ anywhere in the line, it is ignored (strstr is used). */
+ static const char * const ignore_lines[] =
+ {
+ "The following",
+ "not necessarily",
+ "the FROM and TO",
+ "listed with several",
+ NULL
+ };
+ int i;
+
+ for (i = 0; ignore_lines[i] != NULL; ++i)
{
- struct charset *cs = lookup_charset_or_error (arg);
- check_valid_host_charset (cs);
- set_host_and_target_charsets (cs, current_target_charset);
+ if (strstr (line, ignore_lines[i]) != NULL)
+ return 1;
}
-}
+ return 0;
+}
static void
-set_target_charset_command (char *arg, int from_tty)
-{
- if (! arg || arg[0] == '\0')
- list_charsets (0);
- else
+find_charset_names (void)
+{
+ struct pex_obj *child;
+ char *args[3];
+ int err, status;
+ int fail = 1;
+ struct gdb_environ *iconv_env;
+
+ /* Older iconvs, e.g. 2.2.2, don't omit the intro text if stdout is not
+ a tty. We need to recognize it and ignore it. This text is subject
+ to translation, so force LANGUAGE=C. */
+ iconv_env = make_environ ();
+ init_environ (iconv_env);
+ set_in_environ (iconv_env, "LANGUAGE", "C");
+ set_in_environ (iconv_env, "LC_ALL", "C");
+
+ child = pex_init (PEX_USE_PIPES, "iconv", NULL);
+
+ args[0] = "iconv";
+ args[1] = "-l";
+ args[2] = NULL;
+ /* Note that we simply ignore errors here. */
+ if (!pex_run_in_environment (child, PEX_SEARCH | PEX_STDERR_TO_STDOUT,
+ "iconv", args, environ_vector (iconv_env),
+ NULL, NULL, &err))
{
- struct charset *cs = lookup_charset_or_error (arg);
- set_host_and_target_charsets (current_host_charset, cs);
+ FILE *in = pex_read_output (child, 0);
+
+ /* POSIX says that iconv -l uses an unspecified format. We
+ parse the glibc and libiconv formats; feel free to add others
+ as needed. */
+
+ while (!feof (in))
+ {
+ /* The size of buf is chosen arbitrarily. */
+ char buf[1024];
+ char *start, *r;
+ int len;
+
+ r = fgets (buf, sizeof (buf), in);
+ if (!r)
+ break;
+ len = strlen (r);
+ if (len <= 3)
+ continue;
+ if (ignore_line_p (r))
+ continue;
+
+ /* Strip off the newline. */
+ --len;
+ /* Strip off one or two '/'s. glibc will print lines like
+ "8859_7//", but also "10646-1:1993/UCS4/". */
+ if (buf[len - 1] == '/')
+ --len;
+ if (buf[len - 1] == '/')
+ --len;
+ buf[len] = '\0';
+
+ /* libiconv will print multiple entries per line, separated
+ by spaces. Older iconvs will print multiple entries per line,
+ indented by two spaces, and separated by ", "
+ (i.e. the human readable form). */
+ start = buf;
+ while (1)
+ {
+ int keep_going;
+ char *p;
+
+ /* Skip leading blanks. */
+ for (p = start; *p && *p == ' '; ++p)
+ ;
+ start = p;
+ /* Find the next space, comma, or end-of-line. */
+ for ( ; *p && *p != ' ' && *p != ','; ++p)
+ ;
+ /* Ignore an empty result. */
+ if (p == start)
+ break;
+ keep_going = *p;
+ *p = '\0';
+ VEC_safe_push (char_ptr, charsets, xstrdup (start));
+ if (!keep_going)
+ break;
+ /* Skip any extra spaces. */
+ for (start = p + 1; *start && *start == ' '; ++start)
+ ;
+ }
+ }
+
+ if (pex_get_status (child, 1, &status)
+ && WIFEXITED (status) && !WEXITSTATUS (status))
+ fail = 0;
+
}
-}
+ pex_free (child);
+ free_environ (iconv_env);
-static void
-show_charset_command (char *arg, int from_tty)
-{
- if (current_host_charset == current_target_charset)
+ if (fail)
{
- printf_filtered ("The current host and target character set is `%s'.\n",
- host_charset ());
+ /* Some error occurred, so drop the vector. */
+ int ix;
+ char *elt;
+ for (ix = 0; VEC_iterate (char_ptr, charsets, ix, elt); ++ix)
+ xfree (elt);
+ VEC_truncate (char_ptr, charsets, 0);
}
else
- {
- printf_filtered ("The current host character set is `%s'.\n",
- host_charset ());
- printf_filtered ("The current target character set is `%s'.\n",
- target_charset ());
- }
+ VEC_safe_push (char_ptr, charsets, NULL);
}
+#endif /* HAVE_ICONVLIST || HAVE_LIBICONVLIST */
+#endif /* PHONY_ICONV */
-\f
-/* The charset.c module initialization function. */
+/* The "auto" target charset used by default_auto_charset. */
+static const char *auto_target_charset_name = GDB_DEFAULT_TARGET_CHARSET;
-#ifndef GDB_DEFAULT_HOST_CHARSET
-#define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1"
-#endif
+const char *
+default_auto_charset (void)
+{
+ return auto_target_charset_name;
+}
-#ifndef GDB_DEFAULT_TARGET_CHARSET
-#define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1"
-#endif
+const char *
+default_auto_wide_charset (void)
+{
+ return GDB_DEFAULT_TARGET_WIDE_CHARSET;
+}
void
_initialize_charset (void)
{
- /* Register all the character set GDB knows about.
-
- You should use the same names that iconv does, where possible, to
- take advantage of the iconv-based default behaviors.
-
- CAUTION: if you register a character set, you must also register
- as many translations as are necessary to make that character set
- interoperate correctly with all the other character sets. We do
- provide default behaviors when no translation is available, or
- when a translation's function pointer for a particular operation
- is zero. Hopefully, these defaults will be correct often enough
- that we won't need to provide too many translations. */
- register_charset (simple_charset ("ascii", 1,
- ascii_print_literally, 0,
- ascii_to_control, 0));
- register_charset (iso_8859_family_charset ("iso-8859-1"));
- register_charset (ebcdic_family_charset ("ebcdic-us"));
- register_charset (ebcdic_family_charset ("ibm1047"));
- register_iconv_charsets ();
+ /* The first element is always "auto". */
+ VEC_safe_push (char_ptr, charsets, xstrdup ("auto"));
+ find_charset_names ();
+ if (VEC_length (char_ptr, charsets) > 1)
+ charset_enum = (const char **) VEC_address (char_ptr, charsets);
+ else
+ charset_enum = default_charset_names;
+
+#ifndef PHONY_ICONV
+#ifdef HAVE_LANGINFO_CODESET
+ /* The result of nl_langinfo may be overwritten later. This may
+ leak a little memory, if the user later changes the host charset,
+ but that doesn't matter much. */
+ auto_host_charset_name = xstrdup (nl_langinfo (CODESET));
+ /* Solaris will return `646' here -- but the Solaris iconv then
+ does not accept this. Darwin (and maybe FreeBSD) may return "" here,
+ which GNU libiconv doesn't like (infinite loop). */
+ if (!strcmp (auto_host_charset_name, "646") || !*auto_host_charset_name)
+ auto_host_charset_name = "ASCII";
+ auto_target_charset_name = auto_host_charset_name;
+#elif defined (USE_WIN32API)
{
- struct { char *from; char *to; int *table; } tlist[] = {
- { "ascii", "iso-8859-1", ascii_to_iso_8859_1_table },
- { "ascii", "ebcdic-us", ascii_to_ebcdic_us_table },
- { "ascii", "ibm1047", ascii_to_ibm1047_table },
- { "iso-8859-1", "ascii", iso_8859_1_to_ascii_table },
- { "iso-8859-1", "ebcdic-us", iso_8859_1_to_ebcdic_us_table },
- { "iso-8859-1", "ibm1047", iso_8859_1_to_ibm1047_table },
- { "ebcdic-us", "ascii", ebcdic_us_to_ascii_table },
- { "ebcdic-us", "iso-8859-1", ebcdic_us_to_iso_8859_1_table },
- { "ebcdic-us", "ibm1047", ebcdic_us_to_ibm1047_table },
- { "ibm1047", "ascii", ibm1047_to_ascii_table },
- { "ibm1047", "iso-8859-1", ibm1047_to_iso_8859_1_table },
- { "ibm1047", "ebcdic-us", ibm1047_to_ebcdic_us_table }
- };
-
- int i;
+ static char w32_host_default_charset[16]; /* "CP" + x<=5 digits + paranoia. */
- for (i = 0; i < (sizeof (tlist) / sizeof (tlist[0])); i++)
- register_translation (simple_table_translation (tlist[i].from,
- tlist[i].to,
- tlist[i].table));
+ snprintf (w32_host_default_charset, sizeof w32_host_default_charset,
+ "CP%d", GetACP());
+ auto_host_charset_name = w32_host_default_charset;
+ auto_target_charset_name = auto_host_charset_name;
}
+#endif
+#endif
- set_host_charset (GDB_DEFAULT_HOST_CHARSET);
- set_target_charset (GDB_DEFAULT_TARGET_CHARSET);
-
- add_cmd ("charset", class_support, set_charset_command,
- "Use CHARSET as the host and target character set.\n"
- "The `host character set' is the one used by the system GDB is running on.\n"
- "The `target character set' is the one used by the program being debugged.\n"
- "You may only use supersets of ASCII for your host character set; GDB does\n"
- "not support any others.\n"
- "To see a list of the character sets GDB supports, type `set charset'\n"
- "with no argument.",
- &setlist);
-
- add_cmd ("host-charset", class_support, set_host_charset_command,
- "Use CHARSET as the host character set.\n"
- "The `host character set' is the one used by the system GDB is running on.\n"
- "You may only use supersets of ASCII for your host character set; GDB does\n"
- "not support any others.\n"
- "To see a list of the character sets GDB supports, type `set host-charset'\n"
- "with no argument.",
- &setlist);
-
- add_cmd ("target-charset", class_support, set_target_charset_command,
- "Use CHARSET as the target character set.\n"
- "The `target character set' is the one used by the program being debugged.\n"
- "GDB translates characters and strings between the host and target\n"
- "character sets as needed.\n"
- "To see a list of the character sets GDB supports, type `set target-charset'\n"
- "with no argument.",
- &setlist);
-
- add_cmd ("charset", class_support, show_charset_command,
- "Show the current host and target character sets.",
- &showlist);
- add_alias_cmd ("host-charset", "charset", class_alias, 1, &showlist);
- add_alias_cmd ("target-charset", "charset", class_alias, 1, &showlist);
+ add_setshow_enum_cmd ("charset", class_support,
+ charset_enum, &host_charset_name, _("\
+Set the host and target character sets."), _("\
+Show the host and target character sets."), _("\
+The `host character set' is the one used by the system GDB is running on.\n\
+The `target character set' is the one used by the program being debugged.\n\
+You may only use supersets of ASCII for your host character set; GDB does\n\
+not support any others.\n\
+To see a list of the character sets GDB supports, type `set charset <TAB>'."),
+ /* Note that the sfunc below needs to set
+ target_charset_name, because the 'set
+ charset' command sets two variables. */
+ set_charset_sfunc,
+ show_charset,
+ &setlist, &showlist);
+
+ add_setshow_enum_cmd ("host-charset", class_support,
+ charset_enum, &host_charset_name, _("\
+Set the host character set."), _("\
+Show the host character set."), _("\
+The `host character set' is the one used by the system GDB is running on.\n\
+You may only use supersets of ASCII for your host character set; GDB does\n\
+not support any others.\n\
+To see a list of the character sets GDB supports, type `set host-charset <TAB>'."),
+ set_host_charset_sfunc,
+ show_host_charset_name,
+ &setlist, &showlist);
+
+ add_setshow_enum_cmd ("target-charset", class_support,
+ charset_enum, &target_charset_name, _("\
+Set the target character set."), _("\
+Show the target character set."), _("\
+The `target character set' is the one used by the program being debugged.\n\
+GDB translates characters and strings between the host and target\n\
+character sets as needed.\n\
+To see a list of the character sets GDB supports, type `set target-charset'<TAB>"),
+ set_target_charset_sfunc,
+ show_target_charset_name,
+ &setlist, &showlist);
+
+ add_setshow_enum_cmd ("target-wide-charset", class_support,
+ charset_enum, &target_wide_charset_name,
+ _("\
+Set the target wide character set."), _("\
+Show the target wide character set."), _("\
+The `target wide character set' is the one used by the program being debugged.\n\
+In particular it is the encoding used by `wchar_t'.\n\
+GDB translates characters and strings between the host and target\n\
+character sets as needed.\n\
+To see a list of the character sets GDB supports, type\n\
+`set target-wide-charset'<TAB>"),
+ set_target_wide_charset_sfunc,
+ show_target_wide_charset_name,
+ &setlist, &showlist);
}