From: Siva Chandra <sivachandra@google.com>
To: gdb-patches@sourceware.org
Subject: [RFC] A new command 'grep'
Date: Mon, 02 Jan 2012 05:01:00 -0000 [thread overview]
Message-ID: <CAGyQ6gwb0X8KTN8bzWKxzhCyTwN=zhjB=tuz1BNW-TX_KN-TyA@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 2163 bytes --]
Hi all,
Attached is a patch which implements a 'grep' command using the GDB
Python API. The idea behind the 'grep' command is as follows. We often
have deep data structures and are probably interested in some one
particular field or value embedded somewhere deep in that data
structure. For such cases, instead of typing the complete expression
for the field, we can use the 'grep' command to lookup the field or
value of interest. A simple example is as follows:
struct SimpleStruct
{
int int_val;
double double_val;
};
struct SimpleStruct ss;
ss.int_val = 10;
ss.double_val = 1.11;
Examples of grepping for fields:
(gdb) grep int ss
ss.int_val = (int) 10
(gdb) grep dou ss
ss.double_val = (double) 1.11
Examples of grepping for values:
(gdb) grep 10 ss
ss.int_val = (int) 10
(gdb) grep "1\\." ss
ss.double_val = (double) 1.11
In general, one can grep for any matching regular expression in any
valid expression. Few points to note:
1. To restrict searches to values or fields, one can use the sub
commands 'grep value' or 'grep field' respectively.
2. The value grep looks for matches in scalar and string values only.
3. The search goes as deep as the data structure of the expression
with one exception; It does not grep through union values unless it
finds a field selector for that union value. A field selector is a
user defined class with a specific interface which helps the grep
command select the appropriate field of the union to grep through. The
patch includes a field selector, which selects all fields, as an
example.
Thanks,
Siva Chandra
2012-01-02 Siva Chandra <sivachandra@google.com>
New command 'grep' which helps to grep through field names and values
of expressions in scope.
* data-directory/Makefile.in: Add gdb/command/grep.py
* python/lib/gdb/command/grep.py: Implemention of the 'grep'
command using the GDB Python API.
* testsuite/gdb.python/Makefile.in: Add py-grep to EXECUTABLES
* testsuite/gdb.python/py-grep.c: C program used for testing
the new 'grep' command.
* testsuite/gdb-python/py-grep.exp: Tests for the new 'grep'
command.
[-- Attachment #2: grep_command_patch_v1.txt --]
[-- Type: text/plain, Size: 24452 bytes --]
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 <http://www.gnu.org/licenses/>.
+
+"""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 = <array of elements of type '%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 = <value of type '%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 = <value of type '%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 <http://www.gnu.org/licenses/>.
+*/
+
+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 <http://www.gnu.org/licenses/>.
+
+# 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\]*))+"
next reply other threads:[~2012-01-02 5:01 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-02 5:01 Siva Chandra [this message]
2012-01-02 8:54 ` Eli Zaretskii
2012-01-02 9:28 ` Kevin Pouget
2012-01-02 9:35 ` Abhijit Halder
2012-01-02 10:17 ` Siva Chandra
2012-01-02 17:44 ` Doug Evans
2012-01-03 6:02 ` Siva Chandra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAGyQ6gwb0X8KTN8bzWKxzhCyTwN=zhjB=tuz1BNW-TX_KN-TyA@mail.gmail.com' \
--to=sivachandra@google.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox