#include "language.h"
#include "demangle.h"
#include "annotate.h"
+#include "valprint.h"
#include <errno.h>
only a stub and we can't find and substitute its complete type, then
print appropriate string and return. */
- if (TYPE_FLAGS (real_type) & TYPE_FLAG_STUB
- || TYPE_LENGTH (real_type) == 0)
+ if (TYPE_FLAGS (real_type) & TYPE_FLAG_STUB)
{
fprintf_filtered (stream, "<incomplete type>");
gdb_flush (stream);
return LA_VALUE_PRINT (val, stream, format, pretty);
}
-/* Called by various <lang>_val_print routines to print TYPE_CODE_INT's */
+/* Called by various <lang>_val_print routines to print
+ TYPE_CODE_INT's. TYPE is the type. VALADDR is the address of the
+ value. STREAM is where to print the value. */
void
val_print_type_code_int (type, valaddr, stream)
char *valaddr;
GDB_FILE *stream;
{
- char *p;
- /* Pointer to first (i.e. lowest address) nonzero character. */
- char *first_addr;
- unsigned int len;
-
if (TYPE_LENGTH (type) > sizeof (LONGEST))
{
- if (TYPE_UNSIGNED (type))
- {
- /* First figure out whether the number in fact has zeros
- in all its bytes more significant than least significant
- sizeof (LONGEST) ones. */
- len = TYPE_LENGTH (type);
-
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
- {
- for (p = valaddr;
- len > sizeof (LONGEST) && p < valaddr + TYPE_LENGTH (type);
- p++)
- {
- if (*p == 0)
- {
- len--;
- }
- else
- {
- break;
- }
- }
- first_addr = p;
- }
- else
- {
- first_addr = valaddr;
- for (p = valaddr + TYPE_LENGTH (type) - 1;
- len > sizeof (LONGEST) && p >= valaddr;
- p--)
- {
- if (*p == 0)
- {
- len--;
- }
- else
- {
- break;
- }
- }
- }
+ LONGEST val;
- if (len <= sizeof (LONGEST))
- {
- /* The most significant bytes are zero, so we can just get
- the least significant sizeof (LONGEST) bytes and print it
- in decimal. */
- print_longest (stream, 'u', 0,
- extract_unsigned_integer (first_addr,
- sizeof (LONGEST)));
- }
- else
- {
- /* It is big, so print it in hex. */
- print_hex_chars (stream, (unsigned char *) first_addr, len);
- }
+ if (TYPE_UNSIGNED (type)
+ && extract_long_unsigned_integer (valaddr, TYPE_LENGTH (type),
+ &val))
+ {
+ print_longest (stream, 'u', 0, val);
}
else
{
- /* Signed. One could assume two's complement (a reasonable
- assumption, I think) and do better than this. */
+ /* Signed, or we couldn't turn an unsigned value into a
+ LONGEST. For signed values, one could assume two's
+ complement (a reasonable assumption, I think) and do
+ better than this. */
print_hex_chars (stream, (unsigned char *) valaddr,
TYPE_LENGTH (type));
}
{
#if defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG)
long vtop, vbot;
-
- vtop = val_long >> (sizeof (long) * HOST_CHAR_BIT);
+ unsigned int ui_max = UINT_MAX;
+ unsigned long long val_ulonglong;
+
+ /* Do shift in two operations so that if sizeof (long) == sizeof (LONGEST)
+ we can avoid warnings from picky compilers about shifts >= the size of
+ the shiftee in bits */
+ vtop = val_long >> (sizeof (long) * HOST_CHAR_BIT - 1);
+ vtop >>= 1;
vbot = (long) val_long;
-
- if ((format == 'd' && (val_long < INT_MIN || val_long > INT_MAX))
- || ((format == 'u' || format == 'x') && (unsigned long long)val_long > UINT_MAX))
+ val_ulonglong = (unsigned long long) val_long;
+ switch (format)
{
- fprintf_filtered (stream, "0x%lx%08lx", vtop, vbot);
- return;
+ case 'd':
+ if (val_long < INT_MIN || val_long > INT_MAX)
+ {
+ if (sizeof (long long) > sizeof (long))
+ {
+ fprintf_filtered (stream, "0x%lx%08lx", vtop, vbot);
+ }
+ else
+ {
+ fprintf_filtered (stream, "%d", vbot);
+ }
+ return;
+ }
+ break;
+ case 'x':
+ if (val_ulonglong > ui_max)
+ {
+ if (sizeof (long long) > sizeof (long))
+ {
+ fprintf_filtered (stream, "0x%lx%08lx", vtop, vbot);
+ }
+ else
+ {
+ fprintf_filtered (stream, "0x%lx", vbot);
+ }
+ return;
+ }
+ break;
+ case 'u':
+ if (val_ulonglong > ui_max)
+ {
+ if (sizeof (long long) > sizeof (long))
+ {
+ fprintf_filtered (stream, "0x%lx%08lx", vtop, vbot);
+ }
+ else
+ {
+ fprintf_filtered (stream, "%lu", (unsigned long) vbot);
+ }
+ return;
+ }
+ break;
}
#endif
if (sizeof (LONGEST) <= sizeof (int))
return arg;
- if (arg > INT_MAX || arg < INT_MIN)
- error ("Value out of range.");
+ if (arg > INT_MAX)
+ error ("Value is larger than largest signed integer.");
+ if (arg < INT_MIN)
+ error ("Value is smaller than smallest signed integer.");
return arg;
}
struct type *type;
GDB_FILE *stream;
{
- double doub;
+ DOUBLEST doub;
int inv;
unsigned len = TYPE_LENGTH (type);
doub = unpack_double (type, valaddr, &inv);
if (inv)
- fprintf_filtered (stream, "<invalid float value>");
+ {
+ fprintf_filtered (stream, "<invalid float value>");
+ return;
+ }
+
+ if (len < sizeof (double))
+ fprintf_filtered (stream, "%.9g", (double) doub);
+ else if (len == sizeof (double))
+ fprintf_filtered (stream, "%.17g", (double) doub);
else
- fprintf_filtered (stream, len <= sizeof(float) ? "%.9g" : "%.17g", doub);
+#ifdef PRINTF_HAS_LONG_DOUBLE
+ fprintf_filtered (stream, "%.35Lg", doub);
+#else
+ /* This at least wins with values that are representable as doubles */
+ fprintf_filtered (stream, "%.17g", (double) doub);
+#endif
}
/* VALADDR points to an integer of LEN bytes. Print it in hex on stream. */
unsigned int fetchlimit; /* Maximum number of bytes to fetch. */
unsigned int nfetch; /* Bytes to fetch / bytes fetched. */
unsigned int chunksize; /* Size of each fetch, in bytes. */
- int bufsize; /* Size of current fetch buffer. */
+ unsigned int bufsize; /* Size of current fetch buffer. */
char *buffer = NULL; /* Dynamically growable fetch buffer. */
char *bufptr; /* Pointer to next available byte in buffer. */
char *limit; /* First location past end of fetch buffer. */