mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-03 05:12:28 +08:00
* c-exp.y (yylex): Add tempbuf, tempbufindex, and tempbufsize,
which together maintain a dynamically expandable static buffer for the lexer to use when translating C strings to their internal form (other future uses possible). Fix parsing of C style strings to do the normal C style input conversions of escaped character sequences. * valops.c (value_string): Remove translation of escaped character sequences, now done in C expression parser.
This commit is contained in:
@ -1,5 +1,13 @@
|
|||||||
Mon Nov 23 11:14:15 1992 Fred Fish (fnf@cygnus.com)
|
Mon Nov 23 11:14:15 1992 Fred Fish (fnf@cygnus.com)
|
||||||
|
|
||||||
|
* c-exp.y (yylex): Add tempbuf, tempbufindex, and tempbufsize,
|
||||||
|
which together maintain a dynamically expandable static buffer
|
||||||
|
for the lexer to use when translating C strings to their internal
|
||||||
|
form (other future uses possible). Fix parsing of C style strings
|
||||||
|
to do the normal C style input conversions of escaped character
|
||||||
|
sequences.
|
||||||
|
* valops.c (value_string): Remove translation of escaped
|
||||||
|
character sequences, now done in C expression parser.
|
||||||
* language.h (PRINT_LITERAL_FORM): New macro that takes character
|
* language.h (PRINT_LITERAL_FORM): New macro that takes character
|
||||||
and decides if it should be printed in literal form or some other
|
and decides if it should be printed in literal form or some other
|
||||||
form, based on it's ASCII value and setting of sevenbit_strings.
|
form, based on it's ASCII value and setting of sevenbit_strings.
|
||||||
|
74
gdb/c-exp.y
74
gdb/c-exp.y
@ -1079,11 +1079,15 @@ const static struct token tokentab2[] =
|
|||||||
int
|
int
|
||||||
yylex ()
|
yylex ()
|
||||||
{
|
{
|
||||||
register int c;
|
int c;
|
||||||
register int namelen;
|
int namelen;
|
||||||
register unsigned i;
|
unsigned int i;
|
||||||
register char *tokstart;
|
char *tokstart;
|
||||||
|
char *tokptr;
|
||||||
|
int tempbufindex;
|
||||||
|
static char *tempbuf;
|
||||||
|
static int tempbufsize;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
|
||||||
tokstart = lexptr;
|
tokstart = lexptr;
|
||||||
@ -1250,21 +1254,55 @@ yylex ()
|
|||||||
return c;
|
return c;
|
||||||
|
|
||||||
case '"':
|
case '"':
|
||||||
for (namelen = 1; (c = tokstart[namelen]) != '"'; namelen++)
|
|
||||||
if (c == '\\')
|
/* Build the gdb internal form of the input string in tempbuf,
|
||||||
|
translating any standard C escape forms seen. Note that the
|
||||||
|
buffer is null byte terminated *only* for the convenience of
|
||||||
|
debugging gdb itself and printing the buffer contents when
|
||||||
|
the buffer contains no embedded nulls. Gdb does not depend
|
||||||
|
upon the buffer being null byte terminated, it uses the length
|
||||||
|
string instead. This allows gdb to handle C strings (as well
|
||||||
|
as strings in other languages) with embedded null bytes */
|
||||||
|
|
||||||
|
tokptr = ++tokstart;
|
||||||
|
tempbufindex = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Grow the static temp buffer if necessary, including allocating
|
||||||
|
the first one on demand. */
|
||||||
|
if (tempbufindex + 1 >= tempbufsize)
|
||||||
{
|
{
|
||||||
c = tokstart[++namelen];
|
tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
{
|
|
||||||
c = tokstart[++namelen];
|
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
c = tokstart[++namelen];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
yylval.sval.ptr = tokstart + 1;
|
switch (*tokptr)
|
||||||
yylval.sval.length = namelen - 1;
|
{
|
||||||
lexptr += namelen + 1;
|
case '\0':
|
||||||
return STRING;
|
case '"':
|
||||||
|
/* Do nothing, loop will terminate. */
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
tokptr++;
|
||||||
|
c = parse_escape (&tokptr);
|
||||||
|
if (c == -1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tempbuf[tempbufindex++] = c;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tempbuf[tempbufindex++] = *tokptr++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ((*tokptr != '"') && (*tokptr != '\0'));
|
||||||
|
if (*tokptr++ != '"')
|
||||||
|
{
|
||||||
|
error ("Unterminated string in expression.");
|
||||||
|
}
|
||||||
|
tempbuf[tempbufindex] = '\0'; /* See note above */
|
||||||
|
yylval.sval.ptr = tempbuf;
|
||||||
|
yylval.sval.length = tempbufindex;
|
||||||
|
lexptr = tokptr;
|
||||||
|
return (STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(c == '_' || c == '$'
|
if (!(c == '_' || c == '$'
|
||||||
|
78
gdb/valops.c
78
gdb/valops.c
@ -43,7 +43,7 @@ static value
|
|||||||
search_struct_field PARAMS ((char *, value, int, struct type *, int));
|
search_struct_field PARAMS ((char *, value, int, struct type *, int));
|
||||||
|
|
||||||
static value
|
static value
|
||||||
search_struct_method PARAMS ((char *, value, value *, int, int *,
|
search_struct_method PARAMS ((char *, value *, value *, int, int *,
|
||||||
struct type *));
|
struct type *));
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -234,7 +234,7 @@ value_assign (toval, fromval)
|
|||||||
fromval = value_cast (REGISTER_VIRTUAL_TYPE (regno), fromval);
|
fromval = value_cast (REGISTER_VIRTUAL_TYPE (regno), fromval);
|
||||||
memcpy (virtual_buffer, VALUE_CONTENTS (fromval),
|
memcpy (virtual_buffer, VALUE_CONTENTS (fromval),
|
||||||
REGISTER_VIRTUAL_SIZE (regno));
|
REGISTER_VIRTUAL_SIZE (regno));
|
||||||
target_convert_from_virtual (regno, virtual_buffer, raw_buffer);
|
REGISTER_CONVERT_TO_RAW (regno, virtual_buffer, raw_buffer);
|
||||||
use_buffer = REGISTER_RAW_SIZE (regno);
|
use_buffer = REGISTER_RAW_SIZE (regno);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -913,7 +913,8 @@ call_function_by_hand (function, nargs, args)
|
|||||||
Call the function malloc in the inferior to get space for it,
|
Call the function malloc in the inferior to get space for it,
|
||||||
then copy the data into that space
|
then copy the data into that space
|
||||||
and then return the address with type char *.
|
and then return the address with type char *.
|
||||||
PTR points to the string constant data; LEN is number of characters. */
|
PTR points to the string constant data; LEN is number of characters.
|
||||||
|
Note that the string may contain embedded null bytes. */
|
||||||
|
|
||||||
value
|
value
|
||||||
value_string (ptr, len)
|
value_string (ptr, len)
|
||||||
@ -923,36 +924,11 @@ value_string (ptr, len)
|
|||||||
register value val;
|
register value val;
|
||||||
register struct symbol *sym;
|
register struct symbol *sym;
|
||||||
value blocklen;
|
value blocklen;
|
||||||
register char *copy = (char *) alloca (len + 1);
|
|
||||||
char *i = ptr;
|
|
||||||
register char *o = copy, *ibeg = ptr;
|
|
||||||
register int c;
|
|
||||||
|
|
||||||
/* Copy the string into COPY, processing escapes.
|
|
||||||
We could not conveniently process them in the parser
|
|
||||||
because the string there wants to be a substring of the input. */
|
|
||||||
|
|
||||||
while (i - ibeg < len)
|
|
||||||
{
|
|
||||||
c = *i++;
|
|
||||||
if (c == '\\')
|
|
||||||
{
|
|
||||||
c = parse_escape (&i);
|
|
||||||
if (c == -1)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*o++ = c;
|
|
||||||
}
|
|
||||||
*o = 0;
|
|
||||||
|
|
||||||
/* Get the length of the string after escapes are processed. */
|
|
||||||
|
|
||||||
len = o - copy;
|
|
||||||
|
|
||||||
/* Find the address of malloc in the inferior. */
|
/* Find the address of malloc in the inferior. */
|
||||||
|
|
||||||
sym = lookup_symbol ("malloc", 0, VAR_NAMESPACE, 0, NULL);
|
sym = lookup_symbol ("malloc", 0, VAR_NAMESPACE, 0, NULL);
|
||||||
if (sym != 0)
|
if (sym != NULL)
|
||||||
{
|
{
|
||||||
if (SYMBOL_CLASS (sym) != LOC_BLOCK)
|
if (SYMBOL_CLASS (sym) != LOC_BLOCK)
|
||||||
error ("\"malloc\" exists in this program but is not a function.");
|
error ("\"malloc\" exists in this program but is not a function.");
|
||||||
@ -973,9 +949,9 @@ value_string (ptr, len)
|
|||||||
|
|
||||||
blocklen = value_from_longest (builtin_type_int, (LONGEST) (len + 1));
|
blocklen = value_from_longest (builtin_type_int, (LONGEST) (len + 1));
|
||||||
val = call_function_by_hand (val, 1, &blocklen);
|
val = call_function_by_hand (val, 1, &blocklen);
|
||||||
if (value_zerop (val))
|
if (value_logical_not (val))
|
||||||
error ("No memory available for string constant.");
|
error ("No memory available for string constant.");
|
||||||
write_memory (value_as_pointer (val), copy, len + 1);
|
write_memory (value_as_pointer (val), ptr, len + 1);
|
||||||
VALUE_TYPE (val) = lookup_pointer_type (builtin_type_char);
|
VALUE_TYPE (val) = lookup_pointer_type (builtin_type_char);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -1038,6 +1014,7 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
|
|||||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||||
{
|
{
|
||||||
value v2;
|
value v2;
|
||||||
|
/* Fix to use baseclass_offset instead. FIXME */
|
||||||
baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
|
baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
|
||||||
&v2, (int *)NULL);
|
&v2, (int *)NULL);
|
||||||
if (v2 == 0)
|
if (v2 == 0)
|
||||||
@ -1065,9 +1042,9 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
|
|||||||
If found, return value, else return NULL. */
|
If found, return value, else return NULL. */
|
||||||
|
|
||||||
static value
|
static value
|
||||||
search_struct_method (name, arg1, args, offset, static_memfuncp, type)
|
search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
|
||||||
char *name;
|
char *name;
|
||||||
register value arg1, *args;
|
register value *arg1p, *args;
|
||||||
int offset, *static_memfuncp;
|
int offset, *static_memfuncp;
|
||||||
register struct type *type;
|
register struct type *type;
|
||||||
{
|
{
|
||||||
@ -1092,10 +1069,10 @@ search_struct_method (name, arg1, args, offset, static_memfuncp, type)
|
|||||||
TYPE_FN_FIELD_ARGS (f, j), args))
|
TYPE_FN_FIELD_ARGS (f, j), args))
|
||||||
{
|
{
|
||||||
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
|
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
|
||||||
return (value)value_virtual_fn_field (arg1, f, j, type);
|
return (value)value_virtual_fn_field (arg1p, f, j, type, offset);
|
||||||
if (TYPE_FN_FIELD_STATIC_P (f, j) && static_memfuncp)
|
if (TYPE_FN_FIELD_STATIC_P (f, j) && static_memfuncp)
|
||||||
*static_memfuncp = 1;
|
*static_memfuncp = 1;
|
||||||
return (value)value_fn_field (f, j);
|
return (value)value_fn_field (arg1p, f, j, type, offset);
|
||||||
}
|
}
|
||||||
j--;
|
j--;
|
||||||
}
|
}
|
||||||
@ -1104,25 +1081,28 @@ search_struct_method (name, arg1, args, offset, static_memfuncp, type)
|
|||||||
|
|
||||||
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
|
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
value v, v2;
|
value v;
|
||||||
int base_offset;
|
int base_offset;
|
||||||
|
|
||||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||||
{
|
{
|
||||||
baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
|
base_offset =
|
||||||
&v2, (int *)NULL);
|
baseclass_offset (type, i, *arg1p, offset);
|
||||||
if (v2 == 0)
|
if (base_offset == -1)
|
||||||
error ("virtual baseclass botch");
|
error ("virtual baseclass botch");
|
||||||
base_offset = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v2 = arg1;
|
|
||||||
base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
|
base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
|
||||||
}
|
}
|
||||||
v = search_struct_method (name, v2, args, base_offset,
|
v = search_struct_method (name, arg1p, args, base_offset + offset,
|
||||||
static_memfuncp, TYPE_BASECLASS (type, i));
|
static_memfuncp, TYPE_BASECLASS (type, i));
|
||||||
if (v) return v;
|
if (v)
|
||||||
|
{
|
||||||
|
/* FIXME-bothner: Why is this commented out? Why is it here? */
|
||||||
|
/* *arg1p = arg1_tmp;*/
|
||||||
|
return v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1193,7 +1173,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
|
|||||||
if (destructor_name_p (name, t))
|
if (destructor_name_p (name, t))
|
||||||
error ("Cannot get value of destructor");
|
error ("Cannot get value of destructor");
|
||||||
|
|
||||||
v = search_struct_method (name, *argp, args, 0, static_memfuncp, t);
|
v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
|
||||||
|
|
||||||
if (v == 0)
|
if (v == 0)
|
||||||
{
|
{
|
||||||
@ -1210,8 +1190,9 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
|
|||||||
if (!args[1])
|
if (!args[1])
|
||||||
{
|
{
|
||||||
/* destructors are a special case. */
|
/* destructors are a special case. */
|
||||||
return (value)value_fn_field (TYPE_FN_FIELDLIST1 (t, 0),
|
return (value)value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, 0),
|
||||||
TYPE_FN_FIELDLIST_LENGTH (t, 0));
|
TYPE_FN_FIELDLIST_LENGTH (t, 0),
|
||||||
|
0, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1219,7 +1200,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
v = search_struct_method (name, *argp, args, 0, static_memfuncp, t);
|
v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
|
||||||
|
|
||||||
if (v == 0)
|
if (v == 0)
|
||||||
{
|
{
|
||||||
@ -1414,7 +1395,8 @@ value_struct_elt_for_reference (domain, offset, curtype, name, intype)
|
|||||||
(lookup_reference_type
|
(lookup_reference_type
|
||||||
(lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
|
(lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
|
||||||
domain)),
|
domain)),
|
||||||
(LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
|
(LONGEST) METHOD_PTR_FROM_VOFFSET
|
||||||
|
(TYPE_FN_FIELD_VOFFSET (f, j)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user