* 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:
Fred Fish 1993-01-14 05:10:12 +00:00
parent 31883f012e
commit c7da3ed3cd
7 changed files with 389 additions and 198 deletions

View File

@ -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.

View File

@ -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))
{

View File

@ -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)
{

View File

@ -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:

View File

@ -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". */

View File

@ -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

View File

@ -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