2010-07-07 11:36:20 +08: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.
//
//===----------------------------------------------------------------------===//
2012-12-05 08:20:57 +08:00
# include "lldb/lldb-python.h"
2010-07-07 11:36:20 +08:00
# include "CommandObjectCommands.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
2011-04-21 06:55:21 +08:00
# include "llvm/ADT/StringRef.h"
2010-07-07 11:36:20 +08:00
// Project includes
# include "lldb/Core/Debugger.h"
2014-01-28 07:43:24 +08:00
# include "lldb/Core/IOHandler.h"
2011-08-17 00:49:25 +08:00
# include "lldb/Core/StringList.h"
2011-04-21 00:37:46 +08:00
# include "lldb/Interpreter/Args.h"
2013-06-18 06:51:50 +08:00
# include "lldb/Interpreter/CommandHistory.h"
2010-07-07 11:36:20 +08:00
# include "lldb/Interpreter/CommandInterpreter.h"
2011-04-21 00:37:46 +08:00
# include "lldb/Interpreter/CommandObjectRegexCommand.h"
2010-07-07 11:36:20 +08:00
# include "lldb/Interpreter/CommandReturnObject.h"
2013-06-11 09:26:35 +08:00
# include "lldb/Interpreter/OptionValueBoolean.h"
2013-06-18 06:51:50 +08:00
# include "lldb/Interpreter/OptionValueUInt64.h"
2010-07-07 11:36:20 +08:00
# include "lldb/Interpreter/Options.h"
2011-08-17 09:30:04 +08:00
# include "lldb/Interpreter/ScriptInterpreter.h"
# include "lldb/Interpreter/ScriptInterpreterPython.h"
2010-07-07 11:36:20 +08:00
using namespace lldb ;
using namespace lldb_private ;
2011-07-12 11:12:18 +08:00
//-------------------------------------------------------------------------
// CommandObjectCommandsSource
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
class CommandObjectCommandsHistory : public CommandObjectParsed
2011-07-12 11:12:18 +08:00
{
2012-06-09 05:56:10 +08:00
public :
CommandObjectCommandsHistory ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" command history " ,
" Dump the history of commands in this session. " ,
NULL ) ,
m_options ( interpreter )
{
}
~ CommandObjectCommandsHistory ( ) { }
virtual Options *
GetOptions ( )
{
return & m_options ;
}
protected :
2011-07-12 11:12:18 +08:00
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
2013-06-18 06:51:50 +08:00
Options ( interpreter ) ,
m_start_idx ( 0 ) ,
m_stop_idx ( 0 ) ,
m_count ( 0 ) ,
2013-06-18 07:28:27 +08:00
m_clear ( false )
2011-07-12 11:12:18 +08:00
{
}
virtual
~ CommandOptions ( ) { }
virtual Error
SetOptionValue ( uint32_t option_idx , const char * option_arg )
{
Error error ;
2012-12-04 08:32:51 +08:00
const int short_option = m_getopt_table [ option_idx ] . val ;
2011-07-12 11:12:18 +08:00
switch ( short_option )
{
case ' c ' :
2013-06-18 06:51:50 +08:00
error = m_count . SetValueFromCString ( 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 . SetValueFromCString ( option_arg , eVarSetOperationAssign ) ;
2011-07-12 11:12:18 +08:00
break ;
case ' e ' :
2013-06-18 06:51:50 +08:00
error = m_stop_idx . SetValueFromCString ( option_arg , eVarSetOperationAssign ) ;
2011-07-12 11:12:18 +08:00
break ;
2013-06-18 07:28:27 +08:00
case ' C ' :
m_clear . SetCurrentValue ( true ) ;
m_clear . SetOptionWasSet ( ) ;
2011-07-12 11:12:18 +08:00
break ;
default :
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
2011-07-12 11:12:18 +08:00
break ;
}
return error ;
}
void
OptionParsingStarting ( )
{
2013-06-18 06:51:50 +08:00
m_start_idx . Clear ( ) ;
m_stop_idx . Clear ( ) ;
m_count . Clear ( ) ;
2013-06-18 07:28:27 +08:00
m_clear . Clear ( ) ;
2011-07-12 11:12:18 +08:00
}
const OptionDefinition *
GetDefinitions ( )
{
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.
2013-06-18 06:51:50 +08:00
OptionValueUInt64 m_start_idx ;
OptionValueUInt64 m_stop_idx ;
OptionValueUInt64 m_count ;
2013-06-18 07:28:27 +08:00
OptionValueBoolean m_clear ;
2011-07-12 11:12:18 +08:00
} ;
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2011-07-12 11:12:18 +08:00
{
2013-06-18 07:28:27 +08:00
if ( m_options . m_clear . GetCurrentValue ( ) & & m_options . m_clear . OptionWasSet ( ) )
2013-06-18 06:51:50 +08:00
{
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
{
2013-08-28 00:22:29 +08:00
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 ( ) ) ;
2013-06-18 06:51:50 +08:00
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 ;
}
}
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 ;
}
}
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 11:12:18 +08:00
return result . Succeeded ( ) ;
}
2012-06-09 05:56:10 +08:00
CommandOptions m_options ;
2011-07-12 11:12:18 +08:00
} ;
OptionDefinition
CommandObjectCommandsHistory : : CommandOptions : : g_option_table [ ] =
{
2013-09-06 00:42:23 +08:00
{ LLDB_OPT_SET_1 , false , " count " , ' c ' , OptionParser : : eRequiredArgument , NULL , 0 , eArgTypeUnsignedInteger , " How many history commands to print. " } ,
{ LLDB_OPT_SET_1 , false , " start-index " , ' s ' , OptionParser : : eRequiredArgument , NULL , 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 , NULL , 0 , eArgTypeUnsignedInteger , " Index at which to stop printing history commands. " } ,
{ LLDB_OPT_SET_2 , false , " clear " , ' C ' , OptionParser : : eNoArgument , NULL , 0 , eArgTypeBoolean , " Clears the current command history. " } ,
2011-07-12 11:12:18 +08:00
{ 0 , false , NULL , 0 , 0 , NULL , 0 , eArgTypeNone , NULL }
} ;
2010-07-07 11:36:20 +08:00
//-------------------------------------------------------------------------
// CommandObjectCommandsSource
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
class CommandObjectCommandsSource : public CommandObjectParsed
2010-07-07 11:36:20 +08:00
{
2012-06-09 05:56:10 +08:00
public :
CommandObjectCommandsSource ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" command source " ,
" Read in debugger commands from the file <filename> and execute them. " ,
NULL ) ,
m_options ( interpreter )
{
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 ( ) { }
virtual const char *
GetRepeatCommand ( Args & current_command_args , uint32_t index )
{
return " " ;
}
2013-01-26 02:06:21 +08:00
virtual int
2012-06-09 05:56:10 +08:00
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 )
{
std : : string completion_str ( input . GetArgumentAtIndex ( cursor_index ) ) ;
completion_str . erase ( cursor_char_position ) ;
CommandCompletions : : InvokeCommonCompletionCallbacks ( m_interpreter ,
CommandCompletions : : eDiskFileCompletion ,
completion_str . c_str ( ) ,
match_start_point ,
max_return_elements ,
NULL ,
word_complete ,
matches ) ;
return matches . GetSize ( ) ;
}
virtual Options *
GetOptions ( )
{
return & m_options ;
}
protected :
2011-02-18 08:54:25 +08:00
class CommandOptions : public Options
{
public :
2011-04-08 06:46:35 +08:00
CommandOptions ( CommandInterpreter & interpreter ) :
2013-06-11 09:26:35 +08:00
Options ( interpreter ) ,
2014-02-06 01:57:57 +08:00
m_stop_on_error ( true ) ,
m_silent_run ( false ) ,
m_stop_on_continue ( true )
2011-04-08 06:46:35 +08:00
{
}
2011-02-18 08:54:25 +08:00
virtual
~ CommandOptions ( ) { }
virtual Error
2011-04-13 08:18:08 +08:00
SetOptionValue ( uint32_t option_idx , const char * option_arg )
2011-02-18 08:54:25 +08:00
{
Error error ;
2012-12-04 08:32:51 +08:00
const int short_option = m_getopt_table [ option_idx ] . val ;
2011-02-18 08:54:25 +08:00
switch ( short_option )
{
case ' e ' :
2013-06-26 08:36:27 +08:00
error = m_stop_on_error . SetValueFromCString ( option_arg ) ;
2011-02-18 08:54:25 +08:00
break ;
2014-02-06 01:57:57 +08:00
2011-02-18 08:54:25 +08:00
case ' c ' :
2014-02-06 01:57:57 +08:00
error = m_stop_on_continue . SetValueFromCString ( option_arg ) ;
2011-02-18 08:54:25 +08:00
break ;
2014-02-06 01:57:57 +08:00
2013-07-10 07:22:53 +08:00
case ' s ' :
2014-02-06 01:57:57 +08:00
error = m_silent_run . SetValueFromCString ( option_arg ) ;
2013-07-10 07:22:53 +08:00
break ;
2014-02-06 01:57:57 +08:00
2011-02-18 08:54:25 +08:00
default :
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
2011-02-18 08:54:25 +08:00
break ;
}
return error ;
}
void
2011-04-13 08:18:08 +08:00
OptionParsingStarting ( )
2011-02-18 08:54:25 +08:00
{
2013-06-11 09:26:35 +08:00
m_stop_on_error . Clear ( ) ;
2014-02-06 01:57:57 +08:00
m_silent_run . Clear ( ) ;
m_stop_on_continue . Clear ( ) ;
2011-02-18 08:54:25 +08:00
}
2011-03-25 05:19:54 +08:00
const OptionDefinition *
2011-02-18 08:54:25 +08:00
GetDefinitions ( )
{
return g_option_table ;
}
// Options table: Required for subclasses of Options.
2011-03-25 05:19:54 +08:00
static OptionDefinition g_option_table [ ] ;
2011-02-18 08:54:25 +08:00
// Instance variables to hold the values for command options.
2013-06-11 09:26:35 +08:00
OptionValueBoolean m_stop_on_error ;
2014-02-06 01:57:57 +08:00
OptionValueBoolean m_silent_run ;
OptionValueBoolean m_stop_on_continue ;
2011-02-18 08:54:25 +08:00
} ;
2010-07-07 11:36:20 +08:00
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2010-07-07 11:36:20 +08:00
{
2013-01-26 02:06:21 +08:00
const size_t argc = command . GetArgumentCount ( ) ;
2010-07-07 11:36:20 +08:00
if ( argc = = 1 )
{
2012-06-09 05:56:10 +08:00
const char * filename = command . GetArgumentAtIndex ( 0 ) ;
2010-07-07 11:36:20 +08:00
2010-10-21 05:40:50 +08:00
FileSpec cmd_file ( filename , true ) ;
2011-02-18 08:54:25 +08:00
ExecutionContext * exe_ctx = NULL ; // Just use the default context.
2014-02-06 01:57:57 +08:00
// 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
LazyBool print_command = m_options . m_silent_run . GetCurrentValue ( ) ? eLazyBoolNo : eLazyBoolYes ;
m_interpreter . HandleCommandsFromFile ( cmd_file ,
exe_ctx ,
m_options . m_stop_on_continue . GetCurrentValue ( ) ? eLazyBoolYes : eLazyBoolNo , // Stop on continue
m_options . m_stop_on_error . GetCurrentValue ( ) ? eLazyBoolYes : eLazyBoolNo , // Stop on error
print_command , // Echo command
print_command , // Print command output
eLazyBoolCalculate , // Add to history
result ) ;
}
else
{
// No options were set, inherit any settings from nested "command source" commands,
// or set to sane default settings...
m_interpreter . HandleCommandsFromFile ( cmd_file ,
exe_ctx ,
eLazyBoolCalculate , // Stop on continue
eLazyBoolCalculate , // Stop on error
eLazyBoolCalculate , // Echo command
eLazyBoolCalculate , // Print command output
eLazyBoolCalculate , // Add to history
result ) ;
}
2010-07-07 11:36:20 +08:00
}
else
{
result . AppendErrorWithFormat ( " '%s' takes exactly one executable filename argument. \n " , GetCommandName ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
return result . Succeeded ( ) ;
}
2012-06-09 05:56:10 +08:00
CommandOptions m_options ;
2010-07-07 11:36:20 +08:00
} ;
2011-03-25 05:19:54 +08:00
OptionDefinition
2011-02-18 08:54:25 +08:00
CommandObjectCommandsSource : : CommandOptions : : g_option_table [ ] =
{
2013-09-06 00:42:23 +08:00
{ LLDB_OPT_SET_ALL , false , " stop-on-error " , ' e ' , OptionParser : : eRequiredArgument , NULL , 0 , eArgTypeBoolean , " If true, stop executing commands on error. " } ,
{ LLDB_OPT_SET_ALL , false , " stop-on-continue " , ' c ' , OptionParser : : eRequiredArgument , NULL , 0 , eArgTypeBoolean , " If true, stop executing commands on continue. " } ,
{ LLDB_OPT_SET_ALL , false , " silent-run " , ' s ' , OptionParser : : eRequiredArgument , NULL , 0 , eArgTypeBoolean , " If true don't echo commands while executing. " } ,
2011-02-18 08:54:25 +08:00
{ 0 , false , NULL , 0 , 0 , NULL , 0 , eArgTypeNone , NULL }
} ;
2010-07-07 11:36:20 +08:00
# pragma mark CommandObjectCommandsAlias
//-------------------------------------------------------------------------
// CommandObjectCommandsAlias
//-------------------------------------------------------------------------
2011-08-17 00:49:25 +08: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 "
2014-01-28 07:43:24 +08:00
" def my_command_impl(debugger, args, result, internal_dict): \n " ;
2011-08-17 00:49:25 +08:00
2012-06-09 05:56:10 +08:00
class CommandObjectCommandsAlias : public CommandObjectRaw
2010-07-07 11:36:20 +08:00
{
2011-08-17 00:49:25 +08:00
2010-07-07 11:36:20 +08:00
public :
2010-09-18 09:14:36 +08:00
CommandObjectCommandsAlias ( CommandInterpreter & interpreter ) :
2012-06-09 05:56:10 +08:00
CommandObjectRaw ( interpreter ,
2011-04-21 06:55:21 +08:00
" command alias " ,
2010-09-09 05:06:11 +08:00
" Allow users to define their own debugger command abbreviations. " ,
2010-10-05 06:28:36 +08:00
NULL )
2010-07-07 11:36:20 +08:00
{
SetHelpLong (
" 'alias' allows the user to create a short-cut or abbreviation for long \n \
commands , multi - word commands , and commands that take particular options . \ n \
Below are some simple examples of how one might use the ' alias ' command : \ n \
2011-11-11 06:43:35 +08:00
\ n ' command alias sc script ' / / Creates the abbreviation ' sc ' for the ' script ' \ n \
2010-09-09 06:08:58 +08:00
/ / command . \ n \
2011-11-11 06:43:35 +08:00
' command alias bp breakpoint ' / / Creates the abbreviation ' bp ' for the ' breakpoint ' \ n \
2010-09-09 06:08:58 +08:00
/ / command . Since breakpoint commands are two - word \ n \
/ / commands , the user will still need to enter the \ n \
/ / second word after ' bp ' , e . g . ' bp enable ' or \ n \
/ / ' bp delete ' . \ n \
2011-11-11 06:43:35 +08:00
' command alias bpl breakpoint list ' / / Creates the abbreviation ' bpl ' for the \ n \
2010-09-09 06:08:58 +08:00
/ / two - word command ' breakpoint list ' . \ n \
2010-07-07 11:36:20 +08:00
\ nAn alias can include some options for the command , with the values either \ n \
filled in at the time the alias is created , or specified as positional \ n \
arguments , to be filled in when the alias is invoked . The following example \ n \
shows how to create aliases with options : \ n \
\ n \
2011-11-11 06:43:35 +08:00
' command alias bfl breakpoint set - f % 1 - l % 2 ' \ n \
2010-07-07 11:36:20 +08:00
\ nThis creates the abbreviation ' bfl ' ( for break - file - line ) , with the - f and - l \ n \
options already part of the alias . So if the user wants to set a breakpoint \ n \
by file and line without explicitly having to use the - f and - l options , the \ n \
user can now use ' bfl ' instead . The ' % 1 ' and ' % 2 ' are positional placeholders \ n \
for the actual arguments that will be passed when the alias command is used . \ n \
The number in the placeholder refers to the position / order the actual value \ n \
2011-08-18 10:29:05 +08:00
occupies when the alias is used . All the occurrences of ' % 1 ' in the alias \ n \
2010-07-07 11:36:20 +08:00
will be replaced with the first argument , all the occurrences of ' % 2 ' in the \ n \
alias will be replaced with the second argument , and so on . This also allows \ n \
actual arguments to be used multiple times within an alias ( see ' process \ n \
2011-08-18 10:29:05 +08:00
launch ' example below ) . \ n \
Note : the positional arguments must substitute as whole words in the resultant \ n \
command , so you can ' t at present do something like : \ n \
\ n \
2011-11-11 06:43:35 +08:00
command alias bcppfl breakpoint set - f % 1. cpp - l % 2 \ n \
2011-08-18 10:29:05 +08:00
\ n \
to get the file extension \ " .cpp \" automatically appended. For more complex \n \
aliasing , use the \ " command regex \" command instead. \n \
\ nSo in the ' bfl ' case , the actual file value will be \ n \
2010-07-07 11:36:20 +08:00
filled in with the first argument following ' bfl ' and the actual line number \ n \
value will be filled in with the second argument . The user would use this \ n \
alias as follows : \ n \
2011-11-11 06:43:35 +08:00
\ n ( lldb ) command alias bfl breakpoint set - f % 1 - l % 2 \ n \
2010-08-10 02:50:15 +08:00
< . . . some time later . . . > \ n \
2010-09-09 06:08:58 +08:00
( lldb ) bfl my - file . c 137 \ n \
2010-07-07 11:36:20 +08:00
\ nThis would be the same as if the user had entered \ n \
' breakpoint set - f my - file . c - l 137 ' . \ n \
\ nAnother example : \ n \
2011-11-11 06:43:35 +08:00
\ n ( lldb ) command alias pltty process launch - s - o % 1 - e % 1 \ n \
2010-09-09 06:08:58 +08:00
( lldb ) pltty / dev / tty0 \ n \
2010-08-10 02:50:15 +08:00
/ / becomes ' process launch - s - o / dev / tty0 - e / dev / tty0 ' \ n \
2010-07-07 11:36:20 +08:00
\ nIf the user always wanted to pass the same value to a particular option , the \ n \
alias could be defined with that value directly in the alias as a constant , \ n \
rather than using a positional placeholder : \ n \
2011-11-11 06:43:35 +08:00
\ n command alias bl3 breakpoint set - f % 1 - l 3 / / Always sets a breakpoint on line \ n \
2010-08-10 02:50:15 +08:00
// 3 of whatever file is indicated. \n");
2010-07-07 11:36:20 +08:00
2010-10-05 06:28:36 +08:00
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 ;
// 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 ) ;
2010-07-07 11:36:20 +08:00
}
~ CommandObjectCommandsAlias ( )
{
}
2012-06-09 05:56:10 +08:00
protected :
virtual bool
DoExecute ( const char * raw_command_line , CommandReturnObject & result )
2010-12-10 06:52:49 +08:00
{
Args args ( raw_command_line ) ;
std : : string raw_command_string ( raw_command_line ) ;
size_t argc = args . GetArgumentCount ( ) ;
if ( argc < 2 )
{
result . AppendError ( " 'alias' requires at least two arguments " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// Get the alias command.
const std : : string alias_command = args . GetArgumentAtIndex ( 0 ) ;
2011-08-17 00:49:25 +08:00
2010-12-10 06:52:49 +08:00
// 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 ;
}
// 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.
CommandObject * cmd_obj = m_interpreter . GetCommandObjectForCommand ( raw_command_string ) ;
if ( ! cmd_obj )
{
2011-10-26 08:56:27 +08:00
result . AppendErrorWithFormat ( " invalid command given to 'alias'. '%s' does not begin with a valid command. "
2010-12-10 06:52:49 +08:00
" No alias created. " , 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.
2012-06-09 05:56:10 +08:00
return HandleAliasingNormalCommand ( args , result ) ;
2010-12-10 06:52:49 +08:00
}
else
{
2012-06-09 05:56:10 +08:00
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 )
{
2010-12-10 06:52:49 +08:00
// Verify & handle any options/arguments passed to the alias command
OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP ( new OptionArgVector ) ;
OptionArgVector * option_arg_vector = option_arg_vector_sp . get ( ) ;
2012-06-09 05:56:10 +08:00
CommandObjectSP cmd_obj_sp = m_interpreter . GetCommandSPExact ( cmd_obj . GetCommandName ( ) , false ) ;
2011-05-07 05:37:15 +08:00
if ( ! m_interpreter . ProcessAliasOptionsArgs ( cmd_obj_sp , raw_command_string . c_str ( ) , option_arg_vector_sp ) )
2010-12-10 06:52:49 +08:00
{
2011-05-07 05:37:15 +08:00
result . AppendError ( " Unable to create requested alias. \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2010-12-10 06:52:49 +08:00
}
// Create the alias
if ( m_interpreter . AliasExists ( alias_command . c_str ( ) )
| | m_interpreter . UserCommandExists ( alias_command . c_str ( ) ) )
{
OptionArgVectorSP temp_option_arg_sp ( m_interpreter . GetAliasOptions ( alias_command . c_str ( ) ) ) ;
if ( temp_option_arg_sp . get ( ) )
{
if ( option_arg_vector - > size ( ) = = 0 )
m_interpreter . RemoveAliasOptions ( alias_command . c_str ( ) ) ;
}
result . AppendWarningWithFormat ( " Overwriting existing definition for '%s'. \n " ,
alias_command . c_str ( ) ) ;
}
2010-12-15 02:51:39 +08:00
if ( cmd_obj_sp )
{
m_interpreter . AddAlias ( alias_command . c_str ( ) , cmd_obj_sp ) ;
if ( option_arg_vector - > size ( ) > 0 )
m_interpreter . AddOrReplaceAliasOptions ( alias_command . c_str ( ) , option_arg_vector_sp ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendError ( " Unable to create requested alias. \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
2012-06-09 05:56:10 +08:00
return result . Succeeded ( ) ;
2010-12-10 06:52:49 +08:00
}
2012-06-09 05:56:10 +08:00
2010-07-07 11:36:20 +08:00
bool
2012-06-09 05:56:10 +08:00
HandleAliasingNormalCommand ( Args & args , CommandReturnObject & result )
2010-07-07 11:36:20 +08:00
{
2010-09-22 07:25:40 +08:00
size_t argc = args . GetArgumentCount ( ) ;
2010-07-07 11:36:20 +08:00
if ( argc < 2 )
2010-07-10 04:39:50 +08:00
{
2010-07-07 11:36:20 +08:00
result . AppendError ( " 'alias' requires at least two arguments " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2010-07-10 04:39:50 +08:00
}
2010-07-07 11:36:20 +08: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.
2010-09-18 09:14:36 +08:00
if ( m_interpreter . CommandExists ( alias_command . c_str ( ) ) )
2010-07-07 11:36:20 +08:00
{
result . AppendErrorWithFormat ( " '%s' is a permanent debugger command and cannot be redefined. \n " ,
alias_command . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
else
{
2010-09-18 09:14:36 +08:00
CommandObjectSP command_obj_sp ( m_interpreter . GetCommandSPExact ( actual_command . c_str ( ) , true ) ) ;
2010-07-07 11:36:20 +08:00
CommandObjectSP subcommand_obj_sp ;
bool use_subcommand = false ;
if ( command_obj_sp . get ( ) )
{
CommandObject * cmd_obj = command_obj_sp . get ( ) ;
2010-07-10 04:39:50 +08:00
CommandObject * sub_cmd_obj = NULL ;
2010-07-07 11:36:20 +08:00
OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP ( new OptionArgVector ) ;
OptionArgVector * option_arg_vector = option_arg_vector_sp . get ( ) ;
2010-12-10 06:52:49 +08:00
while ( cmd_obj - > IsMultiwordObject ( ) & & args . GetArgumentCount ( ) > 0 )
2010-07-07 11:36:20 +08:00
{
if ( argc > = 3 )
{
const std : : string sub_command = args . GetArgumentAtIndex ( 0 ) ;
assert ( sub_command . length ( ) ! = 0 ) ;
2012-10-13 10:07:45 +08:00
subcommand_obj_sp = cmd_obj - > GetSubcommandSP ( sub_command . c_str ( ) ) ;
2010-07-07 11:36:20 +08:00
if ( subcommand_obj_sp . get ( ) )
{
sub_cmd_obj = subcommand_obj_sp . get ( ) ;
use_subcommand = true ;
args . Shift ( ) ; // Shift the sub_command word off the argument vector.
2010-12-10 06:52:49 +08:00
cmd_obj = sub_cmd_obj ;
2010-07-07 11:36:20 +08:00
}
else
{
2010-11-03 03:00:04 +08:00
result . AppendErrorWithFormat ( " '%s' is not a valid sub-command of '%s'. "
" Unable to create alias. \n " ,
sub_command . c_str ( ) , actual_command . c_str ( ) ) ;
2010-07-07 11:36:20 +08:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
}
// Verify & handle any options/arguments passed to the alias command
if ( args . GetArgumentCount ( ) > 0 )
{
2011-05-07 05:37:15 +08:00
CommandObjectSP tmp_sp = m_interpreter . GetCommandSPExact ( cmd_obj - > GetCommandName ( ) , false ) ;
if ( use_subcommand )
tmp_sp = m_interpreter . GetCommandSPExact ( sub_cmd_obj - > GetCommandName ( ) , false ) ;
std : : string args_string ;
args . GetCommandString ( args_string ) ;
if ( ! m_interpreter . ProcessAliasOptionsArgs ( tmp_sp , args_string . c_str ( ) , option_arg_vector_sp ) )
{
result . AppendError ( " Unable to create requested alias. \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2010-07-07 11:36:20 +08:00
}
// Create the alias.
2010-09-18 09:14:36 +08:00
if ( m_interpreter . AliasExists ( alias_command . c_str ( ) )
| | m_interpreter . UserCommandExists ( alias_command . c_str ( ) ) )
2010-07-07 11:36:20 +08:00
{
2010-09-18 09:14:36 +08:00
OptionArgVectorSP tmp_option_arg_sp ( m_interpreter . GetAliasOptions ( alias_command . c_str ( ) ) ) ;
2010-07-07 11:36:20 +08:00
if ( tmp_option_arg_sp . get ( ) )
{
if ( option_arg_vector - > size ( ) = = 0 )
2010-09-18 09:14:36 +08:00
m_interpreter . RemoveAliasOptions ( alias_command . c_str ( ) ) ;
2010-07-07 11:36:20 +08:00
}
result . AppendWarningWithFormat ( " Overwriting existing definition for '%s'. \n " ,
alias_command . c_str ( ) ) ;
}
if ( use_subcommand )
2010-09-18 09:14:36 +08:00
m_interpreter . AddAlias ( alias_command . c_str ( ) , subcommand_obj_sp ) ;
2010-07-07 11:36:20 +08:00
else
2010-09-18 09:14:36 +08:00
m_interpreter . AddAlias ( alias_command . c_str ( ) , command_obj_sp ) ;
2010-07-07 11:36:20 +08:00
if ( option_arg_vector - > size ( ) > 0 )
2010-09-18 09:14:36 +08:00
m_interpreter . AddOrReplaceAliasOptions ( alias_command . c_str ( ) , option_arg_vector_sp ) ;
2010-07-07 11:36:20 +08:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendErrorWithFormat ( " '%s' is not an existing command. \n " , actual_command . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
2010-10-29 07:17:48 +08:00
return false ;
2010-07-07 11:36:20 +08:00
}
}
return result . Succeeded ( ) ;
}
2012-06-09 05:56:10 +08:00
2010-07-07 11:36:20 +08:00
} ;
# pragma mark CommandObjectCommandsUnalias
//-------------------------------------------------------------------------
// CommandObjectCommandsUnalias
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
class CommandObjectCommandsUnalias : public CommandObjectParsed
2010-07-07 11:36:20 +08:00
{
public :
2010-09-18 09:14:36 +08:00
CommandObjectCommandsUnalias ( CommandInterpreter & interpreter ) :
2012-06-09 05:56:10 +08:00
CommandObjectParsed ( interpreter ,
2011-04-21 06:55:21 +08:00
" command unalias " ,
2010-09-12 12:56:10 +08:00
" Allow the user to remove/delete a user-defined command abbreviation. " ,
2010-10-05 06:28:36 +08:00
NULL )
2010-07-07 11:36:20 +08:00
{
2010-10-05 06:28:36 +08:00
CommandArgumentEntry arg ;
CommandArgumentData alias_arg ;
// 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 ) ;
2010-07-07 11:36:20 +08:00
}
~ CommandObjectCommandsUnalias ( )
{
}
2012-06-09 05:56:10 +08:00
protected :
2010-07-07 11:36:20 +08:00
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & args , CommandReturnObject & result )
2010-07-07 11:36:20 +08:00
{
CommandObject : : CommandMap : : iterator pos ;
CommandObject * cmd_obj ;
if ( args . GetArgumentCount ( ) ! = 0 )
{
const char * command_name = args . GetArgumentAtIndex ( 0 ) ;
2010-09-18 09:14:36 +08:00
cmd_obj = m_interpreter . GetCommandObject ( command_name ) ;
2010-07-07 11:36:20 +08:00
if ( cmd_obj )
{
2010-09-18 09:14:36 +08:00
if ( m_interpreter . CommandExists ( command_name ) )
2010-07-07 11:36:20 +08:00
{
result . AppendErrorWithFormat ( " '%s' is a permanent debugger command and cannot be removed. \n " ,
command_name ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
else
{
2010-09-18 09:14:36 +08:00
if ( m_interpreter . RemoveAlias ( command_name ) = = false )
2010-07-07 11:36:20 +08:00
{
2010-09-18 09:14:36 +08:00
if ( m_interpreter . AliasExists ( command_name ) )
2010-07-07 11:36:20 +08:00
result . AppendErrorWithFormat ( " Error occurred while attempting to unalias '%s'. \n " ,
command_name ) ;
else
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 ) ;
}
return result . Succeeded ( ) ;
}
} ;
2011-04-21 00:37:46 +08:00
//-------------------------------------------------------------------------
// CommandObjectCommandsAddRegex
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
# pragma mark CommandObjectCommandsAddRegex
2011-04-21 00:37:46 +08:00
2014-01-28 07:43:24 +08:00
class CommandObjectCommandsAddRegex :
public CommandObjectParsed ,
public IOHandlerDelegate
2011-04-21 00:37:46 +08:00
{
public :
CommandObjectCommandsAddRegex ( CommandInterpreter & interpreter ) :
2012-06-09 05:56:10 +08:00
CommandObjectParsed ( interpreter ,
2011-04-21 06:55:21 +08:00
" command regex " ,
2011-04-21 00:37:46 +08:00
" Allow the user to create a regular expression command. " ,
2011-04-21 06:55:21 +08:00
" command regex <cmd-name> [s/<regex>/<subst>/ ...] " ) ,
2014-01-28 07:43:24 +08:00
IOHandlerDelegate ( IOHandlerDelegate : : Completion : : LLDBCommand ) ,
2011-04-21 00:37:46 +08:00
m_options ( interpreter )
{
2011-04-21 06:55:21 +08:00
SetHelpLong (
" This command allows the user to create powerful regular expression commands \n "
" with substitutions. The regular expressions and substitutions are specified \n "
" using the regular exression substitution format of: \n "
" \n "
" s/<regex>/<subst>/ \n "
" \n "
" <regex> is a regular expression that can use parenthesis to capture regular \n "
" expression input and substitute the captured matches in the output using %1 \n "
" for the first match, %2 for the second, and so on. \n "
" \n "
" The regular expressions can all be specified on the command line if more than \n "
" one argument is provided. If just the command name is provided on the command \n "
" line, then the regular expressions and substitutions can be entered on separate \n "
" lines, followed by an empty line to terminate the command definition. \n "
" \n "
" EXAMPLES \n "
" \n "
2012-08-17 05:46:58 +08:00
" The following example will define a regular expression command named 'f' that \n "
2011-04-21 06:55:21 +08:00
" will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \n "
" a number follows 'f': \n "
2012-08-17 05:46:58 +08:00
" \n "
" (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/' \n "
" \n "
2011-04-21 06:55:21 +08:00
) ;
2011-04-21 00:37:46 +08:00
}
~ CommandObjectCommandsAddRegex ( )
{
}
2012-06-09 05:56:10 +08:00
protected :
2014-01-28 07:43:24 +08:00
virtual void
IOHandlerActivated ( IOHandler & io_handler )
{
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 ( ) ;
}
}
virtual void
IOHandlerInputComplete ( IOHandler & io_handler , std : : string & data )
{
io_handler . SetIsDone ( true ) ;
if ( m_regex_cmd_ap . get ( ) )
{
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 )
{
printf ( " regex[%zu] = %s \n " , i , lines [ i ] . c_str ( ) ) ;
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 ( ) ) ;
}
}
}
}
if ( m_regex_cmd_ap - > HasRegexEntries ( ) )
{
CommandObjectSP cmd_sp ( m_regex_cmd_ap . release ( ) ) ;
m_interpreter . AddCommand ( cmd_sp - > GetCommandName ( ) , cmd_sp , true ) ;
}
}
}
virtual LineStatus
IOHandlerLinesUpdated ( IOHandler & io_handler ,
StringList & lines ,
uint32_t line_idx ,
Error & error )
{
if ( line_idx = = UINT32_MAX )
{
// Return true to indicate we are done getting lines (this
// is a "fake" line - the real terminating blank line was
// removed during a previous call with the code below)
error . Clear ( ) ;
return LineStatus : : Done ;
}
else
{
const size_t num_lines = lines . GetSize ( ) ;
if ( line_idx + 1 = = num_lines )
{
// The last line was edited, if this line is empty, then we are done
// getting our multiple lines.
if ( lines [ line_idx ] . empty ( ) )
{
// Remove the last empty line from "lines" so it doesn't appear
// in our final expression and return true to indicate we are done
// getting lines
lines . PopBack ( ) ;
return LineStatus : : Done ;
}
}
// Check the current line to make sure it is formatted correctly
bool check_only = true ;
llvm : : StringRef regex_sed ( lines [ line_idx ] ) ;
error = AppendRegexSubstitution ( regex_sed , check_only ) ;
if ( error . Fail ( ) )
{
return LineStatus : : Error ;
}
else
{
return LineStatus : : Success ;
}
}
}
2011-04-21 00:37:46 +08:00
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2011-04-21 00:37:46 +08:00
{
2012-06-09 05:56:10 +08:00
const size_t argc = command . GetArgumentCount ( ) ;
2011-04-21 06:55:21 +08:00
if ( argc = = 0 )
2011-04-21 00:37:46 +08:00
{
2011-11-11 06:43:35 +08:00
result . AppendError ( " usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]' \n " ) ;
2011-04-21 06:55:21 +08:00
result . SetStatus ( eReturnStatusFailed ) ;
}
else
{
Error error ;
2012-06-09 05:56:10 +08:00
const char * name = command . GetArgumentAtIndex ( 0 ) ;
2011-04-21 00:37:46 +08:00
m_regex_cmd_ap . reset ( new CommandObjectRegexCommand ( m_interpreter ,
name ,
m_options . GetHelp ( ) ,
m_options . GetSyntax ( ) ,
10 ) ) ;
2011-04-21 06:55:21 +08:00
if ( argc = = 1 )
2011-04-21 00:37:46 +08:00
{
2014-01-28 07:43:24 +08:00
Debugger & debugger = m_interpreter . GetDebugger ( ) ;
const bool multiple_lines = true ; // Get multiple lines
IOHandlerSP io_handler_sp ( new IOHandlerEditline ( debugger ,
2014-03-07 08:53:24 +08:00
" lldb " , // Name of input reader for history
" \033 [K> " , // Prompt and clear line
2014-01-28 07:43:24 +08:00
multiple_lines ,
2014-03-07 08:53:24 +08:00
0 , // Don't show line numbers
2014-01-28 07:43:24 +08:00
* this ) ) ;
if ( io_handler_sp )
2011-04-21 06:55:21 +08:00
{
2014-01-28 07:43:24 +08:00
debugger . PushIOHandler ( io_handler_sp ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
2011-04-21 06:55:21 +08:00
}
}
else
{
for ( size_t arg_idx = 1 ; arg_idx < argc ; + + arg_idx )
2011-04-21 00:37:46 +08:00
{
2012-06-09 05:56:10 +08:00
llvm : : StringRef arg_strref ( command . GetArgumentAtIndex ( arg_idx ) ) ;
2014-01-28 07:43:24 +08:00
bool check_only = false ;
error = AppendRegexSubstitution ( arg_strref , check_only ) ;
2011-04-21 06:55:21 +08:00
if ( error . Fail ( ) )
break ;
2011-04-21 00:37:46 +08:00
}
2011-04-21 06:55:21 +08:00
if ( error . Success ( ) )
2011-04-21 00:37:46 +08:00
{
2011-04-21 06:55:21 +08:00
AddRegexCommandToInterpreter ( ) ;
2011-04-21 00:37:46 +08:00
}
}
2011-04-21 06:55:21 +08:00
if ( error . Fail ( ) )
{
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
2011-04-21 00:37:46 +08:00
}
2011-04-21 06:55:21 +08:00
2011-04-21 00:37:46 +08:00
return result . Succeeded ( ) ;
}
2011-04-21 06:55:21 +08:00
Error
2014-01-28 07:43:24 +08:00
AppendRegexSubstitution ( const llvm : : StringRef & regex_sed , bool check_only )
2011-04-21 00:37:46 +08:00
{
2011-04-21 06:55:21 +08:00
Error error ;
if ( m_regex_cmd_ap . get ( ) = = NULL )
{
error . SetErrorStringWithFormat ( " invalid regular expression command object for: '%.*s' " ,
( int ) regex_sed . size ( ) ,
regex_sed . data ( ) ) ;
return error ;
}
size_t regex_sed_size = regex_sed . size ( ) ;
if ( regex_sed_size < = 1 )
2011-04-21 00:37:46 +08:00
{
2011-04-21 06:55:21 +08:00
error . SetErrorStringWithFormat ( " regular expression substitution string is too short: '%.*s' " ,
( int ) regex_sed . size ( ) ,
regex_sed . data ( ) ) ;
return error ;
2011-04-21 00:37:46 +08:00
}
2011-04-21 06:55:21 +08: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' " ,
separator_char ,
( int ) ( regex_sed . size ( ) - first_separator_char_pos - 1 ) ,
regex_sed . data ( ) + ( first_separator_char_pos + 1 ) ) ;
return error ;
}
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' " ,
separator_char ,
( int ) ( regex_sed . size ( ) - second_separator_char_pos - 1 ) ,
regex_sed . data ( ) + ( second_separator_char_pos + 1 ) ) ;
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 ) ) ;
return error ;
}
}
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 ;
}
2014-01-28 07:43:24 +08:00
if ( check_only = = false )
{
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 ( ) ) ;
}
2011-04-21 06:55:21 +08:00
return error ;
2011-04-21 00:37:46 +08:00
}
void
2011-04-21 06:55:21 +08:00
AddRegexCommandToInterpreter ( )
2011-04-21 00:37:46 +08:00
{
if ( m_regex_cmd_ap . get ( ) )
{
if ( m_regex_cmd_ap - > HasRegexEntries ( ) )
{
CommandObjectSP cmd_sp ( m_regex_cmd_ap . release ( ) ) ;
m_interpreter . AddCommand ( cmd_sp - > GetCommandName ( ) , cmd_sp , true ) ;
}
}
}
private :
2013-04-19 06:45:39 +08:00
std : : unique_ptr < CommandObjectRegexCommand > m_regex_cmd_ap ;
2011-04-21 00:37:46 +08:00
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter )
{
}
virtual
~ CommandOptions ( ) { }
virtual Error
SetOptionValue ( uint32_t option_idx , const char * option_arg )
{
Error error ;
2012-12-04 08:32:51 +08:00
const int short_option = m_getopt_table [ option_idx ] . val ;
2011-04-21 00:37:46 +08:00
switch ( short_option )
{
case ' h ' :
m_help . assign ( option_arg ) ;
break ;
case ' s ' :
m_syntax . assign ( option_arg ) ;
break ;
default :
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
2011-04-21 00:37:46 +08:00
break ;
}
return error ;
}
void
OptionParsingStarting ( )
{
m_help . clear ( ) ;
m_syntax . clear ( ) ;
}
const OptionDefinition *
GetDefinitions ( )
{
return g_option_table ;
}
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
const char *
GetHelp ( )
{
if ( m_help . empty ( ) )
return NULL ;
return m_help . c_str ( ) ;
}
const char *
GetSyntax ( )
{
if ( m_syntax . empty ( ) )
return NULL ;
return m_syntax . c_str ( ) ;
}
// Instance variables to hold the values for command options.
protected :
std : : string m_help ;
std : : string m_syntax ;
} ;
2012-06-09 05:56:10 +08:00
2011-04-21 00:37:46 +08:00
virtual Options *
GetOptions ( )
{
return & m_options ;
}
2012-06-09 05:56:10 +08:00
CommandOptions m_options ;
2011-04-21 00:37:46 +08:00
} ;
OptionDefinition
CommandObjectCommandsAddRegex : : CommandOptions : : g_option_table [ ] =
{
2013-09-06 00:42:23 +08:00
{ LLDB_OPT_SET_1 , false , " help " , ' h ' , OptionParser : : eRequiredArgument , NULL , 0 , eArgTypeNone , " The help text to display for this command. " } ,
{ LLDB_OPT_SET_1 , false , " syntax " , ' s ' , OptionParser : : eRequiredArgument , NULL , 0 , eArgTypeNone , " A syntax string showing the typical usage syntax. " } ,
2011-04-21 06:55:21 +08:00
{ 0 , false , NULL , 0 , 0 , NULL , 0 , eArgTypeNone , NULL }
2011-04-21 00:37:46 +08:00
} ;
2012-06-09 05:56:10 +08:00
class CommandObjectPythonFunction : public CommandObjectRaw
2011-08-17 07:24:13 +08:00
{
private :
std : : string m_function_name ;
2011-11-08 06:57:04 +08:00
ScriptedCommandSynchronicity m_synchro ;
2012-09-19 05:53:02 +08:00
bool m_fetched_help_long ;
2011-08-17 07:24:13 +08:00
public :
CommandObjectPythonFunction ( CommandInterpreter & interpreter ,
std : : string name ,
2011-11-08 06:57:04 +08:00
std : : string funct ,
ScriptedCommandSynchronicity synch ) :
2012-06-09 05:56:10 +08:00
CommandObjectRaw ( interpreter ,
name . c_str ( ) ,
( std : : string ( " Run Python function " ) + funct ) . c_str ( ) ,
NULL ) ,
m_function_name ( funct ) ,
2012-09-19 05:53:02 +08:00
m_synchro ( synch ) ,
m_fetched_help_long ( false )
2011-08-17 07:24:13 +08:00
{
}
virtual
~ CommandObjectPythonFunction ( )
{
}
virtual bool
2012-10-09 06:41:53 +08:00
IsRemovable ( ) const
2012-06-09 05:56:10 +08:00
{
return true ;
}
const std : : string &
GetFunctionName ( )
{
return m_function_name ;
}
ScriptedCommandSynchronicity
GetSynchronicity ( )
{
return m_synchro ;
}
2012-09-19 05:53:02 +08:00
virtual const char *
GetHelpLong ( )
{
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 ) ;
}
}
return CommandObjectRaw : : GetHelpLong ( ) ;
}
2012-06-09 05:56:10 +08:00
protected :
virtual bool
DoExecute ( const char * raw_command_line , CommandReturnObject & result )
2011-08-17 07:24:13 +08:00
{
ScriptInterpreter * scripter = m_interpreter . GetScriptInterpreter ( ) ;
Error error ;
2012-06-28 01:25:36 +08:00
result . SetStatus ( eReturnStatusInvalid ) ;
2011-08-17 07:24:13 +08:00
if ( ! scripter | | scripter - > RunScriptBasedCommand ( m_function_name . c_str ( ) ,
raw_command_line ,
2011-11-08 06:57:04 +08:00
m_synchro ,
2011-08-17 07:24:13 +08:00
result ,
error ) = = false )
{
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
else
2012-06-28 01:25:36 +08:00
{
// Don't change the status if the command already set it...
if ( result . GetStatus ( ) = = eReturnStatusInvalid )
{
2013-07-04 01:58:31 +08:00
if ( result . GetOutputData ( ) = = NULL | | result . GetOutputData ( ) [ 0 ] = = ' \0 ' )
2012-06-28 01:25:36 +08:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
else
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
}
}
2011-08-17 07:24:13 +08:00
return result . Succeeded ( ) ;
}
2012-06-09 05:56:10 +08:00
} ;
2011-11-08 06:57:04 +08:00
2012-06-09 05:56:10 +08:00
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptImport
//-------------------------------------------------------------------------
2011-11-08 06:57:04 +08:00
2012-06-09 05:56:10 +08:00
class CommandObjectCommandsScriptImport : public CommandObjectParsed
{
public :
CommandObjectCommandsScriptImport ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" command script import " ,
" Import a scripting module in LLDB. " ,
NULL ) ,
m_options ( interpreter )
2011-11-08 06:57:04 +08:00
{
2012-06-09 05:56:10 +08:00
CommandArgumentEntry arg1 ;
CommandArgumentData cmd_arg ;
// Define the first (and only) variant of this arg.
cmd_arg . arg_type = eArgTypeFilename ;
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 ) ;
2011-11-08 06:57:04 +08:00
}
2012-06-09 05:56:10 +08:00
~ CommandObjectCommandsScriptImport ( )
2011-11-08 06:57:04 +08:00
{
}
2012-06-09 05:56:10 +08:00
2013-01-26 02:06:21 +08:00
virtual int
2012-06-09 05:56:10 +08:00
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 )
2011-11-08 06:57:04 +08:00
{
2012-06-09 05:56:10 +08:00
std : : string completion_str ( input . GetArgumentAtIndex ( cursor_index ) ) ;
completion_str . erase ( cursor_char_position ) ;
CommandCompletions : : InvokeCommonCompletionCallbacks ( m_interpreter ,
CommandCompletions : : eDiskFileCompletion ,
completion_str . c_str ( ) ,
match_start_point ,
max_return_elements ,
NULL ,
word_complete ,
matches ) ;
return matches . GetSize ( ) ;
2011-11-08 06:57:04 +08:00
}
2011-08-17 07:24:13 +08:00
2012-06-09 05:56:10 +08:00
virtual Options *
GetOptions ( )
{
return & m_options ;
}
2011-10-18 05:45:27 +08:00
2012-06-09 05:56:10 +08:00
protected :
2011-11-08 06:57:04 +08:00
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
2012-06-09 05:56:10 +08:00
Options ( interpreter )
2011-11-08 06:57:04 +08:00
{
}
virtual
~ CommandOptions ( ) { }
virtual Error
SetOptionValue ( uint32_t option_idx , const char * option_arg )
{
Error error ;
2012-12-04 08:32:51 +08:00
const int short_option = m_getopt_table [ option_idx ] . val ;
2011-11-08 06:57:04 +08:00
switch ( short_option )
{
case ' r ' :
m_allow_reload = true ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
OptionParsingStarting ( )
{
2013-05-31 09:03:09 +08:00
m_allow_reload = true ;
2011-11-08 06:57:04 +08:00
}
const OptionDefinition *
GetDefinitions ( )
{
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 ;
} ;
2011-10-18 05:45:27 +08:00
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2011-10-18 05:45:27 +08:00
{
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-09 05:56:10 +08:00
size_t argc = command . GetArgumentCount ( ) ;
2011-10-18 05:45:27 +08:00
if ( argc ! = 1 )
{
result . AppendError ( " 'command script import' requires one argument " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2012-06-09 05:56:10 +08:00
std : : string path = command . GetArgumentAtIndex ( 0 ) ;
2011-10-18 05:45:27 +08:00
Error error ;
2012-10-19 06:40:37 +08:00
const bool init_session = true ;
2013-05-10 03:33:49 +08:00
// 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 ( ) ;
2011-10-18 05:45:27 +08:00
if ( m_interpreter . GetScriptInterpreter ( ) - > LoadScriptingModule ( path . c_str ( ) ,
2011-11-08 06:57:04 +08:00
m_options . m_allow_reload ,
2012-10-19 06:40:37 +08:00
init_session ,
2011-10-18 05:45:27 +08:00
error ) )
{
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendErrorWithFormat ( " module importing failed: %s " , error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
return result . Succeeded ( ) ;
}
2011-11-08 06:57:04 +08:00
2012-06-09 05:56:10 +08:00
CommandOptions m_options ;
2011-11-08 06:57:04 +08:00
} ;
OptionDefinition
CommandObjectCommandsScriptImport : : CommandOptions : : g_option_table [ ] =
{
2013-09-06 00:42:23 +08:00
{ LLDB_OPT_SET_1 , false , " allow-reload " , ' r ' , OptionParser : : eNoArgument , NULL , 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. " } ,
2011-11-08 06:57:04 +08:00
{ 0 , false , NULL , 0 , 0 , NULL , 0 , eArgTypeNone , NULL }
2011-10-18 05:45:27 +08:00
} ;
2011-08-17 07:24:13 +08:00
2011-11-08 06:57:04 +08:00
2011-08-17 07:24:13 +08:00
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptAdd
//-------------------------------------------------------------------------
2014-01-28 07:43:24 +08:00
class CommandObjectCommandsScriptAdd :
public CommandObjectParsed ,
public IOHandlerDelegateMultiline
2011-08-17 07:24:13 +08:00
{
2012-06-09 05:56:10 +08:00
public :
CommandObjectCommandsScriptAdd ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" command script add " ,
" Add a scripted function as an LLDB command. " ,
NULL ) ,
2014-05-09 00:59:00 +08:00
IOHandlerDelegateMultiline ( " DONE " ) ,
2012-06-09 05:56:10 +08:00
m_options ( interpreter )
{
CommandArgumentEntry arg1 ;
CommandArgumentData cmd_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.
arg1 . push_back ( cmd_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg1 ) ;
}
~ CommandObjectCommandsScriptAdd ( )
{
}
virtual Options *
GetOptions ( )
{
return & m_options ;
}
protected :
2011-08-17 07:24:13 +08:00
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
2014-01-28 07:43:24 +08:00
Options ( interpreter )
2011-08-17 07:24:13 +08:00
{
}
virtual
~ CommandOptions ( ) { }
virtual Error
SetOptionValue ( uint32_t option_idx , const char * option_arg )
{
Error error ;
2012-12-04 08:32:51 +08:00
const int short_option = m_getopt_table [ option_idx ] . val ;
2011-08-17 07:24:13 +08:00
switch ( short_option )
{
case ' f ' :
m_funct_name = std : : string ( option_arg ) ;
break ;
2011-11-08 06:57:04 +08:00
case ' s ' :
2014-01-28 07:43:24 +08:00
m_synchronicity = ( ScriptedCommandSynchronicity ) Args : : StringToOptionEnum ( option_arg , g_option_table [ option_idx ] . enum_values , 0 , error ) ;
2011-11-08 06:57:04 +08:00
if ( ! error . Success ( ) )
error . SetErrorStringWithFormat ( " unrecognized value for synchronicity '%s' " , option_arg ) ;
break ;
2011-08-17 07:24:13 +08:00
default :
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
2011-08-17 07:24:13 +08:00
break ;
}
return error ;
}
void
OptionParsingStarting ( )
{
m_funct_name = " " ;
2014-01-28 07:43:24 +08:00
m_synchronicity = eScriptedCommandSynchronicitySynchronous ;
2011-08-17 07:24:13 +08:00
}
const OptionDefinition *
GetDefinitions ( )
{
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.
std : : string m_funct_name ;
2014-01-28 07:43:24 +08:00
ScriptedCommandSynchronicity m_synchronicity ;
2011-08-17 07:24:13 +08:00
} ;
2012-06-09 05:56:10 +08:00
2014-01-28 07:43:24 +08:00
virtual void
IOHandlerActivated ( IOHandler & io_handler )
2011-08-17 07:24:13 +08:00
{
2014-01-28 07:43:24 +08:00
StreamFileSP output_sp ( io_handler . GetOutputStreamFile ( ) ) ;
if ( output_sp )
2011-08-17 07:24:13 +08:00
{
2014-01-28 07:43:24 +08:00
output_sp - > PutCString ( g_python_command_instructions ) ;
output_sp - > Flush ( ) ;
2011-08-17 07:24:13 +08:00
}
2014-01-28 07:43:24 +08:00
}
virtual void
IOHandlerInputComplete ( IOHandler & io_handler , std : : string & data )
{
StreamFileSP error_sp = io_handler . GetErrorStreamFile ( ) ;
2011-08-17 07:24:13 +08:00
2014-01-28 07:43:24 +08:00
ScriptInterpreter * interpreter = m_interpreter . GetScriptInterpreter ( ) ;
if ( interpreter )
2011-08-17 07:24:13 +08:00
{
2014-01-28 07:43:24 +08:00
StringList lines ;
lines . SplitIntoLines ( data ) ;
if ( lines . GetSize ( ) > 0 )
2011-08-17 07:24:13 +08:00
{
2014-01-28 07:43:24 +08:00
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_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 ( ) ;
}
2011-08-17 07:24:13 +08:00
}
2014-01-28 07:43:24 +08:00
else
2011-08-17 07:24:13 +08:00
{
2014-01-28 07:43:24 +08:00
error_sp - > Printf ( " error: empty function, didn't add python command. \n " ) ;
error_sp - > Flush ( ) ;
2011-08-17 07:24:13 +08:00
}
}
2014-01-28 07:43:24 +08:00
else
2011-08-17 07:24:13 +08:00
{
2014-01-28 07:43:24 +08:00
error_sp - > Printf ( " error: script interpreter missing, didn't add python command. \n " ) ;
error_sp - > Flush ( ) ;
2011-08-17 07:24:13 +08:00
}
2014-01-28 07:43:24 +08:00
io_handler . SetIsDone ( true ) ;
}
2012-06-09 05:56:10 +08:00
protected :
2011-08-17 07:24:13 +08:00
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2011-08-17 07:24:13 +08:00
{
2011-08-17 09:30:04 +08:00
if ( m_interpreter . GetDebugger ( ) . GetScriptLanguage ( ) ! = lldb : : eScriptLanguagePython )
{
result . AppendError ( " only scripting language supported for scripted commands is currently Python " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2012-06-09 05:56:10 +08:00
size_t argc = command . GetArgumentCount ( ) ;
2011-08-17 07:24:13 +08:00
if ( argc ! = 1 )
{
result . AppendError ( " 'command script add' requires one argument " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2014-01-28 07:43:24 +08:00
// Store the command name and synchronicity in case we get multi-line input
m_cmd_name = command . GetArgumentAtIndex ( 0 ) ;
m_synchronicity = m_options . m_synchronicity ;
2011-08-17 07:24:13 +08:00
if ( m_options . m_funct_name . empty ( ) )
{
2014-01-28 07:43:24 +08:00
m_interpreter . GetPythonCommandsFromIOHandler ( " " , // Prompt
* this , // IOHandlerDelegate
true , // Run IOHandler in async mode
NULL ) ; // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
2011-08-17 07:24:13 +08:00
}
else
{
2011-11-08 06:57:04 +08:00
CommandObjectSP new_cmd ( new CommandObjectPythonFunction ( m_interpreter ,
2014-01-28 07:43:24 +08:00
m_cmd_name ,
2011-11-08 06:57:04 +08:00
m_options . m_funct_name ,
2014-01-28 07:43:24 +08:00
m_synchronicity ) ) ;
if ( m_interpreter . AddUserCommand ( m_cmd_name , new_cmd , true ) )
2011-08-17 07:24:13 +08:00
{
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendError ( " cannot add command " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
return result . Succeeded ( ) ;
}
2012-06-09 05:56:10 +08:00
CommandOptions m_options ;
2014-01-28 07:43:24 +08:00
std : : string m_cmd_name ;
ScriptedCommandSynchronicity m_synchronicity ;
2011-08-17 07:24:13 +08:00
} ;
2011-11-08 06:57:04 +08:00
static OptionEnumValueElement g_script_synchro_type [ ] =
{
{ eScriptedCommandSynchronicitySynchronous , " synchronous " , " Run synchronous " } ,
{ eScriptedCommandSynchronicityAsynchronous , " asynchronous " , " Run asynchronous " } ,
{ eScriptedCommandSynchronicityCurrentValue , " current " , " Do not alter current setting " } ,
{ 0 , NULL , NULL }
} ;
2011-08-17 07:24:13 +08:00
OptionDefinition
CommandObjectCommandsScriptAdd : : CommandOptions : : g_option_table [ ] =
{
2013-09-06 00:42:23 +08:00
{ LLDB_OPT_SET_1 , false , " function " , ' f ' , OptionParser : : eRequiredArgument , NULL , 0 , eArgTypePythonFunction , " Name of the Python function to bind to this command name. " } ,
{ LLDB_OPT_SET_1 , false , " synchronicity " , ' s ' , OptionParser : : eRequiredArgument , g_script_synchro_type , 0 , eArgTypeScriptedCommandSynchronicity , " Set the synchronicity of this command's executions with regard to LLDB event system. " } ,
2011-08-17 07:24:13 +08:00
{ 0 , false , NULL , 0 , 0 , NULL , 0 , eArgTypeNone , NULL }
} ;
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptList
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
class CommandObjectCommandsScriptList : public CommandObjectParsed
2011-08-17 07:24:13 +08:00
{
private :
2011-11-08 06:57:04 +08:00
2011-08-17 07:24:13 +08:00
public :
CommandObjectCommandsScriptList ( CommandInterpreter & interpreter ) :
2012-06-09 05:56:10 +08:00
CommandObjectParsed ( interpreter ,
2011-08-17 07:24:13 +08:00
" command script list " ,
" List defined scripted commands. " ,
NULL )
{
}
~ CommandObjectCommandsScriptList ( )
{
}
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2011-08-17 07:24:13 +08:00
{
m_interpreter . GetHelp ( result ,
CommandInterpreter : : eCommandTypesUserDef ) ;
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
return true ;
}
} ;
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptClear
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
class CommandObjectCommandsScriptClear : public CommandObjectParsed
2011-08-17 07:24:13 +08:00
{
private :
public :
CommandObjectCommandsScriptClear ( CommandInterpreter & interpreter ) :
2012-06-09 05:56:10 +08:00
CommandObjectParsed ( interpreter ,
" command script clear " ,
" Delete all scripted commands. " ,
NULL )
2011-08-17 07:24:13 +08:00
{
}
~ CommandObjectCommandsScriptClear ( )
{
}
2012-06-09 05:56:10 +08:00
protected :
2011-08-17 07:24:13 +08:00
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2011-08-17 07:24:13 +08:00
{
m_interpreter . RemoveAllUser ( ) ;
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
return true ;
}
} ;
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptDelete
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
class CommandObjectCommandsScriptDelete : public CommandObjectParsed
2011-08-17 07:24:13 +08:00
{
public :
CommandObjectCommandsScriptDelete ( CommandInterpreter & interpreter ) :
2012-06-09 05:56:10 +08:00
CommandObjectParsed ( interpreter ,
" command script delete " ,
" Delete a scripted command. " ,
NULL )
2011-08-17 07:24:13 +08:00
{
CommandArgumentEntry arg1 ;
CommandArgumentData cmd_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.
arg1 . push_back ( cmd_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg1 ) ;
}
~ CommandObjectCommandsScriptDelete ( )
{
}
2012-06-09 05:56:10 +08:00
protected :
2011-08-17 07:24:13 +08:00
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2011-08-17 07:24:13 +08:00
{
2012-06-09 05:56:10 +08:00
size_t argc = command . GetArgumentCount ( ) ;
2011-08-17 07:24:13 +08:00
if ( argc ! = 1 )
{
result . AppendError ( " 'command script delete' requires one argument " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2012-06-09 05:56:10 +08:00
const char * cmd_name = command . GetArgumentAtIndex ( 0 ) ;
2011-08-17 07:24:13 +08:00
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 ( ) ;
}
} ;
# pragma mark CommandObjectMultiwordCommandsScript
//-------------------------------------------------------------------------
// CommandObjectMultiwordCommandsScript
//-------------------------------------------------------------------------
class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
{
public :
CommandObjectMultiwordCommandsScript ( CommandInterpreter & interpreter ) :
CommandObjectMultiword ( interpreter ,
" command script " ,
" A set of commands for managing or customizing script commands. " ,
" 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 ) ) ) ;
2011-10-18 05:45:27 +08:00
LoadSubCommand ( " import " , CommandObjectSP ( new CommandObjectCommandsScriptImport ( interpreter ) ) ) ;
2011-08-17 07:24:13 +08:00
}
~ CommandObjectMultiwordCommandsScript ( )
{
}
} ;
2010-07-07 11:36:20 +08:00
# pragma mark CommandObjectMultiwordCommands
//-------------------------------------------------------------------------
// CommandObjectMultiwordCommands
//-------------------------------------------------------------------------
CommandObjectMultiwordCommands : : CommandObjectMultiwordCommands ( CommandInterpreter & interpreter ) :
2010-09-18 09:14:36 +08:00
CommandObjectMultiword ( interpreter ,
2011-04-21 06:55:21 +08:00
" command " ,
2010-09-08 06:38:08 +08:00
" A set of commands for managing or customizing the debugger commands. " ,
2011-04-21 06:55:21 +08:00
" command <subcommand> [<subcommand-options>] " )
2010-07-07 11:36:20 +08:00
{
2010-09-18 09:14:36 +08:00
LoadSubCommand ( " source " , CommandObjectSP ( new CommandObjectCommandsSource ( interpreter ) ) ) ;
LoadSubCommand ( " alias " , CommandObjectSP ( new CommandObjectCommandsAlias ( interpreter ) ) ) ;
LoadSubCommand ( " unalias " , CommandObjectSP ( new CommandObjectCommandsUnalias ( interpreter ) ) ) ;
2011-04-21 00:37:46 +08:00
LoadSubCommand ( " regex " , CommandObjectSP ( new CommandObjectCommandsAddRegex ( interpreter ) ) ) ;
2011-07-12 11:12:18 +08:00
LoadSubCommand ( " history " , CommandObjectSP ( new CommandObjectCommandsHistory ( interpreter ) ) ) ;
2011-08-17 07:24:13 +08:00
LoadSubCommand ( " script " , CommandObjectSP ( new CommandObjectMultiwordCommandsScript ( interpreter ) ) ) ;
2010-07-07 11:36:20 +08:00
}
CommandObjectMultiwordCommands : : ~ CommandObjectMultiwordCommands ( )
{
}