#include "defs.h"
#include "charset.h"
#include "gdbcmd.h"
#include "gdb_assert.h"
#include <stddef.h>
#include "gdb_string.h"
#include <ctype.h>
#ifdef HAVE_ICONV
#include <iconv.h>
#endif
struct charset {
struct charset *next;
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 translation {
struct translation *next;
const char *from, *to;
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;
int (*convert_char) (void *baton, int from, int *to);
void *convert_char_baton;
};
#ifdef NM_NEXTSTEP
#ifndef GDB_DEFAULT_HOST_CHARSET
#define GDB_DEFAULT_HOST_CHARSET "UTF-8"
#endif
#ifndef GDB_DEFAULT_TARGET_CHARSET
#define GDB_DEFAULT_TARGET_CHARSET "UTF-8"
#endif
#else
#ifndef GDB_DEFAULT_HOST_CHARSET
#define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1"
#endif
#ifndef GDB_DEFAULT_TARGET_CHARSET
#define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1"
#endif
#endif
static const char *host_charset_name = GDB_DEFAULT_HOST_CHARSET;
static void
show_host_charset_name (struct ui_file *file, int from_tty,
struct cmd_list_element *c,
const char *value)
{
fprintf_filtered (file, _("The host character set is \"%s\".\n"), value);
}
static const char *target_charset_name = GDB_DEFAULT_TARGET_CHARSET;
static void
show_target_charset_name (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
fprintf_filtered (file, _("The target character set is \"%s\".\n"),
value);
}
static const char *host_charset_enum[] =
{
"ASCII",
"ISO-8859-1",
"UTF-8",
0
};
static const char *target_charset_enum[] =
{
"ASCII",
"ISO-8859-1",
"UTF-8",
"EBCDIC-US",
"IBM1047",
0
};
static struct charset *all_charsets;
static void
register_charset (struct charset *cs)
{
struct charset **ptr;
for (ptr = &all_charsets; *ptr; ptr = &(*ptr)->next)
;
cs->next = 0;
*ptr = cs;
}
static struct charset *
lookup_charset (const char *name)
{
struct charset *cs;
for (cs = all_charsets; cs; cs = cs->next)
if (! strcmp (name, cs->name))
return cs;
return NULL;
}
static struct translation *all_translations;
static void
register_translation (struct translation *t)
{
t->next = all_translations;
all_translations = t;
}
static struct translation *
lookup_translation (const char *from, const char *to)
{
struct translation *t;
for (t = all_translations; t; t = t->next)
if (! strcmp (from, t->from)
&& ! strcmp (to, t->to))
return t;
return 0;
}
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;
}
static int
ascii_print_literally (void *baton, int c)
{
c &= 0xff;
return (0x20 <= c && c <= 0x7e);
}
static int
ascii_to_control (void *baton, int c, int *ctrl_char)
{
*ctrl_char = (c & 037);
return 1;
}
static int
iso_8859_print_literally (void *baton, int c)
{
c &= 0xff;
return ((0x20 <= c && c <= 0x7e)
|| (! sevenbit_strings && 0xA0 <= c));
}
static int
iso_8859_to_control (void *baton, int c, int *ctrl_char)
{
*ctrl_char = (c & 0200) | (c & 037);
return 1;
}
static struct charset *
iso_8859_family_charset (const char *name)
{
return simple_charset (name, 1,
iso_8859_print_literally, 0,
iso_8859_to_control, 0);
}
static int
utf_8_print_literally (void *baton, int c)
{
c &= 0xff;
return ((0x20 <= c && c <= 0x7e)
|| (! sevenbit_strings && 0x7e <= c));
}
static int
utf_8_to_control (void *baton, int c, int *ctrl_char)
{
*ctrl_char = (c & 0200) | (c & 037);
return 1;
}
static struct charset *
utf_8_family_charset (const char *name)
{
return simple_charset (name, 1,
utf_8_print_literally, 0,
utf_8_to_control, 0);
}
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)
{
return 0;
}
static struct charset *
ebcdic_family_charset (const char *name)
{
return simple_charset (name, 0,
ebcdic_print_literally, 0,
ebcdic_to_control, 0);
}
#if defined(HAVE_ICONV)
struct cached_iconv {
struct charset *from, *to;
iconv_t i;
};
static int
check_iconv_cache (struct cached_iconv *ci,
struct charset *from,
struct charset *to)
{
iconv_t i;
if (ci->from == from
&& ci->to == to
&& ci->i != (iconv_t) 0)
return 0;
if (ci->i != (iconv_t) 0)
{
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));
}
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;
}
static int
cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char)
{
char from;
ICONV_CONST char *from_ptr = &from;
char to, *to_ptr = &to;
size_t from_left = sizeof (from), to_left = sizeof (to);
gdb_assert (ci->i != (iconv_t) 0);
from = from_char;
if (iconv (ci->i, &from_ptr, &from_left, &to_ptr, &to_left)
== (size_t) -1)
{
gdb_assert (errno != E2BIG && errno != EINVAL);
gdb_assert (errno != EBADF);
if (errno == EILSEQ)
return 0;
internal_error (__FILE__, __LINE__,
_("Error converting character `%d' from `%s' to `%s' "
"character set: %s"),
from_char, ci->from->name, ci->to->name,
safe_strerror (errno));
}
gdb_assert (from_left == 0 && to_left == 0);
*to_char = (unsigned char) to;
return 1;
}
static void
register_iconv_charsets (void)
{
}
#endif
#if ! defined (HAVE_ICONV)
struct cached_iconv { char nothing; };
static int
check_iconv_cache (struct cached_iconv *ci,
struct charset *from,
struct charset *to)
{
errno = EINVAL;
return -1;
}
static int
cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char)
{
gdb_assert (0);
}
static void
register_iconv_charsets (void)
{
}
#endif
static int
identity_either_char_to_other (void *baton, int either_char, int *other_char)
{
*other_char = either_char;
return 1;
}
static char backslashable[] = "abfnrtv";
static char *backslashed[] = {"a", "b", "f", "n", "r", "t", "v", "0"};
static char represented[] = "\a\b\f\n\r\t\v";
static const char *
default_c_target_char_has_backslash_escape (void *baton, int target_char)
{
int host_char;
const char *ix;
if (! target_char_to_host (target_char, &host_char))
return NULL;
ix = strchr (represented, host_char);
if (ix)
return backslashed[ix - represented];
else
return NULL;
}
static int
default_c_parse_backslash (void *baton, int host_char, int *target_char)
{
const char *ix;
ix = strchr (backslashable, host_char);
if (! ix)
return 0;
else
return host_char_to_target (represented[ix - backslashable],
target_char);
}
static int
iconv_convert (void *baton, int from_char, int *to_char)
{
struct cached_iconv *ci = baton;
return cached_iconv_convert (ci, from_char, to_char);
}
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, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
static int ascii_to_ebcdic_us_table[] = {
0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15,
16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31,
64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97,
240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111,
124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214,
215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109,
121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150,
151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
static int ascii_to_ibm1047_table[] = {
0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15,
16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31,
64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97,
240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111,
124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214,
215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109,
121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150,
151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
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, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
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, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31,
64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97,
240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111,
124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214,
215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109,
121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150,
151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7,
32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27,
48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62,255,
-1, -1, 74, -1, -1, -1,106, -1, -1, -1, -1, -1, 95, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
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, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31,
64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97,
240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111,
124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214,
215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109,
121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150,
151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7,
32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27,
48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62,255,
65,170, 74,177,159,178,106,181,187,180,154,138,176,202,175,188,
144,143,234,250,190,160,182,179,157,218,155,139,183,184,185,171,
100,101, 98,102, 99,103,158,104,116,113,114,115,120,117,118,119,
172,105,237,238,235,239,236,191,128,253,254,251,252,186,174, 89,
68, 69, 66, 70, 67, 71,156, 72, 84, 81, 82, 83, 88, 85, 86, 87,
140, 73,205,206,203,207,204,225,112,221,222,219,220,141,142,223
};
static int ebcdic_us_to_ascii_table[] = {
0, 1, 2, 3, -1, 9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15,
16, 17, 18, 19, -1, -1, 8, -1, 24, 25, -1, -1, 28, 29, 30, 31,
-1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1, 5, 6, 7,
-1, -1, 22, -1, -1, -1, -1, 4, -1, -1, -1, -1, 20, 21, -1, 26,
32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124,
38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, -1,
45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34,
-1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1,
-1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1,
-1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1,
125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1,
92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1
};
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, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31,
128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7,
144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26,
32, -1, -1, -1, -1, -1, -1, -1, -1, -1,162, 46, 60, 40, 43,124,
38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59,172,
45, 47, -1, -1, -1, -1, -1, -1, -1, -1,166, 44, 37, 95, 62, 63,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34,
-1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1,
-1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1,
-1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1,
125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1,
92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,159
};
static int ebcdic_us_to_ibm1047_table[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79,
80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94,176,
96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111,
-1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127,
-1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1,
-1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1,
-1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1,
208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1,
224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1,
240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255
};
static int ibm1047_to_ascii_table[] = {
0, 1, 2, 3, -1, 9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15,
16, 17, 18, 19, -1, -1, 8, -1, 24, 25, -1, -1, 28, 29, 30, 31,
-1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1, 5, 6, 7,
-1, -1, 22, -1, -1, -1, -1, 4, -1, -1, -1, -1, 20, 21, -1, 26,
32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124,
38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, 94,
45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34,
-1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1,
-1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1,
-1,126,115,116,117,118,119,120,121,122, -1, -1, -1, 91, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, -1, -1,
123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1,
125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1,
92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1
};
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, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31,
128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7,
144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26,
32,160,226,228,224,225,227,229,231,241,162, 46, 60, 40, 43,124,
38,233,234,235,232,237,238,239,236,223, 33, 36, 42, 41, 59, 94,
45, 47,194,196,192,193,195,197,199,209,166, 44, 37, 95, 62, 63,
248,201,202,203,200,205,206,207,204, 96, 58, 35, 64, 39, 61, 34,
216, 97, 98, 99,100,101,102,103,104,105,171,187,240,253,254,177,
176,106,107,108,109,110,111,112,113,114,170,186,230,184,198,164,
181,126,115,116,117,118,119,120,121,122,161,191,208, 91,222,174,
172,163,165,183,169,167,182,188,189,190,221,168,175, 93,180,215,
123, 65, 66, 67, 68, 69, 70, 71, 72, 73,173,244,246,242,243,245,
125, 74, 75, 76, 77, 78, 79, 80, 81, 82,185,251,252,249,250,255,
92,247, 83, 84, 85, 86, 87, 88, 89, 90,178,212,214,210,211,213,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,179,219,220,217,218,159
};
static int ibm1047_to_ebcdic_us_table[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79,
80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94, -1,
96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111,
-1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127,
-1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1,
-1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1,
-1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1,
95, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1,
208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1,
224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1,
240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255
};
static int
table_convert_char (void *baton, int from, int *to)
{
int *table = (int *) baton;
if (0 <= from && from <= 255
&& table[from] != -1)
{
*to = table[from];
return 1;
}
else
return 0;
}
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)
{
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;
}
static struct translation *
simple_table_translation (const char *from, const char *to, int *table)
{
return table_translation (from, to, table, 0, 0, 0, 0);
}
static struct charset *current_host_charset, *current_target_charset;
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;
static struct cached_iconv cached_iconv_host_to_target;
static struct cached_iconv cached_iconv_target_to_host;
static struct charset *
lookup_charset_or_error (const char *name)
{
struct charset *cs = lookup_charset (name);
if (! cs)
error (_("GDB doesn't know of any character set named `%s'."), name);
return cs;
}
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);
}
static void
set_host_and_target_charsets (struct charset *host, struct charset *target)
{
struct translation *h2t, *t2h;
if (! host || ! target)
{
current_host_charset = host;
current_target_charset = target;
return;
}
h2t = lookup_translation (host->name, target->name);
t2h = lookup_translation (target->name, host->name);
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;
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;
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;
}
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
{
target_char_to_host_func = iconv_convert;
target_char_to_host_baton = &cached_iconv_target_to_host;
}
current_host_charset = host;
current_target_charset = target;
}
static void
set_host_charset (const char *charset)
{
struct charset *cs = lookup_charset_or_error (charset);
check_valid_host_charset (cs);
set_host_and_target_charsets (cs, current_target_charset);
}
static void
set_target_charset (const char *charset)
{
struct charset *cs = lookup_charset_or_error (charset);
set_host_and_target_charsets (current_host_charset, cs);
}
static void
set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c)
{
struct charset *cs = lookup_charset_or_error (host_charset_name);
check_valid_host_charset (cs);
target_charset_name = host_charset_name;
set_host_and_target_charsets (cs, cs);
}
static void
set_host_charset_sfunc (char *charset, int from_tty,
struct cmd_list_element *c)
{
set_host_charset (host_charset_name);
}
static void
set_target_charset_sfunc (char *charset, int from_tty,
struct cmd_list_element *c)
{
set_target_charset (target_charset_name);
}
static void
show_charset (struct ui_file *file, int from_tty, struct cmd_list_element *c,
const char *name)
{
if (current_host_charset == current_target_charset)
fprintf_filtered (file,
_("The current host and target character set is `%s'.\n"),
host_charset ());
else
{
fprintf_filtered (file, _("The current host character set is `%s'.\n"),
host_charset ());
fprintf_filtered (file, _("The current target character set is `%s'.\n"),
target_charset ());
}
}
const char *
host_charset (void)
{
return current_host_charset->name;
}
const char *
target_charset (void)
{
return current_target_charset->name;
}
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));
}
int
c_parse_backslash (int host_char, int *target_char)
{
return (*c_parse_backslash_func) (c_parse_backslash_baton,
host_char, target_char);
}
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));
}
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));
}
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));
}
int
target_char_to_host (int target_char, int *host_char)
{
return ((*target_char_to_host_func)
(target_char_to_host_baton, target_char, host_char));
}
extern initialize_file_ftype _initialize_charset;
void
_initialize_charset (void)
{
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_charset (utf_8_family_charset ("UTF-8"));
register_iconv_charsets ();
{
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 },
{ "ASCII", "UTF-8", ascii_to_iso_8859_1_table },
{ "UTF-8", "ASCII", iso_8859_1_to_ascii_table }
};
int i;
for (i = 0; i < (sizeof (tlist) / sizeof (tlist[0])); i++)
register_translation (simple_table_translation (tlist[i].from,
tlist[i].to,
tlist[i].table));
}
set_host_charset (host_charset_name);
set_target_charset (target_charset_name);
add_setshow_enum_cmd ("charset", class_support,
host_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>'."),
set_charset_sfunc,
show_charset,
&setlist, &showlist);
add_setshow_enum_cmd ("host-charset", class_support,
host_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,
target_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);
}