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.
//
//===----------------------------------------------------------------------===//
# 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"
2011-04-21 00:37:46 +08:00
# include "lldb/Core/InputReader.h"
2011-08-17 00:49:25 +08:00
# include "lldb/Core/InputReaderEZ.h"
# include "lldb/Core/StringList.h"
2011-04-21 00:37:46 +08:00
# include "lldb/Interpreter/Args.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"
# 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 ) :
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-07-12 11:12:18 +08:00
bool success ;
switch ( short_option )
{
case ' c ' :
m_end_idx = Args : : StringToUInt32 ( option_arg , UINT_MAX , 0 , & success ) ;
if ( ! success )
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " invalid value for count: %s " , option_arg ) ;
2011-07-12 11:12:18 +08:00
if ( m_end_idx ! = 0 )
m_end_idx - - ;
m_start_idx = 0 ;
break ;
case ' e ' :
m_end_idx = Args : : StringToUInt32 ( option_arg , 0 , 0 , & success ) ;
if ( ! success )
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " invalid value for end index: %s " , option_arg ) ;
2011-07-12 11:12:18 +08:00
break ;
case ' s ' :
m_start_idx = Args : : StringToUInt32 ( option_arg , 0 , 0 , & success ) ;
if ( ! success )
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " invalid value for start index: %s " , option_arg ) ;
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 ( )
{
m_start_idx = 0 ;
m_end_idx = UINT_MAX ;
}
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.
uint32_t m_start_idx ;
uint32_t m_end_idx ;
} ;
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2011-07-12 11:12:18 +08:00
{
m_interpreter . DumpHistory ( result . GetOutputStream ( ) ,
m_options . m_start_idx ,
m_options . m_end_idx ) ;
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 [ ] =
{
{ LLDB_OPT_SET_1 , false , " count " , ' c ' , required_argument , NULL , 0 , eArgTypeUnsignedInteger , " How many history commands to print. " } ,
{ LLDB_OPT_SET_1 , false , " start-index " , ' s ' , required_argument , NULL , 0 , eArgTypeUnsignedInteger , " Index at which to start printing history commands. " } ,
{ LLDB_OPT_SET_1 , false , " end-index " , ' e ' , required_argument , NULL , 0 , eArgTypeUnsignedInteger , " Index at which to stop printing history commands. " } ,
{ 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 " " ;
}
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 )
{
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 ) :
Options ( interpreter )
{
}
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
bool success ;
switch ( short_option )
{
case ' e ' :
m_stop_on_error = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( ! success )
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " invalid value for stop-on-error: %s " , option_arg ) ;
2011-02-18 08:54:25 +08:00
break ;
case ' c ' :
m_stop_on_continue = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( ! success )
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " invalid value for stop-on-continue: %s " , option_arg ) ;
2011-02-18 08:54:25 +08:00
break ;
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
{
m_stop_on_error = true ;
m_stop_on_continue = true ;
}
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.
bool m_stop_on_error ;
bool m_stop_on_continue ;
} ;
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
{
2012-06-09 05:56:10 +08:00
const int 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
result . AppendMessageWithFormat ( " Executing commands in '%s'. \n " , filename ) ;
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.
bool echo_commands = true ;
bool print_results = true ;
m_interpreter . HandleCommandsFromFile ( cmd_file ,
exe_ctx ,
m_options . m_stop_on_continue ,
m_options . m_stop_on_error ,
echo_commands ,
2012-05-31 09:09:06 +08:00
print_results ,
eLazyBoolCalculate ,
2011-02-18 08:54:25 +08:00
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 [ ] =
{
{ LLDB_OPT_SET_ALL , false , " stop-on-error " , ' e ' , required_argument , NULL , 0 , eArgTypeBoolean , " If true, stop executing commands on error. " } ,
{ LLDB_OPT_SET_ALL , false , " stop-on-continue " , ' c ' , required_argument , NULL , 0 , eArgTypeBoolean , " If true, stop executing commands on continue. " } ,
{ 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 "
2012-08-08 10:06:30 +08:00
" def my_command_impl(debugger, args, result, internal_dict): " ;
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
2012-06-09 05:56:10 +08:00
class CommandObjectCommandsAddRegex : public CommandObjectParsed
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>/ ...] " ) ,
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 :
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
{
2011-04-21 06:55:21 +08:00
InputReaderSP reader_sp ( new InputReader ( m_interpreter . GetDebugger ( ) ) ) ;
if ( reader_sp )
{
error = reader_sp - > Initialize ( CommandObjectCommandsAddRegex : : InputReaderCallback ,
2011-04-21 00:37:46 +08:00
this , // baton
eInputReaderGranularityLine , // token size, to pass to callback function
2011-04-21 06:55:21 +08:00
NULL , // end token
2011-04-21 00:37:46 +08:00
" > " , // prompt
2011-04-21 06:55:21 +08:00
true ) ; // echo input
if ( error . Success ( ) )
{
m_interpreter . GetDebugger ( ) . PushInputReader ( reader_sp ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
return true ;
}
}
}
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 ) ) ;
2011-04-21 06:55:21 +08:00
error = AppendRegexSubstitution ( arg_strref ) ;
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
AppendRegexSubstitution ( const llvm : : StringRef & regex_sed )
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 ;
}
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 ;
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 ) ;
}
}
}
2011-04-21 06:55:21 +08:00
void
InputReaderDidCancel ( )
{
m_regex_cmd_ap . reset ( ) ;
}
2011-04-21 00:37:46 +08:00
static size_t
InputReaderCallback ( void * baton ,
InputReader & reader ,
lldb : : InputReaderAction notification ,
const char * bytes ,
2012-06-09 05:56:10 +08:00
size_t bytes_len )
{
CommandObjectCommandsAddRegex * add_regex_cmd = ( CommandObjectCommandsAddRegex * ) baton ;
bool batch_mode = reader . GetDebugger ( ) . GetCommandInterpreter ( ) . GetBatchCommandMode ( ) ;
switch ( notification )
{
case eInputReaderActivate :
if ( ! batch_mode )
{
StreamSP out_stream = reader . GetDebugger ( ) . GetAsyncOutputStream ( ) ;
out_stream - > Printf ( " %s \n " , " Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line: " ) ;
out_stream - > Flush ( ) ;
}
break ;
case eInputReaderReactivate :
break ;
case eInputReaderDeactivate :
break ;
case eInputReaderAsynchronousOutputWritten :
break ;
case eInputReaderGotToken :
while ( bytes_len > 0 & & ( bytes [ bytes_len - 1 ] = = ' \r ' | | bytes [ bytes_len - 1 ] = = ' \n ' ) )
- - bytes_len ;
if ( bytes_len = = 0 )
reader . SetIsDone ( true ) ;
else if ( bytes )
{
llvm : : StringRef bytes_strref ( bytes , bytes_len ) ;
Error error ( add_regex_cmd - > AppendRegexSubstitution ( bytes_strref ) ) ;
if ( error . Fail ( ) )
{
if ( ! batch_mode )
{
StreamSP out_stream = reader . GetDebugger ( ) . GetAsyncOutputStream ( ) ;
out_stream - > Printf ( " error: %s \n " , error . AsCString ( ) ) ;
out_stream - > Flush ( ) ;
}
add_regex_cmd - > InputReaderDidCancel ( ) ;
reader . SetIsDone ( true ) ;
}
}
break ;
case eInputReaderInterrupt :
{
reader . SetIsDone ( true ) ;
if ( ! batch_mode )
{
StreamSP out_stream = reader . GetDebugger ( ) . GetAsyncOutputStream ( ) ;
out_stream - > PutCString ( " Regular expression command creations was cancelled. \n " ) ;
out_stream - > Flush ( ) ;
}
add_regex_cmd - > InputReaderDidCancel ( ) ;
}
break ;
case eInputReaderEndOfFile :
reader . SetIsDone ( true ) ;
break ;
case eInputReaderDone :
add_regex_cmd - > AddRegexCommandToInterpreter ( ) ;
break ;
}
return bytes_len ;
}
2011-04-21 00:37:46 +08:00
private :
std : : auto_ptr < CommandObjectRegexCommand > m_regex_cmd_ap ;
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 [ ] =
{
2011-04-21 06:55:21 +08:00
{ LLDB_OPT_SET_1 , false , " help " , ' h ' , required_argument , NULL , 0 , eArgTypeNone , " The help text to display for this command. " } ,
2011-04-21 00:37:46 +08:00
{ LLDB_OPT_SET_1 , false , " syntax " , ' s ' , required_argument , 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 )
{
if ( result . GetOutputData ( ) = = NULL | | result . GetOutputData ( ) [ 0 ] = = ' \0 ' )
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
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 )
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 ( )
{
m_allow_reload = false ;
}
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 ;
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 [ ] =
{
{ LLDB_OPT_SET_1 , false , " allow-reload " , ' r ' , no_argument , NULL , 0 , eArgTypeNone , " Allow the script to be loaded even if it was already loaded before (for Python, the __lldb_init_module function will be called again, but the module will not be reloaded from disk). " } ,
{ 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
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
class CommandObjectCommandsScriptAdd : public CommandObjectParsed
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 ) ,
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 ) :
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-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 ' :
m_synchronous = ( 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 ;
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 = " " ;
2011-11-08 06:57:04 +08:00
m_synchronous = 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 ;
2011-11-08 06:57:04 +08:00
ScriptedCommandSynchronicity m_synchronous ;
2011-08-17 07:24:13 +08:00
} ;
2012-06-09 05:56:10 +08:00
private :
2011-08-17 07:24:13 +08:00
class PythonAliasReader : public InputReaderEZ
{
private :
CommandInterpreter & m_interpreter ;
std : : string m_cmd_name ;
2011-11-08 06:57:04 +08:00
ScriptedCommandSynchronicity m_synchronous ;
2011-08-17 07:24:13 +08:00
StringList m_user_input ;
DISALLOW_COPY_AND_ASSIGN ( PythonAliasReader ) ;
public :
PythonAliasReader ( Debugger & debugger ,
CommandInterpreter & interpreter ,
2011-11-08 06:57:04 +08:00
std : : string cmd_name ,
ScriptedCommandSynchronicity synch ) :
2011-08-17 07:24:13 +08:00
InputReaderEZ ( debugger ) ,
m_interpreter ( interpreter ) ,
m_cmd_name ( cmd_name ) ,
2011-11-08 06:57:04 +08:00
m_synchronous ( synch ) ,
2011-08-17 07:24:13 +08:00
m_user_input ( )
{ }
virtual
~ PythonAliasReader ( )
{
}
virtual void ActivateHandler ( HandlerData & data )
{
StreamSP out_stream = data . GetOutStream ( ) ;
bool batch_mode = data . GetBatchMode ( ) ;
if ( ! batch_mode )
{
out_stream - > Printf ( " %s \n " , g_python_command_instructions ) ;
if ( data . reader . GetPrompt ( ) )
out_stream - > Printf ( " %s " , data . reader . GetPrompt ( ) ) ;
out_stream - > Flush ( ) ;
}
}
virtual void ReactivateHandler ( HandlerData & data )
{
StreamSP out_stream = data . GetOutStream ( ) ;
bool batch_mode = data . GetBatchMode ( ) ;
if ( data . reader . GetPrompt ( ) & & ! batch_mode )
{
out_stream - > Printf ( " %s " , data . reader . GetPrompt ( ) ) ;
out_stream - > Flush ( ) ;
}
}
virtual void GotTokenHandler ( HandlerData & data )
{
StreamSP out_stream = data . GetOutStream ( ) ;
bool batch_mode = data . GetBatchMode ( ) ;
if ( data . bytes & & data . bytes_len )
{
m_user_input . AppendString ( data . bytes , data . bytes_len ) ;
}
if ( ! data . reader . IsDone ( ) & & data . reader . GetPrompt ( ) & & ! batch_mode )
{
out_stream - > Printf ( " %s " , data . reader . GetPrompt ( ) ) ;
out_stream - > Flush ( ) ;
}
}
virtual void InterruptHandler ( HandlerData & data )
{
StreamSP out_stream = data . GetOutStream ( ) ;
bool batch_mode = data . GetBatchMode ( ) ;
data . reader . SetIsDone ( true ) ;
if ( ! batch_mode )
{
2011-11-08 06:57:04 +08:00
out_stream - > Printf ( " Warning: No script attached. \n " ) ;
2011-08-17 07:24:13 +08:00
out_stream - > Flush ( ) ;
}
}
virtual void EOFHandler ( HandlerData & data )
{
data . reader . SetIsDone ( true ) ;
}
virtual void DoneHandler ( HandlerData & data )
{
StreamSP out_stream = data . GetOutStream ( ) ;
ScriptInterpreter * interpreter = data . reader . GetDebugger ( ) . GetCommandInterpreter ( ) . GetScriptInterpreter ( ) ;
if ( ! interpreter )
{
2011-11-08 06:57:04 +08:00
out_stream - > Printf ( " Script interpreter missing: no script attached. \n " ) ;
2011-08-17 07:24:13 +08:00
out_stream - > Flush ( ) ;
return ;
}
2012-03-07 07:42:15 +08:00
std : : string funct_name_str ;
2011-08-17 07:24:13 +08:00
if ( ! interpreter - > GenerateScriptAliasFunction ( m_user_input ,
2012-03-07 07:42:15 +08:00
funct_name_str ) )
2011-08-17 07:24:13 +08:00
{
2011-11-08 06:57:04 +08:00
out_stream - > Printf ( " Unable to create function: no script attached. \n " ) ;
2011-08-17 07:24:13 +08:00
out_stream - > Flush ( ) ;
return ;
}
2012-03-07 07:42:15 +08:00
if ( funct_name_str . empty ( ) )
2011-08-17 07:24:13 +08:00
{
2011-11-08 06:57:04 +08:00
out_stream - > Printf ( " Unable to obtain a function name: no script attached. \n " ) ;
2011-08-17 07:24:13 +08:00
out_stream - > Flush ( ) ;
return ;
}
// everything should be fine now, let's add this alias
CommandObjectSP command_obj_sp ( new CommandObjectPythonFunction ( m_interpreter ,
m_cmd_name ,
2012-03-07 07:42:15 +08:00
funct_name_str . c_str ( ) ,
2011-11-08 06:57:04 +08:00
m_synchronous ) ) ;
2011-08-17 07:24:13 +08:00
2011-11-08 06:57:04 +08:00
if ( ! m_interpreter . AddUserCommand ( m_cmd_name , command_obj_sp , true ) )
2011-08-17 07:24:13 +08:00
{
2011-11-08 06:57:04 +08:00
out_stream - > Printf ( " Unable to add selected command: no script attached. \n " ) ;
2011-08-17 07:24:13 +08:00
out_stream - > Flush ( ) ;
return ;
}
}
} ;
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 ;
}
2012-06-09 05:56:10 +08:00
std : : string cmd_name = command . GetArgumentAtIndex ( 0 ) ;
2011-08-17 07:24:13 +08:00
if ( m_options . m_funct_name . empty ( ) )
{
InputReaderSP reader_sp ( new PythonAliasReader ( m_interpreter . GetDebugger ( ) ,
m_interpreter ,
2011-11-08 06:57:04 +08:00
cmd_name ,
m_options . m_synchronous ) ) ;
2011-08-17 07:24:13 +08:00
if ( reader_sp )
{
InputReaderEZ : : InitializationParameters ipr ;
Error err ( reader_sp - > Initialize ( ipr . SetBaton ( NULL ) . SetPrompt ( " " ) ) ) ;
if ( err . Success ( ) )
{
m_interpreter . GetDebugger ( ) . PushInputReader ( reader_sp ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendError ( err . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
else
{
result . AppendError ( " out of memory " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
else
{
2011-11-08 06:57:04 +08:00
CommandObjectSP new_cmd ( new CommandObjectPythonFunction ( m_interpreter ,
cmd_name ,
m_options . m_funct_name ,
m_options . m_synchronous ) ) ;
if ( m_interpreter . AddUserCommand ( 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 ;
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 [ ] =
{
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{ LLDB_OPT_SET_1 , false , " function " , ' f ' , required_argument , NULL , 0 , eArgTypePythonFunction , " Name of the Python function to bind to this command name. " } ,
2011-11-08 06:57:04 +08:00
{ LLDB_OPT_SET_1 , false , " synchronicity " , ' s ' , required_argument , 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 ( )
{
}