public inbox for archer-commits@sourceware.org help / color / mirror / Atom feed
From: tromey@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-tromey-charset: implement %ls and %lc printf formats Date: Fri, 09 Jan 2009 18:04:00 -0000 [thread overview] Message-ID: <20090109180401.10177.qmail@sourceware.org> (raw) 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.
reply other threads:[~2009-01-09 18:04 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20090109180401.10177.qmail@sourceware.org \ --to=tromey@sourceware.org \ --cc=archer-commits@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).