]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
all languages users/palves/value_string
authorPedro Alves <pedro@palves.net>
Thu, 15 Jul 2021 09:47:56 +0000 (10:47 +0100)
committerPedro Alves <pedro@palves.net>
Thu, 15 Jul 2021 14:10:59 +0000 (15:10 +0100)
Change-Id: I79ef914087dbf85e1cbc19263843a6034383afe7

13 files changed:
gdb/ada-lang.c
gdb/c-lang.c
gdb/cli/cli-cmds.c
gdb/f-lang.c
gdb/f-lang.h
gdb/guile/scm-math.c
gdb/language.c
gdb/language.h
gdb/python/py-value.c
gdb/testsuite/gdb.base/internal-string-values.exp
gdb/valops.c
gdb/value.c
gdb/value.h

index b098991612d08ae9db1cf9050ac18df700117885..82319e4932622d4f8407e78f4d3b18acb4f35ed7 100644 (file)
@@ -12900,6 +12900,16 @@ public:
     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.  */
   void language_arch_info (struct gdbarch *gdbarch,
                           struct language_arch_info *lai) const override
index 98f4984b020e4d735f88baa7dfad6254ef2bbcf2..d30cebe9f0c5abfda1f6ee0ec2ac25cb4b3b13f7 100644 (file)
@@ -653,16 +653,11 @@ c_string_operation::evaluate (struct type *expect_type,
     }
   else
     {
-      int i;
-
-      /* Write the terminating character.  */
-      for (i = 0; i < TYPE_LENGTH (type); ++i)
-       obstack_1grow (&output, 0);
+      int element_size = TYPE_LENGTH (type);
 
       if (satisfy_expected)
        {
          LONGEST low_bound, high_bound;
-         int element_size = TYPE_LENGTH (type);
 
          if (!get_discrete_bounds (expect_type->index_type (),
                                    &low_bound, &high_bound))
@@ -677,10 +672,13 @@ c_string_operation::evaluate (struct type *expect_type,
          result = allocate_value (expect_type);
          memcpy (value_contents_raw (result), obstack_base (&output),
                  obstack_object_size (&output));
+         /* Write the terminating character.  */
+         memset (value_contents_raw (result) + obstack_object_size (&output),
+                 0, element_size);
        }
       else
        result = value_cstring ((const char *) obstack_base (&output),
-                               obstack_object_size (&output),
+                               obstack_object_size (&output) / element_size,
                                type);
     }
   return result;
index f6fc5ab854f457cac0500a97c47038263e892dee..b445b75fae2467c65a68760344b40add9387c827 100644 (file)
@@ -2146,12 +2146,10 @@ value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
     case var_filename:
     case var_enum:
       if (*(char **) cmd->var)
-       return value_cstring (*(char **) cmd->var,
-                             strlen (*(char **) cmd->var) + 1,
-                             builtin_type (gdbarch)->builtin_char);
+       return current_language->value_string (gdbarch, *(char **) cmd->var,
+                                              strlen (*(char **) cmd->var));
       else
-       return value_cstring ("", 1,
-                             builtin_type (gdbarch)->builtin_char);
+       return current_language->value_string (gdbarch, "", 0);
     default:
       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);
 
-       return value_cstring (cmd_val.c_str (), cmd_val.size () + 1,
-                             builtin_type (gdbarch)->builtin_char);
+       return current_language->value_string (gdbarch,
+                                              cmd_val.data (),
+                                              cmd_val.size ());
       }
 
     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,
         similarly to the value_from_setting code for these cases.  */
       if (*(char **) cmd->var)
-       return value_cstring (*(char **) cmd->var,
-                             strlen (*(char **) cmd->var) + 1,
-                             builtin_type (gdbarch)->builtin_char);
+       return current_language->value_string (gdbarch,
+                                              *(char **) cmd->var,
+                                              strlen (*(char **) cmd->var));
       else
-       return value_cstring ("", 1,
-                             builtin_type (gdbarch)->builtin_char);
+       return current_language->value_string (gdbarch, "", 0);
 
     default:
       gdb_assert_not_reached ("bad var_type");
index 16ec9e04044b899b59560e9cdc72a15441f98372..869a95d4304689693571782dbcb255206ebb57ee 100644 (file)
@@ -103,6 +103,14 @@ f_language::get_encoding (struct type *type)
 
 \f
 
+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
    is an array.  LBOUND_P is true for lower bound; this is used for
    the error message, if any.  */
index 1ccdd3978eadc9df80e632a29bd1c6fc05860725..1306b135779f73876ea6ba8de3b86dea5c5c2099 100644 (file)
@@ -193,6 +193,9 @@ public:
                && 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.  */
 
   const char *struct_too_deep_ellipsis () const override
index 8b7fe9b69ecd47f342080871e9164a1de9c8add4..a88c805fc232072398c18ba426321116642aedab 100644 (file)
@@ -776,6 +776,8 @@ vlscm_convert_typed_value_from_scheme (const char *func_name,
        }
       else if (scm_is_string (obj))
        {
+         size_t len;
+
          if (type != NULL)
            {
              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.  */
              gdb::unique_xmalloc_ptr<char> s
-               = gdbscm_scm_to_string (obj, nullptr,
+               = gdbscm_scm_to_string (obj, &len,
                                        target_charset (gdbarch),
                                        0 /*non-strict*/,
                                        &except_scm);
              if (s != NULL)
-               value = value_cstring (s.get (), strlen (s.get ()) + 1,
-                                      language_string_char_type (language,
-                                                                 gdbarch));
+               value = language->value_string (gdbarch, s.get (), len);
              else
                value = NULL;
            }
index 0d1e3848de858c0113e8f608768155a86f602fd4..2ee32a1edffcd6cab6fea89d88077c9f5bc14254 100644 (file)
@@ -47,6 +47,7 @@
 #include <algorithm>
 #include "gdbarch.h"
 #include "compile/compile-internal.h"
+#include "arch-utils.h"
 
 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 ();
 }
 
+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.  */
 
 struct type *
index 21ed47b35807f606240c0c6df95eb5f486548bf1..87064962b9ba7d34214509288b43c9dcb850a37c 100644 (file)
@@ -579,6 +579,13 @@ struct language_defn
   virtual char string_lower_bound () const
   { 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
      structures for minimal/partial/full symbols using their linkage (aka
      mangled) form; false if the symbol names should be demangled first.
index bc0f88b7a16632ae57e07c94bd46a18365910c73..f5b72446912082af493e84ba0ac88c2c53d01bc6 100644 (file)
@@ -50,9 +50,6 @@
 #define builtin_type_pybool \
   language_bool_type (python_language, python_gdbarch)
 
-#define builtin_type_pychar \
-  language_string_char_type (python_language, python_gdbarch)
-
 struct value_object {
   PyObject_HEAD
   struct value_object *next;
@@ -1907,8 +1904,9 @@ convert_value_from_python (PyObject *obj)
          gdb::unique_xmalloc_ptr<char> s
            = python_string_to_target_string (obj);
          if (s != NULL)
-           value = value_cstring (s.get (), strlen (s.get ()) + 1,
-                                  builtin_type_pychar);
+           value = python_language->value_string (python_gdbarch,
+                                                  s.get (),
+                                                  strlen (s.get ()));
        }
       else if (PyObject_TypeCheck (obj, &value_object_type))
        value = value_copy (((value_object *) obj)->value);
index 0748ab0984c6a2941e5cd5b44a8b715559f34005..3380d9d80777fea6118eddcee2c998ab98498f5a 100644 (file)
@@ -118,6 +118,86 @@ proc_with_prefix test_setting { } {
        gdb_test_no_output {set $v = $_gdb_setting_str("remotetimeout")}
        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.
index f67612e87b082c1ada4f3cc3d25fa6bd30476ac9..161b8696cb2013ca42c21ac4e17132d01c2c8220 100644 (file)
@@ -1754,12 +1754,15 @@ value_cstring (const char *ptr, ssize_t len, struct type *char_type)
 {
   struct value *val;
   int lowbound = current_language->string_lower_bound ();
-  ssize_t highbound = len / TYPE_LENGTH (char_type);
+  ssize_t highbound = len + 1;
   struct type *stringtype
     = lookup_array_range_type (char_type, lowbound, highbound + lowbound - 1);
 
   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;
 }
 
index db34d2e5762f5520207fda19750233cfea9d1392..092325c87310f7f881691bab115b607ff70a39a8 100644 (file)
@@ -2188,8 +2188,9 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var)
       break;
 
     case INTERNALVAR_STRING:
-      val = value_cstring (var->u.string, strlen (var->u.string) + 1,
-                          builtin_type (gdbarch)->builtin_char);
+      val = current_language->value_string (gdbarch,
+                                           var->u.string,
+                                           strlen (var->u.string));
       break;
 
     case INTERNALVAR_VALUE:
index 24392437ed0bd7f43d21ec7881e5997308ecab21..3313b9fd3469af7b62781267d3842a304033d601 100644 (file)
@@ -782,10 +782,12 @@ class scoped_value_mark
   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
-   NULL terminator.  */
+   PTR points to the string data; LEN is number of characters (does
+   not include the NULL terminator).  CHAR_TYPE is the character
+   type.  */
 
 extern struct value *value_cstring (const char *ptr, ssize_t len,
                                    struct type *char_type);