2009-02-05 Thiago Jung Bauermann <bauerman@br.ibm.com>

* language.h (language_dfn): Add la_get_string member.
	(LA_GET_STRING): New macro.
	(default_get_string): New prototype.
	* language.c (default_get_string): New function.
	(unknown_language_defn, auto_language_defn, local_language_defn): Use
	default_get_string for la_get_string.
	* c-lang.c (c_get_string): New function.
	(c_language_defn, cplus_language_defn, asm_language_defn): Use
	c_get_string for la_get_string.
	(minimal_language_defn): Likewise
	* ada-lang.c (ada_language_defn): Likewise.
	* f-lang.c (f_language_defn): Use default_get_string for
	la_get_string.
	* jv-lang.c (java_language_defn): Likewise.
	* m2-lang.c (m2_language_defn): Likewise.
	* objc-lang.c (objc_language_defn): Likewise.
	* p-lang.c (p_language_defn): Likewise.
	* scm-lang.c (scm_language_defn): Likewise.
	* typeprint.c (type_to_string): New function.
	* value.h (type_to_string): New prototype.
	* valprint.c (val_print_string): Factor out code for reading string
	from the inferior into its own function.  Put 2 spaces after period
	in comments.
	(read_string): New function.
	* valprint.h (read_string): New prototype.
This commit is contained in:
Thiago Jung Bauermann
2009-02-05 12:16:25 +00:00
parent fa8a61dc87
commit ae6a3a4c2a
15 changed files with 326 additions and 61 deletions

View File

@@ -181,6 +181,122 @@ c_printstr (struct ui_file *stream, const gdb_byte *string,
if (force_ellipses || i < length)
fputs_filtered ("...", stream);
}
/* Obtain a C string from the inferior storing it in a newly allocated
buffer in BUFFER, which should be freed by the caller. The string is
read until a null character is found. If VALUE is an array with known
length, the function will not read past the end of the array. LENGTH
will contain the size of the string in bytes (not counting the null
character).
Assumes strings are terminated by a null character. The size of a character
is determined by the length of the target type of the pointer or array.
This means that a null byte present in a multi-byte character will not
terminate the string unless the whole character is null.
CHARSET is always set to the target charset. */
void
c_get_string (struct value *value, gdb_byte **buffer, int *length,
const char **charset)
{
int err, width;
unsigned int fetchlimit;
struct type *type = check_typedef (value_type (value));
struct type *element_type = TYPE_TARGET_TYPE (type);
if (element_type == NULL)
goto error;
if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
{
/* If we know the size of the array, we can use it as a limit on the
number of characters to be fetched. */
if (TYPE_NFIELDS (type) == 1
&& TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE)
{
LONGEST low_bound, high_bound;
get_discrete_bounds (TYPE_FIELD_TYPE (type, 0),
&low_bound, &high_bound);
fetchlimit = high_bound - low_bound + 1;
}
else
fetchlimit = UINT_MAX;
}
else if (TYPE_CODE (type) == TYPE_CODE_PTR)
fetchlimit = UINT_MAX;
else
/* We work only with arrays and pointers. */
goto error;
element_type = check_typedef (element_type);
if (TYPE_CODE (element_type) != TYPE_CODE_INT
&& TYPE_CODE (element_type) != TYPE_CODE_CHAR)
/* If the elements are not integers or characters, we don't consider it
a string. */
goto error;
width = TYPE_LENGTH (element_type);
/* If the string lives in GDB's memory intead of the inferior's, then we
just need to copy it to BUFFER. Also, since such strings are arrays
with known size, FETCHLIMIT will hold the size of the array. */
if ((VALUE_LVAL (value) == not_lval
|| VALUE_LVAL (value) == lval_internalvar)
&& fetchlimit != UINT_MAX)
{
int i;
const gdb_byte *contents = value_contents (value);
/* Look for a null character. */
for (i = 0; i < fetchlimit; i++)
if (extract_unsigned_integer (contents + i * width, width) == 0)
break;
/* I is now either the number of non-null characters, or FETCHLIMIT. */
*length = i * width;
*buffer = xmalloc (*length);
memcpy (*buffer, contents, *length);
err = 0;
}
else
{
err = read_string (value_as_address (value), -1, width, fetchlimit,
buffer, length);
if (err)
{
xfree (buffer);
error (_("Error reading string from inferior: %s"),
safe_strerror (err));
}
}
/* If the last character is null, subtract it from LENGTH. */
if (*length > 0
&& extract_unsigned_integer (*buffer + *length - width, width) == 0)
*length -= width;
*charset = target_charset ();
return;
error:
{
char *type_str;
type_str = type_to_string (type);
if (type_str)
{
make_cleanup (xfree, type_str);
error (_("Trying to read string with inappropriate type `%s'."),
type_str);
}
else
error (_("Trying to read string with inappropriate type."));
}
}
/* Preprocessing and parsing C and C++ expressions. */
@@ -314,6 +430,7 @@ const struct language_defn c_language_defn =
c_language_arch_info,
default_print_array_index,
default_pass_by_reference,
c_get_string,
LANG_MAGIC
};
@@ -432,6 +549,7 @@ const struct language_defn cplus_language_defn =
cplus_language_arch_info,
default_print_array_index,
cp_pass_by_reference,
c_get_string,
LANG_MAGIC
};
@@ -469,6 +587,7 @@ const struct language_defn asm_language_defn =
c_language_arch_info, /* FIXME: la_language_arch_info. */
default_print_array_index,
default_pass_by_reference,
c_get_string,
LANG_MAGIC
};
@@ -511,6 +630,7 @@ const struct language_defn minimal_language_defn =
c_language_arch_info,
default_print_array_index,
default_pass_by_reference,
c_get_string,
LANG_MAGIC
};