diff -rupN src/gdb/data-directory/Makefile.in src_grep/gdb/data-directory/Makefile.in
--- src/gdb/data-directory/Makefile.in 2011-08-17 16:11:20.000000000 +0530
+++ src_grep/gdb/data-directory/Makefile.in 2011-12-11 17:38:40.851766467 +0530
@@ -58,7 +58,8 @@ PYTHON_FILES = \
gdb/prompt.py \
gdb/command/__init__.py \
gdb/command/pretty_printers.py \
- gdb/command/prompt.py
+ gdb/command/prompt.py \
+ gdb/command/grep.py
FLAGS_TO_PASS = \
"prefix=$(prefix)" \
diff -rupN src/gdb/python/lib/gdb/command/grep.py src_grep/gdb/python/lib/gdb/command/grep.py
--- src/gdb/python/lib/gdb/command/grep.py 1970-01-01 05:30:00.000000000 +0530
+++ src_grep/gdb/python/lib/gdb/command/grep.py 2012-01-02 10:20:07.565936926 +0530
@@ -0,0 +1,430 @@
+# GDB 'grep' command.
+# Copyright (C) 2012 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 .
+
+"""Implementation of the GDB 'grep' command using the GDB Python API"""
+
+from collections import deque
+import gdb
+import re
+
+class GrepBase(object):
+ """A base class for classes which can grep through values of a particular
+ type. See below for implementation of the different sub classes.
+ """
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """The method which should perform the actual grep action.
+ The sub classes should override this method to reflect the type specfic
+ grep operation.
+
+ Arguments:
+ regex: The regular expression to match names.
+ name: The name which has to be matched with the regular expression.
+ path: The path (as in the expression) to the current value.
+ value: The value to be grepped.
+ grep_field: A boolean value to indicate whether the field name
+ should be matched or not.
+ grep_value: A boolean value to indicate whether the value should be
+ matched or not.
+ """
+ print "Cannot yet grep through values of type %s." % str(value.type)
+
+
+class GrepScalar(GrepBase):
+ """A class to grep through values which are of a scalar type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of a scalar type.
+ See GrepBase.grep for more information.
+ """
+ if ((grep_field and re.search(regex, name)) or
+ (grep_value and re.search(regex, str(value)))):
+ print "%s = (%s) %s" % (path, str(value.type), str(value))
+
+
+class GrepPointer(GrepBase):
+ """A class to grep through values which are of a pointer type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of a pointer type.
+ See GrepBase.grep for more information.
+ """
+ if str(value.type.target().unqualified()) == "char":
+ try:
+ str_val = value.string()
+ if ((grep_field and re.search(regex, name)) or
+ (grep_value and re.search(regex, str_val))):
+ print "%s = (%s) \"%s\"" % (path, str(value.type), str_val)
+ return
+ except:
+ pass
+
+ if grep_field and re.search(regex, name):
+ print "%s = (%s) %s" % (path, str(value.type), str(value))
+
+ deref_value = None
+ try:
+ deref_value = value.dereference()
+ str(deref_value)
+ except RuntimeError:
+ return
+
+ self._grep_command.grep(
+ regex, name, "(*%s)" % path, deref_value, grep_field, grep_value)
+
+
+class GrepArray(GrepBase):
+ """A class to grep through values which are of an array type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of an array type.
+ See GrepBase.grep for more information.
+ """
+ if grep_field and re.search(regex, name):
+ print ("%s = " %
+ (path, str(value.type.target())))
+
+ if grep_value:
+ array_range = value.type.range()
+ for index in range(array_range[0], array_range[1] + 1):
+ self._grep_command.grep(regex,
+ name,
+ "%s[%d]" % (path, index),
+ value[index],
+ False,
+ True)
+
+
+class GrepStruct(GrepBase):
+ """A class to grep through values which are of a struct type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of a struct type.
+ See GrepBase.grep for more information.
+ """
+ if grep_field and re.search(regex, name):
+ print "%s = " % (path, str(value.type))
+
+ for field in value.type.fields():
+ self._grep_command.grep(regex,
+ field.name,
+ "%s.%s" % (path, field.name),
+ value[field.name],
+ grep_field,
+ grep_value)
+
+
+class GrepUnion(GrepBase):
+ """A class to grep through values which are of a union type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+ self._field_selector_list = [ ]
+
+ def register_field_selector(self, selector):
+ """Method with which one can register a field selector.
+
+ Arguments:
+ selector: The field selector. It should support a method with the
+ following signature:
+ get_field_name_matcher(value)
+ The argument 'value' is the union value which has to be
+ grepped. The method should return a regular expression
+ with which the field names of the union are matched. The
+ grep method greps through a field of the union only if
+ there is a match.
+ See the class AllFieldsSelector below as an example.
+ """
+ self._field_selector_list.append(selector)
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of a union type.
+ See GrepBase.grep for more information.
+ """
+ if grep_field and re.search(regex, name):
+ print "%s = " % (path, str(value.type))
+
+ for field_selector in self._field_selector_list:
+ field_matcher = field_selector.get_field_name_matcher(value)
+ if field_matcher:
+ for field in value.type.fields():
+ if re.search(field_matcher, field.name):
+ self._grep_command.grep(regex,
+ field.name,
+ "%s.%s" % (path, field.name),
+ value[field.name],
+ grep_field,
+ grep_value)
+ return
+
+
+class GrepTypedef(GrepBase):
+ """A class to grep through values which are of a typedef type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of a typdef type.
+ See GrepBase.grep for more information.
+ """
+ base_type_value = value.cast(value.type.strip_typedefs())
+ self._grep_command.grep(
+ regex, name, path, base_type_value, grep_field, grep_value)
+
+
+class GrepUtils(object):
+ """A class of utilities for implementing 'grep' and it's sub commands."""
+
+ @staticmethod
+ def parse_arg_str(arg_str):
+ """A function to help parse the arguments to 'grep' and its sub
+ commands.
+
+ Arguments:
+ arg_str: The argument string as passed to the 'grep' or its sub
+ commands.
+
+ Returns:
+ A 3-tuple of the form (regex, expr, value) where
+ i. regex is the regular expression passed to the command,
+ ii. expr is the expression whose value has to be 'grepped' with the
+ regex,
+ iii. value is the value of the expression.
+
+ Raises:
+ gdb.GdbError if insufficient arguments are provided in the argument
+ string, or if the expression given in the argument string does not
+ evaluate to any value in the current context.
+ """
+ args = gdb.string_to_argv(arg_str)
+ if len(args) < 2:
+ raise gdb.GdbError(
+ "ERROR: 'grep' and its sub commands need two arguments.")
+
+ regex = args[0]
+ expr = ""
+ for i in range(1, len(args) - 1):
+ expr += args[i] + " "
+ expr += args[len(args) - 1]
+
+ value = None
+ try:
+ value = gdb.parse_and_eval(expr)
+ except:
+ raise gdb.GdbError(
+ "ERROR: '%s' does not evaluate to any value in the current "
+ "context." % expr)
+
+ return (regex, expr, value)
+
+
+class GrepCommand(gdb.Command):
+ """Command to 'grep' for field names and values in expressions.
+
+ Usage: grep [OPTION] REGEX EXPR
+
+ OPTION - An optional argument which can be either 'field' or 'value'.
+ If it is 'value', then only values are matched with the REGEX. If it
+ is 'field', then only field names are matched with the REGEX.
+
+ REGEX - A regular expression in double quotes if it contains spaces.
+ EXPR - A valid expression in the current scope.
+
+ The command looks for values (of scalar, enum and string types) and field
+ names matching with the REGEX. It scans through the value of EXPR top-down
+ to look for matches. "Top-down" here means starting from the EXPR itself, to
+ the names and values of the fields (if any) of the type of the EXPR value,
+ and right down to the leaf scalar field names and values of these fields.
+ """
+
+ def __init__(self):
+ super(GrepCommand, self).__init__(name = "grep",
+ command_class = gdb.COMMAND_DATA,
+ prefix = True)
+ self.init_env()
+
+ def init_env(self):
+ """Initializes the internal environment of the command."""
+ self._type_to_greper_map = self._get_type_to_greper_map()
+ self._bfs_queue = deque([ ])
+
+ def register_union_field_selector(self, field_selector):
+ """Registers a field selector with the union grepper.
+ See GrepUnion.register_field_selector for more information.
+ """
+ self._type_to_greper_map[gdb.TYPE_CODE_UNION].register_field_selector(
+ field_selector)
+
+ def _get_type_to_greper_map(self):
+ """An internal method which returns type code to grepper map."""
+ return {
+ gdb.TYPE_CODE_PTR : GrepPointer(self),
+ gdb.TYPE_CODE_ARRAY : GrepArray(self),
+ gdb.TYPE_CODE_STRUCT : GrepStruct(self),
+ gdb.TYPE_CODE_UNION : GrepUnion(self),
+ gdb.TYPE_CODE_ENUM : GrepScalar(self),
+ gdb.TYPE_CODE_INT : GrepScalar(self),
+ gdb.TYPE_CODE_FLT : GrepScalar(self),
+ gdb.TYPE_CODE_CHAR : GrepScalar(self),
+ gdb.TYPE_CODE_BOOL : GrepScalar(self),
+ gdb.TYPE_CODE_TYPEDEF : GrepTypedef(self)
+ }
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """The function to request the 'grep' for a value or a field.
+
+ NOTE: One should invoke the 'start' function to beging the search.
+ """
+ self._bfs_queue.append(
+ (regex, name, path, value, grep_field, grep_value))
+
+ def start(self):
+ """The function which starts the search once a 'grep' has been requested.
+
+ It does something useful if invoked only after making a request with the
+ 'grep' function.
+ """
+ while len(self._bfs_queue) > 0:
+ (regex, name, path, value, grep_field, grep_value) = (
+ self._bfs_queue[0])
+
+ type_code = value.type.code
+ if type_code in self._type_to_greper_map:
+ greper = self._type_to_greper_map[type_code]
+ greper.grep(regex, name, path, value, grep_field, grep_value)
+
+ self._bfs_queue.popleft()
+
+ def invoke(self, arg_str, from_tty):
+ (regex, expr, value) = GrepUtils.parse_arg_str(arg_str)
+ self.grep(regex, expr, expr, value, True, True)
+ self.start()
+
+
+class GrepFieldCommand(GrepCommand):
+ """Command to 'grep' for field names in expressions.
+
+ Usage: grep field REGEX EXPR
+
+ REGEX is a regular expression in double quotes if it contains spaces.
+ EXPR is a valid expression in the current scope.
+
+ The command looks for field names matching with the REGEX. It scans through
+ the value of EXPR top-down to look for matches. "Top-down" here means
+ starting from the EXPR itself, to the names of the fields (if any) of the
+ type of the EXPR value, and right down to the leaf scalar field names of
+ these fields.
+ """
+
+ def __init__(self):
+ super(GrepCommand, self).__init__(name = "grep field",
+ command_class = gdb.COMMAND_DATA)
+ self.init_env()
+
+ def invoke(self, arg_str, from_tty):
+ (regex, expr, value) = GrepUtils.parse_arg_str(arg_str)
+ self.grep(regex, expr, expr, value, True, False)
+ self.start()
+
+
+class GrepValueCommand(GrepCommand):
+ """Command to 'grep' for field values in expressions.
+
+ Usage: grep value REGEX EXPR
+
+ REGEX is a regular expression in double quotes if it contains spaces.
+ EXPR is a valid expression in the current scope.
+
+ The command looks for values (of scalar, enum and string fields) matching
+ with the REGEX. It scans through the value of EXPR top-down
+ to look for matches. "Top-down" here means starting from the EXPR itself, to
+ the values of the fields (if any) of the type of the EXPR value, and right
+ down to the values of the leaf scalar fields of these fields.
+ """
+
+ def __init__(self):
+ super(GrepCommand, self).__init__(name = "grep value",
+ command_class = gdb.COMMAND_DATA)
+ self.init_env()
+
+ def invoke(self, arg_str, from_tty):
+ (regex, expr, value) = GrepUtils.parse_arg_str(arg_str)
+ self.grep(regex, expr, expr, value, False, True)
+ self.start()
+
+
+gc = GrepCommand()
+gfc = GrepFieldCommand()
+gvc = GrepValueCommand()
+
+class AllFieldsSelector(object):
+ """A union field selector which selects all fields.
+ It is defined here as an example and for testing purposes.
+
+ See GrepUnion.register_field_selector for more information.
+ """
+
+ def get_field_name_matcher(self, value):
+ """Returns an all matching regular expression."""
+ return ".*"
+
+def register_union_field_selector(field_selector):
+ gc.register_union_field_selector(field_selector)
+ gfc.register_union_field_selector(field_selector)
+ gvc.register_union_field_selector(field_selector)
diff -rupN src/gdb/testsuite/gdb.python/Makefile.in src_grep/gdb/testsuite/gdb.python/Makefile.in
--- src/gdb/testsuite/gdb.python/Makefile.in 2011-05-16 19:26:40.000000000 +0530
+++ src_grep/gdb/testsuite/gdb.python/Makefile.in 2011-12-11 17:40:06.341794630 +0530
@@ -4,7 +4,8 @@ srcdir = @srcdir@
EXECUTABLES = py-type py-value py-prettyprint py-template py-block \
py-symbol py-mi py-breakpoint py-inferior py-infthread \
py-shared python lib-types py-events py-evthreads py-frame \
- py-mi py-pp-maint py-progspace py-section-script py-objfile
+ py-mi py-pp-maint py-progspace py-section-script py-objfile \
+ py-grep
MISCELLANEOUS = py-shared-sl.sl
diff -rupN src/gdb/testsuite/gdb.python/py-grep.c src_grep/gdb/testsuite/gdb.python/py-grep.c
--- src/gdb/testsuite/gdb.python/py-grep.c 1970-01-01 05:30:00.000000000 +0530
+++ src_grep/gdb/testsuite/gdb.python/py-grep.c 2011-12-31 11:29:58.342047729 +0530
@@ -0,0 +1,79 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2012 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 .
+*/
+
+struct SimpleStruct
+{
+ int int_val;
+ double double_val;
+};
+
+struct ComplexStruct_1
+{
+ struct SimpleStruct ss;
+ char* str_val;
+};
+
+struct ComplexStruct_2
+{
+ struct ComplexStruct_1 cs1;
+ int int_array[10];
+ int* int_ptr;
+};
+
+union UnionOfStructs
+{
+ struct SimpleStruct ss;
+ struct ComplexStruct_1 cs1;
+ struct ComplexStruct_2 cs2;
+};
+
+typedef union UnionOfStructs TheType;
+
+int
+main (void)
+{
+ int i;
+ char* str_val = "I am a string";
+ char char_array[] =
+ { 'n', 'o', 't', ' ' , 'a' , ' ', 's', 't', 'r', 'i', 'n', 'g' };
+
+ char* ptr_to_char_array = char_array;
+
+ struct SimpleStruct ss;
+ ss.int_val = 10;
+ ss.double_val = 1.11;
+
+ struct ComplexStruct_1 cs1;
+ cs1.ss = ss;
+ cs1.str_val = "embedded string value";
+
+ struct ComplexStruct_2 cs2;
+ cs2.cs1 = cs1;
+ cs2.int_ptr = &i;
+ for (i = 0; i < 10; i++)
+ {
+ cs2.int_array[i] = i;
+ }
+
+ union UnionOfStructs us;
+ us.cs2 = cs2;
+
+ TheType* tt = &us;
+
+ return 0; /* Break here. */
+}
diff -rupN src/gdb/testsuite/gdb.python/py-grep.exp src_grep/gdb/testsuite/gdb.python/py-grep.exp
--- src/gdb/testsuite/gdb.python/py-grep.exp 1970-01-01 05:30:00.000000000 +0530
+++ src_grep/gdb/testsuite/gdb.python/py-grep.exp 2011-12-31 11:30:19.782050107 +0530
@@ -0,0 +1,85 @@
+# Copyright (C) 2012 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 .
+
+# This file is part of the GDB testsuite. It tests the command 'grep'
+# which is implemented using the GDB-Python API.
+
+load_lib gdb-python.exp
+
+set testfile "py-grep"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+ return -1
+}
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+if ![runto_main] {
+ return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "Break here."]
+gdb_continue_to_breakpoint "Break here" ".*Break here.*"
+
+gdb_test "python gdb.command.grep.register_union_field_selector(gdb.command.grep.AllFieldsSelector())" ""
+
+gdb_test "grep i i" "i = \\(int\\) 10"
+
+gdb_test "grep str str_val" "str_val = \\(char \\*\\) \"I am a string\""
+
+gdb_test "grep s char_array" "char_array\\\[6\\\] = \\(char\\) 115 's'"
+
+gdb_test "grep not ptr_to_char_array" "ptr_to_char_array = \\(char \\*\\) \"not a string\""
+
+set ss_int "ss\\.int_val = \\(int\\) 10"
+set ss_double "ss\\.double_val = \\(double\\) 1\\.1.*"
+gdb_test "grep \"val\" ss" "(($ss_int\[\\n\\r\]*)|($ss_double\[\\n\\r\]*))+"
+
+gdb_test "grep value \"^10$\" ss" "$ss_int"
+
+set cs1_ss_int "cs1\\.$ss_int"
+set cs1_ss_double "cs1\\.$ss_double"
+set cs1_str "cs1\\.str_val = \\(char \\*\\) \"embedded string value\""
+gdb_test "grep field val cs1" "(($cs1_ss_int\[\\n\\r\]*)|($cs1_ss_double\[\\n\\r\]*)|($cs1_str\[\\n\\r\]*))+"
+gdb_test "grep value val cs1" "$cs1_str"
+
+set cs2_cs1_ss_int "cs2\\.$cs1_ss_int"
+set cs2_int_ptr "\\*\\(cs2\\.int_ptr\\) = \\(int\\) 10"
+gdb_test "grep \"^10$\" cs2" "(($cs2_cs1_ss_int\[\\n\\r\]*)|($cs2_int_ptr\[\\n\\r\]*))+"
+gdb_test "grep \"^9$\" cs2" "cs2\\.int_array\\\[9\\\] = \\(int\\) 9"
+
+set us_val1 "us\\.$ss_int"
+set us_val2 "us\\.$ss_double"
+set us_val3 "us\\.$cs1_str"
+set us_val4 "us\\.$cs1_ss_int"
+set us_val5 "us\\.$cs1_ss_double"
+set us_val6 "us\\.cs2\\.$cs1_str"
+set us_val7 "us\\.cs2\\.$cs1_ss_int"
+set us_val8 "us\\.cs2\\.$cs1_ss_double"
+gdb_test "grep field val us" "(($us_val1\[\\n\\r\]*)|($us_val2\[\\n\\r\]*)|($us_val3\[\\n\\r\]*)|($us_val4\[\\n\\r\]*)|($us_val5\[\\n\\r\]*)|($us_val6\[\\n\\r\]*)|($us_val7\[\\n\\r\]*)|($us_val8\[\\n\\r\]*))+"
+gdb_test "grep value val us" "(($us_val3\[\\n\\r\]*)|($us_val6\[\\n\\r\]*))+"
+
+set tt_val1 "\\(\\*tt\\)\\.$ss_int"
+set tt_val2 "\\(\\*tt\\)\\.$ss_double"
+set tt_val3 "\\(\\*tt\\)\\.$cs1_str"
+set tt_val4 "\\(\\*tt\\)\\.$cs1_ss_int"
+set tt_val5 "\\(\\*tt\\)\\.$cs1_ss_double"
+set tt_val6 "\\(\\*tt\\)\\.cs2\\.$cs1_str"
+set tt_val7 "\\(\\*tt\\)\\.cs2\\.$cs1_ss_int"
+set tt_val8 "\\(\\*tt\\)\\.cs2\\.$cs1_ss_double"
+gdb_test "grep field val tt" "(($tt_val1\[\\n\\r\]*)|($tt_val2\[\\n\\r\]*)|($tt_val3\[\\n\\r\]*)|($tt_val4\[\\n\\r\]*)|($tt_val5\[\\n\\r\]*)|($tt_val6\[\\n\\r\]*)|($tt_val7\[\\n\\r\]*)|($tt_val8\[\\n\\r\]*))+"
+gdb_test "grep value val tt" "(($tt_val3\[\\n\\r\]*)|($tt_val6\[\\n\\r\]*))+"