* c-valprint.c (cp_print_class_member): Add extern decl.
* c-valprint.c (c_val_print): Extract code for printing methods and move it to cp_print_class_method in cp-valprint.c. * c-valprint.c (c_val_print): Extract code to print strings and move it to val_print_string in valprint.c. * cp-valprint.c (cp_print_class_method): New function using code extracted from c_val_print. * valprint.c (val_print_string): New function using code extracted from c_val_print. * value.h (val_print_string): Add prototype. **** start-sanitize-chill **** * ch-exp.y (CHARACTER_STRING_LITERAL): Set correct token type. * ch-exp.y (literal): Add action for CHARACTER_STRING_LITERAL. * ch-exp.y (tempbuf, tempbufsize, tempbufindex, GROWBY_MIN_SIZE, CHECKBUF, growbuf_by_size): New variables, macros, and support functions for implementing a dynamically expandable temp buffer. * ch-exp.y (match_string_literal): New lexer function. * ch-exp.y (match_bitstring_literal): Dynamic buffer code removed and replaced with new CHECKBUF macro. * ch-exp.y (yylex): Call match_string_literal when appropriate. * ch-valprint.c (ch_val_print): Add code for TYPE_CODE_PTR. **** end-sanitize-chill ****
This commit is contained in:
parent
31883f012e
commit
c7da3ed3cd
@ -1,3 +1,28 @@
|
||||
Wed Jan 13 20:49:59 1993 Fred Fish (fnf@cygnus.com)
|
||||
|
||||
* c-valprint.c (cp_print_class_member): Add extern decl.
|
||||
* c-valprint.c (c_val_print): Extract code for printing methods
|
||||
and move it to cp_print_class_method in cp-valprint.c.
|
||||
* c-valprint.c (c_val_print): Extract code to print strings and
|
||||
move it to val_print_string in valprint.c.
|
||||
* cp-valprint.c (cp_print_class_method): New function using
|
||||
code extracted from c_val_print.
|
||||
* valprint.c (val_print_string): New function using code
|
||||
extracted from c_val_print.
|
||||
* value.h (val_print_string): Add prototype.
|
||||
**** start-sanitize-chill ****
|
||||
* ch-exp.y (CHARACTER_STRING_LITERAL): Set correct token type.
|
||||
* ch-exp.y (literal): Add action for CHARACTER_STRING_LITERAL.
|
||||
* ch-exp.y (tempbuf, tempbufsize, tempbufindex, GROWBY_MIN_SIZE,
|
||||
CHECKBUF, growbuf_by_size): New variables, macros, and support
|
||||
functions for implementing a dynamically expandable temp buffer.
|
||||
* ch-exp.y (match_string_literal): New lexer function.
|
||||
* ch-exp.y (match_bitstring_literal): Dynamic buffer code
|
||||
removed and replaced with new CHECKBUF macro.
|
||||
* ch-exp.y (yylex): Call match_string_literal when appropriate.
|
||||
* ch-valprint.c (ch_val_print): Add code for TYPE_CODE_PTR.
|
||||
**** end-sanitize-chill ****
|
||||
|
||||
Sat Jan 9 19:59:33 1993 Stu Grossman (grossman at cygnus.com)
|
||||
|
||||
* Makefile.in: Add info for paread.o.
|
||||
|
156
gdb/c-valprint.c
156
gdb/c-valprint.c
@ -34,13 +34,16 @@ extern int demangle; /* whether to print C++ syms raw or src-form */
|
||||
extern void
|
||||
cp_print_class_member PARAMS ((char *, struct type *, FILE *, char *));
|
||||
|
||||
extern int
|
||||
cp_is_vtbl_ptr_type PARAMS ((struct type *));
|
||||
extern void
|
||||
cp_print_class_method PARAMS ((char *, struct type *, FILE *));
|
||||
|
||||
extern void
|
||||
cp_print_value_fields PARAMS ((struct type *, char *, FILE *, int, int,
|
||||
enum val_prettyprint, struct type **));
|
||||
|
||||
extern int
|
||||
cp_is_vtbl_ptr_type PARAMS ((struct type *));
|
||||
|
||||
extern int
|
||||
cp_is_vtbl_member PARAMS ((struct type *));
|
||||
|
||||
@ -142,78 +145,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
||||
}
|
||||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
|
||||
{
|
||||
struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
|
||||
struct fn_field *f;
|
||||
int j, len2;
|
||||
char *kind = "";
|
||||
CORE_ADDR addr;
|
||||
|
||||
addr = unpack_pointer (lookup_pointer_type (builtin_type_void),
|
||||
valaddr);
|
||||
if (METHOD_PTR_IS_VIRTUAL(addr))
|
||||
{
|
||||
int offset = METHOD_PTR_TO_VOFFSET(addr);
|
||||
len = TYPE_NFN_FIELDS (domain);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
f = TYPE_FN_FIELDLIST1 (domain, i);
|
||||
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
|
||||
|
||||
for (j = 0; j < len2; j++)
|
||||
{
|
||||
QUIT;
|
||||
if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
|
||||
{
|
||||
kind = "virtual ";
|
||||
goto common;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct symbol *sym = find_pc_function (addr);
|
||||
if (sym == 0)
|
||||
{
|
||||
error ("invalid pointer to member function");
|
||||
}
|
||||
len = TYPE_NFN_FIELDS (domain);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
f = TYPE_FN_FIELDLIST1 (domain, i);
|
||||
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
|
||||
|
||||
for (j = 0; j < len2; j++)
|
||||
{
|
||||
QUIT;
|
||||
if (STREQ (SYMBOL_NAME (sym),
|
||||
TYPE_FN_FIELD_PHYSNAME (f, j)))
|
||||
{
|
||||
goto common;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
common:
|
||||
if (i < len)
|
||||
{
|
||||
fprintf_filtered (stream, "&");
|
||||
c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
|
||||
fprintf (stream, kind);
|
||||
if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
|
||||
&& TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER)
|
||||
cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
|
||||
TYPE_FN_FIELDLIST_NAME (domain, i),
|
||||
0, stream);
|
||||
else
|
||||
cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
|
||||
TYPE_FN_FIELDLIST_NAME (domain, i),
|
||||
0, stream);
|
||||
break;
|
||||
}
|
||||
fprintf_filtered (stream, "(");
|
||||
type_print (type, "", stream, -1);
|
||||
fprintf_filtered (stream, ") %d", (int) addr >> 3);
|
||||
cp_print_class_method (valaddr, type, stream);
|
||||
}
|
||||
else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
|
||||
{
|
||||
@ -250,81 +182,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
||||
In that case don't try to print the string. */
|
||||
print_max < UINT_MAX)
|
||||
{
|
||||
int first_addr_err = 0;
|
||||
int errcode = 0;
|
||||
|
||||
/* Get first character. */
|
||||
errcode = target_read_memory (addr, (char *)&c, 1);
|
||||
if (errcode != 0)
|
||||
{
|
||||
/* First address out of bounds. */
|
||||
first_addr_err = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A real string. */
|
||||
char *string = (char *) alloca (print_max);
|
||||
|
||||
/* If the loop ends by us hitting print_max characters,
|
||||
we need to have elipses at the end. */
|
||||
int force_ellipses = 1;
|
||||
|
||||
/* This loop always fetches print_max characters, even
|
||||
though LA_PRINT_STRING might want to print more or fewer
|
||||
(with repeated characters). This is so that
|
||||
we don't spend forever fetching if we print
|
||||
a long string consisting of the same character
|
||||
repeated. Also so we can do it all in one memory
|
||||
operation, which is faster. However, this will be
|
||||
slower if print_max is set high, e.g. if you set
|
||||
print_max to 1000, not only will it take a long
|
||||
time to fetch short strings, but if you are near
|
||||
the end of the address space, it might not work. */
|
||||
QUIT;
|
||||
errcode = target_read_memory (addr, string, print_max);
|
||||
if (errcode != 0)
|
||||
{
|
||||
/* Try reading just one character. If that succeeds,
|
||||
assume we hit the end of the address space, but
|
||||
the initial part of the string is probably safe. */
|
||||
char x[1];
|
||||
errcode = target_read_memory (addr, x, 1);
|
||||
}
|
||||
if (errcode != 0)
|
||||
force_ellipses = 0;
|
||||
else
|
||||
for (i = 0; i < print_max; i++)
|
||||
if (string[i] == '\0')
|
||||
{
|
||||
force_ellipses = 0;
|
||||
break;
|
||||
}
|
||||
QUIT;
|
||||
|
||||
if (addressprint)
|
||||
{
|
||||
fputs_filtered (" ", stream);
|
||||
}
|
||||
LA_PRINT_STRING (stream, string, i, force_ellipses);
|
||||
}
|
||||
|
||||
if (errcode != 0)
|
||||
{
|
||||
if (errcode == EIO)
|
||||
{
|
||||
fprintf_filtered (stream,
|
||||
(" <Address 0x%x out of bounds>" +
|
||||
first_addr_err),
|
||||
addr + i);
|
||||
}
|
||||
else
|
||||
{
|
||||
error ("Error reading memory address 0x%x: %s.",
|
||||
addr + i, safe_strerror (errcode));
|
||||
}
|
||||
}
|
||||
|
||||
fflush (stream);
|
||||
i = val_print_string (addr, stream);
|
||||
}
|
||||
else if (cp_is_vtbl_member(type))
|
||||
{
|
||||
|
134
gdb/ch-exp.y
134
gdb/ch-exp.y
@ -149,7 +149,7 @@ yyerror PARAMS ((char *));
|
||||
%token <ssym> LOCATION_NAME
|
||||
%token <voidval> SET_LITERAL
|
||||
%token <voidval> EMPTINESS_LITERAL
|
||||
%token <voidval> CHARACTER_STRING_LITERAL
|
||||
%token <sval> CHARACTER_STRING_LITERAL
|
||||
%token <sval> BIT_STRING_LITERAL
|
||||
|
||||
%token <voidval> STRING
|
||||
@ -493,7 +493,9 @@ literal : INTEGER_LITERAL
|
||||
}
|
||||
| CHARACTER_STRING_LITERAL
|
||||
{
|
||||
$$ = 0; /* FIXME */
|
||||
write_exp_elt_opcode (OP_STRING);
|
||||
write_exp_string ($1);
|
||||
write_exp_elt_opcode (OP_STRING);
|
||||
}
|
||||
| BIT_STRING_LITERAL
|
||||
{
|
||||
@ -973,6 +975,45 @@ buffer_location : FIXME { $$ = 0; }
|
||||
|
||||
%%
|
||||
|
||||
/* Implementation of a dynamically expandable buffer for processing input
|
||||
characters acquired through lexptr and building a value to return in
|
||||
yylval. */
|
||||
|
||||
static char *tempbuf; /* Current buffer contents */
|
||||
static int tempbufsize; /* Size of allocated buffer */
|
||||
static int tempbufindex; /* Current index into buffer */
|
||||
|
||||
#define GROWBY_MIN_SIZE 64 /* Minimum amount to grow buffer by */
|
||||
|
||||
#define CHECKBUF(size) \
|
||||
do { \
|
||||
if (tempbufindex + (size) >= tempbufsize) \
|
||||
{ \
|
||||
growbuf_by_size (size); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
/* Grow the static temp buffer if necessary, including allocating the first one
|
||||
on demand. */
|
||||
|
||||
static void
|
||||
growbuf_by_size (count)
|
||||
int count;
|
||||
{
|
||||
int growby;
|
||||
|
||||
growby = max (count, GROWBY_MIN_SIZE);
|
||||
tempbufsize += growby;
|
||||
if (tempbuf == NULL)
|
||||
{
|
||||
tempbuf = (char *) malloc (tempbufsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempbuf = (char *) realloc (tempbuf, tempbufsize);
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to consume a simple name string token. If successful, returns
|
||||
a pointer to a nullbyte terminated copy of the name that can be used
|
||||
in symbol table lookups. If not successful, returns NULL. */
|
||||
@ -1270,6 +1311,49 @@ match_float_literal ()
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Recognize a string literal. A string literal is a nonzero sequence
|
||||
of characters enclosed in matching single or double quotes, except that
|
||||
a single character inside single quotes is a character literal, which
|
||||
we reject as a string literal. To embed the terminator character inside
|
||||
a string, it is simply doubled (I.E. "this""is""one""string") */
|
||||
|
||||
static int
|
||||
match_string_literal ()
|
||||
{
|
||||
char *tokptr = lexptr;
|
||||
|
||||
for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++)
|
||||
{
|
||||
CHECKBUF (1);
|
||||
if (*tokptr == *lexptr)
|
||||
{
|
||||
if (*(tokptr + 1) == *lexptr)
|
||||
{
|
||||
tokptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
tempbuf[tempbufindex++] = *tokptr;
|
||||
}
|
||||
if (*tokptr == '\0' /* no terminator */
|
||||
|| tempbufindex == 0 /* no string */
|
||||
|| (tempbufindex == 1 && *tokptr == '\'')) /* char literal */
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempbuf[tempbufindex] = '\0';
|
||||
yylval.sval.ptr = tempbuf;
|
||||
yylval.sval.length = tempbufindex;
|
||||
lexptr = ++tokptr;
|
||||
return (CHARACTER_STRING_LITERAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Recognize a character literal. A character literal is single character
|
||||
or a control sequence, enclosed in single quotes. A control sequence
|
||||
is a comma separated list of one or more integer literals, enclosed
|
||||
@ -1280,6 +1364,9 @@ match_float_literal ()
|
||||
As a GNU chill extension, the syntax C'xx' is also recognized as a
|
||||
character literal, where xx is a hex value for the character.
|
||||
|
||||
Note that more than a single character, enclosed in single quotes, is
|
||||
a string literal.
|
||||
|
||||
Returns CHARACTER_LITERAL if a match is found.
|
||||
*/
|
||||
|
||||
@ -1383,10 +1470,9 @@ match_bitstring_literal ()
|
||||
int bitcount = 0;
|
||||
int base;
|
||||
int digit;
|
||||
static char *tempbuf;
|
||||
static int tempbufsize;
|
||||
static int tempbufindex;
|
||||
|
||||
tempbufindex = 0;
|
||||
|
||||
/* Look for the required explicit base specifier. */
|
||||
|
||||
switch (*tokptr++)
|
||||
@ -1448,20 +1534,7 @@ match_bitstring_literal ()
|
||||
for (mask = (base >> 1); mask > 0; mask >>= 1)
|
||||
{
|
||||
bitcount++;
|
||||
/* Grow the static temp buffer if necessary, including allocating
|
||||
the first one on demand. */
|
||||
if (tempbufindex >= tempbufsize)
|
||||
{
|
||||
tempbufsize += 64;
|
||||
if (tempbuf == NULL)
|
||||
{
|
||||
tempbuf = (char *) malloc (tempbufsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempbuf = (char *) realloc (tempbuf, tempbufsize);
|
||||
}
|
||||
}
|
||||
CHECKBUF (1);
|
||||
if (digit & mask)
|
||||
{
|
||||
tempbuf[tempbufindex] |= (1 << bitoffset);
|
||||
@ -1707,12 +1780,31 @@ yylex ()
|
||||
}
|
||||
/* Look for characters which start a particular kind of multicharacter
|
||||
token, such as a character literal, register name, convenience
|
||||
variable name, etc. */
|
||||
variable name, string literal, etc. */
|
||||
switch (*lexptr)
|
||||
{
|
||||
case '\'':
|
||||
case '\"':
|
||||
/* First try to match a string literal, which is any nonzero
|
||||
sequence of characters enclosed in matching single or double
|
||||
quotes, except that a single character inside single quotes
|
||||
is a character literal, so we have to catch that case also. */
|
||||
token = match_string_literal ();
|
||||
if (token != 0)
|
||||
{
|
||||
return (token);
|
||||
}
|
||||
if (*lexptr == '\'')
|
||||
{
|
||||
token = match_character_literal ();
|
||||
if (token != 0)
|
||||
{
|
||||
return (token);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
case 'c':
|
||||
case '\'':
|
||||
token = match_character_literal ();
|
||||
if (token != 0)
|
||||
{
|
||||
|
@ -52,6 +52,10 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
||||
enum val_prettyprint pretty;
|
||||
{
|
||||
LONGEST val;
|
||||
unsigned int i;
|
||||
struct type *elttype;
|
||||
unsigned eltlen;
|
||||
CORE_ADDR addr;
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
@ -130,6 +134,44 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
||||
break;
|
||||
|
||||
case TYPE_CODE_PTR:
|
||||
if (format && format != 's')
|
||||
{
|
||||
print_scalar_formatted (valaddr, type, format, 0, stream);
|
||||
break;
|
||||
}
|
||||
addr = unpack_pointer (type, valaddr);
|
||||
elttype = TYPE_TARGET_TYPE (type);
|
||||
|
||||
if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
|
||||
{
|
||||
/* Try to print what function it points to. */
|
||||
print_address_demangle (addr, stream, demangle);
|
||||
/* Return value is irrelevant except for string pointers. */
|
||||
return (0);
|
||||
}
|
||||
if (addressprint && format != 's')
|
||||
{
|
||||
fprintf_filtered (stream, "0x%x", addr);
|
||||
}
|
||||
|
||||
/* For a pointer to char or unsigned char, also print the string
|
||||
pointed to, unless pointer is null. */
|
||||
i = 0; /* Number of characters printed. */
|
||||
if (TYPE_LENGTH (elttype) == 1
|
||||
&& TYPE_CODE (elttype) == TYPE_CODE_CHAR
|
||||
&& (format == 0 || format == 's')
|
||||
&& addr != 0
|
||||
&& /* If print_max is UINT_MAX, the alloca below will fail.
|
||||
In that case don't try to print the string. */
|
||||
print_max < UINT_MAX)
|
||||
{
|
||||
i = val_print_string (addr, stream);
|
||||
}
|
||||
/* Return number of characters printed, plus one for the
|
||||
terminating null if we have "reached the end". */
|
||||
return (i + (print_max && i != print_max));
|
||||
break;
|
||||
|
||||
case TYPE_CODE_MEMBER:
|
||||
case TYPE_CODE_REF:
|
||||
case TYPE_CODE_UNION:
|
||||
|
@ -60,6 +60,96 @@ c_val_print PARAMS ((struct type *, char *, CORE_ADDR, FILE *, int, int, int,
|
||||
/* END-FIXME */
|
||||
|
||||
|
||||
void
|
||||
cp_print_class_method (valaddr, type, stream)
|
||||
char *valaddr;
|
||||
struct type *type;
|
||||
FILE *stream;
|
||||
{
|
||||
struct type *domain;
|
||||
struct fn_field *f;
|
||||
int j;
|
||||
int len2;
|
||||
int offset;
|
||||
char *kind = "";
|
||||
CORE_ADDR addr;
|
||||
struct symbol *sym;
|
||||
unsigned len;
|
||||
unsigned int i;
|
||||
|
||||
domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
|
||||
addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr);
|
||||
if (METHOD_PTR_IS_VIRTUAL (addr))
|
||||
{
|
||||
offset = METHOD_PTR_TO_VOFFSET (addr);
|
||||
len = TYPE_NFN_FIELDS (domain);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
f = TYPE_FN_FIELDLIST1 (domain, i);
|
||||
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
|
||||
|
||||
for (j = 0; j < len2; j++)
|
||||
{
|
||||
QUIT;
|
||||
if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
|
||||
{
|
||||
kind = "virtual ";
|
||||
goto common;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sym = find_pc_function (addr);
|
||||
if (sym == 0)
|
||||
{
|
||||
error ("invalid pointer to member function");
|
||||
}
|
||||
len = TYPE_NFN_FIELDS (domain);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
f = TYPE_FN_FIELDLIST1 (domain, i);
|
||||
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
|
||||
|
||||
for (j = 0; j < len2; j++)
|
||||
{
|
||||
QUIT;
|
||||
if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
|
||||
{
|
||||
goto common;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
common:
|
||||
if (i < len)
|
||||
{
|
||||
fprintf_filtered (stream, "&");
|
||||
c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
|
||||
fprintf (stream, kind);
|
||||
if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
|
||||
&& TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER)
|
||||
{
|
||||
cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
|
||||
TYPE_FN_FIELDLIST_NAME (domain, i),
|
||||
0, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
|
||||
TYPE_FN_FIELDLIST_NAME (domain, i),
|
||||
0, stream);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf_filtered (stream, "(");
|
||||
type_print (type, "", stream, -1);
|
||||
fprintf_filtered (stream, ") %d", (int) addr >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return truth value for assertion that TYPE is of the type
|
||||
"pointer to virtual function". */
|
||||
|
||||
|
114
gdb/valprint.c
114
gdb/valprint.c
@ -81,23 +81,28 @@ int unionprint; /* Controls printing of nested unions. */
|
||||
int addressprint; /* Controls printing of machine addresses */
|
||||
|
||||
|
||||
/* Print data of type TYPE located at VALADDR (within GDB),
|
||||
which came from the inferior at address ADDRESS,
|
||||
onto stdio stream STREAM according to FORMAT
|
||||
(a letter or 0 for natural format). The data at VALADDR
|
||||
is in target byte order.
|
||||
/* Print data of type TYPE located at VALADDR (within GDB), which came from
|
||||
the inferior at address ADDRESS, onto stdio stream STREAM according to
|
||||
FORMAT (a letter, or 0 for natural format using TYPE).
|
||||
|
||||
If the data are a string pointer, returns the number of
|
||||
sting characters printed.
|
||||
If DEREF_REF is nonzero, then dereference references, otherwise just print
|
||||
them like pointers.
|
||||
|
||||
if DEREF_REF is nonzero, then dereference references,
|
||||
otherwise just print them like pointers.
|
||||
The PRETTY parameter controls prettyprinting.
|
||||
|
||||
If the data are a string pointer, returns the number of string characters
|
||||
printed.
|
||||
|
||||
FIXME: The data at VALADDR is in target byte order. If gdb is ever
|
||||
enhanced to be able to debug more than the single target it was compiled
|
||||
for (specific CPU type and thus specific target byte ordering), then
|
||||
either the print routines are going to have to take this into account,
|
||||
or the data is going to have to be passed into here already converted
|
||||
to the host byte ordering, whichever is more convenient. */
|
||||
|
||||
The PRETTY parameter controls prettyprinting. */
|
||||
|
||||
int
|
||||
val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
||||
pretty)
|
||||
val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty)
|
||||
struct type *type;
|
||||
char *valaddr;
|
||||
CORE_ADDR address;
|
||||
@ -545,6 +550,91 @@ value_print_array_elements (val, stream, format, pretty)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
val_print_string (addr, stream)
|
||||
CORE_ADDR addr;
|
||||
FILE *stream;
|
||||
{
|
||||
int first_addr_err;
|
||||
int errcode;
|
||||
unsigned char c;
|
||||
char *string;
|
||||
int force_ellipses;
|
||||
unsigned int i = 0; /* Number of characters printed. */
|
||||
|
||||
/* Get first character. */
|
||||
errcode = target_read_memory (addr, (char *)&c, 1);
|
||||
if (errcode != 0)
|
||||
{
|
||||
/* First address out of bounds. */
|
||||
first_addr_err = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_addr_err = 0;
|
||||
/* A real string. */
|
||||
string = (char *) alloca (print_max);
|
||||
|
||||
/* If the loop ends by us hitting print_max characters,
|
||||
we need to have elipses at the end. */
|
||||
force_ellipses = 1;
|
||||
|
||||
/* This loop always fetches print_max characters, even
|
||||
though LA_PRINT_STRING might want to print more or fewer
|
||||
(with repeated characters). This is so that
|
||||
we don't spend forever fetching if we print
|
||||
a long string consisting of the same character
|
||||
repeated. Also so we can do it all in one memory
|
||||
operation, which is faster. However, this will be
|
||||
slower if print_max is set high, e.g. if you set
|
||||
print_max to 1000, not only will it take a long
|
||||
time to fetch short strings, but if you are near
|
||||
the end of the address space, it might not work. */
|
||||
QUIT;
|
||||
errcode = target_read_memory (addr, string, print_max);
|
||||
if (errcode != 0)
|
||||
{
|
||||
/* Try reading just one character. If that succeeds,
|
||||
assume we hit the end of the address space, but
|
||||
the initial part of the string is probably safe. */
|
||||
char x[1];
|
||||
errcode = target_read_memory (addr, x, 1);
|
||||
}
|
||||
if (errcode != 0)
|
||||
force_ellipses = 0;
|
||||
else
|
||||
for (i = 0; i < print_max; i++)
|
||||
if (string[i] == '\0')
|
||||
{
|
||||
force_ellipses = 0;
|
||||
break;
|
||||
}
|
||||
QUIT;
|
||||
|
||||
if (addressprint)
|
||||
{
|
||||
fputs_filtered (" ", stream);
|
||||
}
|
||||
LA_PRINT_STRING (stream, string, i, force_ellipses);
|
||||
}
|
||||
|
||||
if (errcode != 0)
|
||||
{
|
||||
if (errcode == EIO)
|
||||
{
|
||||
fprintf_filtered (stream,
|
||||
(" <Address 0x%x out of bounds>" + first_addr_err),
|
||||
addr + i);
|
||||
}
|
||||
else
|
||||
{
|
||||
error ("Error reading memory address 0x%x: %s.", addr + i,
|
||||
safe_strerror (errcode));
|
||||
}
|
||||
}
|
||||
fflush (stream);
|
||||
return (i);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Validate an input or output radix setting, and make sure the user
|
||||
|
26
gdb/value.h
26
gdb/value.h
@ -197,6 +197,7 @@ struct internalvar
|
||||
|
||||
#ifdef __STDC__
|
||||
struct frame_info;
|
||||
struct fn_field;
|
||||
#endif
|
||||
|
||||
extern void
|
||||
@ -298,7 +299,7 @@ extern value
|
||||
value_neg PARAMS ((value arg1));
|
||||
|
||||
extern value
|
||||
value_lognot PARAMS ((value arg1));
|
||||
value_complement PARAMS ((value arg1));
|
||||
|
||||
extern value
|
||||
value_struct_elt PARAMS ((value *argp, value *args, char *name,
|
||||
@ -390,7 +391,7 @@ extern int
|
||||
value_less PARAMS ((value arg1, value arg2));
|
||||
|
||||
extern int
|
||||
value_zerop PARAMS ((value arg1));
|
||||
value_logical_not PARAMS ((value arg1));
|
||||
|
||||
/* C++ */
|
||||
|
||||
@ -469,19 +470,6 @@ extern void
|
||||
type_print PARAMS ((struct type *type, char *varstring, FILE *stream,
|
||||
int show));
|
||||
|
||||
extern void
|
||||
type_print_1 PARAMS ((struct type *type, char *varstring, FILE *stream,
|
||||
int show, int level));
|
||||
|
||||
/* Possibilities for prettyprint parameters to routines which print
|
||||
things. */
|
||||
enum val_prettyprint {
|
||||
Val_no_prettyprint = 0,
|
||||
Val_prettyprint,
|
||||
/* Use the default setting which the user has specified. */
|
||||
Val_pretty_default
|
||||
};
|
||||
|
||||
extern char *
|
||||
baseclass_addr PARAMS ((struct type *type, int index, char *valaddr,
|
||||
value *valuep, int *errp));
|
||||
@ -498,6 +486,9 @@ val_print PARAMS ((struct type *type, char *valaddr, CORE_ADDR address,
|
||||
FILE *stream, int format, int deref_ref,
|
||||
int recurse, enum val_prettyprint pretty));
|
||||
|
||||
extern int
|
||||
val_print_string PARAMS ((CORE_ADDR addr, FILE *stream));
|
||||
|
||||
/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */
|
||||
extern void
|
||||
print_variable_value PARAMS ((struct symbol *var, struct frame_info *frame,
|
||||
@ -510,7 +501,7 @@ extern int
|
||||
check_field PARAMS ((value, const char *));
|
||||
|
||||
extern void
|
||||
typedef_print PARAMS ((struct type *type, struct symbol *new, FILE *stream));
|
||||
c_typedef_print PARAMS ((struct type *type, struct symbol *new, FILE *stream));
|
||||
|
||||
extern char *
|
||||
internalvar_name PARAMS ((struct internalvar *var));
|
||||
@ -526,6 +517,9 @@ clear_internalvars PARAMS ((void));
|
||||
extern value
|
||||
value_copy PARAMS ((value));
|
||||
|
||||
extern int
|
||||
baseclass_offset PARAMS ((struct type *, int, value, int));
|
||||
|
||||
/* From valops.c */
|
||||
|
||||
extern value
|
||||
|
Loading…
Reference in New Issue
Block a user