+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.
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 *));
}
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)
{
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))
{
%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
}
| CHARACTER_STRING_LITERAL
{
- $$ = 0; /* FIXME */
+ write_exp_elt_opcode (OP_STRING);
+ write_exp_string ($1);
+ write_exp_elt_opcode (OP_STRING);
}
| BIT_STRING_LITERAL
{
%%
+/* 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. */
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
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.
*/
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++)
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);
}
/* 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)
{
enum val_prettyprint pretty;
{
LONGEST val;
+ unsigned int i;
+ struct type *elttype;
+ unsigned eltlen;
+ CORE_ADDR addr;
switch (TYPE_CODE (type))
{
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:
/* 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". */
int addressprint; /* Controls printing of machine addresses */
\f
-/* 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;
}
}
+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);
+}
\f
#if 0
/* Validate an input or output radix setting, and make sure the user
#ifdef __STDC__
struct frame_info;
+struct fn_field;
#endif
extern void
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,
value_less PARAMS ((value arg1, value arg2));
extern int
-value_zerop PARAMS ((value arg1));
+value_logical_not PARAMS ((value arg1));
/* C++ */
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));
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,
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));
extern value
value_copy PARAMS ((value));
+extern int
+baseclass_offset PARAMS ((struct type *, int, value, int));
+
/* From valops.c */
extern value