Turn wchar iterator into a class
This changes wchar_iterator from charset.c into a real C++ class, then updates the users to use the class. This lets us remove some cleanups in favor of the class' destructor. 2016-10-12 Tom Tromey <tom@tromey.com> * valprint.c (generic_emit_char, count_next_character) (generic_printstr): Update. * charset.c (struct wchar_iterator): Move to charset.h. (wchar_iterator::wchar_iterator): Rename from make_wchar_iterator, turn into a constructor. (wchar_iterator::~wchar_iterator): Rename from do_cleanup_iterator, turn into a destructor. (make_cleanup_wchar_iterator): Remove. (wchar_iterator::iterate): Rename from wchar_iterate. Remove "iter" argument. Update. * charset.h: Include <vector>. (class wchar_iterator): New class, from old struct wchar_iterator. (make_wchar_iterator, make_cleanup_wchar_iterator): Don't declare.
This commit is contained in:
parent
816d7b5304
commit
cda6c55bd3
@ -1,3 +1,21 @@
|
|||||||
|
2016-10-12 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
|
* valprint.c (generic_emit_char, count_next_character)
|
||||||
|
(generic_printstr): Update.
|
||||||
|
* charset.c (struct wchar_iterator): Move to charset.h.
|
||||||
|
(wchar_iterator::wchar_iterator): Rename from
|
||||||
|
make_wchar_iterator, turn into a constructor.
|
||||||
|
(wchar_iterator::~wchar_iterator): Rename from
|
||||||
|
do_cleanup_iterator, turn into a destructor.
|
||||||
|
(make_cleanup_wchar_iterator): Remove.
|
||||||
|
(wchar_iterator::iterate): Rename from wchar_iterate. Remove
|
||||||
|
"iter" argument. Update.
|
||||||
|
* charset.h: Include <vector>.
|
||||||
|
(class wchar_iterator): New class, from old struct
|
||||||
|
wchar_iterator.
|
||||||
|
(make_wchar_iterator, make_cleanup_wchar_iterator): Don't
|
||||||
|
declare.
|
||||||
|
|
||||||
2016-10-12 Tom Tromey <tom@tromey.com>
|
2016-10-12 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* selftest.c: Include <vector>, not "vec.h".
|
* selftest.c: Include <vector>, not "vec.h".
|
||||||
|
110
gdb/charset.c
110
gdb/charset.c
@ -589,71 +589,30 @@ convert_between_encodings (const char *from, const char *to,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* An iterator that returns host wchar_t's from a target string. */
|
|
||||||
struct wchar_iterator
|
|
||||||
{
|
|
||||||
/* The underlying iconv descriptor. */
|
|
||||||
iconv_t desc;
|
|
||||||
|
|
||||||
/* The input string. This is updated as convert characters. */
|
|
||||||
const gdb_byte *input;
|
|
||||||
/* The number of bytes remaining in the input. */
|
|
||||||
size_t bytes;
|
|
||||||
|
|
||||||
/* The width of an input character. */
|
|
||||||
size_t width;
|
|
||||||
|
|
||||||
/* The output buffer and its size. */
|
|
||||||
gdb_wchar_t *out;
|
|
||||||
size_t out_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Create a new iterator. */
|
/* Create a new iterator. */
|
||||||
struct wchar_iterator *
|
wchar_iterator::wchar_iterator (const gdb_byte *input, size_t bytes,
|
||||||
make_wchar_iterator (const gdb_byte *input, size_t bytes,
|
const char *charset, size_t width)
|
||||||
const char *charset, size_t width)
|
: m_input (input),
|
||||||
|
m_bytes (bytes),
|
||||||
|
m_width (width),
|
||||||
|
m_out (1)
|
||||||
{
|
{
|
||||||
struct wchar_iterator *result;
|
m_desc = iconv_open (INTERMEDIATE_ENCODING, charset);
|
||||||
iconv_t desc;
|
if (m_desc == (iconv_t) -1)
|
||||||
|
|
||||||
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;
|
|
||||||
result->input = input;
|
|
||||||
result->bytes = bytes;
|
|
||||||
result->width = width;
|
|
||||||
|
|
||||||
result->out = XNEW (gdb_wchar_t);
|
|
||||||
result->out_size = 1;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
wchar_iterator::~wchar_iterator ()
|
||||||
do_cleanup_iterator (void *p)
|
|
||||||
{
|
{
|
||||||
struct wchar_iterator *iter = (struct wchar_iterator *) p;
|
if (m_desc != (iconv_t) -1)
|
||||||
|
iconv_close (m_desc);
|
||||||
iconv_close (iter->desc);
|
|
||||||
xfree (iter->out);
|
|
||||||
xfree (iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cleanup *
|
|
||||||
make_cleanup_wchar_iterator (struct wchar_iterator *iter)
|
|
||||||
{
|
|
||||||
return make_cleanup (do_cleanup_iterator, iter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
wchar_iterate (struct wchar_iterator *iter,
|
wchar_iterator::iterate (enum wchar_iterate_result *out_result,
|
||||||
enum wchar_iterate_result *out_result,
|
gdb_wchar_t **out_chars,
|
||||||
gdb_wchar_t **out_chars,
|
const gdb_byte **ptr,
|
||||||
const gdb_byte **ptr,
|
size_t *len)
|
||||||
size_t *len)
|
|
||||||
{
|
{
|
||||||
size_t out_request;
|
size_t out_request;
|
||||||
|
|
||||||
@ -663,17 +622,17 @@ wchar_iterate (struct wchar_iterator *iter,
|
|||||||
invalid input sequence -- but we want to reliably report this to
|
invalid input sequence -- but we want to reliably report this to
|
||||||
our caller so it can emit an escape sequence. */
|
our caller so it can emit an escape sequence. */
|
||||||
out_request = 1;
|
out_request = 1;
|
||||||
while (iter->bytes > 0)
|
while (m_bytes > 0)
|
||||||
{
|
{
|
||||||
ICONV_CONST char *inptr = (ICONV_CONST char *) iter->input;
|
ICONV_CONST char *inptr = (ICONV_CONST char *) m_input;
|
||||||
char *outptr = (char *) &iter->out[0];
|
char *outptr = (char *) m_out.data ();
|
||||||
const gdb_byte *orig_inptr = iter->input;
|
const gdb_byte *orig_inptr = m_input;
|
||||||
size_t orig_in = iter->bytes;
|
size_t orig_in = m_bytes;
|
||||||
size_t out_avail = out_request * sizeof (gdb_wchar_t);
|
size_t out_avail = out_request * sizeof (gdb_wchar_t);
|
||||||
size_t num;
|
size_t num;
|
||||||
size_t r = iconv (iter->desc, &inptr, &iter->bytes, &outptr, &out_avail);
|
size_t r = iconv (m_desc, &inptr, &m_bytes, &outptr, &out_avail);
|
||||||
|
|
||||||
iter->input = (gdb_byte *) inptr;
|
m_input = (gdb_byte *) inptr;
|
||||||
|
|
||||||
if (r == (size_t) -1)
|
if (r == (size_t) -1)
|
||||||
{
|
{
|
||||||
@ -688,10 +647,10 @@ wchar_iterate (struct wchar_iterator *iter,
|
|||||||
/* Otherwise skip the first invalid character, and let
|
/* Otherwise skip the first invalid character, and let
|
||||||
the caller know about it. */
|
the caller know about it. */
|
||||||
*out_result = wchar_iterate_invalid;
|
*out_result = wchar_iterate_invalid;
|
||||||
*ptr = iter->input;
|
*ptr = m_input;
|
||||||
*len = iter->width;
|
*len = m_width;
|
||||||
iter->input += iter->width;
|
m_input += m_width;
|
||||||
iter->bytes -= iter->width;
|
m_bytes -= m_width;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case E2BIG:
|
case E2BIG:
|
||||||
@ -702,20 +661,17 @@ wchar_iterate (struct wchar_iterator *iter,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
++out_request;
|
++out_request;
|
||||||
if (out_request > iter->out_size)
|
if (out_request > m_out.size ())
|
||||||
{
|
m_out.reserve (out_request);
|
||||||
iter->out_size = out_request;
|
|
||||||
iter->out = XRESIZEVEC (gdb_wchar_t, iter->out, out_request);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case EINVAL:
|
case EINVAL:
|
||||||
/* Incomplete input sequence. Let the caller know, and
|
/* Incomplete input sequence. Let the caller know, and
|
||||||
arrange for future calls to see EOF. */
|
arrange for future calls to see EOF. */
|
||||||
*out_result = wchar_iterate_incomplete;
|
*out_result = wchar_iterate_incomplete;
|
||||||
*ptr = iter->input;
|
*ptr = m_input;
|
||||||
*len = iter->bytes;
|
*len = m_bytes;
|
||||||
iter->bytes = 0;
|
m_bytes = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -727,9 +683,9 @@ wchar_iterate (struct wchar_iterator *iter,
|
|||||||
/* We converted something. */
|
/* We converted something. */
|
||||||
num = out_request - out_avail / sizeof (gdb_wchar_t);
|
num = out_request - out_avail / sizeof (gdb_wchar_t);
|
||||||
*out_result = wchar_iterate_ok;
|
*out_result = wchar_iterate_ok;
|
||||||
*out_chars = iter->out;
|
*out_chars = m_out.data ();
|
||||||
*ptr = orig_inptr;
|
*ptr = orig_inptr;
|
||||||
*len = orig_in - iter->bytes;
|
*len = orig_in - m_bytes;
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#ifndef CHARSET_H
|
#ifndef CHARSET_H
|
||||||
#define CHARSET_H
|
#define CHARSET_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
/* If the target program uses a different character set than the host,
|
/* If the target program uses a different character set than the host,
|
||||||
GDB has some support for translating between the two; GDB converts
|
GDB has some support for translating between the two; GDB converts
|
||||||
characters and strings to the host character set before displaying
|
characters and strings to the host character set before displaying
|
||||||
@ -81,54 +83,67 @@ enum wchar_iterate_result
|
|||||||
wchar_iterate_eof
|
wchar_iterate_eof
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Declaration of the opaque wchar iterator type. */
|
/* An iterator that returns host wchar_t's from a target string. */
|
||||||
struct wchar_iterator;
|
class wchar_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
/* Create a new character iterator which returns wchar_t's. INPUT is
|
/* Create a new character iterator which returns wchar_t's. INPUT is
|
||||||
the input buffer. BYTES is the number of bytes in the input
|
the input buffer. BYTES is the number of bytes in the input
|
||||||
buffer. CHARSET is the name of the character set in which INPUT is
|
buffer. CHARSET is the name of the character set in which INPUT is
|
||||||
encoded. WIDTH is the number of bytes in a base character of
|
encoded. WIDTH is the number of bytes in a base character of
|
||||||
CHARSET.
|
CHARSET.
|
||||||
|
|
||||||
This function either returns a new character set iterator, or calls
|
This function either returns a new character set iterator, or calls
|
||||||
error. The result can be freed using a cleanup; see
|
error. The result can be freed using a cleanup; see
|
||||||
make_cleanup_wchar_iterator. */
|
make_cleanup_wchar_iterator. */
|
||||||
struct wchar_iterator *make_wchar_iterator (const gdb_byte *input,
|
wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset,
|
||||||
size_t bytes,
|
size_t width);
|
||||||
const char *charset,
|
|
||||||
size_t width);
|
|
||||||
|
|
||||||
/* Return a new cleanup suitable for destroying the wchar iterator
|
~wchar_iterator ();
|
||||||
ITER. */
|
|
||||||
struct cleanup *make_cleanup_wchar_iterator (struct wchar_iterator *iter);
|
|
||||||
|
|
||||||
/* Perform a single iteration of a wchar_t iterator.
|
/* Perform a single iteration of a wchar_t iterator.
|
||||||
|
|
||||||
Returns the number of characters converted. A negative result
|
Returns the number of characters converted. A negative result
|
||||||
means that EOF has been reached. A positive result indicates the
|
means that EOF has been reached. A positive result indicates the
|
||||||
number of valid wchar_ts in the result; *OUT_CHARS is updated to
|
number of valid wchar_ts in the result; *OUT_CHARS is updated to
|
||||||
point to the first valid character.
|
point to the first valid character.
|
||||||
|
|
||||||
In all cases aside from EOF, *PTR is set to point to the first
|
In all cases aside from EOF, *PTR is set to point to the first
|
||||||
converted target byte. *LEN is set to the number of bytes
|
converted target byte. *LEN is set to the number of bytes
|
||||||
converted.
|
converted.
|
||||||
|
|
||||||
A zero result means one of several unusual results. *OUT_RESULT is
|
A zero result means one of several unusual results. *OUT_RESULT is
|
||||||
set to indicate the type of un-ordinary return.
|
set to indicate the type of un-ordinary return.
|
||||||
|
|
||||||
wchar_iterate_invalid means that an invalid input character was
|
wchar_iterate_invalid means that an invalid input character was
|
||||||
seen. The iterator is advanced by WIDTH (the argument to
|
seen. The iterator is advanced by WIDTH (the argument to
|
||||||
make_wchar_iterator) bytes.
|
the wchar_iterator constructor) bytes.
|
||||||
|
|
||||||
wchar_iterate_incomplete means that an incomplete character was
|
wchar_iterate_incomplete means that an incomplete character was
|
||||||
seen at the end of the input sequence.
|
seen at the end of the input sequence.
|
||||||
|
|
||||||
wchar_iterate_eof means that all bytes were successfully
|
wchar_iterate_eof means that all bytes were successfully
|
||||||
converted. The other output arguments are not set. */
|
converted. The other output arguments are not set. */
|
||||||
int wchar_iterate (struct wchar_iterator *iter,
|
int iterate (enum wchar_iterate_result *out_result, gdb_wchar_t **out_chars,
|
||||||
enum wchar_iterate_result *out_result,
|
const gdb_byte **ptr, size_t *len);
|
||||||
gdb_wchar_t **out_chars,
|
|
||||||
const gdb_byte **ptr, size_t *len);
|
private:
|
||||||
|
|
||||||
|
/* The underlying iconv descriptor. */
|
||||||
|
iconv_t m_desc;
|
||||||
|
|
||||||
|
/* The input string. This is updated as we convert characters. */
|
||||||
|
const gdb_byte *m_input;
|
||||||
|
/* The number of bytes remaining in the input. */
|
||||||
|
size_t m_bytes;
|
||||||
|
|
||||||
|
/* The width of an input character. */
|
||||||
|
size_t m_width;
|
||||||
|
|
||||||
|
/* The output buffer. */
|
||||||
|
std::vector<gdb_wchar_t> m_out;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2404,19 +2404,16 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream,
|
|||||||
struct obstack wchar_buf, output;
|
struct obstack wchar_buf, output;
|
||||||
struct cleanup *cleanups;
|
struct cleanup *cleanups;
|
||||||
gdb_byte *buf;
|
gdb_byte *buf;
|
||||||
struct wchar_iterator *iter;
|
|
||||||
int need_escape = 0;
|
int need_escape = 0;
|
||||||
|
|
||||||
buf = (gdb_byte *) alloca (TYPE_LENGTH (type));
|
buf = (gdb_byte *) alloca (TYPE_LENGTH (type));
|
||||||
pack_long (buf, type, c);
|
pack_long (buf, type, c);
|
||||||
|
|
||||||
iter = make_wchar_iterator (buf, TYPE_LENGTH (type),
|
wchar_iterator iter (buf, TYPE_LENGTH (type), encoding, TYPE_LENGTH (type));
|
||||||
encoding, TYPE_LENGTH (type));
|
|
||||||
cleanups = make_cleanup_wchar_iterator (iter);
|
|
||||||
|
|
||||||
/* This holds the printable form of the wchar_t data. */
|
/* This holds the printable form of the wchar_t data. */
|
||||||
obstack_init (&wchar_buf);
|
obstack_init (&wchar_buf);
|
||||||
make_cleanup_obstack_free (&wchar_buf);
|
cleanups = make_cleanup_obstack_free (&wchar_buf);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -2427,7 +2424,7 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream,
|
|||||||
int print_escape = 1;
|
int print_escape = 1;
|
||||||
enum wchar_iterate_result result;
|
enum wchar_iterate_result result;
|
||||||
|
|
||||||
num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen);
|
num_chars = iter.iterate (&result, &chars, &buf, &buflen);
|
||||||
if (num_chars < 0)
|
if (num_chars < 0)
|
||||||
break;
|
break;
|
||||||
if (num_chars > 0)
|
if (num_chars > 0)
|
||||||
@ -2481,7 +2478,7 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream,
|
|||||||
storing the result in VEC. */
|
storing the result in VEC. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
count_next_character (struct wchar_iterator *iter,
|
count_next_character (wchar_iterator *iter,
|
||||||
VEC (converted_character_d) **vec)
|
VEC (converted_character_d) **vec)
|
||||||
{
|
{
|
||||||
struct converted_character *current;
|
struct converted_character *current;
|
||||||
@ -2492,7 +2489,7 @@ count_next_character (struct wchar_iterator *iter,
|
|||||||
gdb_wchar_t *chars;
|
gdb_wchar_t *chars;
|
||||||
|
|
||||||
tmp.num_chars
|
tmp.num_chars
|
||||||
= wchar_iterate (iter, &tmp.result, &chars, &tmp.buf, &tmp.buflen);
|
= iter->iterate (&tmp.result, &chars, &tmp.buf, &tmp.buflen);
|
||||||
if (tmp.num_chars > 0)
|
if (tmp.num_chars > 0)
|
||||||
{
|
{
|
||||||
gdb_assert (tmp.num_chars < MAX_WCHARS);
|
gdb_assert (tmp.num_chars < MAX_WCHARS);
|
||||||
@ -2521,8 +2518,7 @@ count_next_character (struct wchar_iterator *iter,
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* Get the next character. */
|
/* Get the next character. */
|
||||||
d.num_chars
|
d.num_chars = iter->iterate (&d.result, &chars, &d.buf, &d.buflen);
|
||||||
= wchar_iterate (iter, &d.result, &chars, &d.buf, &d.buflen);
|
|
||||||
|
|
||||||
/* If a character was successfully converted, save the character
|
/* If a character was successfully converted, save the character
|
||||||
into the converted character. */
|
into the converted character. */
|
||||||
@ -2736,7 +2732,6 @@ generic_printstr (struct ui_file *stream, struct type *type,
|
|||||||
int width = TYPE_LENGTH (type);
|
int width = TYPE_LENGTH (type);
|
||||||
struct obstack wchar_buf, output;
|
struct obstack wchar_buf, output;
|
||||||
struct cleanup *cleanup;
|
struct cleanup *cleanup;
|
||||||
struct wchar_iterator *iter;
|
|
||||||
int finished = 0;
|
int finished = 0;
|
||||||
struct converted_character *last;
|
struct converted_character *last;
|
||||||
VEC (converted_character_d) *converted_chars;
|
VEC (converted_character_d) *converted_chars;
|
||||||
@ -2771,10 +2766,10 @@ generic_printstr (struct ui_file *stream, struct type *type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Arrange to iterate over the characters, in wchar_t form. */
|
/* Arrange to iterate over the characters, in wchar_t form. */
|
||||||
iter = make_wchar_iterator (string, length * width, encoding, width);
|
wchar_iterator iter (string, length * width, encoding, width);
|
||||||
cleanup = make_cleanup_wchar_iterator (iter);
|
|
||||||
converted_chars = NULL;
|
converted_chars = NULL;
|
||||||
make_cleanup (VEC_cleanup (converted_character_d), &converted_chars);
|
cleanup = make_cleanup (VEC_cleanup (converted_character_d),
|
||||||
|
&converted_chars);
|
||||||
|
|
||||||
/* Convert characters until the string is over or the maximum
|
/* Convert characters until the string is over or the maximum
|
||||||
number of printed characters has been reached. */
|
number of printed characters has been reached. */
|
||||||
@ -2786,7 +2781,7 @@ generic_printstr (struct ui_file *stream, struct type *type,
|
|||||||
QUIT;
|
QUIT;
|
||||||
|
|
||||||
/* Grab the next character and repeat count. */
|
/* Grab the next character and repeat count. */
|
||||||
r = count_next_character (iter, &converted_chars);
|
r = count_next_character (&iter, &converted_chars);
|
||||||
|
|
||||||
/* If less than zero, the end of the input string was reached. */
|
/* If less than zero, the end of the input string was reached. */
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user