public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-tromey-charset: implement %ls and %lc printf formats
@ 2009-01-09 18:04 tromey
0 siblings, 0 replies; only message in thread
From: tromey @ 2009-01-09 18:04 UTC (permalink / raw)
To: archer-commits
The branch, archer-tromey-charset has been updated
via dee452204073d6bf0ceffd150dfaf3391be01bd2 (commit)
from 3db781d3884e7b03393020d1851a58985fbe82ab (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit dee452204073d6bf0ceffd150dfaf3391be01bd2
Author: Tom Tromey <tromey@redhat.com>
Date: Fri Jan 9 11:03:24 2009 -0700
implement %ls and %lc printf formats
-----------------------------------------------------------------------
Summary of changes:
gdb/c-lang.c | 9 +++--
gdb/charset.c | 61 ++++++++++++++++++++++----------------
gdb/charset.h | 20 +++++++++---
gdb/printcmd.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
gdb/utils.c | 2 +-
5 files changed, 141 insertions(+), 40 deletions(-)
First 500 lines of diff:
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 746071f..86c1b6d 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -56,7 +56,7 @@ c_emit_char (int c, struct ui_file *stream, int quoter)
cleanups = make_cleanup_obstack_free (&host_data);
convert_between_encodings (target_charset (), host_charset (),
- &the_char, 1, &host_data, 1);
+ &the_char, 1, &host_data, translit_char);
if (obstack_object_size (&host_data) == 1)
{
@@ -257,7 +257,7 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
cleanup = make_cleanup_obstack_free (&internal);
convert_between_encodings (encoding, "wchar_t", string, length * width,
- &internal, 1);
+ &internal, translit_wchar);
new_len = obstack_object_size (&internal) / sizeof (wchar_t);
obj = (wchar_t *) obstack_base (&internal);
@@ -392,7 +392,8 @@ convert_ucn (char *p, struct obstack *output, int length)
result >>= 8;
}
- convert_between_encodings ("UCS-2BE", target_charset (), data, 4, output, 0);
+ convert_between_encodings ("UCS-2BE", target_charset (), data, 4, output,
+ translit_none);
}
static void
@@ -513,7 +514,7 @@ parse_one_string (struct obstack *output, char *data, int len,
/* If we saw a run of characters, convert them all. */
if (p > data)
convert_between_encodings (host_charset (), dest_charset,
- data, p - data, output, 0);
+ data, p - data, output, translit_none);
/* If we saw an escape, convert it. */
if (p < limit)
p = convert_escape (type, dest_charset, p, limit, output);
diff --git a/gdb/charset.c b/gdb/charset.c
index 1631bed..fcf54df 100644
--- a/gdb/charset.c
+++ b/gdb/charset.c
@@ -318,7 +318,8 @@ cleanup_iconv (void *p)
void
convert_between_encodings (const char *from, const char *to,
const gdb_byte *bytes, unsigned int num_bytes,
- struct obstack *output, int translit)
+ struct obstack *output,
+ enum transliterations translit)
{
iconv_t desc;
struct cleanup *cleanups;
@@ -370,31 +371,41 @@ convert_between_encodings (const char *from, const char *to,
case EILSEQ:
{
/* Invalid input sequence. */
- if (translit)
+ switch (translit)
{
- /* We emit an escape sequence for the byte, skip
- it, and try again. */
- char hex[5];
- int i;
-
- /* Translit is only available when converting to
- the host wchar_t. */
- gdb_assert (!strcmp (to, "wchar_t"));
- sprintf (hex, "\\x%02x", *inp);
- for (i = 0; hex[i]; ++i)
- {
- wchar_t w = btowc (hex[i]);
- obstack_grow (output, &w, sizeof (wchar_t));
- }
-
- ++inp;
- }
- else
- {
- /* We are converting from host to target and
- cannot convert a character. There is nothing
- good to do here. FIXME: ought to show the char
- or its position. */
+ case translit_wchar:
+ {
+ /* We emit an escape sequence for the byte, skip
+ it, and try again. */
+ char hex[5];
+ int i;
+
+ /* Translit is only available when converting to
+ the host wchar_t. */
+ gdb_assert (!strcmp (to, "wchar_t"));
+ sprintf (hex, "\\x%02x", *inp);
+ for (i = 0; hex[i]; ++i)
+ {
+ wchar_t w = btowc (hex[i]);
+ obstack_grow (output, &w, sizeof (wchar_t));
+ }
+
+ ++inp;
+ }
+ break;
+ case translit_char:
+ {
+ /* We emit an escape sequence for the byte, skip
+ it, and try again. */
+ char hex[5];
+
+ sprintf (hex, "\\x%02x", *inp);
+ obstack_grow_str (output, hex);
+
+ ++inp;
+ }
+ break;
+ case translit_none:
error ("Could not convert character");
}
}
diff --git a/gdb/charset.h b/gdb/charset.h
index 09a5ae4..6802753 100644
--- a/gdb/charset.h
+++ b/gdb/charset.h
@@ -37,6 +37,18 @@ const char *host_charset (void);
const char *target_charset (void);
const char *target_wide_charset (void);
+/* These values are used to specify the type of transliteration done
+ by convert_between_encodings. */
+enum transliterations
+ {
+ /* Error on failure to convert. */
+ translit_none,
+ /* Transliterate to host wchar_t. */
+ translit_wchar,
+ /* Transliterate to host char. */
+ translit_char
+ };
+
/* Convert between two encodings.
FROM is the name of the source encoding.
@@ -47,13 +59,11 @@ const char *target_wide_charset (void);
OUTPUT is an obstack where the converted data is written. The
caller is responsible for initializing the obstack, and for
destroying the obstack should an error occur.
- TRANSLIT is true if unrecognized characters should be
- transliterated into escape sequences. This is only valid if the
- destination character set is the host character set. If false,
- this function will raise an error on an invalid conversion. */
+ TRANSLIT specifies how invalid conversions should be handled. */
void convert_between_encodings (const char *from, const char *to,
const gdb_byte *bytes, unsigned int num_bytes,
- struct obstack *output, int translit);
+ struct obstack *output,
+ enum transliterations translit);
\f
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 588f6e2..d0429b3 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -43,6 +43,7 @@
#include "disasm.h"
#include "dfp.h"
#include "valprint.h"
+#include "charset.h"
#ifdef TUI
#include "tui/tui.h" /* For tui_active et.al. */
@@ -1864,7 +1865,8 @@ printf_command (char *arg, int from_tty)
enum argclass
{
- int_arg, long_arg, long_long_arg, ptr_arg, string_arg,
+ int_arg, long_arg, long_long_arg, ptr_arg,
+ string_arg, wide_string_arg, wide_char_arg,
double_arg, long_double_arg, decfloat_arg
};
enum argclass *argclass;
@@ -1996,8 +1998,8 @@ printf_command (char *arg, int from_tty)
break;
case 'c':
- this_argclass = int_arg;
- if (lcount || seen_h || seen_big_l)
+ this_argclass = lcount == 0 ? int_arg : wide_char_arg;
+ if (lcount > 1 || seen_h || seen_big_l)
bad = 1;
if (seen_prec || seen_zero || seen_space || seen_plus)
bad = 1;
@@ -2012,8 +2014,8 @@ printf_command (char *arg, int from_tty)
break;
case 's':
- this_argclass = string_arg;
- if (lcount || seen_h || seen_big_l)
+ this_argclass = lcount == 0 ? string_arg : wide_string_arg;
+ if (lcount > 1 || seen_h || seen_big_l)
bad = 1;
if (seen_zero || seen_space || seen_plus)
bad = 1;
@@ -2065,6 +2067,15 @@ printf_command (char *arg, int from_tty)
last_arg[length_before_ll + lcount];
current_substring += length_before_ll + 4;
}
+ else if (this_argclass == wide_string_arg
+ || this_argclass == wide_char_arg)
+ {
+ /* Convert %ls or %lc to %s. */
+ int length_before_ls = f - last_arg - 2;
+ strncpy (current_substring, last_arg, length_before_ls);
+ strcpy (current_substring + length_before_ls, "s");
+ current_substring += length_before_ls + 2;
+ }
else
{
strncpy (current_substring, last_arg, f - last_arg);
@@ -2129,6 +2140,74 @@ printf_command (char *arg, int from_tty)
printf_filtered (current_substring, (char *) str);
}
break;
+ case wide_string_arg:
+ {
+ gdb_byte *str;
+ CORE_ADDR tem;
+ int j;
+ struct type *wctype = lookup_typename ("wchar_t", NULL, 0);
+ int wcwidth = TYPE_LENGTH (wctype);
+ gdb_byte *buf = alloca (wcwidth);
+ struct obstack output;
+ struct cleanup *inner_cleanup;
+
+ tem = value_as_address (val_args[i]);
+
+ /* This is a %s argument. Find the length of the string. */
+ for (j = 0;; j += wcwidth)
+ {
+ QUIT;
+ read_memory (tem + j, buf, wcwidth);
+ if (extract_unsigned_integer (buf, wcwidth) == 0)
+ break;
+ }
+
+ /* Copy the string contents into a string inside GDB. */
+ str = (gdb_byte *) alloca (j + wcwidth);
+ if (j != 0)
+ read_memory (tem, str, j);
+ memset (&str[j], 0, wcwidth);
+
+ obstack_init (&output);
+ inner_cleanup = make_cleanup_obstack_free (&output);
+
+ convert_between_encodings (target_wide_charset (),
+ host_charset (),
+ str, j, &output, translit_char);
+ obstack_grow_str0 (&output, "");
+
+ printf_filtered (current_substring, obstack_base (&output));
+ do_cleanups (inner_cleanup);
+ }
+ break;
+ case wide_char_arg:
+ {
+ struct type *wctype = lookup_typename ("wchar_t", NULL, 0);
+ struct type *valtype;
+ struct obstack output;
+ struct cleanup *inner_cleanup;
+ const gdb_byte *bytes;
+
+ valtype = value_type (val_args[i]);
+ if (TYPE_LENGTH (valtype) != TYPE_LENGTH (wctype)
+ || TYPE_CODE (valtype) != TYPE_CODE_INT)
+ error (_("expected wchar_t argument for %%lc"));
+
+ bytes = value_contents (val_args[i]);
+
+ obstack_init (&output);
+ inner_cleanup = make_cleanup_obstack_free (&output);
+
+ convert_between_encodings (target_wide_charset (),
+ host_charset (),
+ bytes, TYPE_LENGTH (valtype),
+ &output, translit_char);
+ obstack_grow_str0 (&output, "");
+
+ printf_filtered (current_substring, obstack_base (&output));
+ do_cleanups (inner_cleanup);
+ }
+ break;
case double_arg:
{
struct type *type = value_type (val_args[i]);
diff --git a/gdb/utils.c b/gdb/utils.c
index 5f2c0d8..c84a007 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -1504,7 +1504,7 @@ host_char_to_target (int c, int *target_c)
cleanups = make_cleanup_obstack_free (&host_data);
convert_between_encodings (target_charset (), host_charset (),
- &the_char, 1, &host_data, 0);
+ &the_char, 1, &host_data, translit_none);
if (obstack_object_size (&host_data) == 1)
{
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-01-09 18:04 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-09 18:04 [SCM] archer-tromey-charset: implement %ls and %lc printf formats tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).