2010-06-09 00:52:24 +08:00
//===-- CommandObject.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
# include "lldb/Interpreter/CommandObject.h"
# include <map>
2016-09-07 04:57:50 +08:00
# include <sstream>
# include <string>
2010-06-09 00:52:24 +08:00
# include <ctype.h>
2016-09-07 04:57:50 +08:00
# include <stdlib.h>
2010-06-09 00:52:24 +08:00
# include "lldb/Core/Address.h"
2010-06-16 03:49:27 +08:00
# include "lldb/Interpreter/Options.h"
2017-11-14 00:16:33 +08:00
# include "lldb/Utility/ArchSpec.h"
2010-06-09 00:52:24 +08:00
// These are for the Sourcename completers.
// FIXME: Make a separate file for the completers.
# include "lldb/Core/FileSpecList.h"
2015-03-04 07:11:11 +08:00
# include "lldb/DataFormatters/FormatManager.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Target/Process.h"
# include "lldb/Target/Target.h"
2017-03-23 02:40:07 +08:00
# include "lldb/Utility/FileSpec.h"
2010-06-09 00:52:24 +08:00
2015-09-02 09:06:46 +08:00
# include "lldb/Target/Language.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Interpreter/CommandInterpreter.h"
# include "lldb/Interpreter/CommandReturnObject.h"
using namespace lldb ;
using namespace lldb_private ;
//-------------------------------------------------------------------------
// CommandObject
//-------------------------------------------------------------------------
2016-10-06 05:14:38 +08:00
CommandObject : : CommandObject ( CommandInterpreter & interpreter , llvm : : StringRef name ,
llvm : : StringRef help , llvm : : StringRef syntax , uint32_t flags )
: m_interpreter ( interpreter ) , m_cmd_name ( name ) ,
2016-09-07 04:57:50 +08:00
m_cmd_help_short ( ) , m_cmd_help_long ( ) , m_cmd_syntax ( ) , m_flags ( flags ) ,
m_arguments ( ) , m_deprecated_command_override_callback ( nullptr ) ,
m_command_override_callback ( nullptr ) , m_command_override_baton ( nullptr ) {
2016-10-06 05:14:38 +08:00
m_cmd_help_short = help ;
m_cmd_syntax = syntax ;
2010-06-09 00:52:24 +08:00
}
2016-09-07 04:57:50 +08:00
CommandObject : : ~ CommandObject ( ) { }
2010-06-09 00:52:24 +08:00
2016-11-13 04:41:02 +08:00
llvm : : StringRef CommandObject : : GetHelp ( ) { return m_cmd_help_short ; }
llvm : : StringRef CommandObject : : GetHelpLong ( ) { return m_cmd_help_long ; }
llvm : : StringRef CommandObject : : GetSyntax ( ) {
2017-07-25 06:52:39 +08:00
if ( ! m_cmd_syntax . empty ( ) )
2016-11-13 04:41:02 +08:00
return m_cmd_syntax ;
StreamString syntax_str ;
syntax_str . PutCString ( GetCommandName ( ) ) ;
if ( ! IsDashDashCommand ( ) & & GetOptions ( ) ! = nullptr )
syntax_str . PutCString ( " <cmd-options> " ) ;
if ( ! m_arguments . empty ( ) ) {
syntax_str . PutCString ( " " ) ;
if ( ! IsDashDashCommand ( ) & & WantsRawCommandString ( ) & & GetOptions ( ) & &
GetOptions ( ) - > NumCommandOptions ( ) )
syntax_str . PutCString ( " -- " ) ;
GetFormattedCommandArguments ( syntax_str ) ;
2016-09-07 04:57:50 +08:00
}
2016-11-17 05:15:24 +08:00
m_cmd_syntax = syntax_str . GetString ( ) ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
2016-11-13 04:41:02 +08:00
return m_cmd_syntax ;
2010-06-09 00:52:24 +08:00
}
2016-10-06 05:14:38 +08:00
llvm : : StringRef CommandObject : : GetCommandName ( ) const { return m_cmd_name ; }
2010-06-09 00:52:24 +08:00
2016-11-13 04:41:02 +08:00
void CommandObject : : SetCommandName ( llvm : : StringRef name ) { m_cmd_name = name ; }
2010-06-09 00:52:24 +08:00
2016-11-13 04:41:02 +08:00
void CommandObject : : SetHelp ( llvm : : StringRef str ) { m_cmd_help_short = str ; }
2015-03-14 06:22:28 +08:00
2016-11-13 04:41:02 +08:00
void CommandObject : : SetHelpLong ( llvm : : StringRef str ) { m_cmd_help_long = str ; }
2011-08-17 09:30:04 +08:00
2016-11-13 04:41:02 +08:00
void CommandObject : : SetSyntax ( llvm : : StringRef str ) { m_cmd_syntax = str ; }
2010-06-09 00:52:24 +08:00
2016-09-07 04:57:50 +08:00
Options * CommandObject : : GetOptions ( ) {
2018-05-01 00:49:04 +08:00
// By default commands don't have options unless this virtual function is
// overridden by base classes.
2016-09-07 04:57:50 +08:00
return nullptr ;
2010-06-09 00:52:24 +08:00
}
2016-09-07 04:57:50 +08:00
bool CommandObject : : ParseOptions ( Args & args , CommandReturnObject & result ) {
// See if the subclass has options?
Options * options = GetOptions ( ) ;
if ( options ! = nullptr ) {
2017-05-12 12:51:55 +08:00
Status error ;
2016-09-07 04:57:50 +08:00
auto exe_ctx = GetCommandInterpreter ( ) . GetExecutionContext ( ) ;
options - > NotifyOptionParsingStarting ( & exe_ctx ) ;
2012-06-09 05:56:10 +08:00
2016-09-07 04:57:50 +08:00
const bool require_validation = true ;
Move option parsing out of the Args class
Summary:
The args class is used in plenty of places (a lot of them in the lower lldb
layers) for representing a list of arguments, and most of these places don't
care about option parsing. Moving the option parsing out of the class removes
the largest external dependency (there are a couple more, but these are in
static functions), and brings us closer to being able to move it to the
Utility module).
The new home for these functions is the Options class, which was already used
as an argument to the parse calls, so this just inverts the dependency between
the two.
The functions are themselves are mainly just copied -- the biggest functional
change I've made to them is to avoid modifying the input Args argument (getopt
likes to permute the argument vector), as it was weird to have another class
reorder the entries in Args class. So now the functions don't modify the input
arguments, and (for those where it makes sense) return a new Args vector
instead. I've also made the addition of a "fake arg0" (required for getopt
compatibility) an implementation detail rather than a part of interface.
While doing that I noticed that ParseForCompletion function was recording the
option indexes in the shuffled vector, but then the consumer was looking up the
entries in the unshuffled one. This manifested itself as us not being able to
complete "watchpoint set variable foo --" (because getopt would move "foo" to
the end). Surprisingly all other completions (e.g. "watchpoint set variable foo
--w") were not affected by this. However, I couldn't find a comprehensive test
for command argument completion, so I consolidated the existing tests and added
a bunch of new ones.
Reviewers: davide, jingham, zturner
Subscribers: lldb-commits
Differential Revision: https://reviews.llvm.org/D43837
llvm-svn: 327110
2018-03-09 18:39:40 +08:00
llvm : : Expected < Args > args_or = options - > Parse (
args , & exe_ctx , GetCommandInterpreter ( ) . GetPlatform ( true ) ,
require_validation ) ;
2012-06-09 05:56:10 +08:00
Move option parsing out of the Args class
Summary:
The args class is used in plenty of places (a lot of them in the lower lldb
layers) for representing a list of arguments, and most of these places don't
care about option parsing. Moving the option parsing out of the class removes
the largest external dependency (there are a couple more, but these are in
static functions), and brings us closer to being able to move it to the
Utility module).
The new home for these functions is the Options class, which was already used
as an argument to the parse calls, so this just inverts the dependency between
the two.
The functions are themselves are mainly just copied -- the biggest functional
change I've made to them is to avoid modifying the input Args argument (getopt
likes to permute the argument vector), as it was weird to have another class
reorder the entries in Args class. So now the functions don't modify the input
arguments, and (for those where it makes sense) return a new Args vector
instead. I've also made the addition of a "fake arg0" (required for getopt
compatibility) an implementation detail rather than a part of interface.
While doing that I noticed that ParseForCompletion function was recording the
option indexes in the shuffled vector, but then the consumer was looking up the
entries in the unshuffled one. This manifested itself as us not being able to
complete "watchpoint set variable foo --" (because getopt would move "foo" to
the end). Surprisingly all other completions (e.g. "watchpoint set variable foo
--w") were not affected by this. However, I couldn't find a comprehensive test
for command argument completion, so I consolidated the existing tests and added
a bunch of new ones.
Reviewers: davide, jingham, zturner
Subscribers: lldb-commits
Differential Revision: https://reviews.llvm.org/D43837
llvm-svn: 327110
2018-03-09 18:39:40 +08:00
if ( args_or ) {
args = std : : move ( * args_or ) ;
2016-09-07 04:57:50 +08:00
error = options - > NotifyOptionParsingFinished ( & exe_ctx ) ;
Move option parsing out of the Args class
Summary:
The args class is used in plenty of places (a lot of them in the lower lldb
layers) for representing a list of arguments, and most of these places don't
care about option parsing. Moving the option parsing out of the class removes
the largest external dependency (there are a couple more, but these are in
static functions), and brings us closer to being able to move it to the
Utility module).
The new home for these functions is the Options class, which was already used
as an argument to the parse calls, so this just inverts the dependency between
the two.
The functions are themselves are mainly just copied -- the biggest functional
change I've made to them is to avoid modifying the input Args argument (getopt
likes to permute the argument vector), as it was weird to have another class
reorder the entries in Args class. So now the functions don't modify the input
arguments, and (for those where it makes sense) return a new Args vector
instead. I've also made the addition of a "fake arg0" (required for getopt
compatibility) an implementation detail rather than a part of interface.
While doing that I noticed that ParseForCompletion function was recording the
option indexes in the shuffled vector, but then the consumer was looking up the
entries in the unshuffled one. This manifested itself as us not being able to
complete "watchpoint set variable foo --" (because getopt would move "foo" to
the end). Surprisingly all other completions (e.g. "watchpoint set variable foo
--w") were not affected by this. However, I couldn't find a comprehensive test
for command argument completion, so I consolidated the existing tests and added
a bunch of new ones.
Reviewers: davide, jingham, zturner
Subscribers: lldb-commits
Differential Revision: https://reviews.llvm.org/D43837
llvm-svn: 327110
2018-03-09 18:39:40 +08:00
} else
error = args_or . takeError ( ) ;
2016-09-07 04:57:50 +08:00
if ( error . Success ( ) ) {
if ( options - > VerifyOptions ( result ) )
return true ;
} else {
const char * error_cstr = error . AsCString ( ) ;
if ( error_cstr ) {
// We got an error string, lets use that
result . AppendError ( error_cstr ) ;
} else {
// No error string, output the usage information into result
options - > GenerateOptionUsage (
result . GetErrorStream ( ) , this ,
GetCommandInterpreter ( ) . GetDebugger ( ) . GetTerminalWidth ( ) ) ;
}
}
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
return true ;
}
bool CommandObject : : CheckRequirements ( CommandReturnObject & result ) {
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
# ifdef LLDB_CONFIGURATION_DEBUG
2018-05-01 00:49:04 +08:00
// Nothing should be stored in m_exe_ctx between running commands as
// m_exe_ctx has shared pointers to the target, process, thread and frame and
// we don't want any CommandObject instances to keep any of these objects
// around longer than for a single command. Every command should call
2016-09-07 04:57:50 +08:00
// CommandObject::Cleanup() after it has completed
assert ( m_exe_ctx . GetTargetPtr ( ) = = NULL ) ;
assert ( m_exe_ctx . GetProcessPtr ( ) = = NULL ) ;
assert ( m_exe_ctx . GetThreadPtr ( ) = = NULL ) ;
assert ( m_exe_ctx . GetFramePtr ( ) = = NULL ) ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
# endif
2018-05-01 00:49:04 +08:00
// Lock down the interpreter's execution context prior to running the command
// so we guarantee the selected target, process, thread and frame can't go
// away during the execution
2016-09-07 04:57:50 +08:00
m_exe_ctx = m_interpreter . GetExecutionContext ( ) ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
2016-09-07 04:57:50 +08:00
const uint32_t flags = GetFlags ( ) . Get ( ) ;
if ( flags & ( eCommandRequiresTarget | eCommandRequiresProcess |
eCommandRequiresThread | eCommandRequiresFrame |
eCommandTryTargetAPILock ) ) {
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
2016-09-07 04:57:50 +08:00
if ( ( flags & eCommandRequiresTarget ) & & ! m_exe_ctx . HasTargetScope ( ) ) {
result . AppendError ( GetInvalidTargetDescription ( ) ) ;
return false ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
}
2016-09-07 04:57:50 +08:00
if ( ( flags & eCommandRequiresProcess ) & & ! m_exe_ctx . HasProcessScope ( ) ) {
if ( ! m_exe_ctx . HasTargetScope ( ) )
result . AppendError ( GetInvalidTargetDescription ( ) ) ;
else
result . AppendError ( GetInvalidProcessDescription ( ) ) ;
return false ;
}
if ( ( flags & eCommandRequiresThread ) & & ! m_exe_ctx . HasThreadScope ( ) ) {
if ( ! m_exe_ctx . HasTargetScope ( ) )
result . AppendError ( GetInvalidTargetDescription ( ) ) ;
else if ( ! m_exe_ctx . HasProcessScope ( ) )
result . AppendError ( GetInvalidProcessDescription ( ) ) ;
else
result . AppendError ( GetInvalidThreadDescription ( ) ) ;
return false ;
}
if ( ( flags & eCommandRequiresFrame ) & & ! m_exe_ctx . HasFrameScope ( ) ) {
if ( ! m_exe_ctx . HasTargetScope ( ) )
result . AppendError ( GetInvalidTargetDescription ( ) ) ;
else if ( ! m_exe_ctx . HasProcessScope ( ) )
result . AppendError ( GetInvalidProcessDescription ( ) ) ;
else if ( ! m_exe_ctx . HasThreadScope ( ) )
result . AppendError ( GetInvalidThreadDescription ( ) ) ;
else
result . AppendError ( GetInvalidFrameDescription ( ) ) ;
return false ;
}
if ( ( flags & eCommandRequiresRegContext ) & &
( m_exe_ctx . GetRegisterContext ( ) = = nullptr ) ) {
result . AppendError ( GetInvalidRegContextDescription ( ) ) ;
return false ;
}
if ( flags & eCommandTryTargetAPILock ) {
Target * target = m_exe_ctx . GetTargetPtr ( ) ;
if ( target )
m_api_locker =
std : : unique_lock < std : : recursive_mutex > ( target - > GetAPIMutex ( ) ) ;
}
}
if ( GetFlags ( ) . AnySet ( eCommandProcessMustBeLaunched |
eCommandProcessMustBePaused ) ) {
Process * process = m_interpreter . GetExecutionContext ( ) . GetProcessPtr ( ) ;
if ( process = = nullptr ) {
// A process that is not running is considered paused.
if ( GetFlags ( ) . Test ( eCommandProcessMustBeLaunched ) ) {
result . AppendError ( " Process must exist. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
} else {
StateType state = process - > GetState ( ) ;
switch ( state ) {
case eStateInvalid :
case eStateSuspended :
case eStateCrashed :
case eStateStopped :
break ;
case eStateConnected :
case eStateAttaching :
case eStateLaunching :
case eStateDetached :
case eStateExited :
case eStateUnloaded :
if ( GetFlags ( ) . Test ( eCommandProcessMustBeLaunched ) ) {
result . AppendError ( " Process must be launched. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2010-06-09 00:52:24 +08:00
}
2016-09-07 04:57:50 +08:00
break ;
case eStateRunning :
case eStateStepping :
if ( GetFlags ( ) . Test ( eCommandProcessMustBePaused ) ) {
result . AppendError ( " Process is running. Use 'process interrupt' to "
" pause execution. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2010-06-09 00:52:24 +08:00
}
2016-09-07 04:57:50 +08:00
}
2010-06-09 00:52:24 +08:00
}
2016-09-07 04:57:50 +08:00
}
return true ;
2010-06-09 00:52:24 +08:00
}
2016-09-07 04:57:50 +08:00
void CommandObject : : Cleanup ( ) {
m_exe_ctx . Clear ( ) ;
if ( m_api_locker . owns_lock ( ) )
m_api_locker . unlock ( ) ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
}
Refactoring for for the internal command line completion API (NFC)
Summary:
This patch refactors the internal completion API. It now takes (as far as possible) a single
CompletionRequest object instead o half a dozen in/out/in-out parameters. The CompletionRequest
contains a common superset of the different parameters as far as it makes sense. This includes
the raw command line string and raw cursor position, which should make the `expr` command
possible to implement (at least without hacks that reconstruct the command line from the args).
This patch is not intended to change the observable behavior of lldb in any way. It's also as
minimal as possible and doesn't attempt to fix all the problems the API has.
Some Q&A:
Q: Why is this not fixing all the problems in the completion API?
A: Because is a blocker for the expr command completion which I want to get in ASAP. This is the
smallest patch that unblocks the expr completion patch and which allows trivial refactoring in the future.
The patch also doesn't really change the internal information flow in the API, so that hopefully
saves us from ever having to revert and resubmit this humongous patch.
Q: Can we merge all the copy-pasted code in the completion methods
(like computing the current incomplete arg) into CompletionRequest class?
A: Yes, but it's out of scope for this patch.
Q: Why the `word_complete = request.GetWordComplete(); ... ` pattern?
A: I don't want to add a getter that returns a reference to the internal integer. So we have
to use a temporary variable and the Getter/Setter instead. We don't throw exceptions
from what I can tell, so the behavior doesn't change.
Q: Why are we not owning the list of matches?
A: Because that's how the previous API works. But that should be fixed too (in another patch).
Q: Can we make the constructor simpler and compute some of the values from the plain command?
A: I think this works, but I rather want to have this in a follow up commit. Especially when making nested
request it's a bit awkward that the parsed arguments behave as both input/output (as we should in theory
propagate the changes on the nested request back to the parent request if we don't want to change the
behavior too much).
Q: Can't we pass one const request object and then just return another result object instead of mixing
them together in one in/out parameter?
A: It's hard to get keep the same behavior with that pattern, but I think we can also get a nice API with just
a single request object. If we make all input parameters read-only, we have a clear separation between what
is actually an input and what an output parameter (and hopefully we get rid of the in-out parameters).
Q: Can we throw out the 'match' variables that are not implemented according to the comment?
A: We currently just forward them as in the old code to the different methods, even though I think
they are really not used. We can easily remove and readd them once every single completion method just
takes a CompletionRequest, but for now I prefer NFC behavior from the perspective of the API user.
Reviewers: davide, jingham, labath
Reviewed By: jingham
Subscribers: mgorny, friss, lldb-commits
Differential Revision: https://reviews.llvm.org/D48796
llvm-svn: 336146
2018-07-03 05:29:56 +08:00
int CommandObject : : HandleCompletion ( CompletionRequest & request ) {
2016-09-07 04:57:50 +08:00
// Default implementation of WantsCompletion() is !WantsRawCommandString().
2018-05-01 00:49:04 +08:00
// Subclasses who want raw command string but desire, for example, argument
// completion should override WantsCompletion() to return true, instead.
2016-09-07 04:57:50 +08:00
if ( WantsRawCommandString ( ) & & ! WantsCompletion ( ) ) {
// FIXME: Abstract telling the completion to insert the completion
// character.
return - 1 ;
} else {
// Can we do anything generic with the options?
Options * cur_options = GetOptions ( ) ;
CommandReturnObject result ;
OptionElementVector opt_element_vector ;
if ( cur_options ! = nullptr ) {
Refactoring for for the internal command line completion API (NFC)
Summary:
This patch refactors the internal completion API. It now takes (as far as possible) a single
CompletionRequest object instead o half a dozen in/out/in-out parameters. The CompletionRequest
contains a common superset of the different parameters as far as it makes sense. This includes
the raw command line string and raw cursor position, which should make the `expr` command
possible to implement (at least without hacks that reconstruct the command line from the args).
This patch is not intended to change the observable behavior of lldb in any way. It's also as
minimal as possible and doesn't attempt to fix all the problems the API has.
Some Q&A:
Q: Why is this not fixing all the problems in the completion API?
A: Because is a blocker for the expr command completion which I want to get in ASAP. This is the
smallest patch that unblocks the expr completion patch and which allows trivial refactoring in the future.
The patch also doesn't really change the internal information flow in the API, so that hopefully
saves us from ever having to revert and resubmit this humongous patch.
Q: Can we merge all the copy-pasted code in the completion methods
(like computing the current incomplete arg) into CompletionRequest class?
A: Yes, but it's out of scope for this patch.
Q: Why the `word_complete = request.GetWordComplete(); ... ` pattern?
A: I don't want to add a getter that returns a reference to the internal integer. So we have
to use a temporary variable and the Getter/Setter instead. We don't throw exceptions
from what I can tell, so the behavior doesn't change.
Q: Why are we not owning the list of matches?
A: Because that's how the previous API works. But that should be fixed too (in another patch).
Q: Can we make the constructor simpler and compute some of the values from the plain command?
A: I think this works, but I rather want to have this in a follow up commit. Especially when making nested
request it's a bit awkward that the parsed arguments behave as both input/output (as we should in theory
propagate the changes on the nested request back to the parent request if we don't want to change the
behavior too much).
Q: Can't we pass one const request object and then just return another result object instead of mixing
them together in one in/out parameter?
A: It's hard to get keep the same behavior with that pattern, but I think we can also get a nice API with just
a single request object. If we make all input parameters read-only, we have a clear separation between what
is actually an input and what an output parameter (and hopefully we get rid of the in-out parameters).
Q: Can we throw out the 'match' variables that are not implemented according to the comment?
A: We currently just forward them as in the old code to the different methods, even though I think
they are really not used. We can easily remove and readd them once every single completion method just
takes a CompletionRequest, but for now I prefer NFC behavior from the perspective of the API user.
Reviewers: davide, jingham, labath
Reviewed By: jingham
Subscribers: mgorny, friss, lldb-commits
Differential Revision: https://reviews.llvm.org/D48796
llvm-svn: 336146
2018-07-03 05:29:56 +08:00
opt_element_vector = cur_options - > ParseForCompletion (
request . GetParsedLine ( ) , request . GetCursorIndex ( ) ) ;
2016-09-07 04:57:50 +08:00
2018-07-14 02:28:14 +08:00
bool handled_by_options = cur_options - > HandleOptionCompletion (
request , opt_element_vector , GetCommandInterpreter ( ) ) ;
2016-09-07 04:57:50 +08:00
if ( handled_by_options )
2018-07-28 02:42:46 +08:00
return request . GetNumberOfMatches ( ) ;
2010-06-09 00:52:24 +08:00
}
2016-09-07 04:57:50 +08:00
// If we got here, the last word is not an option or an option argument.
Refactoring for for the internal command line completion API (NFC)
Summary:
This patch refactors the internal completion API. It now takes (as far as possible) a single
CompletionRequest object instead o half a dozen in/out/in-out parameters. The CompletionRequest
contains a common superset of the different parameters as far as it makes sense. This includes
the raw command line string and raw cursor position, which should make the `expr` command
possible to implement (at least without hacks that reconstruct the command line from the args).
This patch is not intended to change the observable behavior of lldb in any way. It's also as
minimal as possible and doesn't attempt to fix all the problems the API has.
Some Q&A:
Q: Why is this not fixing all the problems in the completion API?
A: Because is a blocker for the expr command completion which I want to get in ASAP. This is the
smallest patch that unblocks the expr completion patch and which allows trivial refactoring in the future.
The patch also doesn't really change the internal information flow in the API, so that hopefully
saves us from ever having to revert and resubmit this humongous patch.
Q: Can we merge all the copy-pasted code in the completion methods
(like computing the current incomplete arg) into CompletionRequest class?
A: Yes, but it's out of scope for this patch.
Q: Why the `word_complete = request.GetWordComplete(); ... ` pattern?
A: I don't want to add a getter that returns a reference to the internal integer. So we have
to use a temporary variable and the Getter/Setter instead. We don't throw exceptions
from what I can tell, so the behavior doesn't change.
Q: Why are we not owning the list of matches?
A: Because that's how the previous API works. But that should be fixed too (in another patch).
Q: Can we make the constructor simpler and compute some of the values from the plain command?
A: I think this works, but I rather want to have this in a follow up commit. Especially when making nested
request it's a bit awkward that the parsed arguments behave as both input/output (as we should in theory
propagate the changes on the nested request back to the parent request if we don't want to change the
behavior too much).
Q: Can't we pass one const request object and then just return another result object instead of mixing
them together in one in/out parameter?
A: It's hard to get keep the same behavior with that pattern, but I think we can also get a nice API with just
a single request object. If we make all input parameters read-only, we have a clear separation between what
is actually an input and what an output parameter (and hopefully we get rid of the in-out parameters).
Q: Can we throw out the 'match' variables that are not implemented according to the comment?
A: We currently just forward them as in the old code to the different methods, even though I think
they are really not used. We can easily remove and readd them once every single completion method just
takes a CompletionRequest, but for now I prefer NFC behavior from the perspective of the API user.
Reviewers: davide, jingham, labath
Reviewed By: jingham
Subscribers: mgorny, friss, lldb-commits
Differential Revision: https://reviews.llvm.org/D48796
llvm-svn: 336146
2018-07-03 05:29:56 +08:00
return HandleArgumentCompletion ( request , opt_element_vector ) ;
2016-09-07 04:57:50 +08:00
}
2010-06-09 00:52:24 +08:00
}
2016-11-13 10:50:32 +08:00
bool CommandObject : : HelpTextContainsWord ( llvm : : StringRef search_word ,
2016-09-07 04:57:50 +08:00
bool search_short_help ,
bool search_long_help ,
bool search_syntax ,
bool search_options ) {
std : : string options_usage_help ;
bool found_word = false ;
2016-11-13 04:41:02 +08:00
llvm : : StringRef short_help = GetHelp ( ) ;
llvm : : StringRef long_help = GetHelpLong ( ) ;
llvm : : StringRef syntax_help = GetSyntax ( ) ;
2016-09-07 04:57:50 +08:00
2016-11-13 04:41:02 +08:00
if ( search_short_help & & short_help . contains_lower ( search_word ) )
2016-09-07 04:57:50 +08:00
found_word = true ;
2016-11-13 04:41:02 +08:00
else if ( search_long_help & & long_help . contains_lower ( search_word ) )
2016-09-07 04:57:50 +08:00
found_word = true ;
2016-11-13 04:41:02 +08:00
else if ( search_syntax & & syntax_help . contains_lower ( search_word ) )
2016-09-07 04:57:50 +08:00
found_word = true ;
if ( ! found_word & & search_options & & GetOptions ( ) ! = nullptr ) {
StreamString usage_help ;
GetOptions ( ) - > GenerateOptionUsage (
usage_help , this ,
GetCommandInterpreter ( ) . GetDebugger ( ) . GetTerminalWidth ( ) ) ;
2016-11-13 10:50:32 +08:00
if ( ! usage_help . Empty ( ) ) {
llvm : : StringRef usage_text = usage_help . GetString ( ) ;
if ( usage_text . contains_lower ( search_word ) )
2010-06-09 00:52:24 +08:00
found_word = true ;
}
2016-09-07 04:57:50 +08:00
}
2010-06-09 00:52:24 +08:00
2016-09-07 04:57:50 +08:00
return found_word ;
2010-06-09 00:52:24 +08:00
}
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
2018-07-11 04:17:38 +08:00
bool CommandObject : : ParseOptionsAndNotify ( Args & args ,
CommandReturnObject & result ,
OptionGroupOptions & group_options ,
ExecutionContext & exe_ctx ) {
if ( ! ParseOptions ( args , result ) )
return false ;
Status error ( group_options . NotifyOptionParsingFinished ( & exe_ctx ) ) ;
if ( error . Fail ( ) ) {
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
return true ;
}
2016-09-07 04:57:50 +08:00
int CommandObject : : GetNumArgumentEntries ( ) { return m_arguments . size ( ) ; }
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
CommandObject : : CommandArgumentEntry *
2016-09-07 04:57:50 +08:00
CommandObject : : GetArgumentEntryAtIndex ( int idx ) {
if ( static_cast < size_t > ( idx ) < m_arguments . size ( ) )
return & ( m_arguments [ idx ] ) ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
2016-09-07 04:57:50 +08:00
return nullptr ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
}
2015-05-13 08:25:54 +08:00
const CommandObject : : ArgumentTableEntry *
2016-09-07 04:57:50 +08:00
CommandObject : : FindArgumentDataByType ( CommandArgumentType arg_type ) {
const ArgumentTableEntry * table = CommandObject : : GetArgumentTable ( ) ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
2016-09-07 04:57:50 +08:00
for ( int i = 0 ; i < eArgTypeLastArg ; + + i )
if ( table [ i ] . arg_type = = arg_type )
return & ( table [ i ] ) ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
2016-09-07 04:57:50 +08:00
return nullptr ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
}
2016-09-07 04:57:50 +08:00
void CommandObject : : GetArgumentHelp ( Stream & str , CommandArgumentType arg_type ,
CommandInterpreter & interpreter ) {
const ArgumentTableEntry * table = CommandObject : : GetArgumentTable ( ) ;
const ArgumentTableEntry * entry = & ( table [ arg_type ] ) ;
// The table is *supposed* to be kept in arg_type order, but someone *could*
// have messed it up...
if ( entry - > arg_type ! = arg_type )
entry = CommandObject : : FindArgumentDataByType ( arg_type ) ;
if ( ! entry )
return ;
StreamString name_str ;
name_str . Printf ( " <%s> " , entry - > arg_name ) ;
if ( entry - > help_function ) {
2016-11-13 10:08:22 +08:00
llvm : : StringRef help_text = entry - > help_function ( ) ;
2016-09-07 04:57:50 +08:00
if ( ! entry - > help_function . self_formatting ) {
2016-11-17 05:15:24 +08:00
interpreter . OutputFormattedHelpText ( str , name_str . GetString ( ) , " -- " ,
2016-09-07 04:57:50 +08:00
help_text , name_str . GetSize ( ) ) ;
} else {
2016-11-17 05:15:24 +08:00
interpreter . OutputHelpText ( str , name_str . GetString ( ) , " -- " , help_text ,
2016-09-07 04:57:50 +08:00
name_str . GetSize ( ) ) ;
2011-07-07 08:38:40 +08:00
}
2016-09-07 04:57:50 +08:00
} else
2016-11-17 05:15:24 +08:00
interpreter . OutputFormattedHelpText ( str , name_str . GetString ( ) , " -- " ,
2016-09-07 04:57:50 +08:00
entry - > help_text , name_str . GetSize ( ) ) ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
}
2016-09-07 04:57:50 +08:00
const char * CommandObject : : GetArgumentName ( CommandArgumentType arg_type ) {
const ArgumentTableEntry * entry =
& ( CommandObject : : GetArgumentTable ( ) [ arg_type ] ) ;
2010-10-02 03:59:14 +08:00
2016-09-07 04:57:50 +08:00
// The table is *supposed* to be kept in arg_type order, but someone *could*
// have messed it up...
2010-10-02 03:59:14 +08:00
2016-09-07 04:57:50 +08:00
if ( entry - > arg_type ! = arg_type )
entry = CommandObject : : FindArgumentDataByType ( arg_type ) ;
2010-10-02 03:59:14 +08:00
2016-09-07 04:57:50 +08:00
if ( entry )
return entry - > arg_name ;
2010-10-09 06:01:52 +08:00
2016-11-17 05:15:24 +08:00
return nullptr ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
}
2016-09-07 04:57:50 +08:00
bool CommandObject : : IsPairType ( ArgumentRepetitionType arg_repeat_type ) {
if ( ( arg_repeat_type = = eArgRepeatPairPlain ) | |
( arg_repeat_type = = eArgRepeatPairOptional ) | |
( arg_repeat_type = = eArgRepeatPairPlus ) | |
( arg_repeat_type = = eArgRepeatPairStar ) | |
( arg_repeat_type = = eArgRepeatPairRange ) | |
( arg_repeat_type = = eArgRepeatPairRangeOptional ) )
return true ;
2010-10-05 06:28:36 +08:00
2016-09-07 04:57:50 +08:00
return false ;
2010-10-05 06:28:36 +08:00
}
2012-02-08 09:13:31 +08:00
static CommandObject : : CommandArgumentEntry
2016-09-07 04:57:50 +08:00
OptSetFiltered ( uint32_t opt_set_mask ,
CommandObject : : CommandArgumentEntry & cmd_arg_entry ) {
CommandObject : : CommandArgumentEntry ret_val ;
for ( unsigned i = 0 ; i < cmd_arg_entry . size ( ) ; + + i )
if ( opt_set_mask & cmd_arg_entry [ i ] . arg_opt_set_association )
ret_val . push_back ( cmd_arg_entry [ i ] ) ;
return ret_val ;
2012-02-08 09:13:31 +08:00
}
2018-05-01 00:49:04 +08:00
// Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means
// take all the argument data into account. On rare cases where some argument
// sticks with certain option sets, this function returns the option set
// filtered args.
2016-09-07 04:57:50 +08:00
void CommandObject : : GetFormattedCommandArguments ( Stream & str ,
uint32_t opt_set_mask ) {
int num_args = m_arguments . size ( ) ;
for ( int i = 0 ; i < num_args ; + + i ) {
if ( i > 0 )
str . Printf ( " " ) ;
CommandArgumentEntry arg_entry =
opt_set_mask = = LLDB_OPT_SET_ALL
? m_arguments [ i ]
: OptSetFiltered ( opt_set_mask , m_arguments [ i ] ) ;
int num_alternatives = arg_entry . size ( ) ;
if ( ( num_alternatives = = 2 ) & & IsPairType ( arg_entry [ 0 ] . arg_repetition ) ) {
const char * first_name = GetArgumentName ( arg_entry [ 0 ] . arg_type ) ;
const char * second_name = GetArgumentName ( arg_entry [ 1 ] . arg_type ) ;
switch ( arg_entry [ 0 ] . arg_repetition ) {
case eArgRepeatPairPlain :
str . Printf ( " <%s> <%s> " , first_name , second_name ) ;
break ;
case eArgRepeatPairOptional :
str . Printf ( " [<%s> <%s>] " , first_name , second_name ) ;
break ;
case eArgRepeatPairPlus :
str . Printf ( " <%s> <%s> [<%s> <%s> [...]] " , first_name , second_name ,
first_name , second_name ) ;
break ;
case eArgRepeatPairStar :
str . Printf ( " [<%s> <%s> [<%s> <%s> [...]]] " , first_name , second_name ,
first_name , second_name ) ;
break ;
case eArgRepeatPairRange :
str . Printf ( " <%s_1> <%s_1> ... <%s_n> <%s_n> " , first_name , second_name ,
first_name , second_name ) ;
break ;
case eArgRepeatPairRangeOptional :
str . Printf ( " [<%s_1> <%s_1> ... <%s_n> <%s_n>] " , first_name , second_name ,
first_name , second_name ) ;
break ;
// Explicitly test for all the rest of the cases, so if new types get
2018-05-01 00:49:04 +08:00
// added we will notice the missing case statement(s).
2016-09-07 04:57:50 +08:00
case eArgRepeatPlain :
case eArgRepeatOptional :
case eArgRepeatPlus :
case eArgRepeatStar :
case eArgRepeatRange :
// These should not be reached, as they should fail the IsPairType test
// above.
break ;
}
} else {
StreamString names ;
for ( int j = 0 ; j < num_alternatives ; + + j ) {
if ( j > 0 )
names . Printf ( " | " ) ;
names . Printf ( " %s " , GetArgumentName ( arg_entry [ j ] . arg_type ) ) ;
}
2016-11-17 05:15:24 +08:00
std : : string name_str = names . GetString ( ) ;
2016-09-07 04:57:50 +08:00
switch ( arg_entry [ 0 ] . arg_repetition ) {
case eArgRepeatPlain :
2016-11-17 05:15:24 +08:00
str . Printf ( " <%s> " , name_str . c_str ( ) ) ;
2016-09-07 04:57:50 +08:00
break ;
case eArgRepeatPlus :
2016-11-17 05:15:24 +08:00
str . Printf ( " <%s> [<%s> [...]] " , name_str . c_str ( ) , name_str . c_str ( ) ) ;
2016-09-07 04:57:50 +08:00
break ;
case eArgRepeatStar :
2016-11-17 05:15:24 +08:00
str . Printf ( " [<%s> [<%s> [...]]] " , name_str . c_str ( ) , name_str . c_str ( ) ) ;
2016-09-07 04:57:50 +08:00
break ;
case eArgRepeatOptional :
2016-11-17 05:15:24 +08:00
str . Printf ( " [<%s>] " , name_str . c_str ( ) ) ;
2016-09-07 04:57:50 +08:00
break ;
case eArgRepeatRange :
2016-11-17 05:15:24 +08:00
str . Printf ( " <%s_1> .. <%s_n> " , name_str . c_str ( ) , name_str . c_str ( ) ) ;
2016-09-07 04:57:50 +08:00
break ;
// Explicitly test for all the rest of the cases, so if new types get
2018-05-01 00:49:04 +08:00
// added we will notice the missing case statement(s).
2016-09-07 04:57:50 +08:00
case eArgRepeatPairPlain :
case eArgRepeatPairOptional :
case eArgRepeatPairPlus :
case eArgRepeatPairStar :
case eArgRepeatPairRange :
case eArgRepeatPairRangeOptional :
// These should not be hit, as they should pass the IsPairType test
2018-05-01 00:49:04 +08:00
// above, and control should have gone into the other branch of the if
// statement.
2016-09-07 04:57:50 +08:00
break ;
}
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
}
2016-09-07 04:57:50 +08:00
}
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
}
2016-12-09 09:08:29 +08:00
CommandArgumentType
CommandObject : : LookupArgumentName ( llvm : : StringRef arg_name ) {
2016-09-07 04:57:50 +08:00
CommandArgumentType return_type = eArgTypeLastArg ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
2016-12-09 09:08:29 +08:00
arg_name = arg_name . ltrim ( ' < ' ) . rtrim ( ' > ' ) ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
2016-09-07 04:57:50 +08:00
const ArgumentTableEntry * table = GetArgumentTable ( ) ;
for ( int i = 0 ; i < eArgTypeLastArg ; + + i )
2016-12-09 09:08:29 +08:00
if ( arg_name = = table [ i ] . arg_name )
2016-09-07 04:57:50 +08:00
return_type = g_arguments_data [ i ] . arg_type ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
2016-09-07 04:57:50 +08:00
return return_type ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
}
2016-11-13 10:08:22 +08:00
static llvm : : StringRef RegisterNameHelpTextCallback ( ) {
2016-09-07 04:57:50 +08:00
return " Register names can be specified using the architecture specific "
" names. "
" They can also be specified using generic names. Not all generic "
" entities have "
" registers backing them on all architectures. When they don't the "
" generic name "
" will return an error. \n "
" The generic names defined in lldb are: \n "
" \n "
" pc - program counter register \n "
" ra - return address register \n "
" fp - frame pointer register \n "
" sp - stack pointer register \n "
" flags - the flags register \n "
" arg{1-6} - integer argument passing registers. \n " ;
2012-08-24 07:37:31 +08:00
}
2016-11-13 10:08:22 +08:00
static llvm : : StringRef BreakpointIDHelpTextCallback ( ) {
2016-09-07 04:57:50 +08:00
return " Breakpoints are identified using major and minor numbers; the major "
" number corresponds to the single entity that was created with a "
" 'breakpoint "
" set' command; the minor numbers correspond to all the locations that "
" were "
" actually found/set based on the major breakpoint. A full breakpoint "
" ID might "
" look like 3.14, meaning the 14th location set for the 3rd "
" breakpoint. You "
" can specify all the locations of a breakpoint by just indicating the "
" major "
" breakpoint number. A valid breakpoint ID consists either of just the "
" major "
" number, or the major number followed by a dot and the location "
" number (e.g. "
" 3 or 3.2 could both be valid breakpoint IDs.) " ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
}
2016-11-13 10:08:22 +08:00
static llvm : : StringRef BreakpointIDRangeHelpTextCallback ( ) {
2016-09-07 04:57:50 +08:00
return " A 'breakpoint ID list' is a manner of specifying multiple "
" breakpoints. "
" This can be done through several mechanisms. The easiest way is to "
" just "
" enter a space-separated list of breakpoint IDs. To specify all the "
" breakpoint locations under a major breakpoint, you can use the major "
" breakpoint number followed by '.*', eg. '5.*' means all the "
" locations under "
" breakpoint 5. You can also indicate a range of breakpoints by using "
" <start-bp-id> - <end-bp-id>. The start-bp-id and end-bp-id for a "
" range can "
" be any valid breakpoint IDs. It is not legal, however, to specify a "
" range "
" using specific locations that cross major breakpoint numbers. I.e. "
" 3.2 - 3.7 "
" is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal. " ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
}
2016-11-13 10:08:22 +08:00
static llvm : : StringRef BreakpointNameHelpTextCallback ( ) {
2016-09-07 04:57:50 +08:00
return " A name that can be added to a breakpoint when it is created, or "
" later "
" on with the \" breakpoint name add \" command. "
" Breakpoint names can be used to specify breakpoints in all the "
" places breakpoint IDs "
" and breakpoint ID ranges can be used. As such they provide a "
" convenient way to group breakpoints, "
" and to operate on breakpoints you create without having to track the "
" breakpoint number. "
" Note, the attributes you set when using a breakpoint name in a "
" breakpoint command don't "
" adhere to the name, but instead are set individually on all the "
" breakpoints currently tagged with that "
" name. Future breakpoints "
" tagged with that name will not pick up the attributes previously "
" given using that name. "
" In order to distinguish breakpoint names from breakpoint IDs and "
" ranges, "
" names must start with a letter from a-z or A-Z and cannot contain "
" spaces, \" . \" or \" - \" . "
" Also, breakpoint names can only be applied to breakpoints, not to "
" breakpoint locations. " ;
2014-12-17 07:40:14 +08:00
}
2016-11-13 10:08:22 +08:00
static llvm : : StringRef GDBFormatHelpTextCallback ( ) {
2016-09-07 04:57:50 +08:00
return " A GDB format consists of a repeat count, a format letter and a size "
" letter. "
" The repeat count is optional and defaults to 1. The format letter is "
" optional "
" and defaults to the previous format that was used. The size letter "
" is optional "
" and defaults to the previous size that was used. \n "
" \n "
" Format letters include: \n "
" o - octal \n "
" x - hexadecimal \n "
" d - decimal \n "
" u - unsigned decimal \n "
" t - binary \n "
" f - float \n "
" a - address \n "
" i - instruction \n "
" c - char \n "
" s - string \n "
" T - OSType \n "
" A - float as hex \n "
" \n "
" Size letters include: \n "
" b - 1 byte (byte) \n "
" h - 2 bytes (halfword) \n "
" w - 4 bytes (word) \n "
" g - 8 bytes (giant) \n "
" \n "
" Example formats: \n "
" 32xb - show 32 1 byte hexadecimal integer values \n "
" 16xh - show 16 2 byte hexadecimal integer values \n "
" 64 - show 64 2 byte hexadecimal integer values (format and size "
" from the last format) \n "
" dw - show 1 4 byte decimal integer value \n " ;
2011-07-02 08:25:22 +08:00
}
2016-11-13 10:08:22 +08:00
static llvm : : StringRef FormatHelpTextCallback ( ) {
static std : : string help_text ;
2016-09-07 04:57:50 +08:00
2016-11-13 10:08:22 +08:00
if ( ! help_text . empty ( ) )
return help_text ;
2012-10-23 08:50:09 +08:00
2016-09-07 04:57:50 +08:00
StreamString sstr ;
sstr < < " One of the format names (or one-character names) that can be used "
" to show a variable's value: \n " ;
for ( Format f = eFormatDefault ; f < kNumFormats ; f = Format ( f + 1 ) ) {
if ( f ! = eFormatDefault )
sstr . PutChar ( ' \n ' ) ;
char format_char = FormatManager : : GetFormatAsFormatChar ( f ) ;
if ( format_char )
sstr . Printf ( " '%c' or " , format_char ) ;
sstr . Printf ( " \" %s \" " , FormatManager : : GetFormatAsCString ( f ) ) ;
}
sstr . Flush ( ) ;
2016-11-13 10:08:22 +08:00
help_text = sstr . GetString ( ) ;
2016-09-07 04:57:50 +08:00
2016-11-13 10:08:22 +08:00
return help_text ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
}
2016-11-13 10:08:22 +08:00
static llvm : : StringRef LanguageTypeHelpTextCallback ( ) {
static std : : string help_text ;
2016-09-07 04:57:50 +08:00
2016-11-13 10:08:22 +08:00
if ( ! help_text . empty ( ) )
return help_text ;
2016-09-07 04:57:50 +08:00
StreamString sstr ;
sstr < < " One of the following languages: \n " ;
Language : : PrintAllLanguages ( sstr , " " , " \n " ) ;
sstr . Flush ( ) ;
2016-11-13 10:08:22 +08:00
help_text = sstr . GetString ( ) ;
2016-09-07 04:57:50 +08:00
2016-11-13 10:08:22 +08:00
return help_text ;
2011-07-02 08:25:22 +08:00
}
2016-11-13 10:08:22 +08:00
static llvm : : StringRef SummaryStringHelpTextCallback ( ) {
2016-09-07 04:57:50 +08:00
return " A summary string is a way to extract information from variables in "
" order to present them using a summary. \n "
" Summary strings contain static text, variables, scopes and control "
" sequences: \n "
" - Static text can be any sequence of non-special characters, i.e. "
" anything but '{', '}', '$', or ' \\ '. \n "
" - Variables are sequences of characters beginning with ${, ending "
" with } and that contain symbols in the format described below. \n "
" - Scopes are any sequence of text between { and }. Anything "
" included in a scope will only appear in the output summary if there "
" were no errors. \n "
" - Control sequences are the usual C/C++ ' \\ a', ' \\ n', ..., plus "
" ' \\ $', ' \\ {' and ' \\ }'. \n "
" A summary string works by copying static text verbatim, turning "
" control sequences into their character counterpart, expanding "
" variables and trying to expand scopes. \n "
" A variable is expanded by giving it a value other than its textual "
" representation, and the way this is done depends on what comes after "
" the ${ marker. \n "
" The most common sequence if ${var followed by an expression path, "
" which is the text one would type to access a member of an aggregate "
" types, given a variable of that type "
" (e.g. if type T has a member named x, which has a member named y, "
" and if t is of type T, the expression path would be .x.y and the way "
" to fit that into a summary string would be "
" ${var.x.y}). You can also use ${*var followed by an expression path "
" and in that case the object referred by the path will be "
" dereferenced before being displayed. "
" If the object is not a pointer, doing so will cause an error. For "
" additional details on expression paths, you can type 'help "
" expr-path'. \n "
" By default, summary strings attempt to display the summary for any "
" variable they reference, and if that fails the value. If neither can "
" be shown, nothing is displayed. "
" In a summary string, you can also use an array index [n], or a "
" slice-like range [n-m]. This can have two different meanings "
" depending on what kind of object the expression "
" path refers to: \n "
" - if it is a scalar type (any basic type like int, float, ...) the "
" expression is a bitfield, i.e. the bits indicated by the indexing "
" operator are extracted out of the number "
" and displayed as an individual variable \n "
" - if it is an array or pointer the array items indicated by the "
" indexing operator are shown as the result of the variable. if the "
" expression is an array, real array items are "
" printed; if it is a pointer, the pointer-as-array syntax is used to "
" obtain the values (this means, the latter case can have no range "
" checking) \n "
" If you are trying to display an array for which the size is known, "
" you can also use [] instead of giving an exact range. This has the "
" effect of showing items 0 thru size - 1. \n "
" Additionally, a variable can contain an (optional) format code, as "
" in ${var.x.y%code}, where code can be any of the valid formats "
" described in 'help format', or one of the "
" special symbols only allowed as part of a variable: \n "
" %V: show the value of the object by default \n "
" %S: show the summary of the object by default \n "
" %@: show the runtime-provided object description (for "
" Objective-C, it calls NSPrintForDebugger; for C/C++ it does "
" nothing) \n "
" %L: show the location of the object (memory address or a "
" register name) \n "
" %#: show the number of children of the object \n "
" %T: show the type of the object \n "
" Another variable that you can use in summary strings is ${svar . "
" This sequence works exactly like ${var, including the fact that "
" ${*svar is an allowed sequence, but uses "
" the object's synthetic children provider instead of the actual "
" objects. For instance, if you are using STL synthetic children "
" providers, the following summary string would "
" count the number of actual elements stored in an std::list: \n "
" type summary add -s \" ${svar%#} \" -x \" std::list< \" " ;
2015-07-14 13:48:36 +08:00
}
2016-11-13 10:08:22 +08:00
static llvm : : StringRef ExprPathHelpTextCallback ( ) {
2016-09-07 04:57:50 +08:00
return " An expression path is the sequence of symbols that is used in C/C++ "
" to access a member variable of an aggregate object (class). \n "
" For instance, given a class: \n "
" class foo { \n "
" int a; \n "
" int b; . \n "
" foo* next; \n "
" }; \n "
" the expression to read item b in the item pointed to by next for foo "
" aFoo would be aFoo.next->b. \n "
" Given that aFoo could just be any object of type foo, the string "
" '.next->b' is the expression path, because it can be attached to any "
" foo instance to achieve the effect. \n "
" Expression paths in LLDB include dot (.) and arrow (->) operators, "
" and most commands using expression paths have ways to also accept "
" the star (*) operator. \n "
" The meaning of these operators is the same as the usual one given to "
" them by the C/C++ standards. \n "
" LLDB also has support for indexing ([ ]) in expression paths, and "
" extends the traditional meaning of the square brackets operator to "
" allow bitfield extraction: \n "
" for objects of native types (int, float, char, ...) saying '[n-m]' "
" as an expression path (where n and m are any positive integers, e.g. "
" [3-5]) causes LLDB to extract "
" bits n thru m from the value of the variable. If n == m, [n] is "
" also allowed as a shortcut syntax. For arrays and pointers, "
" expression paths can only contain one index "
" and the meaning of the operation is the same as the one defined by "
" C/C++ (item extraction). Some commands extend bitfield-like syntax "
" for arrays and pointers with the "
" meaning of array slicing (taking elements n thru m inside the array "
" or pointed-to memory). " ;
2013-06-12 09:50:57 +08:00
}
2016-09-07 04:57:50 +08:00
void CommandObject : : FormatLongHelpText ( Stream & output_strm ,
2016-11-13 04:41:02 +08:00
llvm : : StringRef long_help ) {
2016-09-07 04:57:50 +08:00
CommandInterpreter & interpreter = GetCommandInterpreter ( ) ;
std : : stringstream lineStream ( long_help ) ;
std : : string line ;
while ( std : : getline ( lineStream , line ) ) {
if ( line . empty ( ) ) {
output_strm < < " \n " ;
continue ;
2013-06-12 09:50:57 +08:00
}
2016-09-07 04:57:50 +08:00
size_t result = line . find_first_not_of ( " \t " ) ;
if ( result = = std : : string : : npos ) {
result = 0 ;
2013-06-12 09:50:57 +08:00
}
2016-09-07 04:57:50 +08:00
std : : string whitespace_prefix = line . substr ( 0 , result ) ;
std : : string remainder = line . substr ( result ) ;
interpreter . OutputFormattedHelpText ( output_strm , whitespace_prefix . c_str ( ) ,
remainder . c_str ( ) ) ;
}
2013-06-12 09:50:57 +08:00
}
2016-09-07 04:57:50 +08:00
void CommandObject : : GenerateHelpText ( CommandReturnObject & result ) {
GenerateHelpText ( result . GetOutputStream ( ) ) ;
2011-09-21 09:00:02 +08:00
2016-09-07 04:57:50 +08:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
2011-09-21 09:00:02 +08:00
2016-09-07 04:57:50 +08:00
void CommandObject : : GenerateHelpText ( Stream & output_strm ) {
CommandInterpreter & interpreter = GetCommandInterpreter ( ) ;
if ( WantsRawCommandString ( ) ) {
std : : string help_text ( GetHelp ( ) ) ;
help_text . append ( " Expects 'raw' input (see 'help raw-input'.) " ) ;
interpreter . OutputFormattedHelpText ( output_strm , " " , " " , help_text . c_str ( ) ,
1 ) ;
} else
interpreter . OutputFormattedHelpText ( output_strm , " " , " " , GetHelp ( ) , 1 ) ;
2016-11-15 07:23:31 +08:00
output_strm < < " \n Syntax: " < < GetSyntax ( ) < < " \n " ;
2016-09-07 04:57:50 +08:00
Options * options = GetOptions ( ) ;
if ( options ! = nullptr ) {
options - > GenerateOptionUsage (
output_strm , this ,
GetCommandInterpreter ( ) . GetDebugger ( ) . GetTerminalWidth ( ) ) ;
}
2016-11-13 04:41:02 +08:00
llvm : : StringRef long_help = GetHelpLong ( ) ;
if ( ! long_help . empty ( ) ) {
2016-09-07 04:57:50 +08:00
FormatLongHelpText ( output_strm , long_help ) ;
}
if ( ! IsDashDashCommand ( ) & & options & & options - > NumCommandOptions ( ) > 0 ) {
if ( WantsRawCommandString ( ) & & ! WantsCompletion ( ) ) {
// Emit the message about using ' -- ' between the end of the command
2018-05-01 00:49:04 +08:00
// options and the raw input conditionally, i.e., only if the command
// object does not want completion.
2016-09-07 04:57:50 +08:00
interpreter . OutputFormattedHelpText (
output_strm , " " , " " ,
" \n Important Note: Because this command takes 'raw' input, if you "
" use any command options "
" you must use ' -- ' between the end of the command options and the "
" beginning of the raw input. " ,
1 ) ;
} else if ( GetNumArgumentEntries ( ) > 0 ) {
// Also emit a warning about using "--" in case you are using a command
// that takes options and arguments.
interpreter . OutputFormattedHelpText (
output_strm , " " , " " ,
" \n This command takes options and free-form arguments. If your "
" arguments resemble "
" option specifiers (i.e., they start with a - or --), you must use "
" ' -- ' between "
" the end of the command options and the beginning of the arguments. " ,
1 ) ;
}
}
}
2011-09-21 09:00:02 +08:00
2016-09-07 04:57:50 +08:00
void CommandObject : : AddIDsArgumentData ( CommandArgumentEntry & arg ,
CommandArgumentType ID ,
CommandArgumentType IDRange ) {
CommandArgumentData id_arg ;
CommandArgumentData id_range_arg ;
// Create the first variant for the first (and only) argument for this
// command.
id_arg . arg_type = ID ;
id_arg . arg_repetition = eArgRepeatOptional ;
// Create the second variant for the first (and only) argument for this
// command.
id_range_arg . arg_type = IDRange ;
id_range_arg . arg_repetition = eArgRepeatOptional ;
// The first (and only) argument for this command could be either an id or an
2018-05-01 00:49:04 +08:00
// id_range. Push both variants into the entry for the first argument for
// this command.
2016-09-07 04:57:50 +08:00
arg . push_back ( id_arg ) ;
arg . push_back ( id_range_arg ) ;
2011-09-21 09:00:02 +08:00
}
2016-09-07 04:57:50 +08:00
const char * CommandObject : : GetArgumentTypeAsCString (
const lldb : : CommandArgumentType arg_type ) {
assert ( arg_type < eArgTypeLastArg & &
" Invalid argument type passed to GetArgumentTypeAsCString " ) ;
return g_arguments_data [ arg_type ] . arg_name ;
2011-02-20 10:15:07 +08:00
}
2016-09-07 04:57:50 +08:00
const char * CommandObject : : GetArgumentDescriptionAsCString (
const lldb : : CommandArgumentType arg_type ) {
assert ( arg_type < eArgTypeLastArg & &
" Invalid argument type passed to GetArgumentDescriptionAsCString " ) ;
return g_arguments_data [ arg_type ] . help_text ;
2011-02-20 10:15:07 +08:00
}
2016-09-07 04:57:50 +08:00
Target * CommandObject : : GetDummyTarget ( ) {
return m_interpreter . GetDebugger ( ) . GetDummyTarget ( ) ;
2014-11-22 09:42:44 +08:00
}
2016-09-07 04:57:50 +08:00
Target * CommandObject : : GetSelectedOrDummyTarget ( bool prefer_dummy ) {
return m_interpreter . GetDebugger ( ) . GetSelectedOrDummyTarget ( prefer_dummy ) ;
2014-11-22 09:42:44 +08:00
}
2016-09-07 04:57:50 +08:00
Thread * CommandObject : : GetDefaultThread ( ) {
Thread * thread_to_use = m_exe_ctx . GetThreadPtr ( ) ;
if ( thread_to_use )
return thread_to_use ;
Process * process = m_exe_ctx . GetProcessPtr ( ) ;
if ( ! process ) {
Target * target = m_exe_ctx . GetTargetPtr ( ) ;
if ( ! target ) {
target = m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) . get ( ) ;
2016-03-12 10:45:34 +08:00
}
2016-09-07 04:57:50 +08:00
if ( target )
process = target - > GetProcessSP ( ) . get ( ) ;
}
2016-03-12 10:45:34 +08:00
2016-09-07 04:57:50 +08:00
if ( process )
return process - > GetThreadList ( ) . GetSelectedThread ( ) . get ( ) ;
else
return nullptr ;
2016-03-12 10:45:34 +08:00
}
2016-09-07 04:57:50 +08:00
bool CommandObjectParsed : : Execute ( const char * args_string ,
CommandReturnObject & result ) {
bool handled = false ;
Args cmd_args ( args_string ) ;
if ( HasOverrideCallback ( ) ) {
Args full_args ( GetCommandName ( ) ) ;
full_args . AppendArguments ( cmd_args ) ;
handled =
InvokeOverrideCallback ( full_args . GetConstArgumentVector ( ) , result ) ;
}
if ( ! handled ) {
2016-10-06 07:40:23 +08:00
for ( auto entry : llvm : : enumerate ( cmd_args . entries ( ) ) ) {
2017-03-14 01:12:12 +08:00
if ( ! entry . value ( ) . ref . empty ( ) & & entry . value ( ) . ref . front ( ) = = ' ` ' ) {
2016-09-07 04:57:50 +08:00
cmd_args . ReplaceArgumentAtIndex (
2017-03-14 01:12:12 +08:00
entry . index ( ) ,
m_interpreter . ProcessEmbeddedScriptCommands ( entry . value ( ) . c_str ( ) ) ) ;
2016-10-06 07:40:23 +08:00
}
2012-06-09 05:56:10 +08:00
}
2016-09-07 04:57:50 +08:00
if ( CheckRequirements ( result ) ) {
if ( ParseOptions ( cmd_args , result ) ) {
// Call the command-specific version of 'Execute', passing it the
// already processed arguments.
handled = DoExecute ( cmd_args , result ) ;
}
2012-06-09 05:56:10 +08:00
}
2016-09-07 04:57:50 +08:00
Cleanup ( ) ;
}
return handled ;
2012-06-09 05:56:10 +08:00
}
2016-09-07 04:57:50 +08:00
bool CommandObjectRaw : : Execute ( const char * args_string ,
CommandReturnObject & result ) {
bool handled = false ;
if ( HasOverrideCallback ( ) ) {
std : : string full_command ( GetCommandName ( ) ) ;
full_command + = ' ' ;
full_command + = args_string ;
const char * argv [ 2 ] = { nullptr , nullptr } ;
argv [ 0 ] = full_command . c_str ( ) ;
handled = InvokeOverrideCallback ( argv , result ) ;
}
if ( ! handled ) {
if ( CheckRequirements ( result ) )
handled = DoExecute ( args_string , result ) ;
Cleanup ( ) ;
}
return handled ;
2012-06-09 05:56:10 +08:00
}
2016-11-13 10:08:22 +08:00
static llvm : : StringRef arch_helper ( ) {
2016-09-07 04:57:50 +08:00
static StreamString g_archs_help ;
if ( g_archs_help . Empty ( ) ) {
StringList archs ;
2018-07-14 02:28:14 +08:00
ArchSpec : : ListSupportedArchNames ( archs ) ;
2016-09-07 04:57:50 +08:00
g_archs_help . Printf ( " These are the supported architecture names: \n " ) ;
archs . Join ( " \n " , g_archs_help ) ;
}
2016-11-13 10:08:22 +08:00
return g_archs_help . GetString ( ) ;
2012-05-26 08:32:39 +08:00
}
2016-07-15 06:03:10 +08:00
CommandObject : : ArgumentTableEntry CommandObject : : g_arguments_data [ ] = {
// clang-format off
2014-04-20 08:31:37 +08:00
{ eArgTypeAddress , " address " , CommandCompletions : : eNoCompletion , { nullptr , false } , " A valid address in the target program's execution space. " } ,
{ eArgTypeAddressOrExpression , " address-expression " , CommandCompletions : : eNoCompletion , { nullptr , false } , " An expression that resolves to an address. " } ,
{ eArgTypeAliasName , " alias-name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of an abbreviation (alias) for a debugger command. " } ,
{ eArgTypeAliasOptions , " options-for-aliased-command " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Command options to be used as part of an alias (abbreviation) definition. (See 'help commands alias' for more information.) " } ,
2012-05-26 08:32:39 +08:00
{ eArgTypeArchitecture , " arch " , CommandCompletions : : eArchitectureCompletion , { arch_helper , true } , " The architecture name, e.g. i386 or x86_64. " } ,
2014-04-20 08:31:37 +08:00
{ eArgTypeBoolean , " boolean " , CommandCompletions : : eNoCompletion , { nullptr , false } , " A Boolean value: 'true' or 'false' " } ,
{ eArgTypeBreakpointID , " breakpt-id " , CommandCompletions : : eNoCompletion , { BreakpointIDHelpTextCallback , false } , nullptr } ,
{ eArgTypeBreakpointIDRange , " breakpt-id-list " , CommandCompletions : : eNoCompletion , { BreakpointIDRangeHelpTextCallback , false } , nullptr } ,
2014-12-17 07:40:14 +08:00
{ eArgTypeBreakpointName , " breakpoint-name " , CommandCompletions : : eNoCompletion , { BreakpointNameHelpTextCallback , false } , nullptr } ,
2014-04-20 08:31:37 +08:00
{ eArgTypeByteSize , " byte-size " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Number of bytes to use. " } ,
{ eArgTypeClassName , " class-name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Then name of a class from the debug information in the program. " } ,
{ eArgTypeCommandName , " cmd-name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " A debugger command (may be multiple words), without any options or arguments. " } ,
{ eArgTypeCount , " count " , CommandCompletions : : eNoCompletion , { nullptr , false } , " An unsigned integer. " } ,
{ eArgTypeDirectoryName , " directory " , CommandCompletions : : eDiskDirectoryCompletion , { nullptr , false } , " A directory name. " } ,
{ eArgTypeDisassemblyFlavor , " disassembly-flavor " , CommandCompletions : : eNoCompletion , { nullptr , false } , " A disassembly flavor recognized by your disassembly plugin. Currently the only valid options are \" att \" and \" intel \" for Intel targets " } ,
{ eArgTypeDescriptionVerbosity , " description-verbosity " , CommandCompletions : : eNoCompletion , { nullptr , false } , " How verbose the output of 'po' should be. " } ,
{ eArgTypeEndAddress , " end-address " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Help text goes here. " } ,
{ eArgTypeExpression , " expr " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Help text goes here. " } ,
{ eArgTypeExpressionPath , " expr-path " , CommandCompletions : : eNoCompletion , { ExprPathHelpTextCallback , true } , nullptr } ,
{ eArgTypeExprFormat , " expression-format " , CommandCompletions : : eNoCompletion , { nullptr , false } , " [ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ] " } ,
{ eArgTypeFilename , " filename " , CommandCompletions : : eDiskFileCompletion , { nullptr , false } , " The name of a file (can include path). " } ,
{ eArgTypeFormat , " format " , CommandCompletions : : eNoCompletion , { FormatHelpTextCallback , true } , nullptr } ,
{ eArgTypeFrameIndex , " frame-index " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Index into a thread's list of frames. " } ,
{ eArgTypeFullName , " fullname " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Help text goes here. " } ,
{ eArgTypeFunctionName , " function-name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of a function. " } ,
{ eArgTypeFunctionOrSymbol , " function-or-symbol " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of a function or symbol. " } ,
{ eArgTypeGDBFormat , " gdb-format " , CommandCompletions : : eNoCompletion , { GDBFormatHelpTextCallback , true } , nullptr } ,
2014-09-16 01:52:44 +08:00
{ eArgTypeHelpText , " help-text " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Text to be used as help for some other entity in LLDB " } ,
2014-04-20 08:31:37 +08:00
{ eArgTypeIndex , " index " , CommandCompletions : : eNoCompletion , { nullptr , false } , " An index into a list. " } ,
2016-03-01 05:37:01 +08:00
{ eArgTypeLanguage , " source-language " , CommandCompletions : : eNoCompletion , { LanguageTypeHelpTextCallback , true } , nullptr } ,
2014-04-20 08:31:37 +08:00
{ eArgTypeLineNum , " linenum " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Line number in a source file. " } ,
{ eArgTypeLogCategory , " log-category " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of a category within a log channel, e.g. all (try \" log list \" to see a list of all channels and their categories. " } ,
{ eArgTypeLogChannel , " log-channel " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of a log channel, e.g. process.gdb-remote (try \" log list \" to see a list of all channels and their categories). " } ,
{ eArgTypeMethod , " method " , CommandCompletions : : eNoCompletion , { nullptr , false } , " A C++ method name. " } ,
{ eArgTypeName , " name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Help text goes here. " } ,
{ eArgTypeNewPathPrefix , " new-path-prefix " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Help text goes here. " } ,
{ eArgTypeNumLines , " num-lines " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The number of lines to use. " } ,
{ eArgTypeNumberPerLine , " number-per-line " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The number of items per line to display. " } ,
{ eArgTypeOffset , " offset " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Help text goes here. " } ,
{ eArgTypeOldPathPrefix , " old-path-prefix " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Help text goes here. " } ,
{ eArgTypeOneLiner , " one-line-command " , CommandCompletions : : eNoCompletion , { nullptr , false } , " A command that is entered as a single line of text. " } ,
{ eArgTypePath , " path " , CommandCompletions : : eDiskFileCompletion , { nullptr , false } , " Path. " } ,
{ eArgTypePermissionsNumber , " perms-numeric " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Permissions given as an octal number (e.g. 755). " } ,
{ eArgTypePermissionsString , " perms=string " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Permissions given as a string value (e.g. rw-r-xr--). " } ,
{ eArgTypePid , " pid " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The process ID number. " } ,
{ eArgTypePlugin , " plugin " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Help text goes here. " } ,
{ eArgTypeProcessName , " process-name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of the process. " } ,
{ eArgTypePythonClass , " python-class " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of a Python class. " } ,
{ eArgTypePythonFunction , " python-function " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of a Python function. " } ,
{ eArgTypePythonScript , " python-script " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Source code written in Python. " } ,
{ eArgTypeQueueName , " queue-name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of the thread queue. " } ,
{ eArgTypeRegisterName , " register-name " , CommandCompletions : : eNoCompletion , { RegisterNameHelpTextCallback , true } , nullptr } ,
{ eArgTypeRegularExpression , " regular-expression " , CommandCompletions : : eNoCompletion , { nullptr , false } , " A regular expression. " } ,
{ eArgTypeRunArgs , " run-args " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Arguments to be passed to the target program when it starts executing. " } ,
{ eArgTypeRunMode , " run-mode " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Help text goes here. " } ,
{ eArgTypeScriptedCommandSynchronicity , " script-cmd-synchronicity " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The synchronicity to use to run scripted commands with regard to LLDB event system. " } ,
{ eArgTypeScriptLang , " script-language " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The scripting language to be used for script-based commands. Currently only Python is valid. " } ,
2016-07-15 06:03:10 +08:00
{ eArgTypeSearchWord , " search-word " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Any word of interest for search purposes. " } ,
2014-04-20 08:31:37 +08:00
{ eArgTypeSelector , " selector " , CommandCompletions : : eNoCompletion , { nullptr , false } , " An Objective-C selector name. " } ,
{ eArgTypeSettingIndex , " setting-index " , CommandCompletions : : eNoCompletion , { nullptr , false } , " An index into a settings variable that is an array (try 'settings list' to see all the possible settings variables and their types). " } ,
{ eArgTypeSettingKey , " setting-key " , CommandCompletions : : eNoCompletion , { nullptr , false } , " A key into a settings variables that is a dictionary (try 'settings list' to see all the possible settings variables and their types). " } ,
{ eArgTypeSettingPrefix , " setting-prefix " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.' " } ,
{ eArgTypeSettingVariableName , " setting-variable-name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of a settable internal debugger variable. Type 'settings list' to see a complete list of such variables. " } ,
{ eArgTypeShlibName , " shlib-name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of a shared library. " } ,
{ eArgTypeSourceFile , " source-file " , CommandCompletions : : eSourceFileCompletion , { nullptr , false } , " The name of a source file.. " } ,
{ eArgTypeSortOrder , " sort-order " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Specify a sort order when dumping lists. " } ,
{ eArgTypeStartAddress , " start-address " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Help text goes here. " } ,
{ eArgTypeSummaryString , " summary-string " , CommandCompletions : : eNoCompletion , { SummaryStringHelpTextCallback , true } , nullptr } ,
{ eArgTypeSymbol , " symbol " , CommandCompletions : : eSymbolCompletion , { nullptr , false } , " Any symbol name (function name, variable, argument, etc.) " } ,
{ eArgTypeThreadID , " thread-id " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Thread ID number. " } ,
{ eArgTypeThreadIndex , " thread-index " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Index into the process' list of threads. " } ,
{ eArgTypeThreadName , " thread-name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The thread's name. " } ,
2015-04-23 03:42:18 +08:00
{ eArgTypeTypeName , " type-name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " A type name. " } ,
2014-04-20 08:31:37 +08:00
{ eArgTypeUnsignedInteger , " unsigned-integer " , CommandCompletions : : eNoCompletion , { nullptr , false } , " An unsigned integer. " } ,
{ eArgTypeUnixSignal , " unix-signal " , CommandCompletions : : eNoCompletion , { nullptr , false } , " A valid Unix signal name or number (e.g. SIGKILL, KILL or 9). " } ,
{ eArgTypeVarName , " variable-name " , CommandCompletions : : eNoCompletion , { nullptr , false } , " The name of a variable in your program. " } ,
{ eArgTypeValue , " value " , CommandCompletions : : eNoCompletion , { nullptr , false } , " A value could be anything, depending on where and how it is used. " } ,
{ eArgTypeWidth , " width " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Help text goes here. " } ,
{ eArgTypeNone , " none " , CommandCompletions : : eNoCompletion , { nullptr , false } , " No help available for this. " } ,
{ eArgTypePlatform , " platform-name " , CommandCompletions : : ePlatformPluginCompletion , { nullptr , false } , " The name of an installed platform plug-in . Type 'platform list' to see a complete list of installed platforms. " } ,
{ eArgTypeWatchpointID , " watchpt-id " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Watchpoint IDs are positive integers. " } ,
{ eArgTypeWatchpointIDRange , " watchpt-id-list " , CommandCompletions : : eNoCompletion , { nullptr , false } , " For example, '1-3' or '1 to 3'. " } ,
2016-07-15 06:03:10 +08:00
{ eArgTypeWatchType , " watch-type " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Specify the type for a watchpoint. " } ,
2017-09-15 04:22:49 +08:00
{ eArgRawInput , " raw-input " , CommandCompletions : : eNoCompletion , { nullptr , false } , " Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input. " } ,
{ eArgTypeCommand , " command " , CommandCompletions : : eNoCompletion , { nullptr , false } , " An LLDB Command line command. " }
2016-07-15 06:03:10 +08:00
// clang-format on
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
} ;
2016-09-07 04:57:50 +08:00
const CommandObject : : ArgumentTableEntry * CommandObject : : GetArgumentTable ( ) {
// If this assertion fires, then the table above is out of date with the
// CommandArgumentType enumeration
assert ( ( sizeof ( CommandObject : : g_arguments_data ) /
sizeof ( CommandObject : : ArgumentTableEntry ) ) = = eArgTypeLastArg ) ;
return CommandObject : : g_arguments_data ;
Add infrastructure for standardizing arguments for commands and
command options; makes it easier to ensure that the same type of
argument will have the same name everywhere, hooks up help for command
arguments, so that users can ask for help when they are confused about
what an argument should be; puts in the beginnings of the ability to
do tab-completion for certain types of arguments, allows automatic
syntax help generation for commands with arguments, and adds command
arguments into command options help correctly.
Currently only the breakpoint-id and breakpoint-id-range arguments, in
the breakpoint commands, have been hooked up to use the new mechanism.
The next steps will be to fix the command options arguments to use
this mechanism, and to fix the rest of the regular command arguments
to use this mechanism. Most of the help text is currently missing or
dummy text; this will need to be filled in, and the existing argument
help text will need to be cleaned up a bit (it was thrown in quickly,
mostly for testing purposes).
Help command now works for all argument types, although the help may not
be very helpful yet.
Those commands that take "raw" command strings now indicate it in their
help text.
llvm-svn: 115318
2010-10-02 01:46:38 +08:00
}