mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 10:03:47 +08:00
all languages
Change-Id: I79ef914087dbf85e1cbc19263843a6034383afe7
This commit is contained in:
parent
67ea24cb99
commit
50991aaf22
@ -12900,6 +12900,16 @@ public:
|
|||||||
return language_defn::read_var_value (var, var_block, frame);
|
return language_defn::read_var_value (var, var_block, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct value *value_string (struct gdbarch *gdbarch,
|
||||||
|
const char *ptr, ssize_t len) const override
|
||||||
|
{
|
||||||
|
struct type *type = language_string_char_type (this, gdbarch);
|
||||||
|
value *val = ::value_string (ptr, len, type);
|
||||||
|
/* See ada_string_operation::evaluate. */
|
||||||
|
value_type (val)->set_code (TYPE_CODE_ARRAY);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
/* See language.h. */
|
/* See language.h. */
|
||||||
void language_arch_info (struct gdbarch *gdbarch,
|
void language_arch_info (struct gdbarch *gdbarch,
|
||||||
struct language_arch_info *lai) const override
|
struct language_arch_info *lai) const override
|
||||||
|
12
gdb/c-lang.c
12
gdb/c-lang.c
@ -653,16 +653,11 @@ c_string_operation::evaluate (struct type *expect_type,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i;
|
int element_size = TYPE_LENGTH (type);
|
||||||
|
|
||||||
/* Write the terminating character. */
|
|
||||||
for (i = 0; i < TYPE_LENGTH (type); ++i)
|
|
||||||
obstack_1grow (&output, 0);
|
|
||||||
|
|
||||||
if (satisfy_expected)
|
if (satisfy_expected)
|
||||||
{
|
{
|
||||||
LONGEST low_bound, high_bound;
|
LONGEST low_bound, high_bound;
|
||||||
int element_size = TYPE_LENGTH (type);
|
|
||||||
|
|
||||||
if (!get_discrete_bounds (expect_type->index_type (),
|
if (!get_discrete_bounds (expect_type->index_type (),
|
||||||
&low_bound, &high_bound))
|
&low_bound, &high_bound))
|
||||||
@ -677,10 +672,13 @@ c_string_operation::evaluate (struct type *expect_type,
|
|||||||
result = allocate_value (expect_type);
|
result = allocate_value (expect_type);
|
||||||
memcpy (value_contents_raw (result), obstack_base (&output),
|
memcpy (value_contents_raw (result), obstack_base (&output),
|
||||||
obstack_object_size (&output));
|
obstack_object_size (&output));
|
||||||
|
/* Write the terminating character. */
|
||||||
|
memset (value_contents_raw (result) + obstack_object_size (&output),
|
||||||
|
0, element_size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = value_cstring ((const char *) obstack_base (&output),
|
result = value_cstring ((const char *) obstack_base (&output),
|
||||||
obstack_object_size (&output),
|
obstack_object_size (&output) / element_size,
|
||||||
type);
|
type);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -2146,12 +2146,10 @@ value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
|
|||||||
case var_filename:
|
case var_filename:
|
||||||
case var_enum:
|
case var_enum:
|
||||||
if (*(char **) cmd->var)
|
if (*(char **) cmd->var)
|
||||||
return value_cstring (*(char **) cmd->var,
|
return current_language->value_string (gdbarch, *(char **) cmd->var,
|
||||||
strlen (*(char **) cmd->var) + 1,
|
strlen (*(char **) cmd->var));
|
||||||
builtin_type (gdbarch)->builtin_char);
|
|
||||||
else
|
else
|
||||||
return value_cstring ("", 1,
|
return current_language->value_string (gdbarch, "", 0);
|
||||||
builtin_type (gdbarch)->builtin_char);
|
|
||||||
default:
|
default:
|
||||||
gdb_assert_not_reached ("bad var_type");
|
gdb_assert_not_reached ("bad var_type");
|
||||||
}
|
}
|
||||||
@ -2199,8 +2197,9 @@ str_value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
|
|||||||
{
|
{
|
||||||
std::string cmd_val = get_setshow_command_value_string (cmd);
|
std::string cmd_val = get_setshow_command_value_string (cmd);
|
||||||
|
|
||||||
return value_cstring (cmd_val.c_str (), cmd_val.size () + 1,
|
return current_language->value_string (gdbarch,
|
||||||
builtin_type (gdbarch)->builtin_char);
|
cmd_val.data (),
|
||||||
|
cmd_val.size ());
|
||||||
}
|
}
|
||||||
|
|
||||||
case var_string:
|
case var_string:
|
||||||
@ -2213,12 +2212,11 @@ str_value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
|
|||||||
escaping quotes. So, we directly use the cmd->var string value,
|
escaping quotes. So, we directly use the cmd->var string value,
|
||||||
similarly to the value_from_setting code for these cases. */
|
similarly to the value_from_setting code for these cases. */
|
||||||
if (*(char **) cmd->var)
|
if (*(char **) cmd->var)
|
||||||
return value_cstring (*(char **) cmd->var,
|
return current_language->value_string (gdbarch,
|
||||||
strlen (*(char **) cmd->var) + 1,
|
*(char **) cmd->var,
|
||||||
builtin_type (gdbarch)->builtin_char);
|
strlen (*(char **) cmd->var));
|
||||||
else
|
else
|
||||||
return value_cstring ("", 1,
|
return current_language->value_string (gdbarch, "", 0);
|
||||||
builtin_type (gdbarch)->builtin_char);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gdb_assert_not_reached ("bad var_type");
|
gdb_assert_not_reached ("bad var_type");
|
||||||
|
@ -103,6 +103,14 @@ f_language::get_encoding (struct type *type)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct value *
|
||||||
|
f_language::value_string (struct gdbarch *gdbarch,
|
||||||
|
const char *ptr, ssize_t len) const
|
||||||
|
{
|
||||||
|
struct type *type = language_string_char_type (this, gdbarch);
|
||||||
|
return ::value_string (ptr, len, type);
|
||||||
|
}
|
||||||
|
|
||||||
/* A helper function for the "bound" intrinsics that checks that TYPE
|
/* A helper function for the "bound" intrinsics that checks that TYPE
|
||||||
is an array. LBOUND_P is true for lower bound; this is used for
|
is an array. LBOUND_P is true for lower bound; this is used for
|
||||||
the error message, if any. */
|
the error message, if any. */
|
||||||
|
@ -193,6 +193,9 @@ public:
|
|||||||
&& TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_CHAR));
|
&& TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_CHAR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct value *value_string (struct gdbarch *gdbarch,
|
||||||
|
const char *ptr, ssize_t len) const override;
|
||||||
|
|
||||||
/* See language.h. */
|
/* See language.h. */
|
||||||
|
|
||||||
const char *struct_too_deep_ellipsis () const override
|
const char *struct_too_deep_ellipsis () const override
|
||||||
|
@ -776,6 +776,8 @@ vlscm_convert_typed_value_from_scheme (const char *func_name,
|
|||||||
}
|
}
|
||||||
else if (scm_is_string (obj))
|
else if (scm_is_string (obj))
|
||||||
{
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if (type != NULL)
|
if (type != NULL)
|
||||||
{
|
{
|
||||||
except_scm = gdbscm_make_misc_error (func_name, type_arg_pos,
|
except_scm = gdbscm_make_misc_error (func_name, type_arg_pos,
|
||||||
@ -787,14 +789,12 @@ vlscm_convert_typed_value_from_scheme (const char *func_name,
|
|||||||
{
|
{
|
||||||
/* TODO: Provide option to specify conversion strategy. */
|
/* TODO: Provide option to specify conversion strategy. */
|
||||||
gdb::unique_xmalloc_ptr<char> s
|
gdb::unique_xmalloc_ptr<char> s
|
||||||
= gdbscm_scm_to_string (obj, nullptr,
|
= gdbscm_scm_to_string (obj, &len,
|
||||||
target_charset (gdbarch),
|
target_charset (gdbarch),
|
||||||
0 /*non-strict*/,
|
0 /*non-strict*/,
|
||||||
&except_scm);
|
&except_scm);
|
||||||
if (s != NULL)
|
if (s != NULL)
|
||||||
value = value_cstring (s.get (), strlen (s.get ()) + 1,
|
value = language->value_string (gdbarch, s.get (), len);
|
||||||
language_string_char_type (language,
|
|
||||||
gdbarch));
|
|
||||||
else
|
else
|
||||||
value = NULL;
|
value = NULL;
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "gdbarch.h"
|
#include "gdbarch.h"
|
||||||
#include "compile/compile-internal.h"
|
#include "compile/compile-internal.h"
|
||||||
|
#include "arch-utils.h"
|
||||||
|
|
||||||
static void set_range_case (void);
|
static void set_range_case (void);
|
||||||
|
|
||||||
@ -976,6 +977,14 @@ language_string_char_type (const struct language_defn *la,
|
|||||||
return ld->arch_info[la->la_language].string_char_type ();
|
return ld->arch_info[la->la_language].string_char_type ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct value *
|
||||||
|
language_defn::value_string (struct gdbarch *gdbarch,
|
||||||
|
const char *ptr, ssize_t len) const
|
||||||
|
{
|
||||||
|
struct type *type = language_string_char_type (this, gdbarch);
|
||||||
|
return value_cstring (ptr, len, type);
|
||||||
|
}
|
||||||
|
|
||||||
/* See language.h. */
|
/* See language.h. */
|
||||||
|
|
||||||
struct type *
|
struct type *
|
||||||
|
@ -579,6 +579,13 @@ struct language_defn
|
|||||||
virtual char string_lower_bound () const
|
virtual char string_lower_bound () const
|
||||||
{ return c_style_arrays_p () ? 0 : 1; }
|
{ return c_style_arrays_p () ? 0 : 1; }
|
||||||
|
|
||||||
|
/* Return the LEN characters long string at STR as a value as
|
||||||
|
represented in this language. GDBARCH is used to infer the
|
||||||
|
character type. The default implementation returns a
|
||||||
|
null-terminated C string. */
|
||||||
|
virtual struct value *value_string (struct gdbarch *gdbarch,
|
||||||
|
const char *ptr, ssize_t len) const;
|
||||||
|
|
||||||
/* Returns true if the symbols names should be stored in GDB's data
|
/* Returns true if the symbols names should be stored in GDB's data
|
||||||
structures for minimal/partial/full symbols using their linkage (aka
|
structures for minimal/partial/full symbols using their linkage (aka
|
||||||
mangled) form; false if the symbol names should be demangled first.
|
mangled) form; false if the symbol names should be demangled first.
|
||||||
|
@ -50,9 +50,6 @@
|
|||||||
#define builtin_type_pybool \
|
#define builtin_type_pybool \
|
||||||
language_bool_type (python_language, python_gdbarch)
|
language_bool_type (python_language, python_gdbarch)
|
||||||
|
|
||||||
#define builtin_type_pychar \
|
|
||||||
language_string_char_type (python_language, python_gdbarch)
|
|
||||||
|
|
||||||
struct value_object {
|
struct value_object {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
struct value_object *next;
|
struct value_object *next;
|
||||||
@ -1907,8 +1904,9 @@ convert_value_from_python (PyObject *obj)
|
|||||||
gdb::unique_xmalloc_ptr<char> s
|
gdb::unique_xmalloc_ptr<char> s
|
||||||
= python_string_to_target_string (obj);
|
= python_string_to_target_string (obj);
|
||||||
if (s != NULL)
|
if (s != NULL)
|
||||||
value = value_cstring (s.get (), strlen (s.get ()) + 1,
|
value = python_language->value_string (python_gdbarch,
|
||||||
builtin_type_pychar);
|
s.get (),
|
||||||
|
strlen (s.get ()));
|
||||||
}
|
}
|
||||||
else if (PyObject_TypeCheck (obj, &value_object_type))
|
else if (PyObject_TypeCheck (obj, &value_object_type))
|
||||||
value = value_copy (((value_object *) obj)->value);
|
value = value_copy (((value_object *) obj)->value);
|
||||||
|
@ -118,6 +118,86 @@ proc_with_prefix test_setting { } {
|
|||||||
gdb_test_no_output {set $v = $_gdb_setting_str("remotetimeout")}
|
gdb_test_no_output {set $v = $_gdb_setting_str("remotetimeout")}
|
||||||
check_v_string "2"
|
check_v_string "2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Test string values made by $_gdb_setting & co. in all languages.
|
||||||
|
with_test_prefix "all langs" {
|
||||||
|
# Get list of supported languages.
|
||||||
|
set langs {}
|
||||||
|
gdb_test_multiple "complete set language " "" {
|
||||||
|
-re "set language (\[^\r\n\]+)" {
|
||||||
|
lappend langs $expect_out(1,string)
|
||||||
|
exp_continue
|
||||||
|
}
|
||||||
|
-re "$::gdb_prompt $" {
|
||||||
|
pass $gdb_test_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc quote {str} {
|
||||||
|
upvar lang lang
|
||||||
|
|
||||||
|
if {$lang == "fortran"} {
|
||||||
|
return "'$str'"
|
||||||
|
} else {
|
||||||
|
return "\"$str\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_test "maintenance set test-settings string foo"
|
||||||
|
foreach_with_prefix lang $langs {
|
||||||
|
gdb_test_no_output "set language $lang"
|
||||||
|
|
||||||
|
if {$lang == "modula-2"} {
|
||||||
|
gdb_test "print \"foo\"" "strings are not implemented"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if {$lang == "rust"} {
|
||||||
|
gdb_test "print \"foo\"" \
|
||||||
|
"evaluation of this expression requires the target program to be active"
|
||||||
|
|
||||||
|
# We could get the above working by starting the
|
||||||
|
# program, but how to make the below work?
|
||||||
|
gdb_test "print \$_gdb_maint_setting(\"test-settings string\")" \
|
||||||
|
"',' or '\\)' expected"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if {$lang == "unknown"} {
|
||||||
|
# Skipped because of PR gdb/28093 -- GDB would crash.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
set print_output ""
|
||||||
|
set ptype_output ""
|
||||||
|
|
||||||
|
set foo_str [quote foo]
|
||||||
|
gdb_test_multiple "print $foo_str" "" {
|
||||||
|
-wrap -re " = (.*)" {
|
||||||
|
set print_output $expect_out(1,string)
|
||||||
|
pass $gdb_test_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_test_multiple "ptype $foo_str" "" {
|
||||||
|
-wrap -re " = (.*)" {
|
||||||
|
set ptype_output $expect_out(1,string)
|
||||||
|
pass $gdb_test_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set cmd_str [quote "test-settings string"]
|
||||||
|
set ptype_output_re [string_to_regexp $ptype_output]
|
||||||
|
set print_output_re [string_to_regexp $print_output]
|
||||||
|
|
||||||
|
foreach_with_prefix conv_func {$_gdb_maint_setting $_gdb_maint_setting_str} {
|
||||||
|
gdb_test "print ${conv_func}($cmd_str)" \
|
||||||
|
" = $print_output_re"
|
||||||
|
gdb_test "ptype \$" \
|
||||||
|
" = $ptype_output_re"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Test with a string value created by gdb.Value in Python.
|
# Test with a string value created by gdb.Value in Python.
|
||||||
|
@ -1754,12 +1754,15 @@ value_cstring (const char *ptr, ssize_t len, struct type *char_type)
|
|||||||
{
|
{
|
||||||
struct value *val;
|
struct value *val;
|
||||||
int lowbound = current_language->string_lower_bound ();
|
int lowbound = current_language->string_lower_bound ();
|
||||||
ssize_t highbound = len / TYPE_LENGTH (char_type);
|
ssize_t highbound = len + 1;
|
||||||
struct type *stringtype
|
struct type *stringtype
|
||||||
= lookup_array_range_type (char_type, lowbound, highbound + lowbound - 1);
|
= lookup_array_range_type (char_type, lowbound, highbound + lowbound - 1);
|
||||||
|
|
||||||
val = allocate_value (stringtype);
|
val = allocate_value (stringtype);
|
||||||
memcpy (value_contents_raw (val), ptr, len);
|
memcpy (value_contents_raw (val), ptr, len * TYPE_LENGTH (char_type));
|
||||||
|
/* Write the terminating character. */
|
||||||
|
memset (value_contents_raw (val) + len * TYPE_LENGTH (char_type),
|
||||||
|
0, TYPE_LENGTH (char_type));
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2188,8 +2188,9 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case INTERNALVAR_STRING:
|
case INTERNALVAR_STRING:
|
||||||
val = value_cstring (var->u.string, strlen (var->u.string) + 1,
|
val = current_language->value_string (gdbarch,
|
||||||
builtin_type (gdbarch)->builtin_char);
|
var->u.string,
|
||||||
|
strlen (var->u.string));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INTERNALVAR_VALUE:
|
case INTERNALVAR_VALUE:
|
||||||
|
@ -782,10 +782,12 @@ class scoped_value_mark
|
|||||||
const struct value *m_value;
|
const struct value *m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Create a not_lval value with type TYPE_CODE_ARRAY.
|
/* Create not_lval value representing a NULL-terminated C string. The
|
||||||
|
resulting value has type TYPE_CODE_ARRAY.
|
||||||
|
|
||||||
PTR points to the string data; LEN is the length of the string including the
|
PTR points to the string data; LEN is number of characters (does
|
||||||
NULL terminator. */
|
not include the NULL terminator). CHAR_TYPE is the character
|
||||||
|
type. */
|
||||||
|
|
||||||
extern struct value *value_cstring (const char *ptr, ssize_t len,
|
extern struct value *value_cstring (const char *ptr, ssize_t len,
|
||||||
struct type *char_type);
|
struct type *char_type);
|
||||||
|
Loading…
Reference in New Issue
Block a user