2010-07-07 03:36:20 +00:00
//===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
2011-04-20 22:55:21 +00:00
# include "llvm/ADT/StringRef.h"
2010-07-07 03:36:20 +00:00
// Project includes
2016-02-22 23:46:47 +00:00
# include "CommandObjectCommands.h"
2016-02-29 23:22:53 +00:00
# include "CommandObjectHelp.h"
2010-07-07 03:36:20 +00:00
# include "lldb/Core/Debugger.h"
2014-01-27 23:43:24 +00:00
# include "lldb/Core/IOHandler.h"
2011-08-16 16:49:25 +00:00
# include "lldb/Core/StringList.h"
2011-04-20 16:37:46 +00:00
# include "lldb/Interpreter/Args.h"
2013-06-17 22:51:50 +00:00
# include "lldb/Interpreter/CommandHistory.h"
2010-07-07 03:36:20 +00:00
# include "lldb/Interpreter/CommandInterpreter.h"
2011-04-20 16:37:46 +00:00
# include "lldb/Interpreter/CommandObjectRegexCommand.h"
2010-07-07 03:36:20 +00:00
# include "lldb/Interpreter/CommandReturnObject.h"
2013-06-11 01:26:35 +00:00
# include "lldb/Interpreter/OptionValueBoolean.h"
2016-03-31 01:10:54 +00:00
# include "lldb/Interpreter/OptionValueString.h"
2013-06-17 22:51:50 +00:00
# include "lldb/Interpreter/OptionValueUInt64.h"
2010-07-07 03:36:20 +00:00
# include "lldb/Interpreter/Options.h"
2011-08-17 01:30:04 +00:00
# include "lldb/Interpreter/ScriptInterpreter.h"
2010-07-07 03:36:20 +00:00
using namespace lldb ;
using namespace lldb_private ;
2011-07-12 03:12:18 +00:00
//-------------------------------------------------------------------------
// CommandObjectCommandsSource
//-------------------------------------------------------------------------
2016-09-06 20:57:50 +00:00
class CommandObjectCommandsHistory : public CommandObjectParsed {
2012-06-08 21:56:10 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectCommandsHistory ( CommandInterpreter & interpreter )
: CommandObjectParsed ( interpreter , " command history " ,
2016-02-22 23:46:47 +00:00
" Dump the history of commands in this session. " ,
nullptr ) ,
2016-09-06 20:57:50 +00:00
m_options ( ) { }
2012-06-08 21:56:10 +00:00
2016-09-06 20:57:50 +00:00
~ CommandObjectCommandsHistory ( ) override = default ;
2012-06-08 21:56:10 +00:00
2016-09-06 20:57:50 +00:00
Options * GetOptions ( ) override { return & m_options ; }
2012-06-08 21:56:10 +00:00
protected :
2016-09-06 20:57:50 +00:00
class CommandOptions : public Options {
public :
CommandOptions ( )
: Options ( ) , m_start_idx ( 0 ) , m_stop_idx ( 0 ) , m_count ( 0 ) , m_clear ( false ) {
}
2011-07-12 03:12:18 +00:00
2016-09-06 20:57:50 +00:00
~ CommandOptions ( ) override = default ;
Error SetOptionValue ( uint32_t option_idx , const char * option_arg ,
ExecutionContext * execution_context ) override {
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option ) {
case ' c ' :
error = m_count . SetValueFromString ( option_arg , eVarSetOperationAssign ) ;
break ;
case ' s ' :
if ( option_arg & & strcmp ( " end " , option_arg ) = = 0 ) {
m_start_idx . SetCurrentValue ( UINT64_MAX ) ;
m_start_idx . SetOptionWasSet ( ) ;
} else
error = m_start_idx . SetValueFromString ( option_arg ,
eVarSetOperationAssign ) ;
break ;
case ' e ' :
error =
m_stop_idx . SetValueFromString ( option_arg , eVarSetOperationAssign ) ;
break ;
case ' C ' :
m_clear . SetCurrentValue ( true ) ;
m_clear . SetOptionWasSet ( ) ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " ,
short_option ) ;
break ;
}
return error ;
}
2011-07-12 03:12:18 +00:00
2016-09-06 20:57:50 +00:00
void OptionParsingStarting ( ExecutionContext * execution_context ) override {
m_start_idx . Clear ( ) ;
m_stop_idx . Clear ( ) ;
m_count . Clear ( ) ;
m_clear . Clear ( ) ;
}
2011-07-12 03:12:18 +00:00
2016-09-06 20:57:50 +00:00
const OptionDefinition * GetDefinitions ( ) override { return g_option_table ; }
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
// Instance variables to hold the values for command options.
OptionValueUInt64 m_start_idx ;
OptionValueUInt64 m_stop_idx ;
OptionValueUInt64 m_count ;
OptionValueBoolean m_clear ;
} ;
bool DoExecute ( Args & command , CommandReturnObject & result ) override {
if ( m_options . m_clear . GetCurrentValue ( ) & &
m_options . m_clear . OptionWasSet ( ) ) {
m_interpreter . GetCommandHistory ( ) . Clear ( ) ;
result . SetStatus ( lldb : : eReturnStatusSuccessFinishNoResult ) ;
} else {
if ( m_options . m_start_idx . OptionWasSet ( ) & &
m_options . m_stop_idx . OptionWasSet ( ) & &
m_options . m_count . OptionWasSet ( ) ) {
result . AppendError ( " --count, --start-index and --end-index cannot be "
" all specified in the same invocation " ) ;
result . SetStatus ( lldb : : eReturnStatusFailed ) ;
} else {
std : : pair < bool , uint64_t > start_idx (
m_options . m_start_idx . OptionWasSet ( ) ,
m_options . m_start_idx . GetCurrentValue ( ) ) ;
std : : pair < bool , uint64_t > stop_idx (
m_options . m_stop_idx . OptionWasSet ( ) ,
m_options . m_stop_idx . GetCurrentValue ( ) ) ;
std : : pair < bool , uint64_t > count ( m_options . m_count . OptionWasSet ( ) ,
m_options . m_count . GetCurrentValue ( ) ) ;
const CommandHistory & history ( m_interpreter . GetCommandHistory ( ) ) ;
if ( start_idx . first & & start_idx . second = = UINT64_MAX ) {
if ( count . first ) {
start_idx . second = history . GetSize ( ) - count . second ;
stop_idx . second = history . GetSize ( ) - 1 ;
} else if ( stop_idx . first ) {
start_idx . second = stop_idx . second ;
stop_idx . second = history . GetSize ( ) - 1 ;
} else {
start_idx . second = 0 ;
stop_idx . second = history . GetSize ( ) - 1 ;
}
} else {
if ( ! start_idx . first & & ! stop_idx . first & & ! count . first ) {
start_idx . second = 0 ;
stop_idx . second = history . GetSize ( ) - 1 ;
} else if ( start_idx . first ) {
if ( count . first ) {
stop_idx . second = start_idx . second + count . second - 1 ;
} else if ( ! stop_idx . first ) {
stop_idx . second = history . GetSize ( ) - 1 ;
2013-06-17 22:51:50 +00:00
}
2016-09-06 20:57:50 +00:00
} else if ( stop_idx . first ) {
if ( count . first ) {
if ( stop_idx . second > = count . second )
start_idx . second = stop_idx . second - count . second + 1 ;
else
start_idx . second = 0 ;
2013-06-17 22:51:50 +00:00
}
2016-09-06 20:57:50 +00:00
} else /* if (count.first) */
{
start_idx . second = 0 ;
stop_idx . second = count . second - 1 ;
}
}
history . Dump ( result . GetOutputStream ( ) , start_idx . second ,
stop_idx . second ) ;
}
2011-07-12 03:12:18 +00:00
}
2016-09-06 20:57:50 +00:00
return result . Succeeded ( ) ;
}
2012-06-08 21:56:10 +00:00
2016-09-06 20:57:50 +00:00
CommandOptions m_options ;
2011-07-12 03:12:18 +00:00
} ;
OptionDefinition
2016-09-06 20:57:50 +00:00
CommandObjectCommandsHistory : : CommandOptions : : g_option_table [ ] = {
// clang-format off
2016-08-26 23:28:47 +00:00
{ LLDB_OPT_SET_1 , false , " count " , ' c ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypeUnsignedInteger , " How many history commands to print. " } ,
{ LLDB_OPT_SET_1 , false , " start-index " , ' s ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypeUnsignedInteger , " Index at which to start printing history commands (or end to mean tail mode). " } ,
{ LLDB_OPT_SET_1 , false , " end-index " , ' e ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypeUnsignedInteger , " Index at which to stop printing history commands. " } ,
{ LLDB_OPT_SET_2 , false , " clear " , ' C ' , OptionParser : : eNoArgument , nullptr , nullptr , 0 , eArgTypeBoolean , " Clears the current command history. " } ,
{ 0 , false , nullptr , 0 , 0 , nullptr , nullptr , 0 , eArgTypeNone , nullptr }
2016-09-06 20:57:50 +00:00
// clang-format on
2011-07-12 03:12:18 +00:00
} ;
2010-07-07 03:36:20 +00:00
//-------------------------------------------------------------------------
// CommandObjectCommandsSource
//-------------------------------------------------------------------------
2016-09-06 20:57:50 +00:00
class CommandObjectCommandsSource : public CommandObjectParsed {
2012-06-08 21:56:10 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectCommandsSource ( CommandInterpreter & interpreter )
: CommandObjectParsed (
interpreter , " command source " ,
" Read and execute LLDB commands from the file <filename>. " ,
nullptr ) ,
m_options ( ) {
CommandArgumentEntry arg ;
CommandArgumentData file_arg ;
// Define the first (and only) variant of this arg.
file_arg . arg_type = eArgTypeFilename ;
file_arg . arg_repetition = eArgRepeatPlain ;
// There is only one variant this argument could be; put it into the
// argument entry.
arg . push_back ( file_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
}
~ CommandObjectCommandsSource ( ) override = default ;
const char * GetRepeatCommand ( Args & current_command_args ,
uint32_t index ) override {
return " " ;
}
int HandleArgumentCompletion ( Args & input , int & cursor_index ,
int & cursor_char_position ,
OptionElementVector & opt_element_vector ,
int match_start_point , int max_return_elements ,
bool & word_complete ,
StringList & matches ) override {
std : : string completion_str ( input . GetArgumentAtIndex ( cursor_index ) ) ;
completion_str . erase ( cursor_char_position ) ;
CommandCompletions : : InvokeCommonCompletionCallbacks (
GetCommandInterpreter ( ) , CommandCompletions : : eDiskFileCompletion ,
completion_str . c_str ( ) , match_start_point , max_return_elements , nullptr ,
word_complete , matches ) ;
return matches . GetSize ( ) ;
}
Options * GetOptions ( ) override { return & m_options ; }
2012-06-08 21:56:10 +00:00
2016-09-06 20:57:50 +00:00
protected :
class CommandOptions : public Options {
public :
CommandOptions ( )
: Options ( ) , m_stop_on_error ( true ) , m_silent_run ( false ) ,
m_stop_on_continue ( true ) { }
~ CommandOptions ( ) override = default ;
Error SetOptionValue ( uint32_t option_idx , const char * option_arg ,
ExecutionContext * execution_context ) override {
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option ) {
case ' e ' :
error = m_stop_on_error . SetValueFromString ( option_arg ) ;
break ;
case ' c ' :
error = m_stop_on_continue . SetValueFromString ( option_arg ) ;
break ;
case ' s ' :
error = m_silent_run . SetValueFromString ( option_arg ) ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " ,
short_option ) ;
break ;
}
return error ;
2012-06-08 21:56:10 +00:00
}
2016-09-06 20:57:50 +00:00
void OptionParsingStarting ( ExecutionContext * execution_context ) override {
m_stop_on_error . Clear ( ) ;
m_silent_run . Clear ( ) ;
m_stop_on_continue . Clear ( ) ;
2012-06-08 21:56:10 +00:00
}
2016-09-06 20:57:50 +00:00
const OptionDefinition * GetDefinitions ( ) override { return g_option_table ; }
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
// Instance variables to hold the values for command options.
OptionValueBoolean m_stop_on_error ;
OptionValueBoolean m_silent_run ;
OptionValueBoolean m_stop_on_continue ;
} ;
bool DoExecute ( Args & command , CommandReturnObject & result ) override {
const size_t argc = command . GetArgumentCount ( ) ;
if ( argc = = 1 ) {
const char * filename = command . GetArgumentAtIndex ( 0 ) ;
FileSpec cmd_file ( filename , true ) ;
ExecutionContext * exe_ctx = nullptr ; // Just use the default context.
// If any options were set, then use them
if ( m_options . m_stop_on_error . OptionWasSet ( ) | |
m_options . m_silent_run . OptionWasSet ( ) | |
m_options . m_stop_on_continue . OptionWasSet ( ) ) {
// Use user set settings
CommandInterpreterRunOptions options ;
options . SetStopOnContinue (
m_options . m_stop_on_continue . GetCurrentValue ( ) ) ;
options . SetStopOnError ( m_options . m_stop_on_error . GetCurrentValue ( ) ) ;
options . SetEchoCommands ( ! m_options . m_silent_run . GetCurrentValue ( ) ) ;
options . SetPrintResults ( ! m_options . m_silent_run . GetCurrentValue ( ) ) ;
m_interpreter . HandleCommandsFromFile ( cmd_file , exe_ctx , options ,
result ) ;
} else {
// No options were set, inherit any settings from nested "command
// source" commands,
// or set to sane default settings...
CommandInterpreterRunOptions options ;
m_interpreter . HandleCommandsFromFile ( cmd_file , exe_ctx , options ,
result ) ;
}
} else {
result . AppendErrorWithFormat (
" '%s' takes exactly one executable filename argument. \n " ,
GetCommandName ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
2010-07-07 03:36:20 +00:00
}
2016-09-06 20:57:50 +00:00
return result . Succeeded ( ) ;
}
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
CommandOptions m_options ;
2010-07-07 03:36:20 +00:00
} ;
2016-09-06 20:57:50 +00:00
OptionDefinition CommandObjectCommandsSource : : CommandOptions : : g_option_table [ ] =
{
// clang-format off
2016-08-26 23:28:47 +00:00
{ LLDB_OPT_SET_ALL , false , " stop-on-error " , ' e ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypeBoolean , " If true, stop executing commands on error. " } ,
{ LLDB_OPT_SET_ALL , false , " stop-on-continue " , ' c ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypeBoolean , " If true, stop executing commands on continue. " } ,
{ LLDB_OPT_SET_ALL , false , " silent-run " , ' s ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypeBoolean , " If true don't echo commands while executing. " } ,
{ 0 , false , nullptr , 0 , 0 , nullptr , nullptr , 0 , eArgTypeNone , nullptr }
2016-09-06 20:57:50 +00:00
// clang-format on
2011-02-18 00:54:25 +00:00
} ;
2010-07-07 03:36:20 +00:00
# pragma mark CommandObjectCommandsAlias
//-------------------------------------------------------------------------
// CommandObjectCommandsAlias
//-------------------------------------------------------------------------
2016-09-06 20:57:50 +00:00
static const char * g_python_command_instructions =
" Enter your Python command(s). Type 'DONE' to end. \n "
" You must define a Python function with this signature: \n "
" def my_command_impl(debugger, args, result, internal_dict): \n " ;
2011-08-16 16:49:25 +00:00
2016-09-06 20:57:50 +00:00
class CommandObjectCommandsAlias : public CommandObjectRaw {
2016-03-31 01:10:54 +00:00
protected :
2016-09-06 20:57:50 +00:00
class CommandOptions : public OptionGroup {
public :
CommandOptions ( ) : OptionGroup ( ) , m_help ( ) , m_long_help ( ) { }
~ CommandOptions ( ) override = default ;
uint32_t GetNumDefinitions ( ) override { return 3 ; }
const OptionDefinition * GetDefinitions ( ) override { return g_option_table ; }
Error SetOptionValue ( uint32_t option_idx , const char * option_value ,
ExecutionContext * execution_context ) override {
Error error ;
const int short_option = g_option_table [ option_idx ] . short_option ;
switch ( short_option ) {
case ' h ' :
m_help . SetCurrentValue ( option_value ) ;
m_help . SetOptionWasSet ( ) ;
break ;
case ' H ' :
m_long_help . SetCurrentValue ( option_value ) ;
m_long_help . SetOptionWasSet ( ) ;
break ;
default :
error . SetErrorStringWithFormat ( " invalid short option character '%c' " ,
short_option ) ;
break ;
}
return error ;
2016-03-31 01:10:54 +00:00
}
2016-09-06 20:57:50 +00:00
void OptionParsingStarting ( ExecutionContext * execution_context ) override {
m_help . Clear ( ) ;
m_long_help . Clear ( ) ;
}
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
OptionValueString m_help ;
OptionValueString m_long_help ;
} ;
2016-03-31 01:10:54 +00:00
2016-09-06 20:57:50 +00:00
OptionGroupOptions m_option_group ;
CommandOptions m_command_options ;
public :
Options * GetOptions ( ) override { return & m_option_group ; }
CommandObjectCommandsAlias ( CommandInterpreter & interpreter )
: CommandObjectRaw (
interpreter , " command alias " ,
" Define a custom command in terms of an existing command. " ,
nullptr ) ,
m_option_group ( ) , m_command_options ( ) {
m_option_group . Append ( & m_command_options ) ;
m_option_group . Finalize ( ) ;
SetHelpLong (
" 'alias' allows the user to create a short-cut or abbreviation for long \
2015-07-14 05:48:36 +00:00
commands , multi - word commands , and commands that take particular options . \
2016-09-06 20:57:50 +00:00
Below are some simple examples of how one might use the ' alias ' command : "
R " (
2015-07-14 05:48:36 +00:00
( lldb ) command alias sc script
Creates the abbreviation ' sc ' for the ' script ' command .
( lldb ) command alias bp breakpoint
2016-09-06 20:57:50 +00:00
) "
" Creates the abbreviation 'bp' for the 'breakpoint' command. Since \
2015-07-14 05:48:36 +00:00
breakpoint commands are two - word commands , the user would still need to \
2016-09-06 20:57:50 +00:00
enter the second word after ' bp ' , e . g . ' bp enable ' or ' bp delete ' . "
R " (
2015-07-14 05:48:36 +00:00
( lldb ) command alias bpl breakpoint list
Creates the abbreviation ' bpl ' for the two - word command ' breakpoint list ' .
2016-09-06 20:57:50 +00:00
) "
" An alias can include some options for the command, with the values either \
2015-07-14 05:48:36 +00:00
filled in at the time the alias is created , or specified as positional \
arguments , to be filled in when the alias is invoked . The following example \
2016-09-06 20:57:50 +00:00
shows how to create aliases with options : "
R " (
2015-07-14 05:48:36 +00:00
( lldb ) command alias bfl breakpoint set - f % 1 - l % 2
2016-09-06 20:57:50 +00:00
) "
" Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
2015-07-14 05:48:36 +00:00
options already part of the alias . So if the user wants to set a breakpoint \
by file and line without explicitly having to use the - f and - l options , the \
user can now use ' bfl ' instead . The ' % 1 ' and ' % 2 ' are positional placeholders \
for the actual arguments that will be passed when the alias command is used . \
The number in the placeholder refers to the position / order the actual value \
occupies when the alias is used . All the occurrences of ' % 1 ' in the alias \
will be replaced with the first argument , all the occurrences of ' % 2 ' in the \
alias will be replaced with the second argument , and so on . This also allows \
actual arguments to be used multiple times within an alias ( see ' process \
2016-09-06 20:57:50 +00:00
launch ' example below ) . "
R " (
2015-07-14 05:48:36 +00:00
2016-09-06 20:57:50 +00:00
) "
" Note: the positional arguments must substitute as whole words in the resultant \
2015-07-14 05:48:36 +00:00
command , so you can ' t at present do something like this to append the file extension \
2016-09-06 20:57:50 +00:00
\ " .cpp \" : "
R " (
2015-07-14 05:48:36 +00:00
( lldb ) command alias bcppfl breakpoint set - f % 1. cpp - l % 2
2016-09-06 20:57:50 +00:00
) "
" For more complex aliasing, use the \" command regex \" command instead. In the \
2015-07-14 05:48:36 +00:00
' bfl ' case above , the actual file value will be filled in with the first argument \
following ' bfl ' and the actual line number value will be filled in with the second \
2016-09-06 20:57:50 +00:00
argument . The user would use this alias as follows : "
R " (
2015-07-14 05:48:36 +00:00
( lldb ) command alias bfl breakpoint set - f % 1 - l % 2
( lldb ) bfl my - file . c 137
This would be the same as if the user had entered ' breakpoint set - f my - file . c - l 137 ' .
Another example :
( lldb ) command alias pltty process launch - s - o % 1 - e % 1
( lldb ) pltty / dev / tty0
Interpreted as ' process launch - s - o / dev / tty0 - e / dev / tty0 '
2016-09-06 20:57:50 +00:00
) "
" If the user always wanted to pass the same value to a particular option, the \
2015-07-14 05:48:36 +00:00
alias could be defined with that value directly in the alias as a constant , \
2016-09-06 20:57:50 +00:00
rather than using a positional placeholder : "
R " (
2015-07-14 05:48:36 +00:00
( lldb ) command alias bl3 breakpoint set - f % 1 - l 3
2016-09-06 20:57:50 +00:00
Always sets a breakpoint on line 3 of whatever file is indicated . ) " );
CommandArgumentEntry arg1 ;
CommandArgumentEntry arg2 ;
CommandArgumentEntry arg3 ;
CommandArgumentData alias_arg ;
CommandArgumentData cmd_arg ;
CommandArgumentData options_arg ;
// Define the first (and only) variant of this arg.
alias_arg . arg_type = eArgTypeAliasName ;
alias_arg . arg_repetition = eArgRepeatPlain ;
2010-07-07 03:36:20 +00:00
2016-09-06 20:57:50 +00:00
// There is only one variant this argument could be; put it into the
// argument entry.
arg1 . push_back ( alias_arg ) ;
// Define the first (and only) variant of this arg.
cmd_arg . arg_type = eArgTypeCommandName ;
cmd_arg . arg_repetition = eArgRepeatPlain ;
// There is only one variant this argument could be; put it into the
// argument entry.
arg2 . push_back ( cmd_arg ) ;
// Define the first (and only) variant of this arg.
options_arg . arg_type = eArgTypeAliasOptions ;
options_arg . arg_repetition = eArgRepeatOptional ;
// There is only one variant this argument could be; put it into the
// argument entry.
arg3 . push_back ( options_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg1 ) ;
m_arguments . push_back ( arg2 ) ;
m_arguments . push_back ( arg3 ) ;
}
~ CommandObjectCommandsAlias ( ) override = default ;
2010-07-07 03:36:20 +00:00
2012-06-08 21:56:10 +00:00
protected :
2016-09-06 20:57:50 +00:00
bool DoExecute ( const char * raw_command_line ,
CommandReturnObject & result ) override {
if ( ! raw_command_line | | ! raw_command_line [ 0 ] ) {
result . AppendError ( " 'command alias' requires at least two arguments " ) ;
return false ;
}
2016-08-11 23:51:28 +00:00
2016-09-06 20:57:50 +00:00
ExecutionContext exe_ctx = GetCommandInterpreter ( ) . GetExecutionContext ( ) ;
m_option_group . NotifyOptionParsingStarting ( & exe_ctx ) ;
const char * remainder = nullptr ;
if ( raw_command_line [ 0 ] = = ' - ' ) {
// We have some options and these options MUST end with --.
const char * end_options = nullptr ;
const char * s = raw_command_line ;
while ( s & & s [ 0 ] ) {
end_options = : : strstr ( s , " -- " ) ;
if ( end_options ) {
end_options + = 2 ; // Get past the "--"
if ( : : isspace ( end_options [ 0 ] ) ) {
remainder = end_options ;
while ( : : isspace ( * remainder ) )
+ + remainder ;
break ;
}
}
s = end_options ;
}
if ( end_options ) {
Args args (
llvm : : StringRef ( raw_command_line , end_options - raw_command_line ) ) ;
if ( ! ParseOptions ( args , result ) )
return false ;
Error error ( m_option_group . NotifyOptionParsingFinished ( & exe_ctx ) ) ;
if ( error . Fail ( ) ) {
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
2012-06-08 21:56:10 +00:00
}
2016-09-06 20:57:50 +00:00
if ( nullptr = = remainder )
remainder = raw_command_line ;
2012-06-08 21:56:10 +00:00
2016-09-06 20:57:50 +00:00
std : : string raw_command_string ( remainder ) ;
Args args ( raw_command_string . c_str ( ) ) ;
2016-03-08 05:37:15 +00:00
2016-09-06 20:57:50 +00:00
size_t argc = args . GetArgumentCount ( ) ;
2016-03-08 05:37:15 +00:00
2016-09-06 20:57:50 +00:00
if ( argc < 2 ) {
result . AppendError ( " 'command alias' requires at least two arguments " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2010-12-09 22:52:49 +00:00
}
2010-07-07 03:36:20 +00:00
2016-09-06 20:57:50 +00:00
// Get the alias command.
const std : : string alias_command = args . GetArgumentAtIndex ( 0 ) ;
if ( alias_command . size ( ) > 1 & & alias_command [ 0 ] = = ' - ' ) {
result . AppendError ( " aliases starting with a dash are not supported " ) ;
if ( alias_command = = " --help " | | alias_command = = " --long-help " ) {
result . AppendWarning ( " if trying to pass options to 'command alias' add "
" a -- at the end of the options " ) ;
}
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// Strip the new alias name off 'raw_command_string' (leave it on args,
// which gets passed to 'Execute', which
// does the stripping itself.
size_t pos = raw_command_string . find ( alias_command ) ;
if ( pos = = 0 ) {
raw_command_string = raw_command_string . substr ( alias_command . size ( ) ) ;
pos = raw_command_string . find_first_not_of ( ' ' ) ;
if ( ( pos ! = std : : string : : npos ) & & ( pos > 0 ) )
raw_command_string = raw_command_string . substr ( pos ) ;
} else {
result . AppendError ( " Error parsing command string. No alias created. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// Verify that the command is alias-able.
if ( m_interpreter . CommandExists ( alias_command . c_str ( ) ) ) {
result . AppendErrorWithFormat (
" '%s' is a permanent debugger command and cannot be redefined. \n " ,
alias_command . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2010-07-07 03:36:20 +00:00
2016-09-06 20:57:50 +00:00
// Get CommandObject that is being aliased. The command name is read from
// the front of raw_command_string.
// raw_command_string is returned with the name of the command object
// stripped off the front.
std : : string original_raw_command_string ( raw_command_string ) ;
CommandObject * cmd_obj =
m_interpreter . GetCommandObjectForCommand ( raw_command_string ) ;
if ( ! cmd_obj ) {
result . AppendErrorWithFormat ( " invalid command given to 'command alias'. "
" '%s' does not begin with a valid command. "
" No alias created. " ,
original_raw_command_string . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
} else if ( ! cmd_obj - > WantsRawCommandString ( ) ) {
// Note that args was initialized with the original command, and has not
// been updated to this point.
// Therefore can we pass it to the version of Execute that does not
// need/expect raw input in the alias.
return HandleAliasingNormalCommand ( args , result ) ;
} else {
return HandleAliasingRawCommand ( alias_command , raw_command_string ,
* cmd_obj , result ) ;
}
return result . Succeeded ( ) ;
}
bool HandleAliasingRawCommand ( const std : : string & alias_command ,
std : : string & raw_command_string ,
CommandObject & cmd_obj ,
CommandReturnObject & result ) {
// Verify & handle any options/arguments passed to the alias command
OptionArgVectorSP option_arg_vector_sp =
OptionArgVectorSP ( new OptionArgVector ) ;
if ( CommandObjectSP cmd_obj_sp =
m_interpreter . GetCommandSPExact ( cmd_obj . GetCommandName ( ) , false ) ) {
if ( m_interpreter . AliasExists ( alias_command . c_str ( ) ) | |
m_interpreter . UserCommandExists ( alias_command . c_str ( ) ) ) {
result . AppendWarningWithFormat (
" Overwriting existing definition for '%s'. \n " ,
alias_command . c_str ( ) ) ;
}
if ( CommandAlias * alias = m_interpreter . AddAlias (
alias_command . c_str ( ) , cmd_obj_sp , raw_command_string . c_str ( ) ) ) {
if ( m_command_options . m_help . OptionWasSet ( ) )
alias - > SetHelp ( m_command_options . m_help . GetCurrentValue ( ) ) ;
if ( m_command_options . m_long_help . OptionWasSet ( ) )
alias - > SetHelpLong ( m_command_options . m_long_help . GetCurrentValue ( ) ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
} else {
result . AppendError ( " Unable to create requested alias. \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
} else {
result . AppendError ( " Unable to create requested alias. \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
2010-07-07 03:36:20 +00:00
2016-09-06 20:57:50 +00:00
return result . Succeeded ( ) ;
}
2010-07-07 03:36:20 +00:00
2016-09-06 20:57:50 +00:00
bool HandleAliasingNormalCommand ( Args & args , CommandReturnObject & result ) {
size_t argc = args . GetArgumentCount ( ) ;
2010-07-07 03:36:20 +00:00
2016-09-06 20:57:50 +00:00
if ( argc < 2 ) {
result . AppendError ( " 'command alias' requires at least two arguments " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2010-07-07 03:36:20 +00:00
2016-09-06 20:57:50 +00:00
const std : : string alias_command = args . GetArgumentAtIndex ( 0 ) ;
const std : : string actual_command = args . GetArgumentAtIndex ( 1 ) ;
args . Shift ( ) ; // Shift the alias command word off the argument vector.
args . Shift ( ) ; // Shift the old command word off the argument vector.
// Verify that the command is alias'able, and get the appropriate command
// object.
if ( m_interpreter . CommandExists ( alias_command . c_str ( ) ) ) {
result . AppendErrorWithFormat (
" '%s' is a permanent debugger command and cannot be redefined. \n " ,
alias_command . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
} else {
CommandObjectSP command_obj_sp (
m_interpreter . GetCommandSPExact ( actual_command . c_str ( ) , true ) ) ;
CommandObjectSP subcommand_obj_sp ;
bool use_subcommand = false ;
if ( command_obj_sp ) {
CommandObject * cmd_obj = command_obj_sp . get ( ) ;
CommandObject * sub_cmd_obj = nullptr ;
OptionArgVectorSP option_arg_vector_sp =
OptionArgVectorSP ( new OptionArgVector ) ;
while ( cmd_obj - > IsMultiwordObject ( ) & & args . GetArgumentCount ( ) > 0 ) {
if ( argc > = 3 ) {
const std : : string sub_command = args . GetArgumentAtIndex ( 0 ) ;
assert ( sub_command . length ( ) ! = 0 ) ;
subcommand_obj_sp = cmd_obj - > GetSubcommandSP ( sub_command . c_str ( ) ) ;
if ( subcommand_obj_sp ) {
sub_cmd_obj = subcommand_obj_sp . get ( ) ;
use_subcommand = true ;
args . Shift ( ) ; // Shift the sub_command word off the argument
// vector.
cmd_obj = sub_cmd_obj ;
} else {
result . AppendErrorWithFormat (
" '%s' is not a valid sub-command of '%s'. "
" Unable to create alias. \n " ,
sub_command . c_str ( ) , actual_command . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
}
// Verify & handle any options/arguments passed to the alias command
std : : string args_string ;
if ( args . GetArgumentCount ( ) > 0 ) {
CommandObjectSP tmp_sp =
m_interpreter . GetCommandSPExact ( cmd_obj - > GetCommandName ( ) , false ) ;
if ( use_subcommand )
tmp_sp = m_interpreter . GetCommandSPExact (
sub_cmd_obj - > GetCommandName ( ) , false ) ;
args . GetCommandString ( args_string ) ;
}
if ( m_interpreter . AliasExists ( alias_command . c_str ( ) ) | |
m_interpreter . UserCommandExists ( alias_command . c_str ( ) ) ) {
result . AppendWarningWithFormat (
" Overwriting existing definition for '%s'. \n " ,
alias_command . c_str ( ) ) ;
}
if ( CommandAlias * alias = m_interpreter . AddAlias (
alias_command . c_str ( ) ,
use_subcommand ? subcommand_obj_sp : command_obj_sp ,
args_string . c_str ( ) ) ) {
if ( m_command_options . m_help . OptionWasSet ( ) )
alias - > SetHelp ( m_command_options . m_help . GetCurrentValue ( ) ) ;
if ( m_command_options . m_long_help . OptionWasSet ( ) )
alias - > SetHelpLong ( m_command_options . m_long_help . GetCurrentValue ( ) ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
} else {
result . AppendError ( " Unable to create requested alias. \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
} else {
result . AppendErrorWithFormat ( " '%s' is not an existing command. \n " ,
actual_command . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2010-07-07 03:36:20 +00:00
}
2016-09-06 20:57:50 +00:00
return result . Succeeded ( ) ;
}
2010-07-07 03:36:20 +00:00
} ;
2016-09-06 20:57:50 +00:00
OptionDefinition CommandObjectCommandsAlias : : CommandOptions : : g_option_table [ ] =
{
// clang-format off
2016-08-26 23:28:47 +00:00
{ LLDB_OPT_SET_ALL , false , " help " , ' h ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypeHelpText , " Help text for this command " } ,
{ LLDB_OPT_SET_ALL , false , " long-help " , ' H ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypeHelpText , " Long help text for this command " } ,
{ 0 , false , nullptr , 0 , 0 , nullptr , nullptr , 0 , eArgTypeNone , nullptr }
2016-09-06 20:57:50 +00:00
// clang-format on
2016-03-31 01:10:54 +00:00
} ;
2010-07-07 03:36:20 +00:00
# pragma mark CommandObjectCommandsUnalias
//-------------------------------------------------------------------------
// CommandObjectCommandsUnalias
//-------------------------------------------------------------------------
2016-09-06 20:57:50 +00:00
class CommandObjectCommandsUnalias : public CommandObjectParsed {
2010-07-07 03:36:20 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectCommandsUnalias ( CommandInterpreter & interpreter )
: CommandObjectParsed (
interpreter , " command unalias " ,
" Delete one or more custom commands defined by 'command alias'. " ,
nullptr ) {
CommandArgumentEntry arg ;
CommandArgumentData alias_arg ;
2010-07-07 03:36:20 +00:00
2016-09-06 20:57:50 +00:00
// Define the first (and only) variant of this arg.
alias_arg . arg_type = eArgTypeAliasName ;
alias_arg . arg_repetition = eArgRepeatPlain ;
// There is only one variant this argument could be; put it into the
// argument entry.
arg . push_back ( alias_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
}
~ CommandObjectCommandsUnalias ( ) override = default ;
2010-07-07 03:36:20 +00:00
2012-06-08 21:56:10 +00:00
protected :
2016-09-06 20:57:50 +00:00
bool DoExecute ( Args & args , CommandReturnObject & result ) override {
CommandObject : : CommandMap : : iterator pos ;
CommandObject * cmd_obj ;
if ( args . GetArgumentCount ( ) ! = 0 ) {
const char * command_name = args . GetArgumentAtIndex ( 0 ) ;
cmd_obj = m_interpreter . GetCommandObject ( command_name ) ;
if ( cmd_obj ) {
if ( m_interpreter . CommandExists ( command_name ) ) {
if ( cmd_obj - > IsRemovable ( ) ) {
result . AppendErrorWithFormat (
" '%s' is not an alias, it is a debugger command which can be "
" removed using the 'command delete' command. \n " ,
command_name ) ;
} else {
result . AppendErrorWithFormat (
" '%s' is a permanent debugger command and cannot be removed. \n " ,
command_name ) ;
}
result . SetStatus ( eReturnStatusFailed ) ;
} else {
if ( ! m_interpreter . RemoveAlias ( command_name ) ) {
if ( m_interpreter . AliasExists ( command_name ) )
result . AppendErrorWithFormat (
" Error occurred while attempting to unalias '%s'. \n " ,
command_name ) ;
2010-07-07 03:36:20 +00:00
else
2016-09-06 20:57:50 +00:00
result . AppendErrorWithFormat ( " '%s' is not an existing alias. \n " ,
command_name ) ;
result . SetStatus ( eReturnStatusFailed ) ;
} else
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
} else {
result . AppendErrorWithFormat (
" '%s' is not a known command. \n Try 'help' to see a "
" current list of commands. \n " ,
command_name ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
} else {
result . AppendError ( " must call 'unalias' with a valid alias " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
2010-07-07 03:36:20 +00:00
}
2016-09-06 20:57:50 +00:00
return result . Succeeded ( ) ;
}
2010-07-07 03:36:20 +00:00
} ;
2015-01-09 19:08:20 +00:00
# pragma mark CommandObjectCommandsDelete
//-------------------------------------------------------------------------
// CommandObjectCommandsDelete
//-------------------------------------------------------------------------
2016-09-06 20:57:50 +00:00
class CommandObjectCommandsDelete : public CommandObjectParsed {
2015-01-09 19:08:20 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectCommandsDelete ( CommandInterpreter & interpreter )
: CommandObjectParsed (
interpreter , " command delete " ,
" Delete one or more custom commands defined by 'command regex'. " ,
nullptr ) {
CommandArgumentEntry arg ;
CommandArgumentData alias_arg ;
2015-01-09 19:08:20 +00:00
2016-09-06 20:57:50 +00:00
// Define the first (and only) variant of this arg.
alias_arg . arg_type = eArgTypeCommandName ;
alias_arg . arg_repetition = eArgRepeatPlain ;
2015-01-09 19:08:20 +00:00
2016-09-06 20:57:50 +00:00
// There is only one variant this argument could be; put it into the
// argument entry.
arg . push_back ( alias_arg ) ;
2015-01-09 19:08:20 +00:00
2016-09-06 20:57:50 +00:00
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
}
2015-01-09 19:08:20 +00:00
2016-09-06 20:57:50 +00:00
~ CommandObjectCommandsDelete ( ) override = default ;
2015-01-09 19:08:20 +00:00
protected :
2016-09-06 20:57:50 +00:00
bool DoExecute ( Args & args , CommandReturnObject & result ) override {
CommandObject : : CommandMap : : iterator pos ;
if ( args . GetArgumentCount ( ) ! = 0 ) {
const char * command_name = args . GetArgumentAtIndex ( 0 ) ;
if ( m_interpreter . CommandExists ( command_name ) ) {
if ( m_interpreter . RemoveCommand ( command_name ) ) {
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
} else {
result . AppendErrorWithFormat (
" '%s' is a permanent debugger command and cannot be removed. \n " ,
command_name ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
} else {
StreamString error_msg_stream ;
const bool generate_apropos = true ;
const bool generate_type_lookup = false ;
CommandObjectHelp : : GenerateAdditionalHelpAvenuesMessage (
& error_msg_stream , command_name , nullptr , nullptr , generate_apropos ,
generate_type_lookup ) ;
result . AppendErrorWithFormat ( " %s " , error_msg_stream . GetData ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
} else {
result . AppendErrorWithFormat ( " must call '%s' with one or more valid user "
" defined regular expression command names " ,
GetCommandName ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
2015-01-09 19:08:20 +00:00
}
2016-09-06 20:57:50 +00:00
return result . Succeeded ( ) ;
}
2015-01-09 19:08:20 +00:00
} ;
2011-04-20 16:37:46 +00:00
//-------------------------------------------------------------------------
// CommandObjectCommandsAddRegex
//-------------------------------------------------------------------------
2012-06-08 21:56:10 +00:00
# pragma mark CommandObjectCommandsAddRegex
2011-04-20 16:37:46 +00:00
2016-09-06 20:57:50 +00:00
class CommandObjectCommandsAddRegex : public CommandObjectParsed ,
public IOHandlerDelegateMultiline {
2011-04-20 16:37:46 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectCommandsAddRegex ( CommandInterpreter & interpreter )
: CommandObjectParsed (
interpreter , " command regex " , " Define a custom command in terms of "
" existing commands by matching "
" regular expressions. " ,
" command regex <cmd-name> [s/<regex>/<subst>/ ...] " ) ,
IOHandlerDelegateMultiline ( " " ,
IOHandlerDelegate : : Completion : : LLDBCommand ) ,
m_options ( ) {
SetHelpLong (
R " (
) "
" This command allows the user to create powerful regular expression commands \
2015-07-14 05:48:36 +00:00
with substitutions . The regular expressions and substitutions are specified \
2016-09-06 20:57:50 +00:00
using the regular expression substitution format of : "
R " (
2015-07-14 05:48:36 +00:00
s / < regex > / < subst > /
2016-09-06 20:57:50 +00:00
) "
" <regex> is a regular expression that can use parenthesis to capture regular \
2015-07-14 05:48:36 +00:00
expression input and substitute the captured matches in the output using % 1 \
2016-09-06 20:57:50 +00:00
for the first match , % 2 for the second , and so on . "
R " (
2015-07-14 05:48:36 +00:00
2016-09-06 20:57:50 +00:00
) "
" The regular expressions can all be specified on the command line if more than \
2015-07-14 05:48:36 +00:00
one argument is provided . If just the command name is provided on the command \
line , then the regular expressions and substitutions can be entered on separate \
2016-09-06 20:57:50 +00:00
lines , followed by an empty line to terminate the command definition . "
R " (
2015-07-14 05:48:36 +00:00
EXAMPLES
2016-09-06 20:57:50 +00:00
) "
" The following example will define a regular expression command named 'f' that \
2015-07-14 05:48:36 +00:00
will call ' finish ' if there are no arguments , or ' frame select < frame - idx > ' if \
2016-09-06 20:57:50 +00:00
a number follows ' f ' : "
R " (
2015-07-14 05:48:36 +00:00
2016-09-06 20:57:50 +00:00
( lldb ) command regex f s / ^ $ / finish / ' s / ( [ 0 - 9 ] + ) / frame select % 1 / ' ) " );
}
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
~ CommandObjectCommandsAddRegex ( ) override = default ;
2016-02-22 23:46:47 +00:00
2012-06-08 21:56:10 +00:00
protected :
2016-09-06 20:57:50 +00:00
void IOHandlerActivated ( IOHandler & io_handler ) override {
StreamFileSP output_sp ( io_handler . GetOutputStreamFile ( ) ) ;
if ( output_sp ) {
output_sp - > PutCString ( " Enter one of more sed substitution commands in "
" the form: 's/<regex>/<subst>/'. \n Terminate the "
" substitution list with an empty line. \n " ) ;
output_sp - > Flush ( ) ;
2014-01-27 23:43:24 +00:00
}
2016-09-06 20:57:50 +00:00
}
void IOHandlerInputComplete ( IOHandler & io_handler ,
std : : string & data ) override {
io_handler . SetIsDone ( true ) ;
if ( m_regex_cmd_ap ) {
StringList lines ;
if ( lines . SplitIntoLines ( data ) ) {
const size_t num_lines = lines . GetSize ( ) ;
bool check_only = false ;
for ( size_t i = 0 ; i < num_lines ; + + i ) {
llvm : : StringRef bytes_strref ( lines [ i ] ) ;
Error error = AppendRegexSubstitution ( bytes_strref , check_only ) ;
if ( error . Fail ( ) ) {
if ( ! m_interpreter . GetDebugger ( )
. GetCommandInterpreter ( )
. GetBatchCommandMode ( ) ) {
StreamSP out_stream =
m_interpreter . GetDebugger ( ) . GetAsyncOutputStream ( ) ;
out_stream - > Printf ( " error: %s \n " , error . AsCString ( ) ) ;
2014-01-27 23:43:24 +00:00
}
2016-09-06 20:57:50 +00:00
}
2014-01-27 23:43:24 +00:00
}
2016-09-06 20:57:50 +00:00
}
if ( m_regex_cmd_ap - > HasRegexEntries ( ) ) {
CommandObjectSP cmd_sp ( m_regex_cmd_ap . release ( ) ) ;
m_interpreter . AddCommand ( cmd_sp - > GetCommandName ( ) , cmd_sp , true ) ;
}
}
}
bool DoExecute ( Args & command , CommandReturnObject & result ) override {
const size_t argc = command . GetArgumentCount ( ) ;
if ( argc = = 0 ) {
result . AppendError ( " usage: 'command regex <command-name> "
" [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]' \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
} else {
Error error ;
const char * name = command . GetArgumentAtIndex ( 0 ) ;
m_regex_cmd_ap . reset ( new CommandObjectRegexCommand (
m_interpreter , name , m_options . GetHelp ( ) , m_options . GetSyntax ( ) , 10 ,
0 , true ) ) ;
if ( argc = = 1 ) {
Debugger & debugger = m_interpreter . GetDebugger ( ) ;
bool color_prompt = debugger . GetUseColor ( ) ;
const bool multiple_lines = true ; // Get multiple lines
IOHandlerSP io_handler_sp ( new IOHandlerEditline (
debugger , IOHandler : : Type : : Other ,
" lldb-regex " , // Name of input reader for history
" > " , // Prompt
nullptr , // Continuation prompt
multiple_lines , color_prompt ,
0 , // Don't show line numbers
* this ) ) ;
if ( io_handler_sp ) {
debugger . PushIOHandler ( io_handler_sp ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
} else {
for ( size_t arg_idx = 1 ; arg_idx < argc ; + + arg_idx ) {
llvm : : StringRef arg_strref ( command . GetArgumentAtIndex ( arg_idx ) ) ;
bool check_only = false ;
error = AppendRegexSubstitution ( arg_strref , check_only ) ;
if ( error . Fail ( ) )
break ;
}
if ( error . Success ( ) ) {
AddRegexCommandToInterpreter ( ) ;
}
}
if ( error . Fail ( ) ) {
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
2014-01-27 23:43:24 +00:00
}
2016-09-06 20:57:50 +00:00
return result . Succeeded ( ) ;
}
Error AppendRegexSubstitution ( const llvm : : StringRef & regex_sed ,
bool check_only ) {
Error error ;
2011-04-20 22:55:21 +00:00
2016-09-06 20:57:50 +00:00
if ( ! m_regex_cmd_ap ) {
error . SetErrorStringWithFormat (
" invalid regular expression command object for: '%.*s' " ,
( int ) regex_sed . size ( ) , regex_sed . data ( ) ) ;
return error ;
2011-04-20 16:37:46 +00:00
}
2011-04-20 22:55:21 +00:00
2016-09-06 20:57:50 +00:00
size_t regex_sed_size = regex_sed . size ( ) ;
2011-04-20 22:55:21 +00:00
2016-09-06 20:57:50 +00:00
if ( regex_sed_size < = 1 ) {
error . SetErrorStringWithFormat (
" regular expression substitution string is too short: '%.*s' " ,
( int ) regex_sed . size ( ) , regex_sed . data ( ) ) ;
return error ;
}
2011-04-20 22:55:21 +00:00
2016-09-06 20:57:50 +00:00
if ( regex_sed [ 0 ] ! = ' s ' ) {
error . SetErrorStringWithFormat ( " regular expression substitution string "
" doesn't start with 's': '%.*s' " ,
( int ) regex_sed . size ( ) , regex_sed . data ( ) ) ;
return error ;
}
const size_t first_separator_char_pos = 1 ;
// use the char that follows 's' as the regex separator character
// so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
const char separator_char = regex_sed [ first_separator_char_pos ] ;
const size_t second_separator_char_pos =
regex_sed . find ( separator_char , first_separator_char_pos + 1 ) ;
if ( second_separator_char_pos = = std : : string : : npos ) {
error . SetErrorStringWithFormat (
" missing second '%c' separator char after '%.*s' in '%.*s' " ,
separator_char ,
( int ) ( regex_sed . size ( ) - first_separator_char_pos - 1 ) ,
regex_sed . data ( ) + ( first_separator_char_pos + 1 ) ,
( int ) regex_sed . size ( ) , regex_sed . data ( ) ) ;
return error ;
}
2014-01-27 23:43:24 +00:00
2016-09-06 20:57:50 +00:00
const size_t third_separator_char_pos =
regex_sed . find ( separator_char , second_separator_char_pos + 1 ) ;
if ( third_separator_char_pos = = std : : string : : npos ) {
error . SetErrorStringWithFormat (
" missing third '%c' separator char after '%.*s' in '%.*s' " ,
separator_char ,
( int ) ( regex_sed . size ( ) - second_separator_char_pos - 1 ) ,
regex_sed . data ( ) + ( second_separator_char_pos + 1 ) ,
( int ) regex_sed . size ( ) , regex_sed . data ( ) ) ;
return error ;
}
if ( third_separator_char_pos ! = regex_sed_size - 1 ) {
// Make sure that everything that follows the last regex
// separator char
if ( regex_sed . find_first_not_of ( " \t \n \v \f \r " ,
third_separator_char_pos + 1 ) ! =
std : : string : : npos ) {
error . SetErrorStringWithFormat (
" extra data found after the '%.*s' regular expression substitution "
" string: '%.*s' " ,
( int ) third_separator_char_pos + 1 , regex_sed . data ( ) ,
( int ) ( regex_sed . size ( ) - third_separator_char_pos - 1 ) ,
regex_sed . data ( ) + ( third_separator_char_pos + 1 ) ) ;
2011-04-20 22:55:21 +00:00
return error ;
2016-09-06 20:57:50 +00:00
}
} else if ( first_separator_char_pos + 1 = = second_separator_char_pos ) {
error . SetErrorStringWithFormat (
" <regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s' " ,
separator_char , separator_char , separator_char , ( int ) regex_sed . size ( ) ,
regex_sed . data ( ) ) ;
return error ;
} else if ( second_separator_char_pos + 1 = = third_separator_char_pos ) {
error . SetErrorStringWithFormat (
" <subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s' " ,
separator_char , separator_char , separator_char , ( int ) regex_sed . size ( ) ,
regex_sed . data ( ) ) ;
return error ;
2011-04-20 16:37:46 +00:00
}
2016-09-06 20:57:50 +00:00
if ( ! check_only ) {
std : : string regex ( regex_sed . substr ( first_separator_char_pos + 1 ,
second_separator_char_pos -
first_separator_char_pos - 1 ) ) ;
std : : string subst ( regex_sed . substr ( second_separator_char_pos + 1 ,
third_separator_char_pos -
second_separator_char_pos - 1 ) ) ;
m_regex_cmd_ap - > AddRegexCommand ( regex . c_str ( ) , subst . c_str ( ) ) ;
}
return error ;
}
void AddRegexCommandToInterpreter ( ) {
if ( m_regex_cmd_ap ) {
if ( m_regex_cmd_ap - > HasRegexEntries ( ) ) {
CommandObjectSP cmd_sp ( m_regex_cmd_ap . release ( ) ) ;
m_interpreter . AddCommand ( cmd_sp - > GetCommandName ( ) , cmd_sp , true ) ;
}
2011-04-20 16:37:46 +00:00
}
2016-09-06 20:57:50 +00:00
}
2011-04-20 16:37:46 +00:00
private :
2016-09-06 20:57:50 +00:00
std : : unique_ptr < CommandObjectRegexCommand > m_regex_cmd_ap ;
class CommandOptions : public Options {
public :
CommandOptions ( ) : Options ( ) { }
~ CommandOptions ( ) override = default ;
Error SetOptionValue ( uint32_t option_idx , const char * option_arg ,
ExecutionContext * execution_context ) override {
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option ) {
case ' h ' :
m_help . assign ( option_arg ) ;
break ;
case ' s ' :
m_syntax . assign ( option_arg ) ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " ,
short_option ) ;
break ;
}
return error ;
}
void OptionParsingStarting ( ExecutionContext * execution_context ) override {
m_help . clear ( ) ;
m_syntax . clear ( ) ;
}
const OptionDefinition * GetDefinitions ( ) override { return g_option_table ; }
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
const char * GetHelp ( ) {
return ( m_help . empty ( ) ? nullptr : m_help . c_str ( ) ) ;
}
const char * GetSyntax ( ) {
return ( m_syntax . empty ( ) ? nullptr : m_syntax . c_str ( ) ) ;
}
protected :
// Instance variables to hold the values for command options.
std : : string m_help ;
std : : string m_syntax ;
} ;
Options * GetOptions ( ) override { return & m_options ; }
CommandOptions m_options ;
2011-04-20 16:37:46 +00:00
} ;
OptionDefinition
2016-09-06 20:57:50 +00:00
CommandObjectCommandsAddRegex : : CommandOptions : : g_option_table [ ] = {
// clang-format off
2016-08-26 23:28:47 +00:00
{ LLDB_OPT_SET_1 , false , " help " , ' h ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypeNone , " The help text to display for this command. " } ,
{ LLDB_OPT_SET_1 , false , " syntax " , ' s ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypeNone , " A syntax string showing the typical usage syntax. " } ,
{ 0 , false , nullptr , 0 , 0 , nullptr , nullptr , 0 , eArgTypeNone , nullptr }
2016-09-06 20:57:50 +00:00
// clang-format on
2011-04-20 16:37:46 +00:00
} ;
2016-09-06 20:57:50 +00:00
class CommandObjectPythonFunction : public CommandObjectRaw {
2011-08-16 23:24:13 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectPythonFunction ( CommandInterpreter & interpreter , std : : string name ,
std : : string funct , std : : string help ,
ScriptedCommandSynchronicity synch )
: CommandObjectRaw ( interpreter , name . c_str ( ) , nullptr , nullptr ) ,
m_function_name ( funct ) , m_synchro ( synch ) , m_fetched_help_long ( false ) {
if ( ! help . empty ( ) )
SetHelp ( help . c_str ( ) ) ;
else {
StreamString stream ;
stream . Printf ( " For more information run 'help %s' " , name . c_str ( ) ) ;
SetHelp ( stream . GetData ( ) ) ;
2011-08-16 23:24:13 +00:00
}
2016-09-06 20:57:50 +00:00
}
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
~ CommandObjectPythonFunction ( ) override = default ;
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
bool IsRemovable ( ) const override { return true ; }
2012-06-08 21:56:10 +00:00
2016-09-06 20:57:50 +00:00
const std : : string & GetFunctionName ( ) { return m_function_name ; }
2012-06-08 21:56:10 +00:00
2016-09-06 20:57:50 +00:00
ScriptedCommandSynchronicity GetSynchronicity ( ) { return m_synchro ; }
const char * GetHelpLong ( ) override {
if ( ! m_fetched_help_long ) {
ScriptInterpreter * scripter = m_interpreter . GetScriptInterpreter ( ) ;
if ( scripter ) {
std : : string docstring ;
m_fetched_help_long = scripter - > GetDocumentationForItem (
m_function_name . c_str ( ) , docstring ) ;
if ( ! docstring . empty ( ) )
SetHelpLong ( docstring . c_str ( ) ) ;
}
2012-09-18 21:53:02 +00:00
}
2016-09-06 20:57:50 +00:00
return CommandObjectRaw : : GetHelpLong ( ) ;
}
2012-06-08 21:56:10 +00:00
protected :
2016-09-06 20:57:50 +00:00
bool DoExecute ( const char * raw_command_line ,
CommandReturnObject & result ) override {
ScriptInterpreter * scripter = m_interpreter . GetScriptInterpreter ( ) ;
Error error ;
result . SetStatus ( eReturnStatusInvalid ) ;
if ( ! scripter | |
! scripter - > RunScriptBasedCommand ( m_function_name . c_str ( ) ,
raw_command_line , m_synchro , result ,
error , m_exe_ctx ) ) {
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
} else {
// Don't change the status if the command already set it...
if ( result . GetStatus ( ) = = eReturnStatusInvalid ) {
if ( result . GetOutputData ( ) = = nullptr | |
result . GetOutputData ( ) [ 0 ] = = ' \0 ' )
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
2011-08-16 23:24:13 +00:00
else
2016-09-06 20:57:50 +00:00
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
}
2011-08-16 23:24:13 +00:00
}
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
return result . Succeeded ( ) ;
}
2016-02-22 23:46:47 +00:00
private :
2016-09-06 20:57:50 +00:00
std : : string m_function_name ;
ScriptedCommandSynchronicity m_synchro ;
bool m_fetched_help_long ;
2012-06-08 21:56:10 +00:00
} ;
2011-11-07 22:57:04 +00:00
2016-09-06 20:57:50 +00:00
class CommandObjectScriptingObject : public CommandObjectRaw {
2015-03-13 02:20:41 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectScriptingObject ( CommandInterpreter & interpreter ,
std : : string name ,
StructuredData : : GenericSP cmd_obj_sp ,
ScriptedCommandSynchronicity synch )
: CommandObjectRaw ( interpreter , name . c_str ( ) , nullptr , nullptr ) ,
m_cmd_obj_sp ( cmd_obj_sp ) , m_synchro ( synch ) , m_fetched_help_short ( false ) ,
m_fetched_help_long ( false ) {
StreamString stream ;
stream . Printf ( " For more information run 'help %s' " , name . c_str ( ) ) ;
SetHelp ( stream . GetData ( ) ) ;
if ( ScriptInterpreter * scripter = m_interpreter . GetScriptInterpreter ( ) )
GetFlags ( ) . Set ( scripter - > GetFlagsForCommandObject ( cmd_obj_sp ) ) ;
}
~ CommandObjectScriptingObject ( ) override = default ;
bool IsRemovable ( ) const override { return true ; }
StructuredData : : GenericSP GetImplementingObject ( ) { return m_cmd_obj_sp ; }
ScriptedCommandSynchronicity GetSynchronicity ( ) { return m_synchro ; }
const char * GetHelp ( ) override {
if ( ! m_fetched_help_short ) {
ScriptInterpreter * scripter = m_interpreter . GetScriptInterpreter ( ) ;
if ( scripter ) {
std : : string docstring ;
m_fetched_help_short =
scripter - > GetShortHelpForCommandObject ( m_cmd_obj_sp , docstring ) ;
if ( ! docstring . empty ( ) )
SetHelp ( docstring . c_str ( ) ) ;
}
2015-03-13 02:20:41 +00:00
}
2016-09-06 20:57:50 +00:00
return CommandObjectRaw : : GetHelp ( ) ;
}
const char * GetHelpLong ( ) override {
if ( ! m_fetched_help_long ) {
ScriptInterpreter * scripter = m_interpreter . GetScriptInterpreter ( ) ;
if ( scripter ) {
std : : string docstring ;
m_fetched_help_long =
scripter - > GetLongHelpForCommandObject ( m_cmd_obj_sp , docstring ) ;
if ( ! docstring . empty ( ) )
SetHelpLong ( docstring . c_str ( ) ) ;
}
2015-03-13 02:20:41 +00:00
}
2016-09-06 20:57:50 +00:00
return CommandObjectRaw : : GetHelpLong ( ) ;
}
2015-03-13 22:22:28 +00:00
2015-03-13 02:20:41 +00:00
protected :
2016-09-06 20:57:50 +00:00
bool DoExecute ( const char * raw_command_line ,
CommandReturnObject & result ) override {
ScriptInterpreter * scripter = m_interpreter . GetScriptInterpreter ( ) ;
Error error ;
result . SetStatus ( eReturnStatusInvalid ) ;
if ( ! scripter | |
! scripter - > RunScriptBasedCommand ( m_cmd_obj_sp , raw_command_line ,
m_synchro , result , error , m_exe_ctx ) ) {
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
} else {
// Don't change the status if the command already set it...
if ( result . GetStatus ( ) = = eReturnStatusInvalid ) {
if ( result . GetOutputData ( ) = = nullptr | |
result . GetOutputData ( ) [ 0 ] = = ' \0 ' )
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
2015-03-13 02:20:41 +00:00
else
2016-09-06 20:57:50 +00:00
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
}
2015-03-13 02:20:41 +00:00
}
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
return result . Succeeded ( ) ;
}
2016-02-22 23:46:47 +00:00
private :
2016-09-06 20:57:50 +00:00
StructuredData : : GenericSP m_cmd_obj_sp ;
ScriptedCommandSynchronicity m_synchro ;
bool m_fetched_help_short : 1 ;
bool m_fetched_help_long : 1 ;
2015-03-13 02:20:41 +00:00
} ;
2012-06-08 21:56:10 +00:00
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptImport
//-------------------------------------------------------------------------
2011-11-07 22:57:04 +00:00
2016-09-06 20:57:50 +00:00
class CommandObjectCommandsScriptImport : public CommandObjectParsed {
2012-06-08 21:56:10 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectCommandsScriptImport ( CommandInterpreter & interpreter )
: CommandObjectParsed ( interpreter , " command script import " ,
" Import a scripting module in LLDB. " , nullptr ) ,
m_options ( ) {
CommandArgumentEntry arg1 ;
CommandArgumentData cmd_arg ;
// Define the first (and only) variant of this arg.
cmd_arg . arg_type = eArgTypeFilename ;
cmd_arg . arg_repetition = eArgRepeatPlus ;
// There is only one variant this argument could be; put it into the
// argument entry.
arg1 . push_back ( cmd_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg1 ) ;
}
~ CommandObjectCommandsScriptImport ( ) override = default ;
int HandleArgumentCompletion ( Args & input , int & cursor_index ,
int & cursor_char_position ,
OptionElementVector & opt_element_vector ,
int match_start_point , int max_return_elements ,
bool & word_complete ,
StringList & matches ) override {
std : : string completion_str ( input . GetArgumentAtIndex ( cursor_index ) ) ;
completion_str . erase ( cursor_char_position ) ;
CommandCompletions : : InvokeCommonCompletionCallbacks (
GetCommandInterpreter ( ) , CommandCompletions : : eDiskFileCompletion ,
completion_str . c_str ( ) , match_start_point , max_return_elements , nullptr ,
word_complete , matches ) ;
return matches . GetSize ( ) ;
}
Options * GetOptions ( ) override { return & m_options ; }
protected :
class CommandOptions : public Options {
public :
CommandOptions ( ) : Options ( ) { }
~ CommandOptions ( ) override = default ;
Error SetOptionValue ( uint32_t option_idx , const char * option_arg ,
ExecutionContext * execution_context ) override {
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option ) {
case ' r ' :
m_allow_reload = true ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " ,
short_option ) ;
break ;
}
return error ;
2011-11-07 22:57:04 +00:00
}
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
void OptionParsingStarting ( ExecutionContext * execution_context ) override {
m_allow_reload = true ;
2011-11-07 22:57:04 +00:00
}
2016-09-06 20:57:50 +00:00
const OptionDefinition * GetDefinitions ( ) override { return g_option_table ; }
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
// Instance variables to hold the values for command options.
bool m_allow_reload ;
} ;
bool DoExecute ( Args & command , CommandReturnObject & result ) override {
if ( m_interpreter . GetDebugger ( ) . GetScriptLanguage ( ) ! =
lldb : : eScriptLanguagePython ) {
result . AppendError ( " only scripting language supported for module "
" importing is currently Python " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2012-06-08 21:56:10 +00:00
}
2011-10-17 21:45:27 +00:00
2016-09-06 20:57:50 +00:00
size_t argc = command . GetArgumentCount ( ) ;
if ( 0 = = argc ) {
result . AppendError ( " command script import needs one or more arguments " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
for ( size_t i = 0 ; i < argc ; i + + ) {
std : : string path = command . GetArgumentAtIndex ( i ) ;
Error error ;
const bool init_session = true ;
// FIXME: this is necessary because CommandObject::CheckRequirements()
// assumes that
// commands won't ever be recursively invoked, but it's actually possible
// to craft
// a Python script that does other "command script imports" in
// __lldb_init_module
// the real fix is to have recursive commands possible with a
// CommandInvocation object
// separate from the CommandObject itself, so that recursive command
// invocations
// won't stomp on each other (wrt to execution contents, options, and
// more)
m_exe_ctx . Clear ( ) ;
if ( m_interpreter . GetScriptInterpreter ( ) - > LoadScriptingModule (
path . c_str ( ) , m_options . m_allow_reload , init_session , error ) ) {
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
} else {
result . AppendErrorWithFormat ( " module importing failed: %s " ,
error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
2011-10-17 21:45:27 +00:00
}
2016-09-06 20:57:50 +00:00
return result . Succeeded ( ) ;
}
CommandOptions m_options ;
2011-11-07 22:57:04 +00:00
} ;
OptionDefinition
2016-09-06 20:57:50 +00:00
CommandObjectCommandsScriptImport : : CommandOptions : : g_option_table [ ] = {
// clang-format off
2016-08-26 23:28:47 +00:00
{ LLDB_OPT_SET_1 , false , " allow-reload " , ' r ' , OptionParser : : eNoArgument , nullptr , nullptr , 0 , eArgTypeNone , " Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not. " } ,
{ 0 , false , nullptr , 0 , 0 , nullptr , nullptr , 0 , eArgTypeNone , nullptr }
2016-09-06 20:57:50 +00:00
// clang-format on
2011-10-17 21:45:27 +00:00
} ;
2011-08-16 23:24:13 +00:00
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptAdd
//-------------------------------------------------------------------------
2016-09-06 20:57:50 +00:00
class CommandObjectCommandsScriptAdd : public CommandObjectParsed ,
public IOHandlerDelegateMultiline {
2012-06-08 21:56:10 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectCommandsScriptAdd ( CommandInterpreter & interpreter )
: CommandObjectParsed ( interpreter , " command script add " ,
2016-02-22 23:46:47 +00:00
" Add a scripted function as an LLDB command. " ,
nullptr ) ,
2016-09-06 20:57:50 +00:00
IOHandlerDelegateMultiline ( " DONE " ) , m_options ( ) {
CommandArgumentEntry arg1 ;
CommandArgumentData cmd_arg ;
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
// Define the first (and only) variant of this arg.
cmd_arg . arg_type = eArgTypeCommandName ;
cmd_arg . arg_repetition = eArgRepeatPlain ;
// There is only one variant this argument could be; put it into the
// argument entry.
arg1 . push_back ( cmd_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg1 ) ;
}
~ CommandObjectCommandsScriptAdd ( ) override = default ;
Options * GetOptions ( ) override { return & m_options ; }
2016-02-22 23:46:47 +00:00
2012-06-08 21:56:10 +00:00
protected :
2016-09-06 20:57:50 +00:00
class CommandOptions : public Options {
public :
CommandOptions ( )
: Options ( ) , m_class_name ( ) , m_funct_name ( ) , m_short_help ( ) ,
m_synchronicity ( eScriptedCommandSynchronicitySynchronous ) { }
~ CommandOptions ( ) override = default ;
Error SetOptionValue ( uint32_t option_idx , const char * option_arg ,
ExecutionContext * execution_context ) override {
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option ) {
case ' f ' :
if ( option_arg )
m_funct_name . assign ( option_arg ) ;
break ;
case ' c ' :
if ( option_arg )
m_class_name . assign ( option_arg ) ;
break ;
case ' h ' :
if ( option_arg )
m_short_help . assign ( option_arg ) ;
break ;
case ' s ' :
m_synchronicity =
( ScriptedCommandSynchronicity ) Args : : StringToOptionEnum (
option_arg , g_option_table [ option_idx ] . enum_values , 0 , error ) ;
if ( ! error . Success ( ) )
error . SetErrorStringWithFormat (
" unrecognized value for synchronicity '%s' " , option_arg ) ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " ,
short_option ) ;
break ;
}
return error ;
}
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
void OptionParsingStarting ( ExecutionContext * execution_context ) override {
m_class_name . clear ( ) ;
m_funct_name . clear ( ) ;
m_short_help . clear ( ) ;
m_synchronicity = eScriptedCommandSynchronicitySynchronous ;
2014-01-27 23:43:24 +00:00
}
2016-09-06 20:57:50 +00:00
const OptionDefinition * GetDefinitions ( ) override { return g_option_table ; }
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
2014-01-27 23:43:24 +00:00
2016-09-06 20:57:50 +00:00
// Instance variables to hold the values for command options.
std : : string m_class_name ;
std : : string m_funct_name ;
std : : string m_short_help ;
ScriptedCommandSynchronicity m_synchronicity ;
} ;
void IOHandlerActivated ( IOHandler & io_handler ) override {
StreamFileSP output_sp ( io_handler . GetOutputStreamFile ( ) ) ;
if ( output_sp ) {
output_sp - > PutCString ( g_python_command_instructions ) ;
output_sp - > Flush ( ) ;
2014-01-27 23:43:24 +00:00
}
2016-09-06 20:57:50 +00:00
}
void IOHandlerInputComplete ( IOHandler & io_handler ,
std : : string & data ) override {
StreamFileSP error_sp = io_handler . GetErrorStreamFile ( ) ;
ScriptInterpreter * interpreter = m_interpreter . GetScriptInterpreter ( ) ;
if ( interpreter ) {
StringList lines ;
lines . SplitIntoLines ( data ) ;
if ( lines . GetSize ( ) > 0 ) {
std : : string funct_name_str ;
if ( interpreter - > GenerateScriptAliasFunction ( lines , funct_name_str ) ) {
if ( funct_name_str . empty ( ) ) {
error_sp - > Printf ( " error: unable to obtain a function name, didn't "
" add python command. \n " ) ;
error_sp - > Flush ( ) ;
} else {
// everything should be fine now, let's add this alias
CommandObjectSP command_obj_sp ( new CommandObjectPythonFunction (
m_interpreter , m_cmd_name , funct_name_str . c_str ( ) , m_short_help ,
m_synchronicity ) ) ;
if ( ! m_interpreter . AddUserCommand ( m_cmd_name , command_obj_sp ,
true ) ) {
error_sp - > Printf ( " error: unable to add selected command, didn't "
" add python command. \n " ) ;
error_sp - > Flush ( ) ;
}
}
} else {
error_sp - > Printf (
" error: unable to create function, didn't add python command. \n " ) ;
error_sp - > Flush ( ) ;
}
} else {
error_sp - > Printf ( " error: empty function, didn't add python command. \n " ) ;
error_sp - > Flush ( ) ;
}
} else {
error_sp - > Printf (
" error: script interpreter missing, didn't add python command. \n " ) ;
error_sp - > Flush ( ) ;
}
io_handler . SetIsDone ( true ) ;
}
2014-01-27 23:43:24 +00:00
2012-06-08 21:56:10 +00:00
protected :
2016-09-06 20:57:50 +00:00
bool DoExecute ( Args & command , CommandReturnObject & result ) override {
if ( m_interpreter . GetDebugger ( ) . GetScriptLanguage ( ) ! =
lldb : : eScriptLanguagePython ) {
result . AppendError ( " only scripting language supported for scripted "
" commands is currently Python " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2011-08-16 23:24:13 +00:00
2016-09-06 20:57:50 +00:00
size_t argc = command . GetArgumentCount ( ) ;
if ( argc ! = 1 ) {
result . AppendError ( " 'command script add' requires one argument " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// Store the options in case we get multi-line input
m_cmd_name = command . GetArgumentAtIndex ( 0 ) ;
m_short_help . assign ( m_options . m_short_help ) ;
m_synchronicity = m_options . m_synchronicity ;
if ( m_options . m_class_name . empty ( ) ) {
if ( m_options . m_funct_name . empty ( ) ) {
m_interpreter . GetPythonCommandsFromIOHandler (
" " , // Prompt
* this , // IOHandlerDelegate
true , // Run IOHandler in async mode
nullptr ) ; // Baton for the "io_handler" that will be passed back
// into our IOHandlerDelegate functions
} else {
CommandObjectSP new_cmd ( new CommandObjectPythonFunction (
m_interpreter , m_cmd_name , m_options . m_funct_name ,
m_options . m_short_help , m_synchronicity ) ) ;
if ( m_interpreter . AddUserCommand ( m_cmd_name , new_cmd , true ) ) {
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
} else {
result . AppendError ( " cannot add command " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
} else {
ScriptInterpreter * interpreter =
GetCommandInterpreter ( ) . GetScriptInterpreter ( ) ;
if ( ! interpreter ) {
result . AppendError ( " cannot find ScriptInterpreter " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
auto cmd_obj_sp = interpreter - > CreateScriptCommandObject (
m_options . m_class_name . c_str ( ) ) ;
if ( ! cmd_obj_sp ) {
result . AppendError ( " cannot create helper object " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
CommandObjectSP new_cmd ( new CommandObjectScriptingObject (
m_interpreter , m_cmd_name , cmd_obj_sp , m_synchronicity ) ) ;
if ( m_interpreter . AddUserCommand ( m_cmd_name , new_cmd , true ) ) {
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
} else {
result . AppendError ( " cannot add command " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
2011-08-16 23:24:13 +00:00
}
2016-09-06 20:57:50 +00:00
return result . Succeeded ( ) ;
}
CommandOptions m_options ;
std : : string m_cmd_name ;
std : : string m_short_help ;
ScriptedCommandSynchronicity m_synchronicity ;
2011-11-07 22:57:04 +00:00
} ;
2016-09-06 20:57:50 +00:00
static OptionEnumValueElement g_script_synchro_type [ ] = {
{ eScriptedCommandSynchronicitySynchronous , " synchronous " ,
" Run synchronous " } ,
{ eScriptedCommandSynchronicityAsynchronous , " asynchronous " ,
" Run asynchronous " } ,
{ eScriptedCommandSynchronicityCurrentValue , " current " ,
" Do not alter current setting " } ,
{ 0 , nullptr , nullptr } } ;
2011-08-16 23:24:13 +00:00
OptionDefinition
2016-09-06 20:57:50 +00:00
CommandObjectCommandsScriptAdd : : CommandOptions : : g_option_table [ ] = {
// clang-format off
2016-08-26 23:28:47 +00:00
{ LLDB_OPT_SET_1 , false , " function " , ' f ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypePythonFunction , " Name of the Python function to bind to this command name. " } ,
{ LLDB_OPT_SET_2 , false , " class " , ' c ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypePythonClass , " Name of the Python class to bind to this command name. " } ,
{ LLDB_OPT_SET_1 , false , " help " , ' h ' , OptionParser : : eRequiredArgument , nullptr , nullptr , 0 , eArgTypeHelpText , " The help text to display for this command. " } ,
{ LLDB_OPT_SET_ALL , false , " synchronicity " , ' s ' , OptionParser : : eRequiredArgument , nullptr , g_script_synchro_type , 0 , eArgTypeScriptedCommandSynchronicity , " Set the synchronicity of this command's executions with regard to LLDB event system. " } ,
{ 0 , false , nullptr , 0 , 0 , nullptr , nullptr , 0 , eArgTypeNone , nullptr }
2016-09-06 20:57:50 +00:00
// clang-format on
2011-08-16 23:24:13 +00:00
} ;
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptList
//-------------------------------------------------------------------------
2016-09-06 20:57:50 +00:00
class CommandObjectCommandsScriptList : public CommandObjectParsed {
2011-08-16 23:24:13 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectCommandsScriptList ( CommandInterpreter & interpreter )
: CommandObjectParsed ( interpreter , " command script list " ,
" List defined scripted commands. " , nullptr ) { }
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
~ CommandObjectCommandsScriptList ( ) override = default ;
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
bool DoExecute ( Args & command , CommandReturnObject & result ) override {
m_interpreter . GetHelp ( result , CommandInterpreter : : eCommandTypesUserDef ) ;
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
return true ;
}
2011-08-16 23:24:13 +00:00
} ;
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptClear
//-------------------------------------------------------------------------
2016-09-06 20:57:50 +00:00
class CommandObjectCommandsScriptClear : public CommandObjectParsed {
2011-08-16 23:24:13 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectCommandsScriptClear ( CommandInterpreter & interpreter )
: CommandObjectParsed ( interpreter , " command script clear " ,
" Delete all scripted commands. " , nullptr ) { }
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
~ CommandObjectCommandsScriptClear ( ) override = default ;
2016-02-22 23:46:47 +00:00
2012-06-08 21:56:10 +00:00
protected :
2016-09-06 20:57:50 +00:00
bool DoExecute ( Args & command , CommandReturnObject & result ) override {
m_interpreter . RemoveAllUser ( ) ;
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
return true ;
}
2011-08-16 23:24:13 +00:00
} ;
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptDelete
//-------------------------------------------------------------------------
2016-09-06 20:57:50 +00:00
class CommandObjectCommandsScriptDelete : public CommandObjectParsed {
2011-08-16 23:24:13 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectCommandsScriptDelete ( CommandInterpreter & interpreter )
: CommandObjectParsed ( interpreter , " command script delete " ,
" Delete a scripted command. " , nullptr ) {
CommandArgumentEntry arg1 ;
CommandArgumentData cmd_arg ;
// Define the first (and only) variant of this arg.
cmd_arg . arg_type = eArgTypeCommandName ;
cmd_arg . arg_repetition = eArgRepeatPlain ;
2016-02-22 23:46:47 +00:00
2016-09-06 20:57:50 +00:00
// There is only one variant this argument could be; put it into the
// argument entry.
arg1 . push_back ( cmd_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg1 ) ;
}
~ CommandObjectCommandsScriptDelete ( ) override = default ;
2016-02-22 23:46:47 +00:00
2012-06-08 21:56:10 +00:00
protected :
2016-09-06 20:57:50 +00:00
bool DoExecute ( Args & command , CommandReturnObject & result ) override {
size_t argc = command . GetArgumentCount ( ) ;
if ( argc ! = 1 ) {
result . AppendError ( " 'command script delete' requires one argument " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2011-08-16 23:24:13 +00:00
}
2016-09-06 20:57:50 +00:00
const char * cmd_name = command . GetArgumentAtIndex ( 0 ) ;
if ( cmd_name & & * cmd_name & & m_interpreter . HasUserCommands ( ) & &
m_interpreter . UserCommandExists ( cmd_name ) ) {
m_interpreter . RemoveUser ( cmd_name ) ;
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
} else {
result . AppendErrorWithFormat ( " command %s not found " , cmd_name ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
return result . Succeeded ( ) ;
}
2011-08-16 23:24:13 +00:00
} ;
# pragma mark CommandObjectMultiwordCommandsScript
//-------------------------------------------------------------------------
// CommandObjectMultiwordCommandsScript
//-------------------------------------------------------------------------
2016-09-06 20:57:50 +00:00
class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword {
2011-08-16 23:24:13 +00:00
public :
2016-09-06 20:57:50 +00:00
CommandObjectMultiwordCommandsScript ( CommandInterpreter & interpreter )
: CommandObjectMultiword (
interpreter , " command script " , " Commands for managing custom "
" commands implemented by "
" interpreter scripts. " ,
" command script <subcommand> [<subcommand-options>] " ) {
LoadSubCommand ( " add " , CommandObjectSP (
new CommandObjectCommandsScriptAdd ( interpreter ) ) ) ;
LoadSubCommand (
" delete " ,
CommandObjectSP ( new CommandObjectCommandsScriptDelete ( interpreter ) ) ) ;
LoadSubCommand (
" clear " ,
CommandObjectSP ( new CommandObjectCommandsScriptClear ( interpreter ) ) ) ;
LoadSubCommand ( " list " , CommandObjectSP ( new CommandObjectCommandsScriptList (
interpreter ) ) ) ;
LoadSubCommand (
" import " ,
CommandObjectSP ( new CommandObjectCommandsScriptImport ( interpreter ) ) ) ;
}
~ CommandObjectMultiwordCommandsScript ( ) override = default ;
2011-08-16 23:24:13 +00:00
} ;
2010-07-07 03:36:20 +00:00
# pragma mark CommandObjectMultiwordCommands
//-------------------------------------------------------------------------
// CommandObjectMultiwordCommands
//-------------------------------------------------------------------------
2016-09-06 20:57:50 +00:00
CommandObjectMultiwordCommands : : CommandObjectMultiwordCommands (
CommandInterpreter & interpreter )
: CommandObjectMultiword ( interpreter , " command " ,
" Commands for managing custom LLDB commands. " ,
" command <subcommand> [<subcommand-options>] " ) {
LoadSubCommand ( " source " ,
CommandObjectSP ( new CommandObjectCommandsSource ( interpreter ) ) ) ;
LoadSubCommand ( " alias " ,
CommandObjectSP ( new CommandObjectCommandsAlias ( interpreter ) ) ) ;
LoadSubCommand ( " unalias " , CommandObjectSP (
new CommandObjectCommandsUnalias ( interpreter ) ) ) ;
LoadSubCommand ( " delete " ,
CommandObjectSP ( new CommandObjectCommandsDelete ( interpreter ) ) ) ;
LoadSubCommand (
" regex " , CommandObjectSP ( new CommandObjectCommandsAddRegex ( interpreter ) ) ) ;
LoadSubCommand ( " history " , CommandObjectSP (
new CommandObjectCommandsHistory ( interpreter ) ) ) ;
LoadSubCommand (
" script " ,
CommandObjectSP ( new CommandObjectMultiwordCommandsScript ( interpreter ) ) ) ;
2010-07-07 03:36:20 +00:00
}
2016-02-22 23:46:47 +00:00
CommandObjectMultiwordCommands : : ~ CommandObjectMultiwordCommands ( ) = default ;