public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP]
@ 2018-07-05 21:37 Philippe Waroquiers
  2018-07-05 21:37 ` [RFA 3/6] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Philippe Waroquiers @ 2018-07-05 21:37 UTC (permalink / raw)
  To: gdb-patches

This patch series adds flags and/or arguments
[-q] [-t TYPEREGEXP] [NAMEREGEXP] to the commands
  info [args|functions|locals|variables]

The additional arguments allow to more precisely specify what to print.
This patch series does not depend on
[RFA_v3 0/8] Implement 'frame apply COMMAND', enhance 'thread apply COMMAND'.
However, the new features above can usefully be combined with
frame apply and thread apply.
So, the documentation gives examples combining the above
and the 'thread apply' and 'frame apply' commands.

Some examples:
* print functions returning an int:
    info functions -t '^int ('
* print local variables having pthread_t type
    info locals -t pthread_t
* print global variables having type 'struct addrinfo'
    info var -t 'struct addrinfo'
* print args that are likely file descriptors
    info arg -t int .*fd.*

Below examples depends on the 'thread/frame apply' patch series.

* Assuming lock_something_t is an RAII type, show all locks:
  thread apply all -s frame apply all -s info locals -q -t lock_something_t
 or shorter equivalent:
  tfaas i lo -q -t lock_something_t

* show frames and args having an arg with type matchin std::.*map
  so likely  std::map or std::unordered_map
  frame apply all -s info args -q std::.*map


The code, documentation, NEWS, test and ChangeLog are (supposed to be) complete.

Compared to the RFC, the changes are:
* All comments of Eli on the documentation have been handled.
* ChangeLog entries added in commit messages
* Test added.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RFA 4/6] Document changes to info [args|functions|locals|variables]
  2018-07-05 21:37 [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
                   ` (4 preceding siblings ...)
  2018-07-05 21:37 ` [RFA 6/6] Add a test case for info args|functions|locals|variables [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
@ 2018-07-05 21:37 ` Philippe Waroquiers
  2018-07-06  5:37   ` Eli Zaretskii
  2018-07-23 20:46 ` [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
  6 siblings, 1 reply; 10+ messages in thread
From: Philippe Waroquiers @ 2018-07-05 21:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Philippe Waroquiers

Document changes to info [args|functions|locals|variables]

gdb/doc/ChangeLog
2018-07-05  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* gdb.texinfo (Information About a Frame): Document changes to 'info args'
	and 'info locals'.
	(Examining the Symbol Table): Document changes to 'info functions'
	and 'info variables'.
---
 gdb/doc/gdb.texinfo | 121 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 109 insertions(+), 12 deletions(-)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 91ec219958..af79c79e3e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -7705,15 +7705,73 @@ architectures) that you specify in the @code{frame} command.
 @xref{Selection, ,Selecting a Frame}.
 
 @kindex info args
-@item info args
+@item info args [-q]
 Print the arguments of the selected frame, each on a separate line.
 
+The optional flag @samp{-q}, which stands for @samp{quiet}, disables
+printing header information and messages explaining why no argument
+have been printed.
+
+@item info args [-q] [-t @var{type_regexp}] [@var{regexp}]
+Like @kbd{info args}, but only print the arguments selected
+with the provided regexp(s).
+
+If @var{regexp} is provided, print only the arguments whose names
+contain a match for regular expression @var{regexp}.
+
+If @var{type_regexp} is provided, print only the arguments whose
+types contain a match for regular expression @var{type_regexp}.
+The matching is done with the argument type as printed by the
+@code{whatis} command.
+If @var{type_regexp} contains space(s), it should be enclosed in single
+quote characters.
+
+If both @var{regexp} and @var{type_regexp} are provided, an argument
+is printed only if it matches the two regexps.
+
 @item info locals
-@kindex info locals
+@kindex info locals [-q]
 Print the local variables of the selected frame, each on a separate
 line.  These are all variables (declared either static or automatic)
 accessible at the point of execution of the selected frame.
 
+The optional flag @samp{-q}, which stands for @samp{quiet}, disables
+printing header information and messages explaining why no local variables
+have been printed.
+
+@item info locals [-q] [-t @var{type_regexp}] [@var{regexp}]
+Like @kbd{info locals}, but only print the local variables selected
+with the provided regexp(s).
+
+If @var{regexp} is provided, print only the local variables whose names
+contain a match for regular expression @var{regexp}.
+
+If @var{type_regexp} is provided, print only the local variables whose
+types contain a match for regular expression @var{type_regexp}.
+The matching is done with the local variable type as printed by the
+@code{whatis} command.
+If @var{type_regexp} contains space(s), it should be enclosed in single
+quote characters.
+
+If both @var{regexp} and @var{type_regexp} are provided, a local variable
+is printed only if it matches the two regexps.
+
+The command @kbd{info locals -q -t @var{type_regexp}} can usefully be
+combined with the commands @kbd{frame apply} and @kbd{thread apply}.
+For example, your program might use Resource Acquisition Is
+Initialization types (RAII) such as @code{lock_something_t} : each
+local variable of type @code{lock_something_t} automatically places a
+lock that is destroyed when the variable goes out of scope.  You can
+then list all acquired locks in your program by doing
+@smallexample
+thread apply all -s frame apply all -s info locals -q -t lock_something_t
+@end smallexample
+@noindent
+or the equivalent shorter form
+@smallexample
+tfaas i lo -q -t lock_something_t
+@end smallexample
+
 @end table
 
 @node Frame Filter Management
@@ -17665,32 +17723,71 @@ debugging information, organized into two lists: files whose symbols
 have already been read, and files whose symbols will be read when needed.
 
 @kindex info functions
-@item info functions
+@item info functions [-q]
 Print the names and data types of all defined functions.
 Similarly to @samp{info types}, this command groups its output by source
 files and annotates each function definition with its source line
 number.
 
-@item info functions @var{regexp}
-Like @samp{info functions}, but only print the names and data types of
-functions whose names contain a match for regular expression
-@var{regexp}.  Thus, @samp{info fun step} finds all functions whose
+The optional flag @samp{-q}, which stands for @samp{quiet}, disables
+printing header information and messages explaining why no functions
+have been printed.
+
+@item info functions [-q] [-t @var{type_regexp}] [@var{regexp}]
+Like @samp{info functions}, but only print the names and data types
+of the functions selected with the provided regexp(s).
+
+If @var{regexp} is provided, print only the functions whose names
+contain a match for regular expression @var{regexp}.
+Thus, @samp{info fun step} finds all functions whose
 names include @code{step}; @samp{info fun ^step} finds those whose names
 start with @code{step}.  If a function name contains characters that
 conflict with the regular expression language (e.g.@:
 @samp{operator*()}), they may be quoted with a backslash.
 
+If @var{type_regexp} is provided, print only the functions whose
+types contain a match for regular expression @var{type_regexp}.
+The matching is done with the function type as printed by the
+@code{whatis} command.
+If @var{type_regexp} contains space(s), it should be enclosed in single
+quote characters.
+Thus, @samp{info fun -t '^int ('} finds the functions that return
+an integer; @samp{info fun -t '(.*int.*'} finds the functions that
+have an argument type containing int; @samp{info fun -t '^int (' ^step}
+finds the functions whose names start with @code{step} and that are returning
+an int.
+
+If both @var{regexp} and @var{type_regexp} are provided, a function
+is printed only if it matches the two regexps.
+
+
 @kindex info variables
-@item info variables
+@item info variables [-q]
 Print the names and data types of all variables that are defined
 outside of functions (i.e.@: excluding local variables).
 The printed variables are grouped by source files and annotated with
 their respective source line numbers.
 
-@item info variables @var{regexp}
-Like @kbd{info variables}, but only print the names and data types of
-non-local variables whose names contain a match for regular expression
-@var{regexp}.
+The optional flag @samp{-q}, which stands for @samp{quiet}, disables
+printing header information and messages explaining why no variables
+have been printed.
+
+@item info variables [-q] [-t @var{type_regexp}] [@var{regexp}]
+Like @kbd{info variables}, but only print the variables selected
+with the provided regexp(s).
+
+If @var{regexp} is provided, print only the variables whose names
+contain a match for regular expression @var{regexp}.
+
+If @var{type_regexp} is provided, print only the variables whose
+types contain a match for regular expression @var{type_regexp}.
+The matching is done with the variable type as printed by the
+@code{whatis} command.
+If @var{type_regexp} contains space(s), it should be enclosed in single
+quote characters.
+
+If both @var{regexp} and @var{type_regexp} are provided, an argument
+is printed only if it matches the two regexps.
 
 @kindex info classes
 @cindex Objective-C, classes and selectors
-- 
2.18.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RFA 1/6] New cli-utils.h/.c function extract_info_print_args
  2018-07-05 21:37 [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
  2018-07-05 21:37 ` [RFA 3/6] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers
  2018-07-05 21:37 ` [RFA 2/6] Make struct type_print_options default_ptype_flags non static Philippe Waroquiers
@ 2018-07-05 21:37 ` Philippe Waroquiers
  2018-07-05 21:37 ` [RFA 5/6] Announce changes in NEWS to info [args|functions|locals|variables] Philippe Waroquiers
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Philippe Waroquiers @ 2018-07-05 21:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Philippe Waroquiers

New cli-utils.h/.c function extract_info_print_args factorises
the extraction of the args '[-q] [-t TYPEREGEXP] [NAMEREGEXP]'.

This function is used by the commands
  info [args|functions|locals|variables]

cli-utils.c has a new static function extract_arg_maybe_quoted
that extracts an argument, possibly single quoted.

gdb/ChangeLog
2018-07-05  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* cli-utils.c (extract_arg_maybe_quoted): New function.
	(extract_info_print_args): New function.
	* cli-utils.h (extract_arg_maybe_quoted): New function.
	(extract_info_print_args): New function.
	(INFO_PRINT_ARGS_HELP): new macro.
---
 gdb/cli/cli-utils.c | 113 ++++++++++++++++++++++++++++++++++++++++++++
 gdb/cli/cli-utils.h |  20 ++++++++
 2 files changed, 133 insertions(+)

diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c
index c55b5035e4..3f33c18a06 100644
--- a/gdb/cli/cli-utils.c
+++ b/gdb/cli/cli-utils.c
@@ -23,6 +23,9 @@
 
 #include <ctype.h>
 
+static std::string
+extract_arg_maybe_quoted (const char **arg);
+
 /* See documentation in cli-utils.h.  */
 
 int
@@ -125,6 +128,56 @@ get_number (char **pp)
   return result;
 }
 
+/* See documentation in cli-utils.h.  */
+
+void
+extract_info_print_args (const char* command,
+			 const char **args,
+			 bool *quiet,
+			 std::string *regexp,
+			 std::string *t_regexp)
+{
+  *quiet = false;
+  *regexp = "";
+  *t_regexp = "";
+
+  while (*args != NULL)
+    {
+      if (check_for_argument (args, "--", 2))
+	{
+	  *args = skip_spaces (*args);
+	  break;
+	}
+
+      if (check_for_argument (args, "-t", 2))
+	{
+	  *t_regexp = extract_arg_maybe_quoted (args);
+	  *args = skip_spaces (*args);
+	  continue;
+	}
+
+      if (check_for_argument (args, "-q", 2))
+	{
+	  *quiet = true;
+	  *args = skip_spaces (*args);
+	  continue;
+	}
+
+      if (**args != '-')
+	break;
+
+      std::string option = extract_arg (args);
+      error (_("Unrecognized option '%s' to %s command.  "
+	       "Try \"help %s\"."), option.c_str (),
+	     command, command);
+    }
+
+  if (*args != NULL && **args != '\000')
+    *regexp = extract_arg (args);
+
+}
+
+
 /* See documentation in cli-utils.h.  */
 
 number_or_range_parser::number_or_range_parser (const char *string)
@@ -253,6 +306,66 @@ remove_trailing_whitespace (const char *start, const char *s)
   return s;
 }
 
+/* A helper function to extract an argument from *ARG.  An argument is
+   delimited by whitespace, but it can also be optionally quoted using
+   single quote characters.  The return value is empty if no argument
+   was found.  */
+
+static std::string
+extract_arg_maybe_quoted (const char **arg)
+{
+  if (!*arg)
+    return std::string ();
+
+  /* Find the start of the argument.  */
+  *arg = skip_spaces (*arg);
+  if (!**arg)
+    return std::string ();
+
+  if (**arg == '\'')
+    {
+      /* Quoted argument.  */
+      const char *orig_arg = *arg;
+      std::string result;
+      const char *p;
+
+      (*arg)++; /* Skip starting quote.  */
+
+      /* Find the end of the quoted argument.  */
+      for (p = *arg; *p != '\0'; p++)
+	{
+	  if (*p == '\'')
+	    {
+	      (*arg)++; /* Skip ending quote.  */
+	      return result;
+	    }
+
+	  if (*p == '\\' && p[1] == '\'')
+	    {
+	      /* Escaped quote.  */
+	      p++;      /* Skip escape char.  */
+	      (*arg)++; /* Skip escape char.  */
+	    }
+
+	  result = result + *p;
+	  (*arg)++;
+	}
+      error (_("Unterminated quoted argument in %s"), orig_arg);
+    }
+  else
+    {
+      const char *result = *arg;
+
+      /* Find the end of the argument.  */
+      *arg = skip_to_space (*arg + 1);
+
+      if (result == *arg)
+	return std::string ();
+
+      return std::string (result, *arg - result);
+    }
+}
+
 /* See documentation in cli-utils.h.  */
 
 std::string
diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h
index e34ee0df37..1014323444 100644
--- a/gdb/cli/cli-utils.h
+++ b/gdb/cli/cli-utils.h
@@ -39,6 +39,26 @@ extern int get_number (const char **);
 
 extern int get_number (char **);
 
+/* Extract from args the arguments [-q] [-t TYPEREGEXP] [--] NAMEREGEXP.
+   Only the above flags are accepted.  Any other flag will raise an error.
+   COMMAND is used to produce the error message if an invalid flag is
+   given.  */
+extern void extract_info_print_args (const char* command,
+				     const char **args,
+				     bool *quiet,
+				     std::string *regexp,
+				     std::string *t_regexp);
+
+#define INFO_PRINT_ARGS_HELP(entity_kind) \
+"If NAMEREGEXP is provided, only prints the " entity_kind " whose name\n\
+matches NAMEREGEXP.\n\
+If -t TYPEREGEXP is provided, only prints the " entity_kind " whose type\n\
+matches TYPEREGEXP.  Note that the matching is done with the type\n\
+printed by the 'whatis' command.\n\
+By default, the command might produce headers and/or messages indicating\n\
+why no " entity_kind " can be printed.\n\
+The flag -q disables the production of these headers and messages."
+
 /* Parse a number or a range.
    A number will be of the form handled by get_number.
    A range will be of the form <number1> - <number2>, and
-- 
2.18.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RFA 3/6] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables]
  2018-07-05 21:37 [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
@ 2018-07-05 21:37 ` Philippe Waroquiers
  2018-07-05 21:37 ` [RFA 2/6] Make struct type_print_options default_ptype_flags non static Philippe Waroquiers
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Philippe Waroquiers @ 2018-07-05 21:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Philippe Waroquiers

Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables]

Main changes are:
* stack.h: add two regexp args to iterate_over_block_arg_vars
  and iterate_over_block_local_vars, and update all impacted files/callers.
  As stack.h now uses a type from gdb_regex.h, all files including stack.h need to
  include gdb_regex.h.

* symtab.h: add a new function bool treg_matches_sym_type_name, that
  factorises type matching logic.

* symbtab.c: add type/name matching logic to 'info functions|variables'.

* stack.c : add type/name matching logic to 'info args|locals'.

gdb/ChangeLog
2018-07-05  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* linespec.c: Include gdb_exex.h.
	* mi/mi-cmd-stack.c: Likewise.
	* python/py-frame.c: Likewise.
	* python/python.c: Likewise.
	* skip.c: Likewise.
	* symfile.c: Likewise.
	* tracepoint.c: Likewise.
	* stack.h (iterate_over_block_arg_vars): Add preg and treg arguments.
	(iterate_over_block_local_vars): Likewise.
	* stack.c (iterate_over_block_arg_vars): Add preg and treg arguments,
	and update callers.
	(iterate_over_block_local_vars): Likewise.
	(print_frame_local_vars): Add quiet, regexp and t_regexp arguments,
	and update callers.
	(print_frame_arg_vars): Likewise.
	(prepare_reg): New function.
	(info_locals_command): Extract info print args and use them.
	(info_args_command): Likewise.
	(_initialize_stack): Modify on-line help.
	* symtab.c (treg_matches_sym_type_name): New function.
	(search_symbols): New arg t_regexp.
	(symtab_symbol_info): New args quiet, regexp, t_regexp.
	(info_variables_command): Extract info print args and use them.
	(info_functions_command): Likewise.
	(info_types_command): Update call to symtab_symbol_info.
	(_initialize_symtab): Modify on-line help.
	* symtab.h (treg_matches_sym_type_name): New function.
	(search_symbols): New t_regexp arg.
---
 gdb/linespec.c        |   1 +
 gdb/mi/mi-cmd-stack.c |   1 +
 gdb/python/py-frame.c |   1 +
 gdb/python/python.c   |   4 +-
 gdb/skip.c            |   1 +
 gdb/stack.c           | 162 ++++++++++++++++++++++++++++++++++-------
 gdb/stack.h           |   4 +
 gdb/symfile.c         |   1 +
 gdb/symtab.c          | 165 ++++++++++++++++++++++++++++++++++++------
 gdb/symtab.h          |   8 +-
 gdb/tracepoint.c      |   8 +-
 11 files changed, 300 insertions(+), 56 deletions(-)

diff --git a/gdb/linespec.c b/gdb/linespec.c
index 2a4189278e..2503ec77ab 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -42,6 +42,7 @@
 #include "cli/cli-utils.h"
 #include "filenames.h"
 #include "ada-lang.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "location.h"
 #include "common/function-view.h"
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
index 52660bdd49..f109353a34 100644
--- a/gdb/mi/mi-cmd-stack.c
+++ b/gdb/mi/mi-cmd-stack.c
@@ -25,6 +25,7 @@
 #include "ui-out.h"
 #include "symtab.h"
 #include "block.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "dictionary.h"
 #include "language.h"
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index ec456e9e77..b566149f76 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -22,6 +22,7 @@
 #include "block.h"
 #include "frame.h"
 #include "symtab.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "value.h"
 #include "python-internal.h"
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 20fc674f20..b80c874c47 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -766,11 +766,11 @@ gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw)
     {
       const char **files = symtab_paths.vec.data ();
 
-      symbols = search_symbols (regex, FUNCTIONS_DOMAIN,
+      symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL,
 				symtab_paths.vec.size (), files);
     }
   else
-    symbols = search_symbols (regex, FUNCTIONS_DOMAIN, 0, NULL);
+    symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, 0, NULL);
 
   /* Count the number of symbols (both symbols and optionally minimal
      symbols) so we can correctly check the throttle limit.  */
diff --git a/gdb/skip.c b/gdb/skip.c
index 7a6f2e712b..b7f7b10167 100644
--- a/gdb/skip.c
+++ b/gdb/skip.c
@@ -24,6 +24,7 @@
 #include "gdbcmd.h"
 #include "command.h"
 #include "completer.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "cli/cli-utils.h"
 #include "arch-utils.h"
diff --git a/gdb/stack.c b/gdb/stack.c
index 13d8cf22b5..ed34b98fa1 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -25,6 +25,7 @@
 #include "language.h"
 #include "frame.h"
 #include "gdbcmd.h"
+#include "gdb_regex.h"
 #include "gdbcore.h"
 #include "target.h"
 #include "source.h"
@@ -89,8 +90,10 @@ const char *print_entry_values = print_entry_values_default;
 
 /* Prototypes for local functions.  */
 
-static void print_frame_local_vars (struct frame_info *, int,
-				    struct ui_file *);
+static void print_frame_local_vars (struct frame_info *frame,
+				    bool quiet,
+				    const char *regexp, const char *t_regexp,
+				    int num_tabs, struct ui_file *stream);
 
 static void print_frame (struct frame_info *frame, int print_level,
 			 enum print_what print_what,  int print_args,
@@ -1792,7 +1795,7 @@ backtrace_command_1 (const char *count_exp, frame_filter_flags flags,
 	    {
 	      struct frame_id frame_id = get_frame_id (fi);
 
-	      print_frame_local_vars (fi, 1, gdb_stdout);
+	      print_frame_local_vars (fi, false, NULL, NULL, 1, gdb_stdout);
 
 	      /* print_frame_local_vars invalidates FI.  */
 	      fi = frame_find_by_id (frame_id);
@@ -1866,10 +1869,14 @@ backtrace_command (const char *arg, int from_tty)
 }
 
 /* Iterate over the local variables of a block B, calling CB with
-   CB_DATA.  */
+   CB_DATA.
+   Only local variables with name/type matching PREG/TREG are iterated
+   on.  */
 
 static void
 iterate_over_block_locals (const struct block *b,
+			   const gdb::optional<compiled_regex> &preg,
+			   const gdb::optional<compiled_regex> &treg,
 			   iterate_over_block_arg_local_vars_cb cb,
 			   void *cb_data)
 {
@@ -1889,6 +1896,13 @@ iterate_over_block_locals (const struct block *b,
 	    break;
 	  if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN)
 	    break;
+	  if (preg
+	      && preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
+			     NULL, 0) != 0)
+	    break;
+	  if (treg
+	      && !treg_matches_sym_type_name (*treg, sym))
+	    break;
 	  (*cb) (SYMBOL_PRINT_NAME (sym), sym, cb_data);
 	  break;
 
@@ -1950,16 +1964,20 @@ print_block_frame_labels (struct gdbarch *gdbarch, struct block *b,
 #endif
 
 /* Iterate over all the local variables in block B, including all its
-   superblocks, stopping when the top-level block is reached.  */
+   superblocks, stopping when the top-level block is reached.
+   Only local variables with name/type matching PREG/TREG are iterated
+   on.  */
 
 void
 iterate_over_block_local_vars (const struct block *block,
+			       const gdb::optional<compiled_regex> &preg,
+			       const gdb::optional<compiled_regex> &treg,
 			       iterate_over_block_arg_local_vars_cb cb,
 			       void *cb_data)
 {
   while (block)
     {
-      iterate_over_block_locals (block, cb, cb_data);
+      iterate_over_block_locals (block, preg, treg, cb, cb_data);
       /* After handling the function's top-level block, stop.  Don't
 	 continue to its superblock, the block of per-file
 	 symbols.  */
@@ -2006,30 +2024,57 @@ do_print_variable_and_value (const char *print_name,
   p->values_printed = 1;
 }
 
+/* Prepares the regular expression REG from REGEXP.
+   If REGEXP is NULL, it results in an empty regular expression.  */
+static void
+prepare_reg (const char *regexp, gdb::optional<compiled_regex> &reg)
+{
+  if (regexp != NULL)
+    {
+      int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
+				? REG_ICASE : 0);
+      reg.emplace (regexp, cflags, _("Invalid regexp"));
+    }
+  else
+    reg.reset ();
+}
+
 /* Print all variables from the innermost up to the function block of FRAME.
    Print them with values to STREAM indented by NUM_TABS.
+   If REGEXP is not NULL, only print local variables whose name
+   matches REGEXP.
+   If T_REGEXP is not NULL, only print local variables whose type
+   matches T_REGEXP.
+   If no local variables have been printed and !QUIET, prints a message
+   explaining why no local variables could be printed.
 
    This function will invalidate FRAME.  */
 
 static void
-print_frame_local_vars (struct frame_info *frame, int num_tabs,
-			struct ui_file *stream)
+print_frame_local_vars (struct frame_info *frame,
+			bool quiet,
+			const char *regexp, const char *t_regexp,
+			int num_tabs, struct ui_file *stream)
 {
   struct print_variable_and_value_data cb_data;
   const struct block *block;
   CORE_ADDR pc;
+  gdb::optional<compiled_regex> preg;
+  gdb::optional<compiled_regex> treg;
 
   if (!get_frame_pc_if_available (frame, &pc))
     {
-      fprintf_filtered (stream,
-			_("PC unavailable, cannot determine locals.\n"));
+      if (!quiet)
+	fprintf_filtered (stream,
+			  _("PC unavailable, cannot determine locals.\n"));
       return;
     }
 
   block = get_frame_block (frame, 0);
   if (block == 0)
     {
-      fprintf_filtered (stream, "No symbol table info available.\n");
+      if (!quiet)
+	fprintf_filtered (stream, "No symbol table info available.\n");
       return;
     }
 
@@ -2038,31 +2083,53 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
   cb_data.stream = stream;
   cb_data.values_printed = 0;
 
+  prepare_reg (regexp, preg);
+  prepare_reg (t_regexp, treg);
+
   /* Temporarily change the selected frame to the given FRAME.
      This allows routines that rely on the selected frame instead
      of being given a frame as parameter to use the correct frame.  */
   scoped_restore_selected_frame restore_selected_frame;
   select_frame (frame);
 
-  iterate_over_block_local_vars (block,
+  iterate_over_block_local_vars (block, preg, treg,
 				 do_print_variable_and_value,
 				 &cb_data);
 
-  if (!cb_data.values_printed)
-    fprintf_filtered (stream, _("No locals.\n"));
+  if (!cb_data.values_printed && !quiet)
+    {
+      if (regexp == NULL && t_regexp == NULL)
+	fprintf_filtered (stream, _("No locals.\n"));
+      else
+	fprintf_filtered (stream, _("No matching locals.\n"));
+    }
 }
 
 void
 info_locals_command (const char *args, int from_tty)
 {
+  std::string regexp;
+  std::string t_regexp;
+  bool quiet;
+
+  extract_info_print_args ("info locals", &args, &quiet, &regexp, &t_regexp);
   print_frame_local_vars (get_selected_frame (_("No frame selected.")),
+			  quiet,
+			  regexp.empty () ? NULL : regexp.c_str (),
+			  t_regexp.empty () ? NULL : t_regexp.c_str (),
 			  0, gdb_stdout);
 }
 
-/* Iterate over all the argument variables in block B.  */
+/* Iterate over all the argument variables in block B.
+   If PREG has a value, only prints the argument variables
+   with name matching PREG.
+   If TREG has a value, only prints the argument variables
+   with type matching TREG.  */
 
 void
 iterate_over_block_arg_vars (const struct block *b,
+			     const gdb::optional<compiled_regex> &preg,
+			     const gdb::optional<compiled_regex> &treg,
 			     iterate_over_block_arg_local_vars_cb cb,
 			     void *cb_data)
 {
@@ -2072,7 +2139,12 @@ iterate_over_block_arg_vars (const struct block *b,
   ALL_BLOCK_SYMBOLS (b, iter, sym)
     {
       /* Don't worry about things which aren't arguments.  */
-      if (SYMBOL_IS_ARGUMENT (sym))
+      if (SYMBOL_IS_ARGUMENT (sym)
+	  && (!preg
+	      || preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
+			     NULL, 0) == 0)
+	  && (!treg
+	      || treg_matches_sym_type_name (*treg, sym)))
 	{
 	  /* We have to look up the symbol because arguments can have
 	     two entries (one a parameter, one a local) and the one we
@@ -2084,7 +2156,6 @@ iterate_over_block_arg_vars (const struct block *b,
 	     symbol is double and the type of the LOC_LOCAL symbol is
 	     float).  There are also LOC_ARG/LOC_REGISTER pairs which
 	     are not combined in symbol-reading.  */
-
 	  sym2 = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
 					    b, VAR_DOMAIN).symbol;
 	  (*cb) (SYMBOL_PRINT_NAME (sym), sym2, cb_data);
@@ -2094,26 +2165,40 @@ iterate_over_block_arg_vars (const struct block *b,
 
 /* Print all argument variables of the function of FRAME.
    Print them with values to STREAM.
+   If REGEXP is not NULL, only print argument variables whose name
+   matches REGEXP.
+   If T_REGEXP is not NULL, only print argument variables whose type
+   matches T_REGEXP.
+   If no argument variables have been printed and !QUIET, prints a message
+   explaining why no argument variables could be printed.
 
    This function will invalidate FRAME.  */
 
 static void
-print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
+print_frame_arg_vars (struct frame_info *frame,
+		      bool quiet,
+		      const char *regexp, const char *t_regexp,
+		      struct ui_file *stream)
 {
   struct print_variable_and_value_data cb_data;
   struct symbol *func;
   CORE_ADDR pc;
+  gdb::optional<compiled_regex> preg;
+  gdb::optional<compiled_regex> treg;
 
   if (!get_frame_pc_if_available (frame, &pc))
     {
-      fprintf_filtered (stream, _("PC unavailable, cannot determine args.\n"));
+      if (!quiet)
+	fprintf_filtered (stream,
+			  _("PC unavailable, cannot determine args.\n"));
       return;
     }
 
   func = get_frame_function (frame);
   if (func == NULL)
     {
-      fprintf_filtered (stream, _("No symbol table info available.\n"));
+      if (!quiet)
+	fprintf_filtered (stream, _("No symbol table info available.\n"));
       return;
     }
 
@@ -2122,20 +2207,37 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
   cb_data.stream = stream;
   cb_data.values_printed = 0;
 
+  prepare_reg (regexp, preg);
+  prepare_reg (t_regexp, treg);
+
   iterate_over_block_arg_vars (SYMBOL_BLOCK_VALUE (func),
+			       preg, treg,
 			       do_print_variable_and_value, &cb_data);
 
   /* do_print_variable_and_value invalidates FRAME.  */
   frame = NULL;
 
-  if (!cb_data.values_printed)
-    fprintf_filtered (stream, _("No arguments.\n"));
+  if (!cb_data.values_printed && !quiet)
+    {
+      if (regexp == NULL && t_regexp == NULL)
+	fprintf_filtered (stream, _("No arguments.\n"));
+      else
+	fprintf_filtered (stream, _("No matching arguments.\n"));
+    }
 }
 
 void
-info_args_command (const char *ignore, int from_tty)
+info_args_command (const char *args, int from_tty)
 {
+  std::string regexp;
+  std::string t_regexp;
+  bool quiet;
+
+  extract_info_print_args ("info args", &args, &quiet, &regexp, &t_regexp);
   print_frame_arg_vars (get_selected_frame (_("No frame selected.")),
+			quiet,
+			regexp.empty () ? NULL : regexp.c_str (),
+			t_regexp.empty () ? NULL : t_regexp.c_str (),
 			gdb_stdout);
 }
 \f
@@ -2549,10 +2651,16 @@ on this backtrace."));
   add_info ("frame", info_frame_command,
 	    _("All about selected stack frame, or frame at ADDR."));
   add_info_alias ("f", "frame", 1);
-  add_info ("locals", info_locals_command,
-	    _("Local variables of current stack frame."));
-  add_info ("args", info_args_command,
-	    _("Argument variables of current stack frame."));
+  add_info ("locals", info_locals_command, _("\
+All local variables of current stack frame or those matching REGEXPs.\n\
+Usage: info locals [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the local variables of the current stack frame.\n"
+INFO_PRINT_ARGS_HELP ("local variables")));
+  add_info ("args", info_args_command, _("\
+All argument variables of current stack frame or those matching REGEXPs.\n\
+Usage: info args [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the argument variables of the current stack frame.\n"
+INFO_PRINT_ARGS_HELP ("argument variables")));
 
   if (dbx_commands)
     add_com ("func", class_stack, func_command, _("\
diff --git a/gdb/stack.h b/gdb/stack.h
index ca190efa9c..c6924d5237 100644
--- a/gdb/stack.h
+++ b/gdb/stack.h
@@ -31,10 +31,14 @@ typedef void (*iterate_over_block_arg_local_vars_cb) (const char *print_name,
 						      void *cb_data);
 
 void iterate_over_block_arg_vars (const struct block *block,
+				  const gdb::optional<compiled_regex> &preg,
+				  const gdb::optional<compiled_regex> &treg,
 				  iterate_over_block_arg_local_vars_cb cb,
 				  void *cb_data);
 
 void iterate_over_block_local_vars (const struct block *block,
+				    const gdb::optional<compiled_regex> &preg,
+				    const gdb::optional<compiled_regex> &treg,
 				    iterate_over_block_arg_local_vars_cb cb,
 				    void *cb_data);
 
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 48eca5cc0e..cf200ec164 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -53,6 +53,7 @@
 #include "elf-bfd.h"
 #include "solib.h"
 #include "remote.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "gdb_bfd.h"
 #include "cli/cli-utils.h"
diff --git a/gdb/symtab.c b/gdb/symtab.c
index d8a7a16e07..e998597135 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -43,6 +43,7 @@
 #include "cli/cli-utils.h"
 #include "fnmatch.h"
 #include "hashtab.h"
+#include "typeprint.h"
 
 #include "gdb_obstack.h"
 #include "block.h"
@@ -4265,6 +4266,51 @@ symbol_search::compare_search_syms (const symbol_search &sym_a,
 		 SYMBOL_PRINT_NAME (sym_b.symbol));
 }
 
+/* Returns true if the type_name of symbol_type of SYM matches TREG.
+   If SYM has no symbol_type or symbol_name, returns false.  */
+
+bool
+treg_matches_sym_type_name (const compiled_regex &treg,
+			    const struct symbol *sym)
+{
+  struct type *sym_type;
+  const char *sym_type_name;
+  string_file printed_sym_type_name;
+
+  if (symbol_lookup_debug > 1)
+    {
+      fprintf_unfiltered (gdb_stdlog,
+			  "treg_matches_sym_type_name\n     sym %s\n",
+			  SYMBOL_NATURAL_NAME (sym));
+    }
+
+  sym_type = SYMBOL_TYPE (sym);
+  if (sym_type == NULL)
+    return false;
+
+  if (language_mode == language_mode_auto)
+    language_def (SYMBOL_LANGUAGE (sym))->la_print_type
+      (sym_type, "", &printed_sym_type_name,
+       -1, 0, &default_ptype_flags);
+  else
+    LA_PRINT_TYPE (sym_type, "", &printed_sym_type_name,
+		   -1, 0, &default_ptype_flags);
+
+  if (symbol_lookup_debug > 1)
+    {
+      fprintf_unfiltered (gdb_stdlog,
+			  "     sym_type_name %s\n",
+			  printed_sym_type_name.c_str ());
+    }
+
+
+  if (printed_sym_type_name.empty ())
+    return false;
+
+  return treg.exec (printed_sym_type_name.c_str (), 0, NULL, 0) == 0;
+}
+
+
 /* Sort the symbols in RESULT and remove duplicates.  */
 
 static void
@@ -4280,7 +4326,9 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
 
    Only symbols of KIND are searched:
    VARIABLES_DOMAIN - search all symbols, excluding functions, type names,
-                      and constants (enums)
+                      and constants (enums).
+		      if T_REGEXP is not NULL, only returns var that have
+		      a type matching regular expression T_REGEXP.
    FUNCTIONS_DOMAIN - search all functions
    TYPES_DOMAIN     - search all type names
    ALL_DOMAIN       - an internal error for this function
@@ -4291,6 +4339,7 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
 
 std::vector<symbol_search>
 search_symbols (const char *regexp, enum search_domain kind,
+		const char *t_regexp,
 		int nfiles, const char *files[])
 {
   struct compunit_symtab *cust;
@@ -4316,6 +4365,7 @@ search_symbols (const char *regexp, enum search_domain kind,
   enum minimal_symbol_type ourtype4;
   std::vector<symbol_search> result;
   gdb::optional<compiled_regex> preg;
+  gdb::optional<compiled_regex> treg;
 
   gdb_assert (kind <= TYPES_DOMAIN);
 
@@ -4365,6 +4415,13 @@ search_symbols (const char *regexp, enum search_domain kind,
       preg.emplace (regexp, cflags, _("Invalid regexp"));
     }
 
+  if (t_regexp != NULL)
+    {
+      int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
+				? REG_ICASE : 0);
+      treg.emplace (t_regexp, cflags, _("Invalid regexp"));
+    }
+
   /* Search through the partial symtabs *first* for all symbols
      matching the regexp.  That way we don't have to reproduce all of
      the machinery below.  */
@@ -4463,9 +4520,13 @@ search_symbols (const char *regexp, enum search_domain kind,
 			    We only want to skip enums here.  */
 			 && !(SYMBOL_CLASS (sym) == LOC_CONST
 			      && (TYPE_CODE (SYMBOL_TYPE (sym))
-				  == TYPE_CODE_ENUM)))
-			|| (kind == FUNCTIONS_DOMAIN 
-			    && SYMBOL_CLASS (sym) == LOC_BLOCK)
+				  == TYPE_CODE_ENUM))
+			 && (!treg
+			     || treg_matches_sym_type_name (*treg, sym)))
+			|| (kind == FUNCTIONS_DOMAIN
+			    && SYMBOL_CLASS (sym) == LOC_BLOCK
+			    && (!treg
+				|| treg_matches_sym_type_name (*treg, sym)))
 			|| (kind == TYPES_DOMAIN
 			    && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
 	      {
@@ -4496,8 +4557,12 @@ search_symbols (const char *regexp, enum search_domain kind,
 	    || MSYMBOL_TYPE (msymbol) == ourtype3
 	    || MSYMBOL_TYPE (msymbol) == ourtype4)
 	  {
-	    if (!preg || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
-				     NULL, 0) == 0)
+	    /* If the user wants to see var matching a type regexp,
+	       then never give a minimal symbol.  */
+	    if (kind != VARIABLES_DOMAIN
+		&& !treg /* a minimal symbol has never a type ???? */
+		&& (!preg || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
+					 NULL, 0) == 0))
 	      {
 		/* For functions we can do a quick check of whether the
 		   symbol might be found via find_pc_symtab.  */
@@ -4598,7 +4663,9 @@ print_msymbol_info (struct bound_minimal_symbol msymbol)
    matches.  */
 
 static void
-symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
+symtab_symbol_info (bool quiet,
+		    const char *regexp, enum search_domain kind,
+		    const char *t_regexp, int from_tty)
 {
   static const char * const classnames[] =
     {"variable", "function", "type"};
@@ -4608,13 +4675,33 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
   gdb_assert (kind <= TYPES_DOMAIN);
 
   /* Must make sure that if we're interrupted, symbols gets freed.  */
-  std::vector<symbol_search> symbols = search_symbols (regexp, kind, 0, NULL);
+  std::vector<symbol_search> symbols = search_symbols (regexp, kind,
+						       t_regexp, 0, NULL);
 
-  if (regexp != NULL)
-    printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
-		     classnames[kind], regexp);
-  else
-    printf_filtered (_("All defined %ss:\n"), classnames[kind]);
+  if (!quiet)
+    {
+      if (regexp != NULL)
+	{
+	  if (t_regexp != NULL)
+	    printf_filtered
+	      (_("All %ss matching regular expression \"%s\""
+		 " with type matching regulation expression \"%s\" :\n"),
+	       classnames[kind], regexp, t_regexp);
+	  else
+	    printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
+			     classnames[kind], regexp);
+	}
+      else
+	{
+	  if (t_regexp != NULL)
+	    printf_filtered
+	      (_("All defined %ss"
+		 " with type matching regulation expression \"%s\" :\n"),
+	       classnames[kind], t_regexp);
+	  else
+	    printf_filtered (_("All defined %ss:\n"), classnames[kind]);
+	}
+    }
 
   for (const symbol_search &p : symbols)
     {
@@ -4624,7 +4711,8 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
 	{
 	  if (first)
 	    {
-	      printf_filtered (_("\nNon-debugging symbols:\n"));
+	      if (!quiet)
+		printf_filtered (_("\nNon-debugging symbols:\n"));
 	      first = 0;
 	    }
 	  print_msymbol_info (p.msymbol);
@@ -4642,22 +4730,41 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
 }
 
 static void
-info_variables_command (const char *regexp, int from_tty)
+info_variables_command (const char *args, int from_tty)
 {
-  symtab_symbol_info (regexp, VARIABLES_DOMAIN, from_tty);
+  std::string regexp;
+  std::string t_regexp;
+  bool quiet;
+
+  extract_info_print_args ("info variables", &args, &quiet, &regexp, &t_regexp);
+  symtab_symbol_info (quiet,
+		      regexp.empty () ? NULL : regexp.c_str (),
+		      VARIABLES_DOMAIN,
+		      t_regexp.empty () ? NULL : t_regexp.c_str (),
+		      from_tty);
 }
 
+
 static void
-info_functions_command (const char *regexp, int from_tty)
+info_functions_command (const char *args, int from_tty)
 {
-  symtab_symbol_info (regexp, FUNCTIONS_DOMAIN, from_tty);
+  std::string regexp;
+  std::string t_regexp;
+  bool quiet;
+
+  extract_info_print_args ("info functions", &args, &quiet, &regexp, &t_regexp);
+  symtab_symbol_info (quiet,
+		      regexp.empty () ? NULL : regexp.c_str (),
+		      FUNCTIONS_DOMAIN,
+		      t_regexp.empty () ? NULL : t_regexp.c_str (),
+		      from_tty);
 }
 
 
 static void
 info_types_command (const char *regexp, int from_tty)
 {
-  symtab_symbol_info (regexp, TYPES_DOMAIN, from_tty);
+  symtab_symbol_info (false, regexp, TYPES_DOMAIN, NULL, from_tty);
 }
 
 /* Breakpoint all functions matching regular expression.  */
@@ -4700,6 +4807,7 @@ rbreak_command (const char *regexp, int from_tty)
 
   std::vector<symbol_search> symbols = search_symbols (regexp,
 						       FUNCTIONS_DOMAIN,
+						       NULL,
 						       nfiles, files);
 
   scoped_rbreak_breakpoints finalize;
@@ -5902,13 +6010,22 @@ _initialize_symtab (void)
     = register_program_space_data_with_cleanup (NULL, symbol_cache_cleanup);
 
   add_info ("variables", info_variables_command, _("\
-All global and static variable names, or those matching REGEXP."));
+All global and static variable names or those matching REGEXPs.\n\
+Usage: info variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the global and static variables.\n"
+INFO_PRINT_ARGS_HELP ("global and static variables")));
   if (dbx_commands)
     add_com ("whereis", class_info, info_variables_command, _("\
-All global and static variable names, or those matching REGEXP."));
-
-  add_info ("functions", info_functions_command,
-	    _("All function names, or those matching REGEXP."));
+All global and static variable names, or those matching REGEXPs.\n\
+Usage: whereis [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the global and static variables.\n"
+INFO_PRINT_ARGS_HELP ("global and static variables")));
+
+  add_info ("functions", info_functions_command, _("\
+All function names or those matching REGEXPs.\n\
+Usage: info functions [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the functions.\n"
+INFO_PRINT_ARGS_HELP ("functions")));
 
   /* FIXME:  This command has at least the following problems:
      1.  It prints builtin types (in a very strange and confusing fashion).
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 0b155d0659..b7ead5b5c4 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -25,6 +25,7 @@
 #include <string>
 #include "gdb_vecs.h"
 #include "gdbtypes.h"
+#include "gdb_regex.h"
 #include "common/enum-flags.h"
 #include "common/function-view.h"
 #include "common/gdb_optional.h"
@@ -2012,8 +2013,13 @@ private:
 };
 
 extern std::vector<symbol_search> search_symbols (const char *,
-						  enum search_domain, int,
+						  enum search_domain,
+						  const char *,
+						  int,
 						  const char **);
+extern bool
+treg_matches_sym_type_name (const compiled_regex &treg,
+			    const struct symbol *sym);
 
 /* The name of the ``main'' function.
    FIXME: cagney/2001-03-20: Can't make main_name() const since some
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index ab80b10ea1..b59487f3cb 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -43,6 +43,7 @@
 #include "objfiles.h"
 #include "filenames.h"
 #include "gdbthread.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "remote.h"
 #include "source.h"
@@ -1038,6 +1039,7 @@ collection_list::add_local_symbols (struct gdbarch *gdbarch, CORE_ADDR pc,
 {
   const struct block *block;
   struct add_local_symbols_data cb_data;
+  const gdb::optional<compiled_regex> nullreg;
 
   cb_data.collect = this;
   cb_data.gdbarch = gdbarch;
@@ -1057,7 +1059,8 @@ collection_list::add_local_symbols (struct gdbarch *gdbarch, CORE_ADDR pc,
 	  return;
 	}
 
-      iterate_over_block_local_vars (block, do_collect_symbol, &cb_data);
+      iterate_over_block_local_vars (block, nullreg, nullreg,
+				     do_collect_symbol, &cb_data);
       if (cb_data.count == 0)
 	warning (_("No locals found in scope."));
     }
@@ -1071,7 +1074,8 @@ collection_list::add_local_symbols (struct gdbarch *gdbarch, CORE_ADDR pc,
 	  return;
 	}
 
-      iterate_over_block_arg_vars (block, do_collect_symbol, &cb_data);
+      iterate_over_block_arg_vars (block, nullreg, nullreg,
+				   do_collect_symbol, &cb_data);
       if (cb_data.count == 0)
 	warning (_("No args found in scope."));
     }
-- 
2.18.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RFA 2/6] Make struct type_print_options default_ptype_flags non static.
  2018-07-05 21:37 [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
  2018-07-05 21:37 ` [RFA 3/6] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers
@ 2018-07-05 21:37 ` Philippe Waroquiers
  2018-07-05 21:37 ` [RFA 1/6] New cli-utils.h/.c function extract_info_print_args Philippe Waroquiers
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Philippe Waroquiers @ 2018-07-05 21:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Philippe Waroquiers

Make struct type_print_options default_ptype_flags non static,
as this is needed in the type matching logic of
info [args|functions|locals|variables],
to ensure the type matching uses the same setting as the whatis command.

gdb/ChangeLog
2018-07-05  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* typeprint.h (default_ptype_flags): New extern.
	* typeprint.c (default_ptype_flags): Make non-static.
---
 gdb/typeprint.c | 5 +++--
 gdb/typeprint.h | 4 ++++
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 7a0b7627ed..20925b7dcc 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -49,9 +49,10 @@ const struct type_print_options type_print_raw_options =
   NULL				/* global_printers */
 };
 
-/* The default flags for 'ptype' and 'whatis'.  */
 
-static struct type_print_options default_ptype_flags =
+/* See typeprint.h.  */
+
+struct type_print_options default_ptype_flags =
 {
   0,				/* raw */
   1,				/* print_methods */
diff --git a/gdb/typeprint.h b/gdb/typeprint.h
index edd8c396c8..e098782cf4 100644
--- a/gdb/typeprint.h
+++ b/gdb/typeprint.h
@@ -105,6 +105,10 @@ struct type_print_options
 
 extern const struct type_print_options type_print_raw_options;
 
+/* The default flags for 'ptype' and 'whatis'.  */
+
+extern struct type_print_options default_ptype_flags;
+
 /* A hash table holding typedef_field objects.  This is more
    complicated than an ordinary hash because it must also track the
    lifetime of some -- but not all -- of the contained objects.  */
-- 
2.18.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RFA 6/6] Add a test case for info args|functions|locals|variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]
  2018-07-05 21:37 [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
                   ` (3 preceding siblings ...)
  2018-07-05 21:37 ` [RFA 5/6] Announce changes in NEWS to info [args|functions|locals|variables] Philippe Waroquiers
@ 2018-07-05 21:37 ` Philippe Waroquiers
  2018-07-05 21:37 ` [RFA 4/6] Document changes to info [args|functions|locals|variables] Philippe Waroquiers
  2018-07-23 20:46 ` [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
  6 siblings, 0 replies; 10+ messages in thread
From: Philippe Waroquiers @ 2018-07-05 21:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Philippe Waroquiers

Add a test case for info args|functions|locals|variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]

gdb/testsuite/ChangeLog
2018-07-05  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

        * gdb.base/info_qt.c: New file.
        * gdb.base/info_qt.exp: New file.
---
 gdb/testsuite/gdb.base/info_qt.c   |  81 +++++++++++
 gdb/testsuite/gdb.base/info_qt.exp | 221 +++++++++++++++++++++++++++++
 2 files changed, 302 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/info_qt.c
 create mode 100644 gdb/testsuite/gdb.base/info_qt.exp

diff --git a/gdb/testsuite/gdb.base/info_qt.c b/gdb/testsuite/gdb.base/info_qt.c
new file mode 100644
index 0000000000..77c4ea8236
--- /dev/null
+++ b/gdb/testsuite/gdb.base/info_qt.c
@@ -0,0 +1,81 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2018 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
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef int entier;
+
+int info_qt_inc = 0;
+entier info_qt_ent = 0;
+
+static void
+setup_done (void)
+{
+}
+
+static void
+setup (char arg_c, int arg_i, int arg_j)
+{
+  char loc_arg_c = arg_c;
+  int loc_arg_i = arg_i;
+  int loc_arg_j = arg_j;
+
+  info_qt_inc += loc_arg_c + loc_arg_i + loc_arg_j;
+  setup_done ();
+}
+
+void info_fun1 (void)
+{
+  info_qt_inc++;
+  info_qt_ent++;
+}
+
+int info_fun2 (char c)
+{
+  info_qt_inc += c;
+  return info_qt_inc;
+}
+
+int info_fun2bis (char c)
+{
+  info_qt_inc += c;
+  return info_qt_inc;
+}
+
+entier info_fun2xxx (char arg_c, int arg_i, int arg_j)
+{
+  info_qt_inc += arg_c + arg_i + arg_j;
+  return info_qt_inc;
+}
+
+entier info_fun2yyy (char arg_c, int arg_i, int arg_j)
+{
+  setup (arg_c, arg_i, arg_j);
+  info_qt_inc += arg_c + arg_i + arg_j;
+  return info_qt_inc;
+}
+
+int
+main (int argc, char **argv, char **envp)
+{
+  info_fun1 ();
+  (void) info_fun2 ('a');
+  (void) info_fun2bis ('b');
+  (void) info_fun2xxx ('c', 1, 2);
+  (void) info_fun2yyy ('d', 3, 4);
+}
diff --git a/gdb/testsuite/gdb.base/info_qt.exp b/gdb/testsuite/gdb.base/info_qt.exp
new file mode 100644
index 0000000000..c6cf158e47
--- /dev/null
+++ b/gdb/testsuite/gdb.base/info_qt.exp
@@ -0,0 +1,221 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2018 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
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+# This test verifies that a macro using backtrace can be applied to all threads
+# and will continue for each thread even though an error may occur in
+# backtracing one of the threads.
+
+# Test info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP]
+standard_testfile
+
+if { [prepare_for_testing "failed to prepare" ${testfile}] } {
+    return -1
+}
+
+clean_restart ${binfile}
+
+if ![runto setup_done] then {
+    gdb_suppress_tests
+}
+set any "\[^\r\n\]*"
+set ws "\[ \t\]\+"
+set number "\[0-9]\+"
+
+
+############# test 'info functions'
+
+# test simple matching with name regexp
+foreach cmd {
+    "info functions info_fun"
+    "info functions -- info_fun"
+    "info functions ^info_fun" } {
+    gdb_test $cmd \
+	[multi_line \
+	     "All functions matching regular expression \".*info_fun.*\":" \
+	     "" \
+	     "File .*info_qt.c:" \
+	     "${number}:	void info_fun1\\\(void\\\);" \
+	     "${number}:	int info_fun2\\\(char\\\);" \
+	     "${number}:	int info_fun2bis\\\(char\\\);" \
+	     "${number}:	entier info_fun2xxx\\\(char, int, int\\\);" \
+	     "${number}:	entier info_fun2yyy\\\(char, int, int\\\);" \
+	    ] \
+	"info functions info_fun"
+}
+
+# test simple matching with name regexp, but with -q to avoid the first header
+foreach cmd {
+    "info functions -q info_fun"
+    "info functions -q -- info_fun" } {
+    gdb_test $cmd \
+	[multi_line \
+	     "" \
+	     "File .*info_qt.c:" \
+	     "${number}:	void info_fun1\\\(void\\\);" \
+	     "${number}:	int info_fun2\\\(char\\\);" \
+	     "${number}:	int info_fun2bis\\\(char\\\);" \
+	     "${number}:	entier info_fun2xxx\\\(char, int, int\\\);" \
+	     "${number}:	entier info_fun2yyy\\\(char, int, int\\\);" \
+	    ] \
+	"info functions -q info_fun"
+}
+
+# test -q and no matching functions
+foreach cmd {
+    "info functions -q nowaythiscanmatch"
+    "info functions -q -- -q" } {
+    gdb_test $cmd "" "test quiet info functions empty output"
+}
+
+# test with a type regexp
+foreach cmd {
+    "info functions -t entier -q info_fun"
+    "info functions -q -t 'entier (' -- info_fun"
+    "info functions -q -t '(char, int, int)' -- info_fun"
+    "info functions -q -t 'entier (char, int, int)' -- info_fun" } {
+    gdb_test $cmd \
+	[multi_line \
+	     "" \
+	     "File .*info_qt.c:" \
+	     "${number}:	entier info_fun2xxx\\\(char, int, int\\\);" \
+	     "${number}:	entier info_fun2yyy\\\(char, int, int\\\);" \
+	    ] \
+	"info functions -q info_fun"
+}
+
+# test with a non matching type regexp
+gdb_test "info functions -t ganze_Zahl -q info_fun" "" \
+    "quiet output info functions non matching type"
+
+
+############# test 'info variables'
+
+# test simple matching with name regexp
+foreach cmd {
+    "info variables info_qt"
+    "info variables -- info_qt"
+    "info variables ^info_qt" } {
+    gdb_test $cmd \
+	[multi_line \
+	     "All variables matching regular expression \".*info_qt.*\":" \
+	     "" \
+	     "File .*info_qt.c:" \
+	     "${number}:	entier info_qt_ent;" \
+	     "${number}:	int info_qt_inc;" \
+	    ] \
+	"info functions info_fun"
+}
+
+# test simple matching with name regexp, but with -q to avoid the first header
+
+# test -q and no matching variables
+foreach cmd {
+    "info variables -q nowaythiscanmatch"
+    "info variables -q -- -q" } {
+    gdb_test $cmd "" "test quiet info variables empty output"
+}
+
+# test with a type regexp
+foreach cmd {
+    "info variables -t entier -q info_qt"
+    "info variables -q -t entier -- info_qt" } {
+    gdb_test $cmd \
+	[multi_line \
+	     "" \
+	     "File .*info_qt.c:" \
+	     "${number}:	entier info_qt_ent;" \
+	    ] \
+	"info variables -q -t entier info_fun"
+}
+
+# test with a non matching type regexp
+gdb_test "info variables -t ganze_Zahl -q info_at" "" \
+    "quiet output info variables non matching type"
+
+
+
+############# test 'info args' in function setup.
+
+gdb_test "frame 1" ".* in setup .*" "set and check frame 1"
+
+# test name regexp matching all
+foreach cmd {
+    "info args"
+    "info args arg_"
+    "info args g"
+    "info args -- .*" } {
+    gdb_test $cmd \
+	[multi_line \
+	     "arg_c = 100 'd'" \
+	     "arg_i = 3" \
+	     "arg_j = 4" \
+	    ] \
+	"info args"
+}
+
+# test name regexp or type regexp matching some
+foreach cmd {
+    "info args -t int"
+    "info args arg_[ij]"} {
+    gdb_test $cmd \
+	[multi_line \
+	     "arg_i = 3" \
+	     "arg_j = 4" \
+	    ] \
+	"info args"
+}
+
+gdb_test "info args nowaythiscanmatch" "No matching arguments." "Test non matching args"
+gdb_test "info args -q nowaythiscanmatch" "" "Test quiet non matching args"
+gdb_test "info args -q -t entier" "" "Test quiet non matching args with type"
+
+############# test 'info locals' in function setup.
+
+gdb_test "frame 1" ".* in setup .*" "set and check frame 1"
+
+# test name regexp matching all
+foreach cmd {
+    "info locals"
+    "info locals loc_arg_"
+    "info locals g"
+    "info locals -- .*" } {
+    gdb_test $cmd \
+	[multi_line \
+	     "loc_arg_c = 100 'd'" \
+	     "loc_arg_i = 3" \
+	     "loc_arg_j = 4" \
+	    ] \
+	"info locals"
+}
+
+# test name regexp or type regexp matching some
+foreach cmd {
+    "info locals -t int"
+    "info locals arg_[ij]"
+    "info locals loc_arg_[ij]"} {
+    gdb_test $cmd \
+	[multi_line \
+	     "loc_arg_i = 3" \
+	     "loc_arg_j = 4" \
+	    ] \
+	"info args"
+}
+
+gdb_test "info locals nowaythiscanmatch" "No matching locals." "Test non matching locals"
+gdb_test "info locals -q nowaythiscanmatch" "" "Test quiet non matching locals"
+gdb_test "info locals -q -t ganze_Zahl loc" "" "Test quiet non matching locals with a type"
-- 
2.18.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RFA 5/6] Announce changes in NEWS to info [args|functions|locals|variables]
  2018-07-05 21:37 [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
                   ` (2 preceding siblings ...)
  2018-07-05 21:37 ` [RFA 1/6] New cli-utils.h/.c function extract_info_print_args Philippe Waroquiers
@ 2018-07-05 21:37 ` Philippe Waroquiers
  2018-07-06  5:36   ` Eli Zaretskii
  2018-07-05 21:37 ` [RFA 6/6] Add a test case for info args|functions|locals|variables [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Philippe Waroquiers @ 2018-07-05 21:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Philippe Waroquiers

Announce changes in NEWS to info [args|functions|locals|variables]

gdb/ChangeLog
2018-07-05  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

        * NEWS: Mention changes to 'info [args|functions|locals|variables]'
---
 gdb/NEWS | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/gdb/NEWS b/gdb/NEWS
index 2d1d161233..1f94110ff0 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,17 @@
 
 *** Changes since GDB 8.2
 
+* Changed commands
+
+info args [-q] [-t TYPEREGEXP] [NAMEREGEXP]
+info functions [-q] [-t TYPEREGEXP] [NAMEREGEXP]
+info locals [-q] [-t TYPEREGEXP] [NAMEREGEXP]
+info variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]
+  These commands can now print only the searched entities
+  matching the provided regexp(s), giving a condition
+  on the entity names or entity types.  The flag -q
+  disables printing headers or informations messages.
+
 *** Changes in GDB 8.2
 
 * The 'set disassembler-options' command now supports specifying options
-- 
2.18.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFA 5/6] Announce changes in NEWS to info [args|functions|locals|variables]
  2018-07-05 21:37 ` [RFA 5/6] Announce changes in NEWS to info [args|functions|locals|variables] Philippe Waroquiers
@ 2018-07-06  5:36   ` Eli Zaretskii
  0 siblings, 0 replies; 10+ messages in thread
From: Eli Zaretskii @ 2018-07-06  5:36 UTC (permalink / raw)
  To: Philippe Waroquiers; +Cc: gdb-patches

> From: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Cc: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Date: Thu,  5 Jul 2018 23:37:16 +0200
> 
> Announce changes in NEWS to info [args|functions|locals|variables]
> 
> gdb/ChangeLog
> 2018-07-05  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
> 
>         * NEWS: Mention changes to 'info [args|functions|locals|variables]'

OK, thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFA 4/6] Document changes to info [args|functions|locals|variables]
  2018-07-05 21:37 ` [RFA 4/6] Document changes to info [args|functions|locals|variables] Philippe Waroquiers
@ 2018-07-06  5:37   ` Eli Zaretskii
  0 siblings, 0 replies; 10+ messages in thread
From: Eli Zaretskii @ 2018-07-06  5:37 UTC (permalink / raw)
  To: Philippe Waroquiers; +Cc: gdb-patches

> From: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Cc: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Date: Thu,  5 Jul 2018 23:37:15 +0200
> 
> Document changes to info [args|functions|locals|variables]
> 
> gdb/doc/ChangeLog
> 2018-07-05  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
> 
> 	* gdb.texinfo (Information About a Frame): Document changes to 'info args'

This line is too long, please wrap it before pushing.

> 	and 'info locals'.
> 	(Examining the Symbol Table): Document changes to 'info functions'
> 	and 'info variables'.
> ---
>  gdb/doc/gdb.texinfo | 121 +++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 109 insertions(+), 12 deletions(-)

Otherwise, this part is OK.  Thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP]
  2018-07-05 21:37 [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
                   ` (5 preceding siblings ...)
  2018-07-05 21:37 ` [RFA 4/6] Document changes to info [args|functions|locals|variables] Philippe Waroquiers
@ 2018-07-23 20:46 ` Philippe Waroquiers
  6 siblings, 0 replies; 10+ messages in thread
From: Philippe Waroquiers @ 2018-07-23 20:46 UTC (permalink / raw)
  To: gdb-patches

Ping ?

Thanks

Philippe

On Thu, 2018-07-05 at 23:37 +0200, Philippe Waroquiers wrote:
> This patch series adds flags and/or arguments
> [-q] [-t TYPEREGEXP] [NAMEREGEXP] to the commands
>   info [args|functions|locals|variables]
> 
> The additional arguments allow to more precisely specify what to print.
> This patch series does not depend on
> [RFA_v3 0/8] Implement 'frame apply COMMAND', enhance 'thread apply COMMAND'.
> However, the new features above can usefully be combined with
> frame apply and thread apply.
> So, the documentation gives examples combining the above
> and the 'thread apply' and 'frame apply' commands.
> 
> Some examples:
> * print functions returning an int:
>     info functions -t '^int ('
> * print local variables having pthread_t type
>     info locals -t pthread_t
> * print global variables having type 'struct addrinfo'
>     info var -t 'struct addrinfo'
> * print args that are likely file descriptors
>     info arg -t int .*fd.*
> 
> Below examples depends on the 'thread/frame apply' patch series.
> 
> * Assuming lock_something_t is an RAII type, show all locks:
>   thread apply all -s frame apply all -s info locals -q -t lock_something_t
>  or shorter equivalent:
>   tfaas i lo -q -t lock_something_t
> 
> * show frames and args having an arg with type matchin std::.*map
>   so likely  std::map or std::unordered_map
>   frame apply all -s info args -q std::.*map
> 
> 
> The code, documentation, NEWS, test and ChangeLog are (supposed to be) complete.
> 
> Compared to the RFC, the changes are:
> * All comments of Eli on the documentation have been handled.
> * ChangeLog entries added in commit messages
> * Test added.
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-07-23 20:46 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-05 21:37 [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
2018-07-05 21:37 ` [RFA 3/6] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers
2018-07-05 21:37 ` [RFA 2/6] Make struct type_print_options default_ptype_flags non static Philippe Waroquiers
2018-07-05 21:37 ` [RFA 1/6] New cli-utils.h/.c function extract_info_print_args Philippe Waroquiers
2018-07-05 21:37 ` [RFA 5/6] Announce changes in NEWS to info [args|functions|locals|variables] Philippe Waroquiers
2018-07-06  5:36   ` Eli Zaretskii
2018-07-05 21:37 ` [RFA 6/6] Add a test case for info args|functions|locals|variables [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
2018-07-05 21:37 ` [RFA 4/6] Document changes to info [args|functions|locals|variables] Philippe Waroquiers
2018-07-06  5:37   ` Eli Zaretskii
2018-07-23 20:46 ` [RFA 0/6] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).