diff options
Diffstat (limited to 'gdb/valprint.c')
-rw-r--r-- | gdb/valprint.c | 137 |
1 files changed, 92 insertions, 45 deletions
diff --git a/gdb/valprint.c b/gdb/valprint.c index 6937dab..aa34b68 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -1264,7 +1264,7 @@ val_print_type_code_int (struct type *type, const gdb_byte *valaddr, complement (a reasonable assumption, I think) and do better than this. */ print_hex_chars (stream, (unsigned char *) valaddr, - TYPE_LENGTH (type), byte_order); + TYPE_LENGTH (type), byte_order, false); } } else @@ -1537,7 +1537,7 @@ print_decimal_floating (const gdb_byte *valaddr, struct type *type, void print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr, - unsigned len, enum bfd_endian byte_order) + unsigned len, enum bfd_endian byte_order, bool zero_pad) { #define BITS_IN_BYTES 8 @@ -1545,14 +1545,13 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr, const gdb_byte *p; unsigned int i; int b; + bool seen_a_one = false; /* Declared "int" so it will be signed. This ensures that right shift will shift in zeros. */ const int mask = 0x080; - /* FIXME: We should be not printing leading zeroes in most cases. */ - if (byte_order == BFD_ENDIAN_BIG) { for (p = valaddr; @@ -1565,11 +1564,14 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr, for (i = 0; i < (BITS_IN_BYTES * sizeof (*p)); i++) { if (*p & (mask >> i)) - b = 1; + b = '1'; else - b = 0; + b = '0'; - fprintf_filtered (stream, "%1d", b); + if (zero_pad || seen_a_one || b == '1') + fputc_filtered (b, stream); + if (b == '1') + seen_a_one = true; } } } @@ -1582,14 +1584,34 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr, for (i = 0; i < (BITS_IN_BYTES * sizeof (*p)); i++) { if (*p & (mask >> i)) - b = 1; + b = '1'; else - b = 0; + b = '0'; - fprintf_filtered (stream, "%1d", b); + if (zero_pad || seen_a_one || b == '1') + fputc_filtered (b, stream); + if (b == '1') + seen_a_one = true; } } } + + /* When not zero-padding, ensure that something is printed when the + input is 0. */ + if (!zero_pad && !seen_a_one) + fputc_filtered ('0', stream); +} + +/* A helper for print_octal_chars that emits a single octal digit, + optionally suppressing it if is zero and updating SEEN_A_ONE. */ + +static void +emit_octal_digit (struct ui_file *stream, bool *seen_a_one, int digit) +{ + if (*seen_a_one || digit != 0) + fprintf_filtered (stream, "%o", digit); + if (digit != 0) + *seen_a_one = true; } /* VALADDR points to an integer of LEN bytes. @@ -1603,9 +1625,6 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, unsigned char octa1, octa2, octa3, carry; int cycle; - /* FIXME: We should be not printing leading zeroes in most cases. */ - - /* Octal is 3 bits, which doesn't fit. Yuk. So we have to track * the extra bits, which cycle every three bytes: * @@ -1640,6 +1659,7 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, carry = 0; fputs_filtered ("0", stream); + bool seen_a_one = false; if (byte_order == BFD_ENDIAN_BIG) { for (p = valaddr; @@ -1654,8 +1674,8 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa1 = (HIGH_ZERO & *p) >> 5; octa2 = (LOW_ZERO & *p) >> 2; carry = (CARRY_ZERO & *p); - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); break; case 1: @@ -1665,9 +1685,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa2 = (MID_ONE & *p) >> 4; octa3 = (LOW_ONE & *p) >> 1; carry = (CARRY_ONE & *p); - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); - fprintf_filtered (stream, "%o", octa3); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); + emit_octal_digit (stream, &seen_a_one, octa3); break; case 2: @@ -1677,9 +1697,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa2 = (MID_TWO & *p) >> 3; octa3 = (LOW_TWO & *p); carry = 0; - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); - fprintf_filtered (stream, "%o", octa3); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); + emit_octal_digit (stream, &seen_a_one, octa3); break; default: @@ -1704,8 +1724,8 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa1 = (HIGH_ZERO & *p) >> 5; octa2 = (LOW_ZERO & *p) >> 2; carry = (CARRY_ZERO & *p); - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); break; case 1: @@ -1715,9 +1735,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa2 = (MID_ONE & *p) >> 4; octa3 = (LOW_ONE & *p) >> 1; carry = (CARRY_ONE & *p); - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); - fprintf_filtered (stream, "%o", octa3); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); + emit_octal_digit (stream, &seen_a_one, octa3); break; case 2: @@ -1727,9 +1747,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa2 = (MID_TWO & *p) >> 3; octa3 = (LOW_TWO & *p); carry = 0; - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); - fprintf_filtered (stream, "%o", octa3); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); + emit_octal_digit (stream, &seen_a_one, octa3); break; default: @@ -1758,7 +1778,6 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr, #define HIGH_NIBBLE( x ) (((x) & 0x0F0) >> 4) const gdb_byte *p; - unsigned char *digits; int carry; int decimal_len; int i, j, decimal_digits; @@ -1769,12 +1788,7 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr, as the base 16 number, which is 2 digits per byte. */ decimal_len = len * 2 * 2; - digits = (unsigned char *) xmalloc (decimal_len); - - for (i = 0; i < decimal_len; i++) - { - digits[i] = 0; - } + std::vector<unsigned char> digits (decimal_len, 0); /* Ok, we have an unknown number of bytes of data to be printed in * decimal. @@ -1868,40 +1882,73 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr, /* Ok, now "digits" is the decimal representation, with the "decimal_digits" actual digits. Print! */ - for (i = decimal_digits - 1; i >= 0; i--) + for (i = decimal_digits - 1; i > 0 && digits[i] == 0; --i) + ; + + for (; i >= 0; i--) { fprintf_filtered (stream, "%1d", digits[i]); } - xfree (digits); } /* VALADDR points to an integer of LEN bytes. Print it in hex on stream. */ void print_hex_chars (struct ui_file *stream, const gdb_byte *valaddr, - unsigned len, enum bfd_endian byte_order) + unsigned len, enum bfd_endian byte_order, + bool zero_pad) { const gdb_byte *p; - /* FIXME: We should be not printing leading zeroes in most cases. */ - fputs_filtered ("0x", stream); if (byte_order == BFD_ENDIAN_BIG) { - for (p = valaddr; + p = valaddr; + + if (!zero_pad) + { + /* Strip leading 0 bytes, but be sure to leave at least a + single byte at the end. */ + for (; p < valaddr + len - 1 && !*p; ++p) + ; + } + + const gdb_byte *first = p; + for (; p < valaddr + len; p++) { - fprintf_filtered (stream, "%02x", *p); + /* When not zero-padding, use a different format for the + very first byte printed. */ + if (!zero_pad && p == first) + fprintf_filtered (stream, "%x", *p); + else + fprintf_filtered (stream, "%02x", *p); } } else { - for (p = valaddr + len - 1; + p = valaddr + len - 1; + + if (!zero_pad) + { + /* Strip leading 0 bytes, but be sure to leave at least a + single byte at the end. */ + for (; p >= valaddr + 1 && !*p; --p) + ; + } + + const gdb_byte *first = p; + for (; p >= valaddr; p--) { - fprintf_filtered (stream, "%02x", *p); + /* When not zero-padding, use a different format for the + very first byte printed. */ + if (!zero_pad && p == first) + fprintf_filtered (stream, "%x", *p); + else + fprintf_filtered (stream, "%02x", *p); } } } |