* c-lang.c (c_emit_char): Use INTERMEDIATE_ENCODING.
	(c_printstr): Likewise.
	* charset.c: Include gdb_wait.h.
	(make_wchar_iterator): Use INTERMEDIATE_ENCODING.
	(find_charset_names): Use pexecute.  Handle libiconv's output.
	Detect errors.
	(_initialize_charset): Use xstrdup.
	* gdb_wchar.h: Check HAVE_BTOWC.  Split PHONY_ICONV and wchar
	cases.
	(INTERMEDIATE_ENCODING): New define.
	* configure, config.in: Rebuild.
	* configure.ac: Check for btowc.
gdb/doc
	* gdb.texinfo (Character Sets): Document default character set.
This commit is contained in:
Tom Tromey 2009-04-15 22:20:32 +00:00
parent 334cc82d44
commit 732f6a935c
9 changed files with 150 additions and 39 deletions

View File

@ -1,3 +1,18 @@
2009-04-14 Tom Tromey <tromey@redhat.com>
* c-lang.c (c_emit_char): Use INTERMEDIATE_ENCODING.
(c_printstr): Likewise.
* charset.c: Include gdb_wait.h.
(make_wchar_iterator): Use INTERMEDIATE_ENCODING.
(find_charset_names): Use pexecute. Handle libiconv's output.
Detect errors.
(_initialize_charset): Use xstrdup.
* gdb_wchar.h: Check HAVE_BTOWC. Split PHONY_ICONV and wchar
cases.
(INTERMEDIATE_ENCODING): New define.
* configure, config.in: Rebuild.
* configure.ac: Check for btowc.
2009-04-15 Tom Tromey <tromey@redhat.com>
* c-lang.c (evaluate_subexp_c): Correctly handle EVAL_SKIP.

View File

@ -296,7 +296,7 @@ c_emit_char (int c, struct type *type, struct ui_file *stream, int quoter)
obstack_init (&output);
make_cleanup_obstack_free (&output);
convert_between_encodings ("wchar_t", host_charset (),
convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
obstack_base (&wchar_buf),
obstack_object_size (&wchar_buf),
1, &output, translit_char);
@ -562,7 +562,7 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
obstack_init (&output);
make_cleanup_obstack_free (&output);
convert_between_encodings ("wchar_t", host_charset (),
convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
obstack_base (&wchar_buf),
obstack_object_size (&wchar_buf),
1, &output, translit_char);

View File

@ -22,6 +22,7 @@
#include "gdbcmd.h"
#include "gdb_assert.h"
#include "gdb_obstack.h"
#include "gdb_wait.h"
#include "charset-list.h"
#include "vec.h"
@ -536,7 +537,7 @@ make_wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset,
struct wchar_iterator *result;
iconv_t desc;
desc = iconv_open ("wchar_t", charset);
desc = iconv_open (INTERMEDIATE_ENCODING, charset);
if (desc == (iconv_t) -1)
perror_with_name ("Converting character sets");
@ -707,35 +708,92 @@ find_charset_names (void)
static void
find_charset_names (void)
{
FILE *in;
struct pex_obj *child;
char *args[3];
int err, status;
int fail = 1;
in = popen ("iconv -l", "r");
/* It is ok to ignore errors; we'll fall back on a default. */
if (!in)
return;
child = pex_init (0, "iconv", NULL);
/* POSIX says that iconv -l uses an unspecified format. We parse
the glibc format; feel free to add others as needed. */
while (!feof (in))
args[0] = "iconv";
args[1] = "-l";
args[2] = NULL;
/* Note that we simply ignore errors here. */
if (!pex_run (child, PEX_SEARCH | PEX_STDERR_TO_STDOUT, "iconv",
args, NULL, NULL, &err))
{
/* The size of buf is chosen arbitrarily. A character set name
longer than this would not be very nice. */
char buf[80];
int len;
char *r = fgets (buf, sizeof (buf), in);
if (!r)
break;
len = strlen (r);
if (len <= 3)
continue;
if (buf[len - 2] == '/' && buf[len - 3] == '/')
buf[len - 3] = '\0';
VEC_safe_push (char_ptr, charsets, xstrdup (buf));
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, keep_going;
r = fgets (buf, sizeof (buf), in);
if (!r)
break;
len = strlen (r);
if (len <= 3)
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. */
start = buf;
while (1)
{
int keep_going;
char *p;
/* Find the next space, or end-of-line. */
for (p = start; *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;
}
pclose (in);
pex_free (child);
VEC_safe_push (char_ptr, charsets, NULL);
if (fail)
{
/* 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
VEC_safe_push (char_ptr, charsets, NULL);
}
#endif /* HAVE_ICONVLIST || HAVE_LIBICONVLIST */
@ -748,7 +806,7 @@ _initialize_charset (void)
/* The first element is always "auto"; then we skip it for the
commands where it is not allowed. */
VEC_safe_push (char_ptr, charsets, "auto");
VEC_safe_push (char_ptr, charsets, xstrdup ("auto"));
find_charset_names ();
if (VEC_length (char_ptr, charsets) > 1)

View File

@ -70,6 +70,9 @@
/* Define to 1 if you have the <bp-sym.h> header file. */
#undef HAVE_BP_SYM_H
/* Define to 1 if you have the `btowc' function. */
#undef HAVE_BTOWC
/* Define to 1 if you have the `canonicalize_file_name' function. */
#undef HAVE_CANONICALIZE_FILE_NAME

3
gdb/configure vendored
View File

@ -15774,12 +15774,13 @@ fi
for ac_func in canonicalize_file_name realpath getrusage getuid \
getgid poll pread64 sbrk setpgid setpgrp setsid \
sigaction sigprocmask sigsetmask socketpair syscall \
ttrace wborder setlocale iconvlist libiconvlist
ttrace wborder setlocale iconvlist libiconvlist btowc
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5

View File

@ -796,7 +796,7 @@ AC_FUNC_VFORK
AC_CHECK_FUNCS([canonicalize_file_name realpath getrusage getuid \
getgid poll pread64 sbrk setpgid setpgrp setsid \
sigaction sigprocmask sigsetmask socketpair syscall \
ttrace wborder setlocale iconvlist libiconvlist])
ttrace wborder setlocale iconvlist libiconvlist btowc])
AM_LANGINFO_CODESET
# Check the return and argument types of ptrace. No canned test for

View File

@ -1,3 +1,7 @@
2009-04-15 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Character Sets): Document default character set.
2009-04-14 Pierre Muller <muller@ics.u-strasbg.fr>
* gdbint.texinfo: Change server name from sources.redhat.com to

View File

@ -7998,7 +7998,9 @@ Set the current host character set to @var{charset}.
By default, @value{GDBN} uses a host character set appropriate to the
system it is running on; you can override that default using the
@code{set host-charset} command.
@code{set host-charset} command. On some systems, @value{GDBN} cannot
automatically determine the appropriate host character set. In this
case, @value{GDBN} uses @samp{UTF-8}.
@value{GDBN} can only use certain character sets as its host character
set. If you type @kbd{@w{set target-charset @key{TAB}@key{TAB}}},

View File

@ -19,13 +19,36 @@
#ifndef GDB_WCHAR_H
#define GDB_WCHAR_H
/* If this host has wchar_t and if iconv is available (perhaps via GNU
libiconv), then we arrange to use those. Otherwise, we provide a
phony iconv which only handles a single character set, and we
provide wrappers for the wchar_t functionality we use. */
#if defined(HAVE_ICONV) && defined(HAVE_WCHAR_H)
/* We handle three different modes here.
Capable systems have the full suite: wchar_t support and iconv
(perhaps via GNU libiconv). On these machines, full functionality
is available.
DJGPP is known to have libiconv but not wchar_t support. On
systems like this, we use the narrow character functions. The full
functionality is available to the user, but many characters (those
outside the narrow range) will be displayed as escapes.
Finally, some systems do not have iconv. Here we provide a phony
iconv which only handles a single character set, and we provide
wrappers for the wchar_t functionality we use. */
#define INTERMEDIATE_ENCODING "wchar_t"
#if defined (HAVE_ICONV)
#include <iconv.h>
#else
/* This define is used elsewhere so we don't need to duplicate the
same checking logic in multiple places. */
#define PHONY_ICONV
#endif
/* We use "btowc" as a sentinel to detect functioning wchar_t
support. */
#if defined (HAVE_ICONV) && defined (HAVE_WCHAR_H) && defined (HAVE_BTOWC)
#include <wchar.h>
#include <wctype.h>
@ -53,10 +76,15 @@ typedef int gdb_wint_t;
#define LCST(X) X
/* This define is used elsewhere so we don't need to duplicate the
same checking logic in multiple places. */
#define PHONY_ICONV
/* If we are using the narrow character set, we want to use the host
narrow encoding as our intermediate encoding. However, if we are
also providing a phony iconv, we might as well just stick with
"wchar_t". */
#ifndef PHONY_ICONV
#undef INTERMEDIATE_ENCODING
#define INTERMEDIATE_ENCODING host_charset ()
#endif
#endif /* defined(HAVE_ICONV) && defined(HAVE_WCHAR_H) */
#endif
#endif /* GDB_WCHAR_H */