[Lldb-commits] [lldb] r116178 - in /lldb/trunk: include/lldb/Core/RegularExpression.h include/lldb/Symbol/VariableList.h source/Commands/CommandObjectFrame.cpp source/Core/RegularExpression.cpp source/Symbol/VariableList.cpp
Greg Clayton
gclayton at apple.com
Sun Oct 10 16:55:27 PDT 2010
Author: gclayton
Date: Sun Oct 10 18:55:27 2010
New Revision: 116178
URL: http://llvm.org/viewvc/llvm-project?rev=116178&view=rev
Log:
Added the ability to get error strings back from failed
lldb_private::RegularExpression compiles and matches with:
size_t
RegularExpression::GetErrorAsCString (char *err_str,
size_t err_str_max_len) const;
Added the ability to search a variable list for variables whose names match
a regular expression:
size_t
VariableList::AppendVariablesIfUnique (const RegularExpression& regex,
VariableList &var_list,
size_t& total_matches);
Also added the ability to append a variable to a VariableList only if it is
not already in the list:
bool
VariableList::AddVariableIfUnique (const lldb::VariableSP &var_sp);
Cleaned up the "frame variable" command:
- Removed the "-n NAME" option as this is the default way for the command to
work.
- Enable uniqued regex searches on variable names by fixing the "--regex RE"
command to work correctly. It will match all variables that match any
regular expressions and only print each variable the first time it matches.
- Fixed the option type for the "--regex" command to by eArgTypeRegularExpression
instead of eArgTypeCount
Modified:
lldb/trunk/include/lldb/Core/RegularExpression.h
lldb/trunk/include/lldb/Symbol/VariableList.h
lldb/trunk/source/Commands/CommandObjectFrame.cpp
lldb/trunk/source/Core/RegularExpression.cpp
lldb/trunk/source/Symbol/VariableList.cpp
Modified: lldb/trunk/include/lldb/Core/RegularExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RegularExpression.h?rev=116178&r1=116177&r2=116178&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/RegularExpression.h (original)
+++ lldb/trunk/include/lldb/Core/RegularExpression.h Sun Oct 10 18:55:27 2010
@@ -115,6 +115,9 @@
bool
Execute (const char* string, size_t match_count = 0, int execute_flags = 0) const;
+ size_t
+ GetErrorAsCString (char *err_str, size_t err_str_max_len) const;
+
bool
GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const;
//------------------------------------------------------------------
Modified: lldb/trunk/include/lldb/Symbol/VariableList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/VariableList.h?rev=116178&r1=116177&r2=116178&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/VariableList.h (original)
+++ lldb/trunk/include/lldb/Symbol/VariableList.h Sun Oct 10 18:55:27 2010
@@ -29,8 +29,11 @@
void
AddVariable (const lldb::VariableSP &var_sp);
+ bool
+ AddVariableIfUnique (const lldb::VariableSP &var_sp);
+
void
- AddVariables(VariableList *variable_list);
+ AddVariables (VariableList *variable_list);
void
Clear();
@@ -45,6 +48,19 @@
FindVariable (const ConstString& name);
uint32_t
+ FindVariableIndex (const lldb::VariableSP &var_sp);
+
+ // Returns the actual number of unique variables that were added to the
+ // list. "total_matches" will get updated with the actualy number of
+ // matches that were found regardless of whether they were unique or not
+ // to allow for error conditions when nothing is found, versus conditions
+ // where any varaibles that match "regex" were already in "var_list".
+ size_t
+ AppendVariablesIfUnique (const RegularExpression& regex,
+ VariableList &var_list,
+ size_t& total_matches);
+
+ uint32_t
FindIndexForVariable (Variable* variable);
size_t
Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=116178&r1=116177&r2=116178&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Sun Oct 10 18:55:27 2010
@@ -309,7 +309,6 @@
switch (short_option)
{
case 'o': use_objc = true; break;
- case 'n': name = option_arg; break;
case 'r': use_regex = true; break;
case 'a': show_args = false; break;
case 'l': show_locals = false; break;
@@ -352,7 +351,6 @@
{
Options::ResetOptionValues();
- name.clear();
use_objc = false;
use_regex = false;
show_args = true;
@@ -378,7 +376,6 @@
// Options table: Required for subclasses of Options.
static lldb::OptionDefinition g_option_table[];
- std::string name;
bool use_objc:1,
use_regex:1,
show_args:1,
@@ -520,168 +517,230 @@
{
if (command.GetArgumentCount() > 0)
{
+ VariableList regex_var_list;
+
// If we have any args to the variable command, we will make
// variable objects from them...
for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != NULL; ++idx)
{
uint32_t ptr_depth = m_options.ptr_depth;
- // If first character is a '*', then show pointer contents
- if (name_cstr[0] == '*')
+
+ if (m_options.use_regex)
{
- ++ptr_depth;
- name_cstr++; // Skip the '*'
+ const uint32_t regex_start_index = regex_var_list.GetSize();
+ RegularExpression regex (name_cstr);
+ if (regex.Compile(name_cstr))
+ {
+ size_t num_matches = 0;
+ const size_t num_new_regex_vars = variable_list->AppendVariablesIfUnique(regex, regex_var_list, num_matches);
+ if (num_new_regex_vars > 0)
+ {
+ for (uint32_t regex_idx = regex_start_index, end_index = regex_var_list.GetSize();
+ regex_idx < end_index;
+ ++regex_idx)
+ {
+ var_sp = regex_var_list.GetVariableAtIndex (regex_idx);
+ if (var_sp)
+ {
+ valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp);
+ if (valobj_sp)
+ {
+ if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
+ {
+ var_sp->GetDeclaration ().DumpStopContext (&s, false);
+ s.PutCString (": ");
+ }
+
+ ValueObject::DumpValueObject (result.GetOutputStream(),
+ exe_ctx.frame,
+ valobj_sp.get(),
+ var_sp->GetName().AsCString(),
+ m_options.ptr_depth,
+ 0,
+ m_options.max_depth,
+ m_options.show_types,
+ m_options.show_location,
+ m_options.use_objc,
+ false);
+ s.EOL();
+ }
+ }
+ }
+ }
+ else if (num_matches == 0)
+ {
+ result.GetErrorStream().Printf ("error: no variables matched the regular expression '%s'.\n", name_cstr);
+ }
+ }
+ else
+ {
+ char regex_error[1024];
+ if (regex.GetErrorAsCString(regex_error, sizeof(regex_error)))
+ result.GetErrorStream().Printf ("error: %s\n", regex_error);
+ else
+ result.GetErrorStream().Printf ("error: unkown regex error when compiling '%s'\n", name_cstr);
+ }
}
-
- std::string var_path (name_cstr);
- size_t separator_idx = var_path.find_first_of(".-[");
-
- ConstString name_const_string;
- if (separator_idx == std::string::npos)
- name_const_string.SetCString (var_path.c_str());
else
- name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
-
- var_sp = variable_list->FindVariable(name_const_string);
- if (var_sp)
{
- valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp);
+ // If first character is a '*', then show pointer contents
+ if (name_cstr[0] == '*')
+ {
+ ++ptr_depth;
+ name_cstr++; // Skip the '*'
+ }
- var_path.erase (0, name_const_string.GetLength ());
- // We are dumping at least one child
- while (separator_idx != std::string::npos)
+ std::string var_path (name_cstr);
+ size_t separator_idx = var_path.find_first_of(".-[");
+
+ ConstString name_const_string;
+ if (separator_idx == std::string::npos)
+ name_const_string.SetCString (var_path.c_str());
+ else
+ name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
+
+ var_sp = variable_list->FindVariable(name_const_string);
+ if (var_sp)
{
- // Calculate the next separator index ahead of time
- ValueObjectSP child_valobj_sp;
- const char separator_type = var_path[0];
- switch (separator_type)
- {
+ valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp);
- case '-':
- if (var_path.size() >= 2 && var_path[1] != '>')
- {
- result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n",
- var_path.c_str());
- var_path.clear();
- valobj_sp.reset();
- break;
- }
- var_path.erase (0, 1); // Remove the '-'
- // Fall through
- case '.':
+ var_path.erase (0, name_const_string.GetLength ());
+ // We are dumping at least one child
+ while (separator_idx != std::string::npos)
+ {
+ // Calculate the next separator index ahead of time
+ ValueObjectSP child_valobj_sp;
+ const char separator_type = var_path[0];
+ switch (separator_type)
{
- var_path.erase (0, 1); // Remove the '.' or '>'
- separator_idx = var_path.find_first_of(".-[");
- ConstString child_name;
- if (separator_idx == std::string::npos)
- child_name.SetCString (var_path.c_str());
- else
- child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
- child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
- if (!child_valobj_sp)
+ case '-':
+ if (var_path.size() >= 2 && var_path[1] != '>')
{
- result.GetErrorStream().Printf ("error: can't find child of '%s' named '%s'\n",
- valobj_sp->GetName().AsCString(),
- child_name.GetCString());
+ result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n",
+ var_path.c_str());
var_path.clear();
valobj_sp.reset();
break;
}
- // Remove the child name from the path
- var_path.erase(0, child_name.GetLength());
- }
- break;
-
- case '[':
- // Array member access, or treating pointer as an array
- if (var_path.size() > 2) // Need at least two brackets and a number
- {
- char *end = NULL;
- int32_t child_index = ::strtol (&var_path[1], &end, 0);
- if (end && *end == ']')
+ var_path.erase (0, 1); // Remove the '-'
+ // Fall through
+ case '.':
{
-
- if (valobj_sp->IsPointerType ())
- {
- child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
- }
+ var_path.erase (0, 1); // Remove the '.' or '>'
+ separator_idx = var_path.find_first_of(".-[");
+ ConstString child_name;
+ if (separator_idx == std::string::npos)
+ child_name.SetCString (var_path.c_str());
else
- {
- child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
- }
+ child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
+ child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
if (!child_valobj_sp)
{
- result.GetErrorStream().Printf ("error: invalid array index %u in '%s'\n",
- child_index,
- valobj_sp->GetName().AsCString());
+ result.GetErrorStream().Printf ("error: can't find child of '%s' named '%s'\n",
+ valobj_sp->GetName().AsCString(),
+ child_name.GetCString());
var_path.clear();
valobj_sp.reset();
break;
}
+ // Remove the child name from the path
+ var_path.erase(0, child_name.GetLength());
+ }
+ break;
- // Erase the array member specification '[%i]' where %i is the array index
- var_path.erase(0, (end - var_path.c_str()) + 1);
- separator_idx = var_path.find_first_of(".-[");
+ case '[':
+ // Array member access, or treating pointer as an array
+ if (var_path.size() > 2) // Need at least two brackets and a number
+ {
+ char *end = NULL;
+ int32_t child_index = ::strtol (&var_path[1], &end, 0);
+ if (end && *end == ']')
+ {
- // Break out early from the switch since we were able to find the child member
- break;
+ if (valobj_sp->IsPointerType ())
+ {
+ child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
+ }
+ else
+ {
+ child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
+ }
+
+ if (!child_valobj_sp)
+ {
+ result.GetErrorStream().Printf ("error: invalid array index %u in '%s'\n",
+ child_index,
+ valobj_sp->GetName().AsCString());
+ var_path.clear();
+ valobj_sp.reset();
+ break;
+ }
+
+ // Erase the array member specification '[%i]' where %i is the array index
+ var_path.erase(0, (end - var_path.c_str()) + 1);
+ separator_idx = var_path.find_first_of(".-[");
+
+ // Break out early from the switch since we were able to find the child member
+ break;
+ }
}
- }
- result.GetErrorStream().Printf ("error: invalid array member specification for '%s' starting at '%s'\n",
- valobj_sp->GetName().AsCString(),
- var_path.c_str());
- var_path.clear();
- valobj_sp.reset();
- break;
+ result.GetErrorStream().Printf ("error: invalid array member specification for '%s' starting at '%s'\n",
+ valobj_sp->GetName().AsCString(),
+ var_path.c_str());
+ var_path.clear();
+ valobj_sp.reset();
+ break;
- break;
+ break;
- default:
- result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n",
- var_path.c_str());
- var_path.clear();
- valobj_sp.reset();
- separator_idx = std::string::npos;
- break;
- }
+ default:
+ result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n",
+ var_path.c_str());
+ var_path.clear();
+ valobj_sp.reset();
+ separator_idx = std::string::npos;
+ break;
+ }
- if (child_valobj_sp)
- valobj_sp = child_valobj_sp;
+ if (child_valobj_sp)
+ valobj_sp = child_valobj_sp;
- if (var_path.empty())
- break;
+ if (var_path.empty())
+ break;
- }
+ }
- if (valobj_sp)
- {
- if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
+ if (valobj_sp)
{
- var_sp->GetDeclaration ().DumpStopContext (&s, false);
- s.PutCString (": ");
- }
+ if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
+ {
+ var_sp->GetDeclaration ().DumpStopContext (&s, false);
+ s.PutCString (": ");
+ }
- ValueObject::DumpValueObject (result.GetOutputStream(),
- exe_ctx.frame,
- valobj_sp.get(),
- name_cstr,
- ptr_depth,
- 0,
- m_options.max_depth,
- m_options.show_types,
- m_options.show_location,
- m_options.use_objc,
- false);
+ ValueObject::DumpValueObject (result.GetOutputStream(),
+ exe_ctx.frame,
+ valobj_sp.get(),
+ name_cstr,
+ ptr_depth,
+ 0,
+ m_options.max_depth,
+ m_options.show_types,
+ m_options.show_location,
+ m_options.use_objc,
+ false);
- s.EOL();
+ s.EOL();
+ }
+ }
+ else
+ {
+ result.GetErrorStream().Printf ("error: unable to find any variables named '%s'\n", name_cstr);
+ var_path.clear();
}
- }
- else
- {
- result.GetErrorStream().Printf ("error: unable to find any variables named '%s'\n", name_cstr);
- var_path.clear();
}
}
}
@@ -782,7 +841,6 @@
{ LLDB_OPT_SET_1, false, "find-global",'G', required_argument, NULL, 0, eArgTypeVarName, "Find a global variable by name (which might not be in the current stack frame source file)."},
{ LLDB_OPT_SET_1, false, "location", 'L', no_argument, NULL, 0, eArgTypeNone, "Show variable location information."},
{ LLDB_OPT_SET_1, false, "show-declaration", 'c', no_argument, NULL, 0, eArgTypeNone, "Show variable declaration information (source file and line where the variable was declared)."},
-{ LLDB_OPT_SET_1, false, "name", 'n', required_argument, NULL, 0, eArgTypeVarName, "Lookup a variable by name or regex (--regex) for the current execution context."},
{ LLDB_OPT_SET_1, false, "no-args", 'a', no_argument, NULL, 0, eArgTypeNone, "Omit function arguments."},
{ LLDB_OPT_SET_1, false, "no-locals", 'l', no_argument, NULL, 0, eArgTypeNone, "Omit local variables."},
{ LLDB_OPT_SET_1, false, "no-types", 't', no_argument, NULL, 0, eArgTypeNone, "Omit variable type names."},
@@ -790,7 +848,7 @@
{ LLDB_OPT_SET_1, false, "scope", 's', no_argument, NULL, 0, eArgTypeNone, "Show variable scope (argument, local, global, static)."},
{ LLDB_OPT_SET_1, false, "objc", 'o', no_argument, NULL, 0, eArgTypeNone, "When looking up a variable by name (--name), print as an Objective-C object."},
{ LLDB_OPT_SET_1, false, "ptr-depth", 'p', required_argument, NULL, 0, eArgTypeCount, "The number of pointers to be traversed when dumping values (default is zero)."},
-{ LLDB_OPT_SET_1, false, "regex", 'r', no_argument, NULL, 0, eArgTypeCount, "The <name> argument for name lookups are regular expressions."},
+{ LLDB_OPT_SET_1, false, "regex", 'r', no_argument, NULL, 0, eArgTypeRegularExpression, "The <variable-name> argument for name lookups are regular expressions."},
{ 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
};
#pragma mark CommandObjectMultiwordFrame
Modified: lldb/trunk/source/Core/RegularExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/RegularExpression.cpp?rev=116178&r1=116177&r2=116178&view=diff
==============================================================================
--- lldb/trunk/source/Core/RegularExpression.cpp (original)
+++ lldb/trunk/source/Core/RegularExpression.cpp Sun Oct 10 18:55:27 2010
@@ -153,3 +153,18 @@
m_comp_err = 1;
}
}
+
+size_t
+RegularExpression::GetErrorAsCString (char *err_str, size_t err_str_max_len) const
+{
+ if (m_comp_err == 0)
+ {
+ if (err_str && err_str_max_len)
+ *err_str = '\0';
+ return 0;
+ }
+
+ return ::regerror (m_comp_err, &m_preg, err_str, err_str_max_len);
+}
+
+
Modified: lldb/trunk/source/Symbol/VariableList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/VariableList.cpp?rev=116178&r1=116177&r2=116178&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/VariableList.cpp (original)
+++ lldb/trunk/source/Symbol/VariableList.cpp Sun Oct 10 18:55:27 2010
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "lldb/Symbol/VariableList.h"
+
+#include "lldb/Core/RegularExpression.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -30,13 +32,22 @@
{
}
-
void
-VariableList::AddVariable(const VariableSP &variable_sp)
+VariableList::AddVariable(const VariableSP &var_sp)
{
- m_variables.push_back(variable_sp);
+ m_variables.push_back(var_sp);
}
+bool
+VariableList::AddVariableIfUnique (const lldb::VariableSP &var_sp)
+{
+ if (FindVariableIndex (var_sp) == UINT32_MAX)
+ {
+ m_variables.push_back(var_sp);
+ return true;
+ }
+ return false;
+}
void
VariableList::AddVariables(VariableList *variable_list)
@@ -46,25 +57,32 @@
back_inserter(m_variables)); // destination
}
-
void
VariableList::Clear()
{
m_variables.clear();
}
-
-
VariableSP
VariableList::GetVariableAtIndex(uint32_t idx)
{
- VariableSP variable_sp;
+ VariableSP var_sp;
if (idx < m_variables.size())
- variable_sp = m_variables[idx];
- return variable_sp;
+ var_sp = m_variables[idx];
+ return var_sp;
}
-
+uint32_t
+VariableList::FindVariableIndex (const VariableSP &var_sp)
+{
+ iterator pos, end = m_variables.end();
+ for (pos = m_variables.begin(); pos != end; ++pos)
+ {
+ if (pos->get() == var_sp.get())
+ return std::distance (m_variables.begin(), pos);
+ }
+ return UINT32_MAX;
+}
VariableSP
VariableList::FindVariable(const ConstString& name)
@@ -82,6 +100,25 @@
return var_sp;
}
+size_t
+VariableList::AppendVariablesIfUnique (const RegularExpression& regex, VariableList &var_list, size_t& total_matches)
+{
+ const size_t initial_size = var_list.GetSize();
+ iterator pos, end = m_variables.end();
+ for (pos = m_variables.begin(); pos != end; ++pos)
+ {
+ if (regex.Execute ((*pos)->GetName().AsCString()))
+ {
+ // Note the total matches found
+ total_matches++;
+ // Only add this variable if it isn't already in the "var_list"
+ var_list.AddVariableIfUnique (*pos);
+ }
+ }
+ // Return the number of new unique variables added to "var_list"
+ return var_list.GetSize() - initial_size;
+}
+
uint32_t
VariableList::FindIndexForVariable (Variable* variable)
{
@@ -113,7 +150,6 @@
return m_variables.size();
}
-
void
VariableList::Dump(Stream *s, bool show_context) const
{
More information about the lldb-commits
mailing list