gdb: LoongArch: Remove nonportable #include
[binutils-gdb.git] / gdb / command.h
index e7b81100f26e98cee7c4822b5be2edbc848bf389..d901da3c8cbbf7f8695d2f26e88f9027d4825253 100644 (file)
@@ -1,6 +1,6 @@
 /* Header file for command creation.
 
-   Copyright (C) 1986-2021 Free Software Foundation, Inc.
+   Copyright (C) 1986-2022 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -46,7 +46,6 @@ enum command_class
      Note that help accepts unambiguous abbreviated class names.  */
 
   /* Special classes to help_list */
-  class_deprecated = -3,
   all_classes = -2,  /* help without <classname> */
   all_commands = -1, /* all */
 
@@ -72,7 +71,7 @@ enum command_class
 };
 
 /* Types of "set" or "show" command.  */
-typedef enum var_types
+enum var_types
   {
     /* "on" or "off".  *VAR is a bool which is true for on,
        false for off.  */
@@ -97,16 +96,15 @@ typedef enum var_types
 
     /* String which the user enters with escapes (e.g. the user types
        \n and it is a real newline in the stored string).
-       *VAR is a malloc'd string, or NULL if the string is empty.  */
+       *VAR is a std::string, "" if the string is empty.  */
     var_string,
     /* String which stores what the user types verbatim.
-       *VAR is a malloc'd string, or NULL if the string is empty.  */
+       *VAR is std::string, "" if the string is empty.  */
     var_string_noescape,
-    /* String which stores a filename.  (*VAR) is a malloc'd string,
-       or "" if the string was empty.  */
+    /* String which stores a filename.  (*VAR) is a std::string,
+       "" if the string was empty.  */
     var_optional_filename,
-    /* String which stores a filename.  (*VAR) is a malloc'd
-       string.  */
+    /* String which stores a filename.  (*VAR) is a std::string.  */
     var_filename,
     /* ZeroableInteger.  *VAR is an int.  Like var_integer except
        that zero really means zero.  */
@@ -122,8 +120,7 @@ typedef enum var_types
        *VAR is a char pointer to the name of the element that we
        find.  */
     var_enum
-  }
-var_types;
+  };
 
 /* Return true if a setting of type VAR_TYPE is backed with type T.
 
@@ -166,9 +163,9 @@ inline bool var_type_uses<int> (var_types t)
          || t == var_zuinteger_unlimited);
 }
 
-/* Return true if a setting of type T is backed by a char * variable.  */
+/* Return true if a setting of type T is backed by a std::string variable.  */
 template<>
-inline bool var_type_uses<char *> (var_types t)
+inline bool var_type_uses<std::string> (var_types t)
 {
   return (t == var_string || t == var_string_noescape
          || t == var_optional_filename || t == var_filename);
@@ -182,6 +179,36 @@ inline bool var_type_uses<const char *> (var_types t)
   return t == var_enum;
 }
 
+template<bool is_scalar, typename T> struct setting_func_types_1;
+
+template<typename T>
+struct setting_func_types_1<true, T>
+{
+  using type = T;
+  using set = void (*) (type);
+  using get = type (*) ();
+};
+
+template<typename T>
+struct setting_func_types_1<false, T>
+{
+  using type = const T &;
+  using set = void (*) (type);
+  using get = type (*) ();
+};
+
+template<typename T>
+struct setting_func_types
+{
+  using type = typename setting_func_types_1<std::is_scalar<T>::value, T>::type;
+  using set = typename setting_func_types_1<std::is_scalar<T>::value, T>::set;
+  using get = typename setting_func_types_1<std::is_scalar<T>::value, T>::get;
+};
+
+/* Generic/type-erased function pointer.  */
+
+using erased_func = void (*) ();
+
 /* Interface for getting and setting a setting's value.
 
    The underlying data can be of any VAR_TYPES type.  */
@@ -205,14 +232,30 @@ struct setting
   struct erased_args
   {
     void *var;
+    erased_func setter;
+    erased_func getter;
   };
 
   template<typename T>
-  static erased_args erase_args (var_types var_type, T *var)
+  static erased_args erase_args (var_types var_type,
+                                T *var,
+                                typename setting_func_types<T>::set set_setting_func,
+                                typename setting_func_types<T>::get get_setting_func)
   {
     gdb_assert (var_type_uses<T> (var_type));
-
-    return {var};
+  /* The getter and the setter must be both provided or both omitted.  */
+    gdb_assert
+      ((set_setting_func == nullptr) == (get_setting_func == nullptr));
+
+  /* The caller must provide a pointer to a variable or get/set functions, but
+     not both.  */
+    gdb_assert ((set_setting_func == nullptr) != (var == nullptr));
+
+    return {
+       var,
+       reinterpret_cast<erased_func> (set_setting_func),
+       reinterpret_cast<erased_func> (get_setting_func)
+    };
   }
 
   /* Create a setting backed by pre-validated type-erased args.
@@ -220,52 +263,104 @@ struct setting
      (see VAR_TYPE_USES).  */
   setting (var_types var_type, const erased_args &args)
     : m_var_type (var_type),
-      m_var (args.var)
+      m_var (args.var),
+      m_getter (args.getter),
+      m_setter (args.setter)
   {
   }
 
-  /* Access the type of the current setting.  */
-  var_types type () const
+  /* Create a setting backed by setter and getter functions.
+
+     Type T must match the var type VAR_TYPE (see VAR_TYPE_USES).  */
+  template<typename T>
+  setting (var_types var_type,
+          typename setting_func_types<T>::set setter,
+          typename setting_func_types<T>::get getter)
+    : m_var_type (var_type)
   {
-    return m_var_type;
+    gdb_assert (var_type_uses<T> (var_type));
+
+    /* Getters and setters are cast to and from the arbitrary `void (*) ()`
+       function pointer type.  Make sure that the two types are really of the
+       same size.  */
+    gdb_static_assert (sizeof (m_getter) == sizeof (getter));
+    gdb_static_assert (sizeof (m_setter) == sizeof (setter));
+
+    m_getter = reinterpret_cast<erased_func> (getter);
+    m_setter = reinterpret_cast<erased_func> (setter);
   }
 
+  /* Access the type of the current setting.  */
+  var_types type () const
+  { return m_var_type; }
+
   /* Return the current value.
 
      The template parameter T is the type of the variable used to store the
      setting.  */
   template<typename T>
-  const T &get () const
+  typename setting_func_types<T>::type get () const
   {
     gdb_assert (var_type_uses<T> (m_var_type));
-    gdb_assert (m_var != nullptr);
 
-    return *static_cast<const T *> (m_var);
+    if (m_var == nullptr)
+      {
+       gdb_assert (m_getter != nullptr);
+       auto getter = reinterpret_cast<typename setting_func_types<T>::get> (m_getter);
+       return getter ();
+      }
+    else
+      return *static_cast<const T *> (m_var);
   }
 
-  /* Sets the value of the setting to V.
+  /* Sets the value of the setting to V.  Returns true if the setting was
+     effectively changed, false if the update failed and the setting is left
+     unchanged.
+
+     If we have a user-provided setter, use it to set the setting.  Otherwise
+     copy the value V to the internally referenced buffer.
 
-     The template parameter T indicates the type of the variable used to
-     store the setting.
+     The template parameter T indicates the type of the variable used to store
+     the setting.
 
      The var_type of the setting must match T.  */
   template<typename T>
-  void set (const T &v)
+  bool set (const T &v)
   {
     /* Check that the current instance is of one of the supported types for
        this instantiation.  */
     gdb_assert (var_type_uses<T> (m_var_type));
 
-    *static_cast<T *> (m_var) = v;
+    const T old_value = this->get<T> ();
+
+    if (m_var == nullptr)
+      {
+       gdb_assert (m_setter != nullptr);
+       auto setter = reinterpret_cast<typename setting_func_types<T>::set> (m_setter);
+       setter (v);
+      }
+    else
+      *static_cast<T *> (m_var) = v;
+
+    return old_value != this->get<T> ();
   }
 
 private:
-  /* The type of the variable M_VAR is pointing to.  */
+  /* The type of the variable M_VAR is pointing to, or that M_GETTER / M_SETTER
+     get or set.  */
   var_types m_var_type;
 
-  /* Pointer to the enclosed variable.  The type of the variable is encoded
-     in M_VAR_TYPE.  */
-  void *m_var;
+  /* Pointer to the enclosed variable
+
+     Either M_VAR is non-nullptr, or both M_GETTER and M_SETTER are
+     non-nullptr.  */
+  void *m_var = nullptr;
+
+  /* Pointer to a user provided getter.  */
+  erased_func m_getter = nullptr;
+
+  /* Pointer to a user provided setter.  */
+  erased_func m_setter = nullptr;
 };
 
 /* This structure records one command'd definition.  */
@@ -282,7 +377,10 @@ typedef void cmd_simple_func_ftype (const char *args, int from_tty);
 struct cli_suppress_notification
 {
   /* Inferior, thread, frame selected notification suppressed?  */
-  int user_selected_context;
+  bool user_selected_context = false;
+
+  /* Normal stop event suppressed? */
+  bool normal_stop = false;
 };
 
 extern struct cli_suppress_notification cli_suppress_notification;
@@ -301,6 +399,13 @@ extern bool valid_user_defined_cmd_name_p (const char *name);
 
 extern bool valid_cmd_char_p (int c);
 
+/* Return value type for the add_setshow_* functions.  */
+
+struct set_show_commands
+{
+  cmd_list_element *set, *show;
+};
+
 /* Const-correct variant of the above.  */
 
 extern struct cmd_list_element *add_cmd (const char *, enum command_class,
@@ -318,7 +423,7 @@ extern struct cmd_list_element *add_cmd_suppress_notification
                        (const char *name, enum command_class theclass,
                         cmd_simple_func_ftype *fun, const char *doc,
                         struct cmd_list_element **list,
-                        int *suppress_notification);
+                        bool *suppress_notification);
 
 extern struct cmd_list_element *add_alias_cmd (const char *,
                                               cmd_list_element *,
@@ -347,13 +452,24 @@ extern struct cmd_list_element *add_show_prefix_cmd
   (const char *, enum command_class, const char *, struct cmd_list_element **,
    int, struct cmd_list_element **);
 
+/* Add matching set and show commands using add_basic_prefix_cmd and
+   add_show_prefix_cmd.  */
+
+extern set_show_commands add_setshow_prefix_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc,
+   cmd_list_element **set_subcommands_list,
+   cmd_list_element **show_subcommands_list,
+   cmd_list_element **set_list,
+   cmd_list_element **show_list);
+
 extern struct cmd_list_element *add_prefix_cmd_suppress_notification
                        (const char *name, enum command_class theclass,
                         cmd_simple_func_ftype *fun,
                         const char *doc, struct cmd_list_element **subcommands,
                         int allow_unknown,
                         struct cmd_list_element **list,
-                        int *suppress_notification);
+                        bool *suppress_notification);
 
 extern struct cmd_list_element *add_abbrev_prefix_cmd (const char *,
                                                       enum command_class,
@@ -501,7 +617,7 @@ extern cmd_list_element *add_com_alias (const char *name,
 extern struct cmd_list_element *add_com_suppress_notification
                       (const char *name, enum command_class theclass,
                        cmd_simple_func_ftype *fun, const char *doc,
-                       int *supress_notification);
+                       bool *supress_notification);
 
 extern struct cmd_list_element *add_info (const char *,
                                          cmd_simple_func_ftype *fun,
@@ -535,13 +651,6 @@ typedef void (show_value_ftype) (struct ui_file *file,
    instead print the value out directly.  */
 extern show_value_ftype deprecated_show_value_hack;
 
-/* Return value type for the add_setshow_* functions.  */
-
-struct set_show_commands
-{
-  cmd_list_element *set, *show;
-};
-
 extern set_show_commands add_setshow_enum_cmd
   (const char *name, command_class theclass, const char *const *enumlist,
    const char **var, const char *set_doc, const char *show_doc,
@@ -549,72 +658,159 @@ extern set_show_commands add_setshow_enum_cmd
    show_value_ftype *show_func, cmd_list_element **set_list,
    cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_enum_cmd
+  (const char *name, command_class theclass, const char *const *enumlist,
+   const char *set_doc, const char *show_doc,
+   const char *help_doc, setting_func_types<const char *>::set set_func,
+   setting_func_types<const char *>::get get_func, show_value_ftype *show_func,
+   cmd_list_element **set_list, cmd_list_element **show_list);
+
 extern set_show_commands add_setshow_auto_boolean_cmd
   (const char *name, command_class theclass, auto_boolean *var,
    const char *set_doc, const char *show_doc, const char *help_doc,
    cmd_func_ftype *set_func, show_value_ftype *show_func,
    cmd_list_element **set_list, cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_auto_boolean_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc, const char *help_doc,
+   setting_func_types<enum auto_boolean>::set set_func,
+   setting_func_types<enum auto_boolean>::get get_func,
+   show_value_ftype *show_func, cmd_list_element **set_list,
+   cmd_list_element **show_list);
+
 extern set_show_commands add_setshow_boolean_cmd
   (const char *name, command_class theclass, bool *var, const char *set_doc,
    const char *show_doc, const char *help_doc, cmd_func_ftype *set_func,
    show_value_ftype *show_func, cmd_list_element **set_list,
    cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_boolean_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc, const char *help_doc,
+   setting_func_types<bool>::set set_func,
+   setting_func_types<bool>::get get_func, show_value_ftype *show_func,
+   cmd_list_element **set_list, cmd_list_element **show_list);
+
 extern set_show_commands add_setshow_filename_cmd
-  (const char *name, command_class theclass, char **var, const char *set_doc,
+  (const char *name, command_class theclass, std::string *var, const char *set_doc,
    const char *show_doc, const char *help_doc, cmd_func_ftype *set_func,
    show_value_ftype *show_func, cmd_list_element **set_list,
    cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_filename_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc, const char *help_doc,
+   setting_func_types<std::string>::set set_func,
+   setting_func_types<std::string>::get get_func, show_value_ftype *show_func,
+   cmd_list_element **set_list, cmd_list_element **show_list);
+
 extern set_show_commands add_setshow_string_cmd
-  (const char *name, command_class theclass, char **var, const char *set_doc,
+  (const char *name, command_class theclass, std::string *var, const char *set_doc,
    const char *show_doc, const char *help_doc, cmd_func_ftype *set_func,
    show_value_ftype *show_func, cmd_list_element **set_list,
    cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_string_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc, const char *help_doc,
+   setting_func_types<std::string>::set set_func,
+   setting_func_types<std::string>::get get_func,
+   show_value_ftype *show_func, cmd_list_element **set_list,
+   cmd_list_element **show_list);
+
 extern set_show_commands add_setshow_string_noescape_cmd
-  (const char *name, command_class theclass, char **var, const char *set_doc,
+  (const char *name, command_class theclass, std::string *var, const char *set_doc,
    const char *show_doc, const char *help_doc, cmd_func_ftype *set_func,
    show_value_ftype *show_func, cmd_list_element **set_list,
    cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_string_noescape_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc, const char *help_doc,
+   setting_func_types<std::string>::set set_func,
+   setting_func_types<std::string>::get get_func, show_value_ftype *show_func,
+   cmd_list_element **set_list, cmd_list_element **show_list);
+
 extern set_show_commands add_setshow_optional_filename_cmd
-  (const char *name, command_class theclass, char **var, const char *set_doc,
+  (const char *name, command_class theclass, std::string *var, const char *set_doc,
    const char *show_doc, const char *help_doc, cmd_func_ftype *set_func,
    show_value_ftype *show_func, cmd_list_element **set_list,
    cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_optional_filename_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc, const char *help_doc,
+   setting_func_types<std::string>::set set_func,
+   setting_func_types<std::string>::get get_func,
+   show_value_ftype *show_func, cmd_list_element **set_list,
+   cmd_list_element **show_list);
+
 extern set_show_commands add_setshow_integer_cmd
   (const char *name, command_class theclass, int *var, const char *set_doc,
    const char *show_doc, const char *help_doc, cmd_func_ftype *set_func,
    show_value_ftype *show_func, cmd_list_element **set_list,
    cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_integer_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc, const char *help_doc,
+   setting_func_types<int>::set set_func,
+   setting_func_types<int>::get get_func, show_value_ftype *show_func,
+   cmd_list_element **set_list, cmd_list_element **show_list);
+
 extern set_show_commands add_setshow_uinteger_cmd
   (const char *name, command_class theclass, unsigned int *var,
    const char *set_doc, const char *show_doc, const char *help_doc,
    cmd_func_ftype *set_func, show_value_ftype *show_func,
    cmd_list_element **set_list, cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_uinteger_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc, const char *help_doc,
+   setting_func_types<unsigned int>::set set_func,
+   setting_func_types<unsigned int>::get get_func, show_value_ftype *show_func,
+   cmd_list_element **set_list, cmd_list_element **show_list);
+
 extern set_show_commands add_setshow_zinteger_cmd
   (const char *name, command_class theclass, int *var, const char *set_doc,
    const char *show_doc, const char *help_doc, cmd_func_ftype *set_func,
    show_value_ftype *show_func, cmd_list_element **set_list,
    cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_zinteger_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc, const char *help_doc,
+   setting_func_types<int>::set set_func,
+   setting_func_types<int>::get get_func, show_value_ftype *show_func,
+   cmd_list_element **set_list, cmd_list_element **show_list);
+
 extern set_show_commands add_setshow_zuinteger_cmd
   (const char *name, command_class theclass, unsigned int *var,
    const char *set_doc, const char *show_doc, const char *help_doc,
    cmd_func_ftype *set_func, show_value_ftype *show_func,
    cmd_list_element **set_list, cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_zuinteger_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc, const char *help_doc,
+   setting_func_types<unsigned int>::set set_func,
+   setting_func_types<unsigned int>::get get_func, show_value_ftype *show_func,
+   cmd_list_element **set_list, cmd_list_element **show_list);
+
 extern set_show_commands add_setshow_zuinteger_unlimited_cmd
   (const char *name, command_class theclass, int *var, const char *set_doc,
    const char *show_doc, const char *help_doc, cmd_func_ftype *set_func,
    show_value_ftype *show_func, cmd_list_element **set_list,
    cmd_list_element **show_list);
 
+extern set_show_commands add_setshow_zuinteger_unlimited_cmd
+  (const char *name, command_class theclass, const char *set_doc,
+   const char *show_doc, const char *help_doc,
+   setting_func_types<int>::set set_func, setting_func_types<int>::get get_func,
+   show_value_ftype *show_func, cmd_list_element **set_list,
+   cmd_list_element **show_list);
+
 /* Do a "show" command for each thing on a command list.  */
 
 extern void cmd_show_list (struct cmd_list_element *, int);