/* Character set conversion support for GDB.
- Copyright (C) 2001, 2003, 2007, 2008, 2009, 2010
+ Copyright (C) 2001, 2003, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GDB.
#include "gdb_string.h"
#include <ctype.h>
+#ifdef USE_WIN32API
+#include <windows.h>
+#endif
\f
/* How GDB's character set support works
#undef iconv_t
#define iconv_t int
#undef iconv_open
+#define iconv_open phony_iconv_open
#undef iconv
+#define iconv phony_iconv
#undef iconv_close
+#define iconv_close phony_iconv_close
#undef ICONV_CONST
#define ICONV_CONST const
#endif
iconv_t
-iconv_open (const char *to, const char *from)
+phony_iconv_open (const char *to, const char *from)
{
/* We allow conversions from UTF-32BE, wchar_t, and the host charset.
We allow conversions to wchar_t and the host charset. */
}
int
-iconv_close (iconv_t arg)
+phony_iconv_close (iconv_t arg)
{
return 0;
}
size_t
-iconv (iconv_t utf_flag, const char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
+phony_iconv (iconv_t utf_flag, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
{
if (utf_flag)
{
/* 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);
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)
+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,
const char *host_cset = host_charset ();
const char *target_cset = target_charset (gdbarch);
const char *target_wide_cset = target_wide_charset_name;
+
if (!strcmp (target_wide_cset, "auto"))
target_wide_cset = gdbarch_auto_wide_charset (gdbarch);
desc = iconv_open (target_wide_cset, host_cset);
if (desc == (iconv_t) -1)
- error ("Cannot convert between character sets `%s' and `%s'",
+ error (_("Cannot convert between character sets `%s' and `%s'"),
target_wide_cset, host_cset);
iconv_close (desc);
desc = iconv_open (target_cset, host_cset);
if (desc == (iconv_t) -1)
- error ("Cannot convert between character sets `%s' and `%s'",
+ error (_("Cannot convert between character sets `%s' and `%s'"),
target_cset, host_cset);
iconv_close (desc);
/* This is the sfunc for the 'set charset' command. */
static void
-set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c)
+set_charset_sfunc (char *charset, int from_tty,
+ struct cmd_list_element *c)
{
- /* CAREFUL: set the target charset here as well. */
+ /* CAREFUL: set the target charset here as well. */
target_charset_name = host_charset_name;
validate (get_current_arch ());
}
/* sfunc for the 'show charset' command. */
static void
-show_charset (struct ui_file *file, int from_tty, struct cmd_list_element *c,
+show_charset (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
const char *name)
{
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);
+ show_target_wide_charset_name (file, from_tty, c,
+ target_wide_charset_name);
}
\f
desc = iconv_open (to, from);
if (desc == (iconv_t) -1)
- perror_with_name ("Converting character sets");
+ perror_with_name (_("Converting character sets"));
cleanups = make_cleanup (cleanup_iconv, &desc);
inleft = num_bytes;
/* Invalid input sequence. */
if (translit == translit_none)
- error (_("Could not convert character to `%s' character set"),
- to);
+ error (_("Could not convert character "
+ "to `%s' character set"), to);
/* We emit escape sequence for the bytes, skip them,
and try again. */
break;
default:
- perror_with_name ("Internal error while converting character sets");
+ perror_with_name (_("Internal error while "
+ "converting character sets"));
}
}
}
/* Create a new iterator. */
struct wchar_iterator *
-make_wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset,
- size_t width)
+make_wchar_iterator (const gdb_byte *input, size_t bytes,
+ const char *charset, size_t width)
{
struct wchar_iterator *result;
iconv_t desc;
desc = iconv_open (INTERMEDIATE_ENCODING, charset);
if (desc == (iconv_t) -1)
- perror_with_name ("Converting character sets");
+ perror_with_name (_("Converting character sets"));
result = XNEW (struct wchar_iterator);
result->desc = desc;
size_t orig_in = iter->bytes;
size_t out_avail = out_request * sizeof (gdb_wchar_t);
size_t num;
- gdb_wchar_t result;
-
size_t r = iconv (iter->desc,
- (ICONV_CONST char **) &iter->input, &iter->bytes,
- &outptr, &out_avail);
+ (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. */
+ /* Invalid input sequence. We still might have
+ converted a character; if so, return it. */
+ if (out_avail < out_request * sizeof (gdb_wchar_t))
+ break;
+
+ /* Otherwise skip the first invalid character, and let
+ the caller know about it. */
*out_result = wchar_iterate_invalid;
*ptr = iter->input;
*len = iter->width;
return 0;
default:
- perror_with_name ("Internal error while converting character sets");
+ perror_with_name (_("Internal error while "
+ "converting character sets"));
}
}
extern initialize_file_ftype _initialize_charset; /* -Wmissing-prototype */
-typedef char *char_ptr;
DEF_VEC_P (char_ptr);
static VEC (char_ptr) *charsets;
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. */
+ /* 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 (0, "iconv", NULL);
+ child = pex_init (PEX_USE_PIPES, "iconv", NULL);
args[0] = "iconv";
args[1] = "-l";
/* The size of buf is chosen arbitrarily. */
char buf[1024];
char *start, *r;
- int len, keep_going;
+ int len;
r = fgets (buf, sizeof (buf), in);
if (!r)
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 ", "
+ 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)
void
_initialize_charset (void)
{
- struct cmd_list_element *new_cmd;
-
/* The first element is always "auto". */
VEC_safe_push (char_ptr, charsets, xstrdup ("auto"));
find_charset_names ();
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,
+ /* 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)
{
- static w32_host_default_charset[16]; /* "CP" + x<=5 digits + paranoia. */
+ /* "CP" + x<=5 digits + paranoia. */
+ static char w32_host_default_charset[16];
snprintf (w32_host_default_charset, sizeof w32_host_default_charset,
"CP%d", GetACP());
_("\
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\
+The `target wide character set' is the one used by the program being debugged.\
+\nIn 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\