2010-06-08 16:52:24 +00:00
//===-- CommandObjectExpression.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 00:20:57 +00:00
# include "lldb/lldb-python.h"
2010-06-08 16:52:24 +00:00
# include "CommandObjectExpression.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
2010-07-23 00:16:21 +00:00
# include "lldb/Interpreter/Args.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Core/Value.h"
# include "lldb/Core/InputReader.h"
2010-09-30 00:54:27 +00:00
# include "lldb/Core/ValueObjectVariable.h"
2013-09-30 19:11:51 +00:00
# include "lldb/DataFormatters/ValueObjectPrinter.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Expression/ClangExpressionVariable.h"
2010-08-27 01:01:44 +00:00
# include "lldb/Expression/ClangUserExpression.h"
2010-07-23 21:47:22 +00:00
# include "lldb/Expression/ClangFunction.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Expression/DWARFExpression.h"
# include "lldb/Host/Host.h"
2010-07-23 00:16:21 +00:00
# include "lldb/Core/Debugger.h"
2010-06-23 01:19:29 +00:00
# include "lldb/Interpreter/CommandInterpreter.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Interpreter/CommandReturnObject.h"
2010-09-30 00:54:27 +00:00
# include "lldb/Target/ObjCLanguageRuntime.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Symbol/ObjectFile.h"
# include "lldb/Symbol/Variable.h"
# include "lldb/Target/Process.h"
2013-11-04 09:33:30 +00:00
# include "lldb/Target/StackFrame.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Target/Target.h"
2011-04-18 08:33:37 +00:00
# include "lldb/Target/Thread.h"
2010-07-23 00:16:21 +00:00
# include "llvm/ADT/StringRef.h"
2010-06-08 16:52:24 +00:00
using namespace lldb ;
using namespace lldb_private ;
2011-10-25 06:44:01 +00:00
CommandObjectExpression : : CommandOptions : : CommandOptions ( ) :
OptionGroup ( )
2010-06-08 16:52:24 +00:00
{
}
CommandObjectExpression : : CommandOptions : : ~ CommandOptions ( )
{
}
2013-09-30 19:11:51 +00:00
static OptionEnumValueElement g_description_verbosity_type [ ] =
{
{ eLanguageRuntimeDescriptionDisplayVerbosityCompact , " compact " , " Only show the description string " } ,
{ eLanguageRuntimeDescriptionDisplayVerbosityFull , " full " , " Show the full output, including persistent variable's name and type " } ,
{ 0 , NULL , NULL }
} ;
2011-10-25 06:44:01 +00:00
OptionDefinition
CommandObjectExpression : : CommandOptions : : g_option_table [ ] =
{
2013-09-05 16:42:23 +00:00
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2 , false , " all-threads " , ' a ' , OptionParser : : eRequiredArgument , NULL , 0 , eArgTypeBoolean , " Should we run all threads if the execution doesn't complete on one thread. " } ,
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2 , false , " ignore-breakpoints " , ' i ' , OptionParser : : eRequiredArgument , NULL , 0 , eArgTypeBoolean , " Ignore breakpoint hits while running expressions " } ,
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2 , false , " timeout " , ' t ' , OptionParser : : eRequiredArgument , NULL , 0 , eArgTypeUnsignedInteger , " Timeout value (in microseconds) for running the expression. " } ,
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2 , false , " unwind-on-error " , ' u ' , OptionParser : : eRequiredArgument , NULL , 0 , eArgTypeBoolean , " Clean up program state if the expression causes a crash, or raises a signal. Note, unlike gdb hitting a breakpoint is controlled by another option (-i). " } ,
2013-11-04 19:35:17 +00:00
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2 , false , " debug " , ' g ' , OptionParser : : eNoArgument , NULL , 0 , eArgTypeNone , " When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0). " } ,
2013-09-30 19:11:51 +00:00
{ LLDB_OPT_SET_1 , false , " description-verbosity " , ' v ' , OptionParser : : eOptionalArgument , g_description_verbosity_type , 0 , eArgTypeDescriptionVerbosity , " How verbose should the output of this expression be, if the object description is asked for. " } ,
2011-10-25 06:44:01 +00:00
} ;
uint32_t
CommandObjectExpression : : CommandOptions : : GetNumDefinitions ( )
{
return sizeof ( g_option_table ) / sizeof ( OptionDefinition ) ;
}
2010-06-08 16:52:24 +00:00
Error
2011-10-25 06:44:01 +00:00
CommandObjectExpression : : CommandOptions : : SetOptionValue ( CommandInterpreter & interpreter ,
uint32_t option_idx ,
const char * option_arg )
2010-06-08 16:52:24 +00:00
{
Error error ;
2012-12-04 00:32:51 +00:00
const int short_option = g_option_table [ option_idx ] . short_option ;
2010-06-08 16:52:24 +00:00
switch ( short_option )
{
2010-09-07 22:38:08 +00:00
//case 'l':
//if (language.SetLanguageFromCString (option_arg) == false)
//{
2011-10-26 00:56:27 +00:00
// error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
2010-09-07 22:38:08 +00:00
//}
//break;
2010-06-08 16:52:24 +00:00
2012-10-16 21:41:58 +00:00
case ' a ' :
{
bool success ;
bool result ;
result = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( ! success )
error . SetErrorStringWithFormat ( " invalid all-threads value setting: \" %s \" " , option_arg ) ;
else
try_all_threads = result ;
}
2010-09-30 00:54:27 +00:00
break ;
2010-11-05 19:25:48 +00:00
2013-01-15 02:47:48 +00:00
case ' i ' :
{
bool success ;
bool tmp_value = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( success )
ignore_breakpoints = tmp_value ;
else
error . SetErrorStringWithFormat ( " could not convert \" %s \" to a boolean value. " , option_arg ) ;
break ;
}
2012-10-16 21:41:58 +00:00
case ' t ' :
{
bool success ;
uint32_t result ;
result = Args : : StringToUInt32 ( option_arg , 0 , 0 , & success ) ;
if ( success )
timeout = result ;
else
error . SetErrorStringWithFormat ( " invalid timeout setting \" %s \" " , option_arg ) ;
}
break ;
2010-11-05 19:25:48 +00:00
case ' u ' :
2011-09-15 02:13:07 +00:00
{
bool success ;
2013-01-15 02:47:48 +00:00
bool tmp_value = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( success )
unwind_on_error = tmp_value ;
else
2011-10-26 00:56:27 +00:00
error . SetErrorStringWithFormat ( " could not convert \" %s \" to a boolean value. " , option_arg ) ;
2011-09-15 02:13:07 +00:00
break ;
}
2013-09-30 19:11:51 +00:00
case ' v ' :
if ( ! option_arg )
{
m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull ;
break ;
}
m_verbosity = ( LanguageRuntimeDescriptionDisplayVerbosity ) Args : : StringToOptionEnum ( option_arg , g_option_table [ option_idx ] . enum_values , 0 , error ) ;
if ( ! error . Success ( ) )
error . SetErrorStringWithFormat ( " unrecognized value for description-verbosity '%s' " , option_arg ) ;
break ;
2013-11-04 19:35:17 +00:00
case ' g ' :
debug = true ;
unwind_on_error = false ;
ignore_breakpoints = false ;
break ;
2010-06-08 16:52:24 +00:00
default :
2011-10-26 00:56:27 +00:00
error . SetErrorStringWithFormat ( " invalid short option character '%c' " , short_option ) ;
2010-06-08 16:52:24 +00:00
break ;
}
return error ;
}
void
2011-10-25 06:44:01 +00:00
CommandObjectExpression : : CommandOptions : : OptionParsingStarting ( CommandInterpreter & interpreter )
2010-06-08 16:52:24 +00:00
{
2013-01-15 02:47:48 +00:00
Process * process = interpreter . GetExecutionContext ( ) . GetProcessPtr ( ) ;
if ( process ! = NULL )
{
ignore_breakpoints = process - > GetIgnoreBreakpointsInExpressions ( ) ;
unwind_on_error = process - > GetUnwindOnErrorInExpressions ( ) ;
}
else
{
ignore_breakpoints = false ;
unwind_on_error = true ;
}
2010-06-08 16:52:24 +00:00
show_summary = true ;
2012-10-16 21:41:58 +00:00
try_all_threads = true ;
timeout = 0 ;
2013-11-04 19:35:17 +00:00
debug = false ;
2013-09-30 19:11:51 +00:00
m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact ;
2010-06-08 16:52:24 +00:00
}
2011-03-24 21:19:54 +00:00
const OptionDefinition *
2010-06-08 16:52:24 +00:00
CommandObjectExpression : : CommandOptions : : GetDefinitions ( )
{
return g_option_table ;
}
2010-09-18 01:14:36 +00:00
CommandObjectExpression : : CommandObjectExpression ( CommandInterpreter & interpreter ) :
2012-06-08 21:56:10 +00:00
CommandObjectRaw ( interpreter ,
" expression " ,
2012-10-25 18:11:24 +00:00
" Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope. " ,
2012-06-08 21:56:10 +00:00
NULL ,
2013-01-09 19:44:40 +00:00
eFlagProcessMustBePaused | eFlagTryTargetAPILock ) ,
2011-10-25 06:44:01 +00:00
m_option_group ( interpreter ) ,
m_format_options ( eFormatDefault ) ,
m_command_options ( ) ,
2010-09-30 18:30:25 +00:00
m_expr_line_count ( 0 ) ,
2010-06-08 16:52:24 +00:00
m_expr_lines ( )
{
SetHelpLong (
2012-10-16 21:41:58 +00:00
" Timeouts: \n \
If the expression can be evaluated statically (without runnning code) then it will be. \n \
Otherwise, by default the expression will run on the current thread with a short timeout: \n \
currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted \n \
and resumed with all threads running. You can use the -a option to disable retrying on all \n \
threads. You can use the -t option to set a shorter timeout. \n \
2012-10-25 18:11:24 +00:00
\n \
User defined variables: \n \
You can define your own variables for convenience or to be used in subsequent expressions. \n \
You define them the same way you would define variables in C. If the first character of \n \
your user defined variable is a $, then the variable's value will be available in future \n \
expressions, otherwise it will just be available in the current expression. \n \
\n \
2012-10-16 21:41:58 +00:00
Examples: \n \
2010-06-08 16:52:24 +00:00
\n \
expr my_struct->a = my_array[3] \n \
expr -f bin -- (index * 8) + 5 \n \
2012-10-25 18:11:24 +00:00
expr unsigned int $foo = 5 \n \
2010-06-08 16:52:24 +00:00
expr char c[] = \" foo \" ; c[0] \n " ) ;
2010-10-04 22:28:36 +00:00
CommandArgumentEntry arg ;
CommandArgumentData expression_arg ;
// Define the first (and only) variant of this arg.
expression_arg . arg_type = eArgTypeExpression ;
expression_arg . arg_repetition = eArgRepeatPlain ;
// There is only one variant this argument could be; put it into the argument entry.
arg . push_back ( expression_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
2011-10-25 06:44:01 +00:00
2011-10-27 17:55:14 +00:00
// Add the "--format" and "--gdb-format"
m_option_group . Append ( & m_format_options , OptionGroupFormat : : OPTION_GROUP_FORMAT | OptionGroupFormat : : OPTION_GROUP_GDB_FMT , LLDB_OPT_SET_1 ) ;
2011-10-25 06:44:01 +00:00
m_option_group . Append ( & m_command_options ) ;
2013-01-09 20:12:53 +00:00
m_option_group . Append ( & m_varobj_options , LLDB_OPT_SET_ALL , LLDB_OPT_SET_1 | LLDB_OPT_SET_2 ) ;
2011-10-25 06:44:01 +00:00
m_option_group . Finalize ( ) ;
2010-06-08 16:52:24 +00:00
}
CommandObjectExpression : : ~ CommandObjectExpression ( )
{
}
Options *
CommandObjectExpression : : GetOptions ( )
{
2011-10-25 06:44:01 +00:00
return & m_option_group ;
2010-06-08 16:52:24 +00:00
}
size_t
CommandObjectExpression : : MultiLineExpressionCallback
(
void * baton ,
2010-06-23 01:19:29 +00:00
InputReader & reader ,
2010-06-08 16:52:24 +00:00
lldb : : InputReaderAction notification ,
const char * bytes ,
size_t bytes_len
)
{
CommandObjectExpression * cmd_object_expr = ( CommandObjectExpression * ) baton ;
2011-06-16 16:27:19 +00:00
bool batch_mode = reader . GetDebugger ( ) . GetCommandInterpreter ( ) . GetBatchCommandMode ( ) ;
2010-06-08 16:52:24 +00:00
switch ( notification )
{
case eInputReaderActivate :
2011-06-16 16:27:19 +00:00
if ( ! batch_mode )
2011-06-15 19:35:17 +00:00
{
2011-07-20 03:41:06 +00:00
StreamSP async_strm_sp ( reader . GetDebugger ( ) . GetAsyncOutputStream ( ) ) ;
if ( async_strm_sp )
{
async_strm_sp - > PutCString ( " Enter expressions, then terminate with an empty line to evaluate: \n " ) ;
async_strm_sp - > Flush ( ) ;
}
2011-06-15 19:35:17 +00:00
}
2010-06-08 16:52:24 +00:00
// Fall through
case eInputReaderReactivate :
break ;
case eInputReaderDeactivate :
break ;
2011-05-02 20:41:46 +00:00
case eInputReaderAsynchronousOutputWritten :
break ;
2010-06-08 16:52:24 +00:00
case eInputReaderGotToken :
+ + cmd_object_expr - > m_expr_line_count ;
if ( bytes & & bytes_len )
{
cmd_object_expr - > m_expr_lines . append ( bytes , bytes_len + 1 ) ;
}
if ( bytes_len = = 0 )
2010-06-23 01:19:29 +00:00
reader . SetIsDone ( true ) ;
2010-06-08 16:52:24 +00:00
break ;
2010-11-19 20:47:54 +00:00
case eInputReaderInterrupt :
cmd_object_expr - > m_expr_lines . clear ( ) ;
reader . SetIsDone ( true ) ;
2011-06-16 16:27:19 +00:00
if ( ! batch_mode )
2011-06-15 19:35:17 +00:00
{
2011-07-20 03:41:06 +00:00
StreamSP async_strm_sp ( reader . GetDebugger ( ) . GetAsyncOutputStream ( ) ) ;
if ( async_strm_sp )
{
async_strm_sp - > PutCString ( " Expression evaluation cancelled. \n " ) ;
async_strm_sp - > Flush ( ) ;
}
2011-06-15 19:35:17 +00:00
}
2010-11-19 20:47:54 +00:00
break ;
case eInputReaderEndOfFile :
reader . SetIsDone ( true ) ;
break ;
2010-06-08 16:52:24 +00:00
case eInputReaderDone :
2010-11-19 20:47:54 +00:00
if ( cmd_object_expr - > m_expr_lines . size ( ) > 0 )
2010-06-08 16:52:24 +00:00
{
2011-06-13 20:20:29 +00:00
StreamSP output_stream = reader . GetDebugger ( ) . GetAsyncOutputStream ( ) ;
StreamSP error_stream = reader . GetDebugger ( ) . GetAsyncErrorStream ( ) ;
2010-06-08 16:52:24 +00:00
cmd_object_expr - > EvaluateExpression ( cmd_object_expr - > m_expr_lines . c_str ( ) ,
2011-06-13 20:20:29 +00:00
output_stream . get ( ) ,
error_stream . get ( ) ) ;
output_stream - > Flush ( ) ;
error_stream - > Flush ( ) ;
2010-06-08 16:52:24 +00:00
}
break ;
}
return bytes_len ;
}
bool
2010-10-05 00:00:42 +00:00
CommandObjectExpression : : EvaluateExpression
(
const char * expr ,
2011-06-13 20:20:29 +00:00
Stream * output_stream ,
Stream * error_stream ,
2010-10-05 00:00:42 +00:00
CommandReturnObject * result
)
2010-06-08 16:52:24 +00:00
{
2013-01-26 23:54:29 +00:00
// Don't use m_exe_ctx as this might be called asynchronously
// after the command object DoExecute has finished when doing
// multi-line expression that use an input reader...
ExecutionContext exe_ctx ( m_interpreter . GetExecutionContext ( ) ) ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
2011-10-27 21:22:25 +00:00
if ( ! target )
target = Host : : GetDummyTarget ( m_interpreter . GetDebugger ( ) ) . get ( ) ;
2011-09-22 04:58:26 +00:00
if ( target )
2010-06-08 16:52:24 +00:00
{
2010-12-14 02:59:59 +00:00
lldb : : ValueObjectSP result_valobj_sp ;
2010-10-06 03:09:11 +00:00
2011-03-24 21:19:54 +00:00
ExecutionResults exe_results ;
2011-01-13 08:53:35 +00:00
bool keep_in_memory = true ;
2013-01-09 20:12:53 +00:00
2012-10-16 21:41:58 +00:00
EvaluateExpressionOptions options ;
2013-11-07 00:11:47 +00:00
options . SetCoerceToId ( m_varobj_options . use_objc ) ;
options . SetUnwindOnError ( m_command_options . unwind_on_error ) ;
options . SetIgnoreBreakpoints ( m_command_options . ignore_breakpoints ) ;
options . SetKeepInMemory ( keep_in_memory ) ;
options . SetUseDynamic ( m_varobj_options . use_dynamic ) ;
options . SetTryAllThreads ( m_command_options . try_all_threads ) ;
options . SetDebug ( m_command_options . debug ) ;
2013-11-04 19:35:17 +00:00
if ( m_command_options . timeout > 0 )
options . SetTimeoutUsec ( m_command_options . timeout ) ;
2012-09-05 20:41:26 +00:00
2011-09-22 04:58:26 +00:00
exe_results = target - > EvaluateExpression ( expr ,
2013-01-26 23:54:29 +00:00
exe_ctx . GetFramePtr ( ) ,
2012-07-16 23:10:35 +00:00
result_valobj_sp ,
2012-09-05 20:41:26 +00:00
options ) ;
2013-07-30 19:54:09 +00:00
2010-12-14 02:59:59 +00:00
if ( result_valobj_sp )
{
2012-08-08 17:35:10 +00:00
Format format = m_format_options . GetFormat ( ) ;
2010-12-14 02:59:59 +00:00
if ( result_valobj_sp - > GetError ( ) . Success ( ) )
{
2012-08-08 17:35:10 +00:00
if ( format ! = eFormatVoid )
{
if ( format ! = eFormatDefault )
result_valobj_sp - > SetFormat ( format ) ;
2010-12-14 02:59:59 +00:00
2013-09-30 19:11:51 +00:00
DumpValueObjectOptions options ( m_varobj_options . GetAsDumpOptions ( m_command_options . m_verbosity , format ) ) ;
2013-01-09 20:12:53 +00:00
2013-09-30 19:11:51 +00:00
result_valobj_sp - > Dump ( * output_stream , options ) ;
2012-08-08 17:35:10 +00:00
if ( result )
result - > SetStatus ( eReturnStatusSuccessFinishResult ) ;
}
2010-12-14 02:59:59 +00:00
}
else
{
2011-08-23 21:20:51 +00:00
if ( result_valobj_sp - > GetError ( ) . GetError ( ) = = ClangUserExpression : : kNoResult )
2011-06-24 22:31:10 +00:00
{
2012-08-09 18:18:47 +00:00
if ( format ! = eFormatVoid & & m_interpreter . GetDebugger ( ) . GetNotifyVoid ( ) )
2012-08-08 17:35:10 +00:00
{
2012-08-09 18:18:47 +00:00
error_stream - > PutCString ( " (void) \n " ) ;
2012-08-08 17:35:10 +00:00
}
2012-08-09 18:18:47 +00:00
if ( result )
result - > SetStatus ( eReturnStatusSuccessFinishResult ) ;
2011-06-24 22:31:10 +00:00
}
else
{
2011-08-23 21:20:51 +00:00
const char * error_cstr = result_valobj_sp - > GetError ( ) . AsCString ( ) ;
if ( error_cstr & & error_cstr [ 0 ] )
{
2013-01-25 18:06:21 +00:00
const size_t error_cstr_len = strlen ( error_cstr ) ;
2011-08-23 21:20:51 +00:00
const bool ends_with_newline = error_cstr [ error_cstr_len - 1 ] = = ' \n ' ;
if ( strstr ( error_cstr , " error: " ) ! = error_cstr )
error_stream - > PutCString ( " error: " ) ;
error_stream - > Write ( error_cstr , error_cstr_len ) ;
if ( ! ends_with_newline )
error_stream - > EOL ( ) ;
}
else
{
error_stream - > PutCString ( " error: unknown error \n " ) ;
}
if ( result )
result - > SetStatus ( eReturnStatusFailed ) ;
2011-06-24 22:31:10 +00:00
}
2010-11-30 02:22:11 +00:00
}
}
2010-12-14 02:59:59 +00:00
}
else
{
2011-06-13 20:20:29 +00:00
error_stream - > Printf ( " error: invalid execution context for expression \n " ) ;
2010-12-14 02:59:59 +00:00
return false ;
2010-07-23 00:16:21 +00:00
}
2010-08-12 01:56:52 +00:00
2010-07-23 00:16:21 +00:00
return true ;
2010-06-08 16:52:24 +00:00
}
bool
2012-06-08 21:56:10 +00:00
CommandObjectExpression : : DoExecute
2010-06-08 16:52:24 +00:00
(
const char * command ,
CommandReturnObject & result
)
{
2011-10-25 06:44:01 +00:00
m_option_group . NotifyOptionParsingStarting ( ) ;
2010-06-08 16:52:24 +00:00
const char * expr = NULL ;
if ( command [ 0 ] = = ' \0 ' )
{
m_expr_lines . clear ( ) ;
m_expr_line_count = 0 ;
2010-09-18 01:14:36 +00:00
InputReaderSP reader_sp ( new InputReader ( m_interpreter . GetDebugger ( ) ) ) ;
2010-06-08 16:52:24 +00:00
if ( reader_sp )
{
Error err ( reader_sp - > Initialize ( CommandObjectExpression : : MultiLineExpressionCallback ,
this , // baton
eInputReaderGranularityLine , // token size, to pass to callback function
2010-06-23 01:19:29 +00:00
NULL , // end token
2010-06-08 16:52:24 +00:00
NULL , // prompt
true ) ) ; // echo input
if ( err . Success ( ) )
{
2010-09-18 01:14:36 +00:00
m_interpreter . GetDebugger ( ) . PushInputReader ( reader_sp ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendError ( err . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
else
{
result . AppendError ( " out of memory " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
return result . Succeeded ( ) ;
}
if ( command [ 0 ] = = ' - ' )
{
// We have some options and these options MUST end with --.
const char * end_options = NULL ;
const char * s = command ;
while ( s & & s [ 0 ] )
{
end_options = : : strstr ( s , " -- " ) ;
if ( end_options )
{
end_options + = 2 ; // Get past the "--"
if ( : : isspace ( end_options [ 0 ] ) )
{
expr = end_options ;
while ( : : isspace ( * expr ) )
+ + expr ;
break ;
}
}
s = end_options ;
}
if ( end_options )
{
2010-06-23 01:19:29 +00:00
Args args ( command , end_options - command ) ;
2010-09-18 01:14:36 +00:00
if ( ! ParseOptions ( args , result ) )
2010-06-08 16:52:24 +00:00
return false ;
2011-04-13 00:18:08 +00:00
2011-10-25 06:44:01 +00:00
Error error ( m_option_group . NotifyOptionParsingFinished ( ) ) ;
2011-04-13 00:18:08 +00:00
if ( error . Fail ( ) )
{
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2010-06-08 16:52:24 +00:00
}
}
if ( expr = = NULL )
expr = command ;
2010-06-24 00:16:27 +00:00
2011-06-13 20:20:29 +00:00
if ( EvaluateExpression ( expr , & ( result . GetOutputStream ( ) ) , & ( result . GetErrorStream ( ) ) , & result ) )
2010-08-13 00:42:30 +00:00
return true ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2010-06-08 16:52:24 +00:00
}