2013-08-23 13:46:38 -04:00
//===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
# include "CommandObjectType.h"
// C Includes
# include <ctype.h>
// C++ Includes
2015-02-06 16:38:51 -05:00
# include <functional>
2013-08-23 13:46:38 -04:00
2014-11-25 16:00:58 -05:00
# include "llvm/ADT/StringRef.h"
2013-08-23 13:46:38 -04:00
# include "lldb/Core/ConstString.h"
# include "lldb/Core/Debugger.h"
2014-02-18 11:23:10 -05:00
# include "lldb/Core/IOHandler.h"
2013-08-23 13:46:38 -04:00
# include "lldb/Core/RegularExpression.h"
# include "lldb/Core/State.h"
# include "lldb/Core/StringList.h"
# include "lldb/DataFormatters/DataVisualization.h"
# include "lldb/Interpreter/CommandInterpreter.h"
# include "lldb/Interpreter/CommandObject.h"
# include "lldb/Interpreter/CommandReturnObject.h"
# include "lldb/Interpreter/Options.h"
# include "lldb/Interpreter/OptionGroupFormat.h"
2015-12-30 06:55:28 -05:00
# include "lldb/Interpreter/OptionValueBoolean.h"
# include "lldb/Interpreter/OptionValueLanguage.h"
# include "lldb/Interpreter/OptionValueString.h"
# include "lldb/Target/Language.h"
2015-02-06 16:38:51 -05:00
# include "lldb/Target/Process.h"
# include "lldb/Target/StackFrame.h"
# include "lldb/Target/Target.h"
# include "lldb/Target/Thread.h"
# include "lldb/Target/ThreadList.h"
2013-08-23 13:46:38 -04:00
using namespace lldb ;
using namespace lldb_private ;
class ScriptAddOptions
{
public :
TypeSummaryImpl : : Flags m_flags ;
StringList m_target_types ;
bool m_regex ;
ConstString m_name ;
std : : string m_category ;
ScriptAddOptions ( const TypeSummaryImpl : : Flags & flags ,
bool regx ,
const ConstString & name ,
std : : string catg ) :
m_flags ( flags ) ,
m_regex ( regx ) ,
m_name ( name ) ,
m_category ( catg )
{
}
typedef std : : shared_ptr < ScriptAddOptions > SharedPointer ;
} ;
class SynthAddOptions
{
public :
bool m_skip_pointers ;
bool m_skip_references ;
bool m_cascade ;
bool m_regex ;
StringList m_target_types ;
std : : string m_category ;
SynthAddOptions ( bool sptr ,
bool sref ,
bool casc ,
bool regx ,
std : : string catg ) :
m_skip_pointers ( sptr ) ,
m_skip_references ( sref ) ,
m_cascade ( casc ) ,
m_regex ( regx ) ,
m_target_types ( ) ,
m_category ( catg )
{
}
typedef std : : shared_ptr < SynthAddOptions > SharedPointer ;
} ;
2014-02-18 11:23:10 -05:00
static bool
WarnOnPotentialUnquotedUnsignedType ( Args & command , CommandReturnObject & result )
{
2014-11-25 16:00:58 -05:00
for ( unsigned idx = 0 ; idx < command . GetArgumentCount ( ) ; idx + + )
2014-02-18 11:23:10 -05:00
{
const char * arg = command . GetArgumentAtIndex ( idx ) ;
if ( idx + 1 < command . GetArgumentCount ( ) )
{
if ( arg & & 0 = = strcmp ( arg , " unsigned " ) )
{
const char * next = command . GetArgumentAtIndex ( idx + 1 ) ;
if ( next & &
( 0 = = strcmp ( next , " int " ) | |
0 = = strcmp ( next , " short " ) | |
0 = = strcmp ( next , " char " ) | |
0 = = strcmp ( next , " long " ) ) )
{
result . AppendWarningWithFormat ( " %s %s being treated as two types. if you meant the combined type name use quotes, as in \" %s %s \" \n " ,
arg , next , arg , next ) ;
return true ;
}
}
}
}
return false ;
}
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
class CommandObjectTypeSummaryAdd :
public CommandObjectParsed ,
public IOHandlerDelegateMultiline
2013-08-23 13:46:38 -04:00
{
private :
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter )
{
}
2015-12-30 06:55:28 -05:00
~ CommandOptions ( ) override { }
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override ;
2013-08-23 13:46:38 -04:00
void
2015-12-30 06:55:28 -05:00
OptionParsingStarting ( ) override ;
2013-08-23 13:46:38 -04:00
const OptionDefinition *
2015-12-30 06:55:28 -05:00
GetDefinitions ( ) override
2013-08-23 13:46:38 -04:00
{
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.
TypeSummaryImpl : : Flags m_flags ;
bool m_regex ;
std : : string m_format_string ;
ConstString m_name ;
std : : string m_python_script ;
std : : string m_python_function ;
bool m_is_add_script ;
std : : string m_category ;
} ;
CommandOptions m_options ;
2015-12-30 06:55:28 -05:00
Options *
GetOptions ( ) override
2013-08-23 13:46:38 -04:00
{
return & m_options ;
}
bool
Execute_ScriptSummary ( Args & command , CommandReturnObject & result ) ;
bool
Execute_StringSummary ( Args & command , CommandReturnObject & result ) ;
public :
enum SummaryFormatType
{
eRegularSummary ,
eRegexSummary ,
eNamedSummary
} ;
CommandObjectTypeSummaryAdd ( CommandInterpreter & interpreter ) ;
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeSummaryAdd ( ) override
2013-08-23 13:46:38 -04:00
{
}
2015-12-30 06:55:28 -05:00
void
IOHandlerActivated ( IOHandler & io_handler ) override
2014-02-18 11:23:10 -05:00
{
static const char * g_summary_addreader_instructions = " Enter your Python command(s). Type 'DONE' to end. \n "
" def function (valobj,internal_dict): \n "
" \" \" \" valobj: an SBValue which you want to provide a summary for \n "
2014-11-25 16:00:58 -05:00
" internal_dict: an LLDB support object not to be used \" \" \" \n " ;
2014-02-18 11:23:10 -05:00
StreamFileSP output_sp ( io_handler . GetOutputStreamFile ( ) ) ;
if ( output_sp )
{
output_sp - > PutCString ( g_summary_addreader_instructions ) ;
output_sp - > Flush ( ) ;
}
}
2015-12-30 06:55:28 -05:00
void
IOHandlerInputComplete ( IOHandler & io_handler , std : : string & data ) override
2014-02-18 11:23:10 -05:00
{
StreamFileSP error_sp = io_handler . GetErrorStreamFile ( ) ;
# ifndef LLDB_DISABLE_PYTHON
ScriptInterpreter * interpreter = m_interpreter . GetScriptInterpreter ( ) ;
if ( interpreter )
{
StringList lines ;
lines . SplitIntoLines ( data ) ;
if ( lines . GetSize ( ) > 0 )
{
ScriptAddOptions * options_ptr = ( ( ScriptAddOptions * ) io_handler . GetUserData ( ) ) ;
if ( options_ptr )
{
ScriptAddOptions : : SharedPointer options ( options_ptr ) ; // this will ensure that we get rid of the pointer when going out of scope
ScriptInterpreter * interpreter = m_interpreter . GetScriptInterpreter ( ) ;
if ( interpreter )
{
std : : string funct_name_str ;
if ( interpreter - > GenerateTypeScriptFunction ( lines , funct_name_str ) )
{
if ( funct_name_str . empty ( ) )
{
error_sp - > Printf ( " unable to obtain a valid function name from the script interpreter. \n " ) ;
error_sp - > Flush ( ) ;
}
else
{
// now I have a valid function name, let's add this as script for every type in the list
TypeSummaryImplSP script_format ;
script_format . reset ( new ScriptSummaryFormat ( options - > m_flags ,
funct_name_str . c_str ( ) ,
lines . CopyList ( " " ) . c_str ( ) ) ) ;
Error error ;
for ( size_t i = 0 ; i < options - > m_target_types . GetSize ( ) ; i + + )
{
const char * type_name = options - > m_target_types . GetStringAtIndex ( i ) ;
CommandObjectTypeSummaryAdd : : AddSummary ( ConstString ( type_name ) ,
script_format ,
( options - > m_regex ? CommandObjectTypeSummaryAdd : : eRegexSummary : CommandObjectTypeSummaryAdd : : eRegularSummary ) ,
options - > m_category ,
& error ) ;
if ( error . Fail ( ) )
{
error_sp - > Printf ( " error: %s " , error . AsCString ( ) ) ;
error_sp - > Flush ( ) ;
}
}
if ( options - > m_name )
{
CommandObjectTypeSummaryAdd : : AddSummary ( options - > m_name ,
script_format ,
CommandObjectTypeSummaryAdd : : eNamedSummary ,
options - > m_category ,
& error ) ;
if ( error . Fail ( ) )
{
CommandObjectTypeSummaryAdd : : AddSummary ( options - > m_name ,
script_format ,
CommandObjectTypeSummaryAdd : : eNamedSummary ,
options - > m_category ,
& error ) ;
if ( error . Fail ( ) )
{
error_sp - > Printf ( " error: %s " , error . AsCString ( ) ) ;
error_sp - > Flush ( ) ;
}
}
else
{
error_sp - > Printf ( " error: %s " , error . AsCString ( ) ) ;
error_sp - > Flush ( ) ;
}
}
else
{
if ( error . AsCString ( ) )
{
error_sp - > Printf ( " error: %s " , error . AsCString ( ) ) ;
error_sp - > Flush ( ) ;
}
}
}
}
else
{
error_sp - > Printf ( " error: unable to generate a function. \n " ) ;
error_sp - > Flush ( ) ;
}
}
else
{
error_sp - > Printf ( " error: no script interpreter. \n " ) ;
error_sp - > Flush ( ) ;
}
}
else
{
error_sp - > Printf ( " error: internal synchronization information missing or invalid. \n " ) ;
error_sp - > Flush ( ) ;
}
}
else
{
error_sp - > Printf ( " error: empty function, didn't add python command. \n " ) ;
error_sp - > Flush ( ) ;
}
}
else
{
error_sp - > Printf ( " error: script interpreter missing, didn't add python command. \n " ) ;
error_sp - > Flush ( ) ;
}
# endif // #ifndef LLDB_DISABLE_PYTHON
io_handler . SetIsDone ( true ) ;
}
2013-08-23 13:46:38 -04:00
static bool
AddSummary ( ConstString type_name ,
lldb : : TypeSummaryImplSP entry ,
SummaryFormatType type ,
std : : string category ,
Error * error = NULL ) ;
protected :
bool
2015-12-30 06:55:28 -05:00
DoExecute ( Args & command , CommandReturnObject & result ) override ;
2013-08-23 13:46:38 -04:00
} ;
2014-02-18 11:23:10 -05:00
static const char * g_synth_addreader_instructions = " Enter your Python command(s). Type 'DONE' to end. \n "
" You must define a Python class with these methods: \n "
" def __init__(self, valobj, dict): \n "
" def num_children(self): \n "
" def get_child_at_index(self, index): \n "
" def get_child_index(self, name): \n "
" def update(self): \n "
" '''Optional''' \n "
" class synthProvider: \n " ;
class CommandObjectTypeSynthAdd :
public CommandObjectParsed ,
public IOHandlerDelegateMultiline
2013-08-23 13:46:38 -04:00
{
private :
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
2014-02-18 11:23:10 -05:00
Options ( interpreter )
2013-08-23 13:46:38 -04:00
{
}
2015-12-30 06:55:28 -05:00
~ CommandOptions ( ) override { }
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-08-23 13:46:38 -04:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
bool success ;
switch ( short_option )
{
case ' C ' :
m_cascade = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( ! success )
error . SetErrorStringWithFormat ( " invalid value for cascade: %s " , option_arg ) ;
break ;
case ' P ' :
handwrite_python = true ;
break ;
case ' l ' :
m_class_name = std : : string ( option_arg ) ;
is_class_based = true ;
break ;
case ' p ' :
m_skip_pointers = true ;
break ;
case ' r ' :
m_skip_references = true ;
break ;
case ' w ' :
m_category = std : : string ( option_arg ) ;
break ;
case ' x ' :
m_regex = true ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 06:55:28 -05:00
OptionParsingStarting ( ) override
2013-08-23 13:46:38 -04:00
{
m_cascade = true ;
m_class_name = " " ;
m_skip_pointers = false ;
m_skip_references = false ;
m_category = " default " ;
is_class_based = false ;
handwrite_python = false ;
m_regex = false ;
}
const OptionDefinition *
2015-12-30 06:55:28 -05:00
GetDefinitions ( ) override
2013-08-23 13:46:38 -04:00
{
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_cascade ;
bool m_skip_references ;
bool m_skip_pointers ;
std : : string m_class_name ;
bool m_input_python ;
std : : string m_category ;
bool is_class_based ;
bool handwrite_python ;
bool m_regex ;
} ;
CommandOptions m_options ;
2015-12-30 06:55:28 -05:00
Options *
GetOptions ( ) override
2013-08-23 13:46:38 -04:00
{
return & m_options ;
}
bool
Execute_HandwritePython ( Args & command , CommandReturnObject & result ) ;
bool
Execute_PythonClass ( Args & command , CommandReturnObject & result ) ;
protected :
bool
2015-12-30 06:55:28 -05:00
DoExecute ( Args & command , CommandReturnObject & result ) override
2014-02-18 11:23:10 -05:00
{
WarnOnPotentialUnquotedUnsignedType ( command , result ) ;
if ( m_options . handwrite_python )
return Execute_HandwritePython ( command , result ) ;
else if ( m_options . is_class_based )
return Execute_PythonClass ( command , result ) ;
else
{
result . AppendError ( " must either provide a children list, a Python class name, or use -P and type a Python class line-by-line " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
2015-12-30 06:55:28 -05:00
void
IOHandlerActivated ( IOHandler & io_handler ) override
2014-02-18 11:23:10 -05:00
{
StreamFileSP output_sp ( io_handler . GetOutputStreamFile ( ) ) ;
if ( output_sp )
{
output_sp - > PutCString ( g_synth_addreader_instructions ) ;
output_sp - > Flush ( ) ;
}
}
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
void
IOHandlerInputComplete ( IOHandler & io_handler , std : : string & data ) override
2014-02-18 11:23:10 -05:00
{
StreamFileSP error_sp = io_handler . GetErrorStreamFile ( ) ;
# ifndef LLDB_DISABLE_PYTHON
ScriptInterpreter * interpreter = m_interpreter . GetScriptInterpreter ( ) ;
if ( interpreter )
{
StringList lines ;
lines . SplitIntoLines ( data ) ;
if ( lines . GetSize ( ) > 0 )
{
SynthAddOptions * options_ptr = ( ( SynthAddOptions * ) io_handler . GetUserData ( ) ) ;
if ( options_ptr )
{
SynthAddOptions : : SharedPointer options ( options_ptr ) ; // this will ensure that we get rid of the pointer when going out of scope
ScriptInterpreter * interpreter = m_interpreter . GetScriptInterpreter ( ) ;
if ( interpreter )
{
std : : string class_name_str ;
if ( interpreter - > GenerateTypeSynthClass ( lines , class_name_str ) )
{
if ( class_name_str . empty ( ) )
{
error_sp - > Printf ( " error: unable to obtain a proper name for the class. \n " ) ;
error_sp - > Flush ( ) ;
}
else
{
// everything should be fine now, let's add the synth provider class
SyntheticChildrenSP synth_provider ;
synth_provider . reset ( new ScriptedSyntheticChildren ( SyntheticChildren : : Flags ( ) . SetCascades ( options - > m_cascade ) .
SetSkipPointers ( options - > m_skip_pointers ) .
SetSkipReferences ( options - > m_skip_references ) ,
class_name_str . c_str ( ) ) ) ;
lldb : : TypeCategoryImplSP category ;
DataVisualization : : Categories : : GetCategory ( ConstString ( options - > m_category . c_str ( ) ) , category ) ;
Error error ;
for ( size_t i = 0 ; i < options - > m_target_types . GetSize ( ) ; i + + )
{
const char * type_name = options - > m_target_types . GetStringAtIndex ( i ) ;
ConstString const_type_name ( type_name ) ;
if ( const_type_name )
{
if ( ! CommandObjectTypeSynthAdd : : AddSynth ( const_type_name ,
synth_provider ,
options - > m_regex ? CommandObjectTypeSynthAdd : : eRegexSynth : CommandObjectTypeSynthAdd : : eRegularSynth ,
options - > m_category ,
& error ) )
{
error_sp - > Printf ( " error: %s \n " , error . AsCString ( ) ) ;
error_sp - > Flush ( ) ;
break ;
}
}
else
{
error_sp - > Printf ( " error: invalid type name. \n " ) ;
error_sp - > Flush ( ) ;
break ;
}
}
}
}
else
{
error_sp - > Printf ( " error: unable to generate a class. \n " ) ;
error_sp - > Flush ( ) ;
}
}
else
{
error_sp - > Printf ( " error: no script interpreter. \n " ) ;
error_sp - > Flush ( ) ;
}
}
else
{
error_sp - > Printf ( " error: internal synchronization data missing. \n " ) ;
error_sp - > Flush ( ) ;
}
}
else
{
error_sp - > Printf ( " error: empty function, didn't add python command. \n " ) ;
error_sp - > Flush ( ) ;
}
}
else
{
error_sp - > Printf ( " error: script interpreter missing, didn't add python command. \n " ) ;
error_sp - > Flush ( ) ;
}
# endif // #ifndef LLDB_DISABLE_PYTHON
io_handler . SetIsDone ( true ) ;
}
2013-08-23 13:46:38 -04:00
public :
enum SynthFormatType
{
eRegularSynth ,
eRegexSynth
} ;
CommandObjectTypeSynthAdd ( CommandInterpreter & interpreter ) ;
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeSynthAdd ( ) override
2013-08-23 13:46:38 -04:00
{
}
static bool
AddSynth ( ConstString type_name ,
lldb : : SyntheticChildrenSP entry ,
SynthFormatType type ,
std : : string category_name ,
Error * error ) ;
} ;
//-------------------------------------------------------------------------
// CommandObjectTypeFormatAdd
//-------------------------------------------------------------------------
class CommandObjectTypeFormatAdd : public CommandObjectParsed
{
private :
class CommandOptions : public OptionGroup
{
public :
CommandOptions ( ) :
OptionGroup ( )
{
}
2015-12-30 06:55:28 -05:00
~ CommandOptions ( ) override
2013-08-23 13:46:38 -04:00
{
}
2015-12-30 06:55:28 -05:00
uint32_t
GetNumDefinitions ( ) override ;
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
const OptionDefinition *
GetDefinitions ( ) override
2013-08-23 13:46:38 -04:00
{
return g_option_table ;
}
2015-12-30 06:55:28 -05:00
void
OptionParsingStarting ( CommandInterpreter & interpreter ) override
2013-08-23 13:46:38 -04:00
{
m_cascade = true ;
m_skip_pointers = false ;
m_skip_references = false ;
2013-11-06 11:48:53 -05:00
m_regex = false ;
m_category . assign ( " default " ) ;
2014-02-18 11:23:10 -05:00
m_custom_type_name . clear ( ) ;
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
Error
2013-08-23 13:46:38 -04:00
SetOptionValue ( CommandInterpreter & interpreter ,
uint32_t option_idx ,
2015-12-30 06:55:28 -05:00
const char * option_value ) override
2013-08-23 13:46:38 -04:00
{
Error error ;
const int short_option = g_option_table [ option_idx ] . short_option ;
bool success ;
switch ( short_option )
{
case ' C ' :
m_cascade = Args : : StringToBoolean ( option_value , true , & success ) ;
if ( ! success )
error . SetErrorStringWithFormat ( " invalid value for cascade: %s " , option_value ) ;
break ;
case ' p ' :
m_skip_pointers = true ;
break ;
2013-11-06 11:48:53 -05:00
case ' w ' :
m_category . assign ( option_value ) ;
break ;
2013-08-23 13:46:38 -04:00
case ' r ' :
m_skip_references = true ;
break ;
2013-11-06 11:48:53 -05:00
case ' x ' :
m_regex = true ;
break ;
2014-02-18 11:23:10 -05:00
case ' t ' :
m_custom_type_name . assign ( option_value ) ;
break ;
2013-08-23 13:46:38 -04:00
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
// Instance variables to hold the values for command options.
bool m_cascade ;
bool m_skip_references ;
bool m_skip_pointers ;
2013-11-06 11:48:53 -05:00
bool m_regex ;
std : : string m_category ;
2014-02-18 11:23:10 -05:00
std : : string m_custom_type_name ;
2013-08-23 13:46:38 -04:00
} ;
OptionGroupOptions m_option_group ;
OptionGroupFormat m_format_options ;
CommandOptions m_command_options ;
2015-12-30 06:55:28 -05:00
Options *
GetOptions ( ) override
2013-08-23 13:46:38 -04:00
{
return & m_option_group ;
}
public :
CommandObjectTypeFormatAdd ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" type format add " ,
" Add a new formatting style for a type. " ,
NULL ) ,
m_option_group ( interpreter ) ,
m_format_options ( eFormatInvalid ) ,
m_command_options ( )
{
CommandArgumentEntry type_arg ;
CommandArgumentData type_style_arg ;
type_style_arg . arg_type = eArgTypeName ;
type_style_arg . arg_repetition = eArgRepeatPlus ;
type_arg . push_back ( type_style_arg ) ;
m_arguments . push_back ( type_arg ) ;
SetHelpLong (
2015-09-06 10:32:30 -04:00
R " (
The following examples of ' type format add ' refer to this code snippet for context :
typedef int Aint ;
typedef float Afloat ;
typedef Aint Bint ;
typedef Afloat Bfloat ;
Aint ix = 5 ;
Bint iy = 5 ;
Afloat fx = 3.14 ;
BFloat fy = 3.14 ;
Adding default formatting :
( lldb ) type format add - f hex AInt
( lldb ) frame variable iy
) " " Produces hexidecimal display of iy , because no formatter is available for Bint and \
the one for Aint is used instead . " R " (
To prevent this use the cascade option ' - C no ' to prevent evaluation of typedef chains :
( lldb ) type format add - f hex - C no AInt
Similar reasoning applies to this :
( lldb ) type format add - f hex - C no float - p
) " " All float values and float references are now formatted as hexadecimal , but not \
pointers to floats . Nor will it change the default display for Afloat and Bfloat objects . "
2013-08-23 13:46:38 -04:00
) ;
// Add the "--format" to all options groups
2014-02-18 11:23:10 -05:00
m_option_group . Append ( & m_format_options , OptionGroupFormat : : OPTION_GROUP_FORMAT , LLDB_OPT_SET_1 ) ;
2013-08-23 13:46:38 -04:00
m_option_group . Append ( & m_command_options ) ;
m_option_group . Finalize ( ) ;
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeFormatAdd ( ) override
2013-08-23 13:46:38 -04:00
{
}
protected :
bool
2015-12-30 06:55:28 -05:00
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 13:46:38 -04:00
{
const size_t argc = command . GetArgumentCount ( ) ;
if ( argc < 1 )
{
result . AppendErrorWithFormat ( " %s takes one or more args. \n " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
const Format format = m_format_options . GetFormat ( ) ;
2014-02-18 11:23:10 -05:00
if ( format = = eFormatInvalid & & m_command_options . m_custom_type_name . empty ( ) )
2013-08-23 13:46:38 -04:00
{
result . AppendErrorWithFormat ( " %s needs a valid format. \n " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
TypeFormatImplSP entry ;
2014-02-18 11:23:10 -05:00
if ( m_command_options . m_custom_type_name . empty ( ) )
entry . reset ( new TypeFormatImpl_Format ( format ,
TypeFormatImpl : : Flags ( ) . SetCascades ( m_command_options . m_cascade ) .
SetSkipPointers ( m_command_options . m_skip_pointers ) .
SetSkipReferences ( m_command_options . m_skip_references ) ) ) ;
else
entry . reset ( new TypeFormatImpl_EnumType ( ConstString ( m_command_options . m_custom_type_name . c_str ( ) ) ,
TypeFormatImpl : : Flags ( ) . SetCascades ( m_command_options . m_cascade ) .
SetSkipPointers ( m_command_options . m_skip_pointers ) .
SetSkipReferences ( m_command_options . m_skip_references ) ) ) ;
2013-08-23 13:46:38 -04:00
// now I have a valid format, let's add it to every type
2013-11-06 11:48:53 -05:00
TypeCategoryImplSP category_sp ;
DataVisualization : : Categories : : GetCategory ( ConstString ( m_command_options . m_category ) , category_sp ) ;
if ( ! category_sp )
return false ;
2014-02-18 11:23:10 -05:00
WarnOnPotentialUnquotedUnsignedType ( command , result ) ;
2013-08-23 13:46:38 -04:00
for ( size_t i = 0 ; i < argc ; i + + )
{
const char * typeA = command . GetArgumentAtIndex ( i ) ;
ConstString typeCS ( typeA ) ;
if ( typeCS )
2013-11-06 11:48:53 -05:00
{
if ( m_command_options . m_regex )
{
RegularExpressionSP typeRX ( new RegularExpression ( ) ) ;
if ( ! typeRX - > Compile ( typeCS . GetCString ( ) ) )
{
result . AppendError ( " regex format error (maybe this is not really a regex?) " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2014-02-18 11:23:10 -05:00
category_sp - > GetRegexTypeSummariesContainer ( ) - > Delete ( typeCS ) ;
category_sp - > GetRegexTypeFormatsContainer ( ) - > Add ( typeRX , entry ) ;
2013-11-06 11:48:53 -05:00
}
else
2014-02-18 11:23:10 -05:00
category_sp - > GetTypeFormatsContainer ( ) - > Add ( typeCS , entry ) ;
2013-11-06 11:48:53 -05:00
}
2013-08-23 13:46:38 -04:00
else
{
result . AppendError ( " empty typenames not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
return result . Succeeded ( ) ;
}
} ;
OptionDefinition
CommandObjectTypeFormatAdd : : CommandOptions : : g_option_table [ ] =
{
2014-11-25 16:00:58 -05:00
{ LLDB_OPT_SET_ALL , false , " category " , ' w ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeName , " Add this to the given category instead of the default one. " } ,
{ LLDB_OPT_SET_ALL , false , " cascade " , ' C ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBoolean , " If true, cascade through typedef chains. " } ,
{ LLDB_OPT_SET_ALL , false , " skip-pointers " , ' p ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Don't use this format for pointers-to-type objects. " } ,
{ LLDB_OPT_SET_ALL , false , " skip-references " , ' r ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Don't use this format for references-to-type objects. " } ,
{ LLDB_OPT_SET_ALL , false , " regex " , ' x ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Type names are actually regular expressions. " } ,
{ LLDB_OPT_SET_2 , false , " type " , ' t ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeName , " Format variables as if they were of this type. " } ,
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-08-23 13:46:38 -04:00
} ;
uint32_t
CommandObjectTypeFormatAdd : : CommandOptions : : GetNumDefinitions ( )
{
return sizeof ( g_option_table ) / sizeof ( OptionDefinition ) ;
}
2015-12-30 06:55:28 -05:00
class CommandObjectTypeFormatterDelete : public CommandObjectParsed
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
protected :
2013-11-06 11:48:53 -05:00
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter )
{
}
2015-12-30 06:55:28 -05:00
~ CommandOptions ( ) override { }
2013-11-06 11:48:53 -05:00
2015-12-30 06:55:28 -05:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-11-06 11:48:53 -05:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
case ' a ' :
m_delete_all = true ;
break ;
case ' w ' :
m_category = std : : string ( option_arg ) ;
break ;
2015-12-30 06:55:28 -05:00
case ' l ' :
m_language = Language : : GetLanguageTypeFromString ( option_arg ) ;
break ;
2013-11-06 11:48:53 -05:00
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 06:55:28 -05:00
OptionParsingStarting ( ) override
2013-11-06 11:48:53 -05:00
{
m_delete_all = false ;
m_category = " default " ;
2015-12-30 06:55:28 -05:00
m_language = lldb : : eLanguageTypeUnknown ;
2013-11-06 11:48:53 -05:00
}
const OptionDefinition *
2015-12-30 06:55:28 -05:00
GetDefinitions ( ) override
2013-11-06 11:48:53 -05:00
{
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_delete_all ;
std : : string m_category ;
2015-12-30 06:55:28 -05:00
lldb : : LanguageType m_language ;
2013-11-06 11:48:53 -05:00
} ;
CommandOptions m_options ;
2015-12-30 06:55:28 -05:00
uint32_t m_formatter_kind_mask ;
2013-11-06 11:48:53 -05:00
2015-12-30 06:55:28 -05:00
Options *
GetOptions ( ) override
2013-11-06 11:48:53 -05:00
{
return & m_options ;
}
2013-08-23 13:46:38 -04:00
public :
2015-12-30 06:55:28 -05:00
CommandObjectTypeFormatterDelete ( CommandInterpreter & interpreter ,
uint32_t formatter_kind_mask ,
const char * name ,
const char * help ) :
CommandObjectParsed ( interpreter ,
name ,
help ,
NULL ) ,
m_options ( interpreter ) ,
m_formatter_kind_mask ( formatter_kind_mask )
2013-08-23 13:46:38 -04:00
{
CommandArgumentEntry type_arg ;
CommandArgumentData type_style_arg ;
type_style_arg . arg_type = eArgTypeName ;
type_style_arg . arg_repetition = eArgRepeatPlain ;
type_arg . push_back ( type_style_arg ) ;
m_arguments . push_back ( type_arg ) ;
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeFormatterDelete ( ) override = default ;
protected :
virtual bool
FormatterSpecificDeletion ( ConstString typeCS )
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
return false ;
2013-08-23 13:46:38 -04:00
}
bool
2015-12-30 06:55:28 -05:00
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 13:46:38 -04:00
{
const size_t argc = command . GetArgumentCount ( ) ;
if ( argc ! = 1 )
{
result . AppendErrorWithFormat ( " %s takes 1 arg. \n " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
const char * typeA = command . GetArgumentAtIndex ( 0 ) ;
ConstString typeCS ( typeA ) ;
if ( ! typeCS )
{
result . AppendError ( " empty typenames not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2013-11-06 11:48:53 -05:00
if ( m_options . m_delete_all )
{
2015-12-30 06:55:28 -05:00
DataVisualization : : Categories : : ForEach ( [ this , typeCS ] ( const lldb : : TypeCategoryImplSP & category_sp ) - > bool {
category_sp - > Delete ( typeCS , m_formatter_kind_mask ) ;
return true ;
} ) ;
2013-11-06 11:48:53 -05:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
return result . Succeeded ( ) ;
}
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
bool delete_category = false ;
bool extra_deletion = false ;
2013-11-06 11:48:53 -05:00
2015-12-30 06:55:28 -05:00
if ( m_options . m_language ! = lldb : : eLanguageTypeUnknown )
{
lldb : : TypeCategoryImplSP category ;
DataVisualization : : Categories : : GetCategory ( m_options . m_language , category ) ;
if ( category )
delete_category = category - > Delete ( typeCS , m_formatter_kind_mask ) ;
extra_deletion = FormatterSpecificDeletion ( typeCS ) ;
}
else
{
lldb : : TypeCategoryImplSP category ;
DataVisualization : : Categories : : GetCategory ( ConstString ( m_options . m_category . c_str ( ) ) , category ) ;
if ( category )
delete_category = category - > Delete ( typeCS , m_formatter_kind_mask ) ;
extra_deletion = FormatterSpecificDeletion ( typeCS ) ;
}
2013-11-06 11:48:53 -05:00
2015-12-30 06:55:28 -05:00
if ( delete_category | | extra_deletion )
2013-08-23 13:46:38 -04:00
{
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
return result . Succeeded ( ) ;
}
else
{
2015-12-30 06:55:28 -05:00
result . AppendErrorWithFormat ( " no custom formatter for %s. \n " , typeA ) ;
2013-08-23 13:46:38 -04:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
} ;
2013-11-06 11:48:53 -05:00
OptionDefinition
2015-12-30 06:55:28 -05:00
CommandObjectTypeFormatterDelete : : CommandOptions : : g_option_table [ ] =
2013-11-06 11:48:53 -05:00
{
2014-11-25 16:00:58 -05:00
{ LLDB_OPT_SET_1 , false , " all " , ' a ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Delete from every category. " } ,
{ LLDB_OPT_SET_2 , false , " category " , ' w ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeName , " Delete from given category. " } ,
2015-12-30 06:55:28 -05:00
{ LLDB_OPT_SET_3 , false , " language " , ' l ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeLanguage , " Delete from given language's category. " } ,
2014-11-25 16:00:58 -05:00
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-11-06 11:48:53 -05:00
} ;
2015-12-30 06:55:28 -05:00
class CommandObjectTypeFormatterClear : public CommandObjectParsed
2013-08-23 13:46:38 -04:00
{
2013-11-06 11:48:53 -05:00
private :
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter )
{
}
2015-12-30 06:55:28 -05:00
~ CommandOptions ( ) override { }
2013-11-06 11:48:53 -05:00
2015-12-30 06:55:28 -05:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-11-06 11:48:53 -05:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
case ' a ' :
m_delete_all = true ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 06:55:28 -05:00
OptionParsingStarting ( ) override
2013-11-06 11:48:53 -05:00
{
m_delete_all = false ;
}
const OptionDefinition *
2015-12-30 06:55:28 -05:00
GetDefinitions ( ) override
2013-11-06 11:48:53 -05:00
{
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_delete_all ;
} ;
CommandOptions m_options ;
2015-12-30 06:55:28 -05:00
uint32_t m_formatter_kind_mask ;
Options *
GetOptions ( ) override
2013-11-06 11:48:53 -05:00
{
return & m_options ;
}
2015-12-30 06:55:28 -05:00
public :
CommandObjectTypeFormatterClear ( CommandInterpreter & interpreter ,
uint32_t formatter_kind_mask ,
const char * name ,
const char * help ) :
CommandObjectParsed ( interpreter ,
name ,
help ,
NULL ) ,
m_options ( interpreter ) ,
m_formatter_kind_mask ( formatter_kind_mask )
2013-11-06 11:48:53 -05:00
{
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeFormatterClear ( ) override
2013-08-23 13:46:38 -04:00
{
}
2015-12-30 06:55:28 -05:00
protected :
virtual void
FormatterSpecificDeletion ( )
2013-08-23 13:46:38 -04:00
{
}
bool
2015-12-30 06:55:28 -05:00
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 13:46:38 -04:00
{
2013-11-06 11:48:53 -05:00
if ( m_options . m_delete_all )
2015-12-30 06:55:28 -05:00
{
DataVisualization : : Categories : : ForEach ( [ this ] ( const TypeCategoryImplSP & category_sp ) - > bool {
category_sp - > Clear ( m_formatter_kind_mask ) ;
return true ;
} ) ;
}
2013-11-06 11:48:53 -05:00
else
{
lldb : : TypeCategoryImplSP category ;
if ( command . GetArgumentCount ( ) > 0 )
{
const char * cat_name = command . GetArgumentAtIndex ( 0 ) ;
ConstString cat_nameCS ( cat_name ) ;
DataVisualization : : Categories : : GetCategory ( cat_nameCS , category ) ;
}
else
2015-12-30 06:55:28 -05:00
{
2013-11-06 11:48:53 -05:00
DataVisualization : : Categories : : GetCategory ( ConstString ( NULL ) , category ) ;
2015-12-30 06:55:28 -05:00
}
category - > Clear ( m_formatter_kind_mask ) ;
2013-11-06 11:48:53 -05:00
}
2015-12-30 06:55:28 -05:00
FormatterSpecificDeletion ( ) ;
2013-08-23 13:46:38 -04:00
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
return result . Succeeded ( ) ;
}
} ;
2013-11-06 11:48:53 -05:00
OptionDefinition
2015-12-30 06:55:28 -05:00
CommandObjectTypeFormatterClear : : CommandOptions : : g_option_table [ ] =
2013-11-06 11:48:53 -05:00
{
2014-11-25 16:00:58 -05:00
{ LLDB_OPT_SET_ALL , false , " all " , ' a ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Clear every category. " } ,
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-11-06 11:48:53 -05:00
} ;
2013-08-23 13:46:38 -04:00
//-------------------------------------------------------------------------
2015-12-30 06:55:28 -05:00
// CommandObjectTypeFormatDelete
2013-08-23 13:46:38 -04:00
//-------------------------------------------------------------------------
2015-12-30 06:55:28 -05:00
class CommandObjectTypeFormatDelete : public CommandObjectTypeFormatterDelete
{
public :
CommandObjectTypeFormatDelete ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterDelete ( interpreter ,
eFormatCategoryItemValue | eFormatCategoryItemRegexValue ,
" type format delete " ,
" Delete an existing formatting style for a type. " )
{
}
~ CommandObjectTypeFormatDelete ( ) override
{
}
} ;
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
//-------------------------------------------------------------------------
// CommandObjectTypeFormatClear
//-------------------------------------------------------------------------
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
class CommandObjectTypeFormatClear : public CommandObjectTypeFormatterClear
{
public :
CommandObjectTypeFormatClear ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterClear ( interpreter ,
eFormatCategoryItemValue | eFormatCategoryItemRegexValue ,
" type format clear " ,
" Delete all existing format styles. " )
{
}
2013-08-23 13:46:38 -04:00
} ;
2015-12-30 06:55:28 -05:00
template < typename FormatterType >
class CommandObjectTypeFormatterList : public CommandObjectParsed
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
typedef typename FormatterType : : SharedPointer FormatterSharedPointer ;
2013-11-06 11:48:53 -05:00
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
2015-12-30 06:55:28 -05:00
Options ( interpreter ) ,
m_category_regex ( " " , " " ) ,
m_category_language ( lldb : : eLanguageTypeUnknown , lldb : : eLanguageTypeUnknown )
2013-11-06 11:48:53 -05:00
{
}
2015-12-30 06:55:28 -05:00
~ CommandOptions ( ) override { }
2013-11-06 11:48:53 -05:00
2015-12-30 06:55:28 -05:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-11-06 11:48:53 -05:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
case ' w ' :
2015-12-30 06:55:28 -05:00
m_category_regex . SetCurrentValue ( option_arg ) ;
break ;
case ' l ' :
error = m_category_language . SetValueFromString ( option_arg ) ;
2013-11-06 11:48:53 -05:00
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 06:55:28 -05:00
OptionParsingStarting ( ) override
2013-11-06 11:48:53 -05:00
{
2015-12-30 06:55:28 -05:00
m_category_regex . Clear ( ) ;
m_category_language . Clear ( ) ;
2013-11-06 11:48:53 -05:00
}
const OptionDefinition *
2015-12-30 06:55:28 -05:00
GetDefinitions ( ) override
2013-11-06 11:48:53 -05:00
{
2015-12-30 06:55:28 -05:00
static OptionDefinition g_option_table [ ] =
{
{ LLDB_OPT_SET_1 , false , " category-regex " , ' w ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeName , " Only show categories matching this filter. " } ,
{ LLDB_OPT_SET_2 , false , " language " , ' l ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeLanguage , " Only show the category for a specific language. " } ,
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
} ;
2013-11-06 11:48:53 -05:00
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.
2015-12-30 06:55:28 -05:00
OptionValueString m_category_regex ;
OptionValueLanguage m_category_language ;
2013-11-06 11:48:53 -05:00
} ;
CommandOptions m_options ;
2015-12-30 06:55:28 -05:00
Options *
GetOptions ( ) override
2013-11-06 11:48:53 -05:00
{
return & m_options ;
}
2013-08-23 13:46:38 -04:00
public :
2015-12-30 06:55:28 -05:00
CommandObjectTypeFormatterList ( CommandInterpreter & interpreter ,
const char * name ,
const char * help ) :
2013-08-23 13:46:38 -04:00
CommandObjectParsed ( interpreter ,
2015-12-30 06:55:28 -05:00
name ,
help ,
2013-11-06 11:48:53 -05:00
NULL ) ,
m_options ( interpreter )
2013-08-23 13:46:38 -04:00
{
CommandArgumentEntry type_arg ;
CommandArgumentData type_style_arg ;
type_style_arg . arg_type = eArgTypeName ;
type_style_arg . arg_repetition = eArgRepeatOptional ;
type_arg . push_back ( type_style_arg ) ;
m_arguments . push_back ( type_arg ) ;
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeFormatterList ( ) override
2013-08-23 13:46:38 -04:00
{
}
protected :
2015-12-30 06:55:28 -05:00
virtual void
FormatterSpecificList ( CommandReturnObject & result )
{
}
2013-08-23 13:46:38 -04:00
bool
2015-12-30 06:55:28 -05:00
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 13:46:38 -04:00
{
const size_t argc = command . GetArgumentCount ( ) ;
2015-12-30 06:55:28 -05:00
std : : unique_ptr < RegularExpression > category_regex ;
std : : unique_ptr < RegularExpression > formatter_regex ;
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
if ( m_options . m_category_regex . OptionWasSet ( ) )
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
category_regex . reset ( new RegularExpression ( ) ) ;
if ( ! category_regex - > Compile ( m_options . m_category_regex . GetCurrentValue ( ) ) )
{
result . AppendErrorWithFormat ( " syntax error in category regular expression '%s' " , m_options . m_category_regex . GetCurrentValue ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2013-08-23 13:46:38 -04:00
}
2013-11-06 11:48:53 -05:00
2015-12-30 06:55:28 -05:00
if ( argc = = 1 )
{
const char * arg = command . GetArgumentAtIndex ( 1 ) ;
formatter_regex . reset ( new RegularExpression ( ) ) ;
if ( ! formatter_regex - > Compile ( arg ) )
{
result . AppendErrorWithFormat ( " syntax error in regular expression '%s' " , arg ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
2013-11-06 11:48:53 -05:00
2015-12-30 06:55:28 -05:00
auto category_closure = [ & result , & formatter_regex ] ( const lldb : : TypeCategoryImplSP & category ) - > void {
result . GetOutputStream ( ) . Printf ( " ----------------------- \n Category: %s \n ----------------------- \n " , category - > GetName ( ) ) ;
TypeCategoryImpl : : ForEachCallbacks < FormatterType > foreach ;
foreach . SetExact ( [ & result , & formatter_regex ] ( ConstString name , const FormatterSharedPointer & format_sp ) - > bool {
if ( formatter_regex )
{
bool escape = true ;
if ( 0 = = strcmp ( name . AsCString ( ) , formatter_regex - > GetText ( ) ) )
{
escape = false ;
}
else if ( formatter_regex - > Execute ( name . AsCString ( ) ) )
{
escape = false ;
}
if ( escape )
return true ;
}
result . GetOutputStream ( ) . Printf ( " %s: %s \n " , name . AsCString ( ) , format_sp - > GetDescription ( ) . c_str ( ) ) ;
return true ;
} ) ;
foreach . SetWithRegex ( [ & result , & formatter_regex ] ( RegularExpressionSP regex_sp , const FormatterSharedPointer & format_sp ) - > bool {
if ( formatter_regex )
{
bool escape = true ;
if ( 0 = = strcmp ( regex_sp - > GetText ( ) , formatter_regex - > GetText ( ) ) )
{
escape = false ;
}
else if ( formatter_regex - > Execute ( regex_sp - > GetText ( ) ) )
{
escape = false ;
}
if ( escape )
return true ;
}
result . GetOutputStream ( ) . Printf ( " %s: %s \n " , regex_sp - > GetText ( ) , format_sp - > GetDescription ( ) . c_str ( ) ) ;
return true ;
} ) ;
category - > ForEach ( foreach ) ;
} ;
2013-11-06 11:48:53 -05:00
2015-12-30 06:55:28 -05:00
if ( m_options . m_category_language . OptionWasSet ( ) )
2013-11-06 11:48:53 -05:00
{
2015-12-30 06:55:28 -05:00
lldb : : TypeCategoryImplSP category_sp ;
DataVisualization : : Categories : : GetCategory ( m_options . m_category_language . GetCurrentValue ( ) , category_sp ) ;
if ( category_sp )
category_closure ( category_sp ) ;
2013-11-06 11:48:53 -05:00
}
2015-12-30 06:55:28 -05:00
else
{
DataVisualization : : Categories : : ForEach ( [ this , & command , & result , & category_regex , & formatter_regex , & category_closure ] ( const lldb : : TypeCategoryImplSP & category ) - > bool {
if ( category_regex )
{
bool escape = true ;
if ( 0 = = strcmp ( category - > GetName ( ) , category_regex - > GetText ( ) ) )
{
escape = false ;
}
else if ( category_regex - > Execute ( category - > GetName ( ) ) )
{
escape = false ;
}
if ( escape )
return true ;
}
category_closure ( category ) ;
return true ;
} ) ;
FormatterSpecificList ( result ) ;
}
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
return result . Succeeded ( ) ;
2013-08-23 13:46:38 -04:00
}
} ;
2015-12-30 06:55:28 -05:00
//-------------------------------------------------------------------------
// CommandObjectTypeFormatList
//-------------------------------------------------------------------------
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
class CommandObjectTypeFormatList : public CommandObjectTypeFormatterList < TypeFormatImpl >
2013-11-06 11:48:53 -05:00
{
2015-12-30 06:55:28 -05:00
public :
CommandObjectTypeFormatList ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterList ( interpreter ,
" type format list " ,
" Show a list of current formats. " )
{
}
2013-11-06 11:48:53 -05:00
} ;
2013-08-23 13:46:38 -04:00
# ifndef LLDB_DISABLE_PYTHON
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryAdd
//-------------------------------------------------------------------------
# endif // #ifndef LLDB_DISABLE_PYTHON
Error
CommandObjectTypeSummaryAdd : : CommandOptions : : SetOptionValue ( uint32_t option_idx , const char * option_arg )
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
bool success ;
switch ( short_option )
{
case ' C ' :
m_flags . SetCascades ( Args : : StringToBoolean ( option_arg , true , & success ) ) ;
if ( ! success )
error . SetErrorStringWithFormat ( " invalid value for cascade: %s " , option_arg ) ;
break ;
case ' e ' :
m_flags . SetDontShowChildren ( false ) ;
break ;
2015-12-30 06:55:28 -05:00
case ' h ' :
m_flags . SetHideEmptyAggregates ( true ) ;
break ;
2013-08-23 13:46:38 -04:00
case ' v ' :
m_flags . SetDontShowValue ( true ) ;
break ;
case ' c ' :
m_flags . SetShowMembersOneLiner ( true ) ;
break ;
case ' s ' :
m_format_string = std : : string ( option_arg ) ;
break ;
case ' p ' :
m_flags . SetSkipPointers ( true ) ;
break ;
case ' r ' :
m_flags . SetSkipReferences ( true ) ;
break ;
case ' x ' :
m_regex = true ;
break ;
case ' n ' :
m_name . SetCString ( option_arg ) ;
break ;
case ' o ' :
m_python_script = std : : string ( option_arg ) ;
m_is_add_script = true ;
break ;
case ' F ' :
m_python_function = std : : string ( option_arg ) ;
m_is_add_script = true ;
break ;
case ' P ' :
m_is_add_script = true ;
break ;
case ' w ' :
m_category = std : : string ( option_arg ) ;
break ;
case ' O ' :
m_flags . SetHideItemNames ( true ) ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
CommandObjectTypeSummaryAdd : : CommandOptions : : OptionParsingStarting ( )
{
m_flags . Clear ( ) . SetCascades ( ) . SetDontShowChildren ( ) . SetDontShowValue ( false ) ;
m_flags . SetShowMembersOneLiner ( false ) . SetSkipPointers ( false ) . SetSkipReferences ( false ) . SetHideItemNames ( false ) ;
m_regex = false ;
m_name . Clear ( ) ;
m_python_script = " " ;
m_python_function = " " ;
m_format_string = " " ;
m_is_add_script = false ;
m_category = " default " ;
}
2014-02-18 11:23:10 -05:00
2013-08-23 13:46:38 -04:00
# ifndef LLDB_DISABLE_PYTHON
bool
CommandObjectTypeSummaryAdd : : Execute_ScriptSummary ( Args & command , CommandReturnObject & result )
{
const size_t argc = command . GetArgumentCount ( ) ;
if ( argc < 1 & & ! m_options . m_name )
{
result . AppendErrorWithFormat ( " %s takes one or more args. \n " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
TypeSummaryImplSP script_format ;
if ( ! m_options . m_python_function . empty ( ) ) // we have a Python function ready to use
{
const char * funct_name = m_options . m_python_function . c_str ( ) ;
if ( ! funct_name | | ! funct_name [ 0 ] )
{
result . AppendError ( " function name empty. \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2014-02-18 11:23:10 -05:00
std : : string code = ( " " + m_options . m_python_function + " (valobj,internal_dict) " ) ;
2013-08-23 13:46:38 -04:00
script_format . reset ( new ScriptSummaryFormat ( m_options . m_flags ,
funct_name ,
code . c_str ( ) ) ) ;
ScriptInterpreter * interpreter = m_interpreter . GetScriptInterpreter ( ) ;
if ( interpreter & & interpreter - > CheckObjectExists ( funct_name ) = = false )
result . AppendWarningWithFormat ( " The provided function \" %s \" does not exist - "
" please define it before attempting to use this summary. \n " ,
funct_name ) ;
}
else if ( ! m_options . m_python_script . empty ( ) ) // we have a quick 1-line script, just use it
{
ScriptInterpreter * interpreter = m_interpreter . GetScriptInterpreter ( ) ;
if ( ! interpreter )
{
result . AppendError ( " script interpreter missing - unable to generate function wrapper. \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
StringList funct_sl ;
funct_sl < < m_options . m_python_script . c_str ( ) ;
std : : string funct_name_str ;
if ( ! interpreter - > GenerateTypeScriptFunction ( funct_sl ,
funct_name_str ) )
{
result . AppendError ( " unable to generate function wrapper. \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( funct_name_str . empty ( ) )
{
result . AppendError ( " script interpreter failed to generate a valid function name. \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2014-02-18 11:23:10 -05:00
std : : string code = " " + m_options . m_python_script ;
2013-08-23 13:46:38 -04:00
script_format . reset ( new ScriptSummaryFormat ( m_options . m_flags ,
funct_name_str . c_str ( ) ,
code . c_str ( ) ) ) ;
}
2014-02-18 11:23:10 -05:00
else
{
// Use an IOHandler to grab Python code from the user
2013-08-23 13:46:38 -04:00
ScriptAddOptions * options = new ScriptAddOptions ( m_options . m_flags ,
m_options . m_regex ,
m_options . m_name ,
m_options . m_category ) ;
for ( size_t i = 0 ; i < argc ; i + + )
{
const char * typeA = command . GetArgumentAtIndex ( i ) ;
if ( typeA & & * typeA )
options - > m_target_types < < typeA ;
else
{
result . AppendError ( " empty typenames not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
2014-02-18 11:23:10 -05:00
m_interpreter . GetPythonCommandsFromIOHandler ( " " , // Prompt
* this , // IOHandlerDelegate
true , // Run IOHandler in async mode
options ) ; // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
2013-08-23 13:46:38 -04:00
return result . Succeeded ( ) ;
}
// if I am here, script_format must point to something good, so I can add that
// as a script summary to all interested parties
Error error ;
for ( size_t i = 0 ; i < command . GetArgumentCount ( ) ; i + + )
{
const char * type_name = command . GetArgumentAtIndex ( i ) ;
CommandObjectTypeSummaryAdd : : AddSummary ( ConstString ( type_name ) ,
script_format ,
( m_options . m_regex ? eRegexSummary : eRegularSummary ) ,
m_options . m_category ,
& error ) ;
if ( error . Fail ( ) )
{
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
if ( m_options . m_name )
{
AddSummary ( m_options . m_name , script_format , eNamedSummary , m_options . m_category , & error ) ;
if ( error . Fail ( ) )
{
result . AppendError ( error . AsCString ( ) ) ;
result . AppendError ( " added to types, but not given a name " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
return result . Succeeded ( ) ;
}
# endif
bool
CommandObjectTypeSummaryAdd : : Execute_StringSummary ( Args & command , CommandReturnObject & result )
{
const size_t argc = command . GetArgumentCount ( ) ;
if ( argc < 1 & & ! m_options . m_name )
{
result . AppendErrorWithFormat ( " %s takes one or more args. \n " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( ! m_options . m_flags . GetShowMembersOneLiner ( ) & & m_options . m_format_string . empty ( ) )
{
result . AppendError ( " empty summary strings not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
const char * format_cstr = ( m_options . m_flags . GetShowMembersOneLiner ( ) ? " " : m_options . m_format_string . c_str ( ) ) ;
// ${var%S} is an endless recursion, prevent it
if ( strcmp ( format_cstr , " ${var%S} " ) = = 0 )
{
result . AppendError ( " recursive summary not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
Error error ;
lldb : : TypeSummaryImplSP entry ( new StringSummaryFormat ( m_options . m_flags ,
format_cstr ) ) ;
if ( error . Fail ( ) )
{
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// now I have a valid format, let's add it to every type
for ( size_t i = 0 ; i < argc ; i + + )
{
const char * typeA = command . GetArgumentAtIndex ( i ) ;
if ( ! typeA | | typeA [ 0 ] = = ' \0 ' )
{
result . AppendError ( " empty typenames not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
ConstString typeCS ( typeA ) ;
AddSummary ( typeCS ,
entry ,
( m_options . m_regex ? eRegexSummary : eRegularSummary ) ,
m_options . m_category ,
& error ) ;
if ( error . Fail ( ) )
{
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
if ( m_options . m_name )
{
AddSummary ( m_options . m_name , entry , eNamedSummary , m_options . m_category , & error ) ;
if ( error . Fail ( ) )
{
result . AppendError ( error . AsCString ( ) ) ;
result . AppendError ( " added to types, but not given a name " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
return result . Succeeded ( ) ;
}
CommandObjectTypeSummaryAdd : : CommandObjectTypeSummaryAdd ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" type summary add " ,
" Add a new summary style for a type. " ,
NULL ) ,
2014-02-18 11:23:10 -05:00
IOHandlerDelegateMultiline ( " DONE " ) ,
2013-08-23 13:46:38 -04:00
m_options ( interpreter )
{
CommandArgumentEntry type_arg ;
CommandArgumentData type_style_arg ;
type_style_arg . arg_type = eArgTypeName ;
type_style_arg . arg_repetition = eArgRepeatPlus ;
type_arg . push_back ( type_style_arg ) ;
m_arguments . push_back ( type_arg ) ;
SetHelpLong (
2015-09-06 10:32:30 -04:00
R " (
The following examples of ' type summary add ' refer to this code snippet for context :
struct JustADemo
{
int * ptr ;
float value ;
JustADemo ( int p = 1 , float v = 0.1 ) : ptr ( new int ( p ) ) , value ( v ) { }
} ;
JustADemo demo_instance ( 42 , 3.14 ) ;
typedef JustADemo NewDemo ;
NewDemo new_demo_instance ( 42 , 3.14 ) ;
( lldb ) type summary add - - summary - string " the answer is ${*var.ptr} " JustADemo
Subsequently displaying demo_instance with ' frame variable ' or ' expression ' will display " the answer is 42 "
( lldb ) type summary add - - summary - string " the answer is ${*var.ptr}, and the question is ${var.value} " JustADemo
Subsequently displaying demo_instance with ' frame variable ' or ' expression ' will display " the answer is 42 and the question is 3.14 "
) " " Alternatively , you could define formatting for all pointers to integers and \
rely on that when formatting JustADemo to obtain the same result : " R " (
( lldb ) type summary add - - summary - string " ${var%V} -> ${*var} " " int * "
( lldb ) type summary add - - summary - string " the answer is ${var.ptr}, and the question is ${var.value} " JustADemo
) " " Type summaries are automatically applied to derived typedefs , so the examples \
above apply to both JustADemo and NewDemo . The cascade option can be used to \
suppress this behavior : " R " (
( lldb ) type summary add - - summary - string " ${var.ptr}, ${var.value},{${var.byte}} " JustADemo - C no
The summary will now be used for values of JustADemo but not NewDemo .
) " " By default summaries are shown for pointers and references to values of the \
specified type . To suppress formatting for pointers use the - p option , or apply \
the corresponding - r option to suppress formatting for references : " R " (
( lldb ) type summary add - p - r - - summary - string " ${var.ptr}, ${var.value},{${var.byte}} " JustADemo
) " " One - line summaries including all fields in a type can be inferred without supplying an \
explicit summary string by passing the - c option : " R " (
( lldb ) type summary add - c JustADemo
( lldb ) frame variable demo_instance
( ptr = < address > , value = 3.14 )
) " " Type summaries normally suppress the nested display of individual fields . To \
supply a summary to supplement the default structure add the - e option : " R " (
( lldb ) type summary add - e - - summary - string " *ptr = ${*var.ptr} " JustADemo
) " " Now when displaying JustADemo values the int * is displayed , followed by the \
standard LLDB sequence of children , one per line : " R " (
* ptr = 42 {
ptr = < address >
value = 3.14
}
) " " You can also add summaries written in Python . These scripts use lldb public API to \
gather information from your variables and produce a meaningful summary . To start a \
multi - line script use the - P option . The function declaration will be displayed along with \
a comment describing the two arguments . End your script with the word ' DONE ' on a line by \
itself : " R " (
( lldb ) type summary add JustADemo - P
def function ( valobj , internal_dict ) :
" " " valobj: an SBValue which you want to provide a summary for
internal_dict : an LLDB support object not to be used " " "
value = valobj . GetChildMemberWithName ( ' value ' ) ;
return ' My value is ' + value . GetValue ( ) ;
DONE
Alternatively , the - o option can be used when providing a simple one - line Python script :
( lldb ) type summary add JustADemo - o " value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue(); " ) "
) ;
2013-08-23 13:46:38 -04:00
}
bool
CommandObjectTypeSummaryAdd : : DoExecute ( Args & command , CommandReturnObject & result )
{
2014-02-18 11:23:10 -05:00
WarnOnPotentialUnquotedUnsignedType ( command , result ) ;
2013-08-23 13:46:38 -04:00
if ( m_options . m_is_add_script )
{
# ifndef LLDB_DISABLE_PYTHON
return Execute_ScriptSummary ( command , result ) ;
# else
result . AppendError ( " python is disabled " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
# endif
}
return Execute_StringSummary ( command , result ) ;
}
2014-11-25 16:00:58 -05:00
static bool
FixArrayTypeNameWithRegex ( ConstString & type_name )
{
llvm : : StringRef type_name_ref ( type_name . GetStringRef ( ) ) ;
if ( type_name_ref . endswith ( " [] " ) )
{
std : : string type_name_str ( type_name . GetCString ( ) ) ;
type_name_str . resize ( type_name_str . length ( ) - 2 ) ;
if ( type_name_str . back ( ) ! = ' ' )
type_name_str . append ( " \\ [[0-9]+ \\ ] " ) ;
else
type_name_str . append ( " \\ [[0-9]+ \\ ] " ) ;
type_name . SetCString ( type_name_str . c_str ( ) ) ;
return true ;
}
return false ;
}
2013-08-23 13:46:38 -04:00
bool
CommandObjectTypeSummaryAdd : : AddSummary ( ConstString type_name ,
TypeSummaryImplSP entry ,
SummaryFormatType type ,
std : : string category_name ,
Error * error )
{
lldb : : TypeCategoryImplSP category ;
DataVisualization : : Categories : : GetCategory ( ConstString ( category_name . c_str ( ) ) , category ) ;
if ( type = = eRegularSummary )
{
2014-11-25 16:00:58 -05:00
if ( FixArrayTypeNameWithRegex ( type_name ) )
2013-08-23 13:46:38 -04:00
type = eRegexSummary ;
}
if ( type = = eRegexSummary )
{
RegularExpressionSP typeRX ( new RegularExpression ( ) ) ;
if ( ! typeRX - > Compile ( type_name . GetCString ( ) ) )
{
if ( error )
error - > SetErrorString ( " regex format error (maybe this is not really a regex?) " ) ;
return false ;
}
2014-02-18 11:23:10 -05:00
category - > GetRegexTypeSummariesContainer ( ) - > Delete ( type_name ) ;
category - > GetRegexTypeSummariesContainer ( ) - > Add ( typeRX , entry ) ;
2013-08-23 13:46:38 -04:00
return true ;
}
else if ( type = = eNamedSummary )
{
// system named summaries do not exist (yet?)
DataVisualization : : NamedSummaryFormats : : Add ( type_name , entry ) ;
return true ;
}
else
{
2014-02-18 11:23:10 -05:00
category - > GetTypeSummariesContainer ( ) - > Add ( type_name , entry ) ;
2013-08-23 13:46:38 -04:00
return true ;
}
}
OptionDefinition
CommandObjectTypeSummaryAdd : : CommandOptions : : g_option_table [ ] =
{
2014-11-25 16:00:58 -05:00
{ LLDB_OPT_SET_ALL , false , " category " , ' w ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeName , " Add this to the given category instead of the default one. " } ,
{ LLDB_OPT_SET_ALL , false , " cascade " , ' C ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBoolean , " If true, cascade through typedef chains. " } ,
{ LLDB_OPT_SET_ALL , false , " no-value " , ' v ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Don't show the value, just show the summary, for this type. " } ,
{ LLDB_OPT_SET_ALL , false , " skip-pointers " , ' p ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Don't use this format for pointers-to-type objects. " } ,
{ LLDB_OPT_SET_ALL , false , " skip-references " , ' r ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Don't use this format for references-to-type objects. " } ,
{ LLDB_OPT_SET_ALL , false , " regex " , ' x ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Type names are actually regular expressions. " } ,
{ LLDB_OPT_SET_1 , true , " inline-children " , ' c ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " If true, inline all child values into summary string. " } ,
{ LLDB_OPT_SET_1 , false , " omit-names " , ' O ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " If true, omit value names in the summary display. " } ,
{ LLDB_OPT_SET_2 , true , " summary-string " , ' s ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeSummaryString , " Summary string used to display text and object contents. " } ,
{ LLDB_OPT_SET_3 , false , " python-script " , ' o ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypePythonScript , " Give a one-liner Python script as part of the command. " } ,
{ LLDB_OPT_SET_3 , false , " python-function " , ' F ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypePythonFunction , " Give the name of a Python function to use for this type. " } ,
{ LLDB_OPT_SET_3 , false , " input-python " , ' P ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Input Python code to use for this type manually. " } ,
{ LLDB_OPT_SET_2 | LLDB_OPT_SET_3 , false , " expand " , ' e ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Expand aggregate data types to show children on separate lines. " } ,
2015-12-30 06:55:28 -05:00
{ LLDB_OPT_SET_2 | LLDB_OPT_SET_3 , false , " hide-empty " , ' h ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Do not expand aggregate data types with no children. " } ,
2014-11-25 16:00:58 -05:00
{ LLDB_OPT_SET_2 | LLDB_OPT_SET_3 , false , " name " , ' n ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeName , " A name for this summary string. " } ,
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-08-23 13:46:38 -04:00
} ;
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryDelete
//-------------------------------------------------------------------------
2015-12-30 06:55:28 -05:00
class CommandObjectTypeSummaryDelete : public CommandObjectTypeFormatterDelete
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
public :
CommandObjectTypeSummaryDelete ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterDelete ( interpreter ,
eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary ,
" type summary delete " ,
" Delete an existing summary for a type. " )
{
}
~ CommandObjectTypeSummaryDelete ( ) override
{
}
protected :
bool
FormatterSpecificDeletion ( ConstString typeCS ) override
{
if ( m_options . m_language ! = lldb : : eLanguageTypeUnknown )
return false ;
return DataVisualization : : NamedSummaryFormats : : Delete ( typeCS ) ;
}
} ;
class CommandObjectTypeSummaryClear : public CommandObjectTypeFormatterClear
{
public :
CommandObjectTypeSummaryClear ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterClear ( interpreter ,
eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary ,
" type summary clear " ,
" Delete all existing summaries. " )
{
}
protected :
void
FormatterSpecificDeletion ( ) override
{
DataVisualization : : NamedSummaryFormats : : Clear ( ) ;
}
} ;
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryList
//-------------------------------------------------------------------------
class CommandObjectTypeSummaryList : public CommandObjectTypeFormatterList < TypeSummaryImpl >
{
public :
CommandObjectTypeSummaryList ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterList ( interpreter ,
" type summary list " ,
" Show a list of current summaries. " )
{
}
protected :
void
FormatterSpecificList ( CommandReturnObject & result ) override
{
if ( DataVisualization : : NamedSummaryFormats : : GetCount ( ) > 0 )
{
result . GetOutputStream ( ) . Printf ( " Named summaries: \n " ) ;
DataVisualization : : NamedSummaryFormats : : ForEach ( [ & result ] ( ConstString name , const TypeSummaryImplSP & summary_sp ) - > bool {
result . GetOutputStream ( ) . Printf ( " %s: %s \n " , name . AsCString ( ) , summary_sp - > GetDescription ( ) . c_str ( ) ) ;
return true ;
} ) ;
}
}
} ;
//-------------------------------------------------------------------------
// CommandObjectTypeCategoryDefine
//-------------------------------------------------------------------------
class CommandObjectTypeCategoryDefine : public CommandObjectParsed
{
2013-08-23 13:46:38 -04:00
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
2015-12-30 06:55:28 -05:00
Options ( interpreter ) ,
m_define_enabled ( false , false ) ,
m_cate_language ( eLanguageTypeUnknown , eLanguageTypeUnknown )
2013-08-23 13:46:38 -04:00
{
}
2015-12-30 06:55:28 -05:00
~ CommandOptions ( ) override { }
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-08-23 13:46:38 -04:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
2015-12-30 06:55:28 -05:00
case ' e ' :
m_define_enabled . SetValueFromString ( " true " ) ;
2013-08-23 13:46:38 -04:00
break ;
2015-12-30 06:55:28 -05:00
case ' l ' :
error = m_cate_language . SetValueFromString ( option_arg ) ;
2013-08-23 13:46:38 -04:00
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 06:55:28 -05:00
OptionParsingStarting ( ) override
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
m_define_enabled . Clear ( ) ;
m_cate_language . Clear ( ) ;
2013-08-23 13:46:38 -04:00
}
const OptionDefinition *
2015-12-30 06:55:28 -05:00
GetDefinitions ( ) override
2013-08-23 13:46:38 -04:00
{
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.
2015-12-30 06:55:28 -05:00
OptionValueBoolean m_define_enabled ;
OptionValueLanguage m_cate_language ;
2013-08-23 13:46:38 -04:00
} ;
CommandOptions m_options ;
2015-12-30 06:55:28 -05:00
Options *
GetOptions ( ) override
2013-08-23 13:46:38 -04:00
{
return & m_options ;
}
public :
2015-12-30 06:55:28 -05:00
CommandObjectTypeCategoryDefine ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" type category define " ,
" Define a new category as a source of formatters. " ,
NULL ) ,
m_options ( interpreter )
2013-08-23 13:46:38 -04:00
{
CommandArgumentEntry type_arg ;
CommandArgumentData type_style_arg ;
type_style_arg . arg_type = eArgTypeName ;
2015-12-30 06:55:28 -05:00
type_style_arg . arg_repetition = eArgRepeatPlus ;
2013-08-23 13:46:38 -04:00
type_arg . push_back ( type_style_arg ) ;
m_arguments . push_back ( type_arg ) ;
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeCategoryDefine ( ) override
2013-08-23 13:46:38 -04:00
{
}
protected :
bool
2015-12-30 06:55:28 -05:00
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 13:46:38 -04:00
{
const size_t argc = command . GetArgumentCount ( ) ;
2015-12-30 06:55:28 -05:00
if ( argc < 1 )
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
result . AppendErrorWithFormat ( " %s takes 1 or more args. \n " , m_cmd_name . c_str ( ) ) ;
2013-08-23 13:46:38 -04:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2015-12-30 06:55:28 -05:00
for ( size_t i = 0 ; i < argc ; i + + )
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
const char * cateName = command . GetArgumentAtIndex ( i ) ;
TypeCategoryImplSP category_sp ;
if ( DataVisualization : : Categories : : GetCategory ( ConstString ( cateName ) , category_sp ) & & category_sp )
{
category_sp - > AddLanguage ( m_options . m_cate_language . GetCurrentValue ( ) ) ;
if ( m_options . m_define_enabled . GetCurrentValue ( ) )
DataVisualization : : Categories : : Enable ( category_sp , TypeCategoryMap : : Default ) ;
}
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
return result . Succeeded ( ) ;
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
2013-08-23 13:46:38 -04:00
} ;
OptionDefinition
2015-12-30 06:55:28 -05:00
CommandObjectTypeCategoryDefine : : CommandOptions : : g_option_table [ ] =
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
{ LLDB_OPT_SET_ALL , false , " enabled " , ' e ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " If specified, this category will be created enabled. " } ,
{ LLDB_OPT_SET_ALL , false , " language " , ' l ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeLanguage , " Specify the language that this category is supported for. " } ,
2014-11-25 16:00:58 -05:00
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-08-23 13:46:38 -04:00
} ;
2015-12-30 06:55:28 -05:00
//-------------------------------------------------------------------------
// CommandObjectTypeCategoryEnable
//-------------------------------------------------------------------------
class CommandObjectTypeCategoryEnable : public CommandObjectParsed
2013-08-23 13:46:38 -04:00
{
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter )
{
}
2015-12-30 06:55:28 -05:00
~ CommandOptions ( ) override { }
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-08-23 13:46:38 -04:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
2015-12-30 06:55:28 -05:00
case ' l ' :
if ( option_arg )
{
m_language = Language : : GetLanguageTypeFromString ( option_arg ) ;
if ( m_language = = lldb : : eLanguageTypeUnknown )
error . SetErrorStringWithFormat ( " unrecognized language '%s' " , option_arg ) ;
}
2013-08-23 13:46:38 -04:00
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 06:55:28 -05:00
OptionParsingStarting ( ) override
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
m_language = lldb : : eLanguageTypeUnknown ;
2013-08-23 13:46:38 -04:00
}
const OptionDefinition *
2015-12-30 06:55:28 -05:00
GetDefinitions ( ) override
2013-08-23 13:46:38 -04:00
{
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.
2015-12-30 06:55:28 -05:00
lldb : : LanguageType m_language ;
2013-08-23 13:46:38 -04:00
} ;
CommandOptions m_options ;
2015-12-30 06:55:28 -05:00
Options *
GetOptions ( ) override
2013-08-23 13:46:38 -04:00
{
return & m_options ;
}
public :
2015-12-30 06:55:28 -05:00
CommandObjectTypeCategoryEnable ( CommandInterpreter & interpreter ) :
2013-08-23 13:46:38 -04:00
CommandObjectParsed ( interpreter ,
2015-12-30 06:55:28 -05:00
" type category enable " ,
" Enable a category as a source of formatters. " ,
2013-08-23 13:46:38 -04:00
NULL ) ,
m_options ( interpreter )
{
2015-12-30 06:55:28 -05:00
CommandArgumentEntry type_arg ;
CommandArgumentData type_style_arg ;
type_style_arg . arg_type = eArgTypeName ;
type_style_arg . arg_repetition = eArgRepeatPlus ;
type_arg . push_back ( type_style_arg ) ;
m_arguments . push_back ( type_arg ) ;
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeCategoryEnable ( ) override
2013-08-23 13:46:38 -04:00
{
}
protected :
bool
2015-12-30 06:55:28 -05:00
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
const size_t argc = command . GetArgumentCount ( ) ;
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
if ( argc < 1 & &
m_options . m_language = = lldb : : eLanguageTypeUnknown )
{
result . AppendErrorWithFormat ( " %s takes arguments and/or a language " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
if ( argc = = 1 & & strcmp ( command . GetArgumentAtIndex ( 0 ) , " * " ) = = 0 )
{
DataVisualization : : Categories : : EnableStar ( ) ;
}
else if ( argc > 0 )
{
for ( int i = argc - 1 ; i > = 0 ; i - - )
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
const char * typeA = command . GetArgumentAtIndex ( i ) ;
ConstString typeCS ( typeA ) ;
if ( ! typeCS )
{
result . AppendError ( " empty category name not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
DataVisualization : : Categories : : Enable ( typeCS ) ;
lldb : : TypeCategoryImplSP cate ;
if ( DataVisualization : : Categories : : GetCategory ( typeCS , cate ) & & cate . get ( ) )
{
if ( cate - > GetCount ( ) = = 0 )
{
result . AppendWarning ( " empty category enabled (typo?) " ) ;
}
}
2013-08-23 13:46:38 -04:00
}
}
2015-12-30 06:55:28 -05:00
if ( m_options . m_language ! = lldb : : eLanguageTypeUnknown )
DataVisualization : : Categories : : Enable ( m_options . m_language ) ;
2013-08-23 13:46:38 -04:00
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
return result . Succeeded ( ) ;
}
} ;
OptionDefinition
2015-12-30 06:55:28 -05:00
CommandObjectTypeCategoryEnable : : CommandOptions : : g_option_table [ ] =
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
{ LLDB_OPT_SET_ALL , false , " language " , ' l ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeLanguage , " Enable the category for this language. " } ,
2014-11-25 16:00:58 -05:00
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-08-23 13:46:38 -04:00
} ;
//-------------------------------------------------------------------------
2015-12-30 06:55:28 -05:00
// CommandObjectTypeCategoryDelete
2013-08-23 13:46:38 -04:00
//-------------------------------------------------------------------------
2015-12-30 06:55:28 -05:00
class CommandObjectTypeCategoryDelete : public CommandObjectParsed
{
public :
CommandObjectTypeCategoryDelete ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" type category delete " ,
" Delete a category and all associated formatters. " ,
NULL )
{
CommandArgumentEntry type_arg ;
CommandArgumentData type_style_arg ;
type_style_arg . arg_type = eArgTypeName ;
type_style_arg . arg_repetition = eArgRepeatPlus ;
type_arg . push_back ( type_style_arg ) ;
m_arguments . push_back ( type_arg ) ;
}
~ CommandObjectTypeCategoryDelete ( ) override
{
}
protected :
bool
DoExecute ( Args & command , CommandReturnObject & result ) override
{
const size_t argc = command . GetArgumentCount ( ) ;
if ( argc < 1 )
{
result . AppendErrorWithFormat ( " %s takes 1 or more arg. \n " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
bool success = true ;
// the order is not relevant here
for ( int i = argc - 1 ; i > = 0 ; i - - )
{
const char * typeA = command . GetArgumentAtIndex ( i ) ;
ConstString typeCS ( typeA ) ;
if ( ! typeCS )
{
result . AppendError ( " empty category name not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( ! DataVisualization : : Categories : : Delete ( typeCS ) )
success = false ; // keep deleting even if we hit an error
}
if ( success )
{
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
return result . Succeeded ( ) ;
}
else
{
result . AppendError ( " cannot delete one or more categories \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
2013-08-23 13:46:38 -04:00
} ;
2015-12-30 06:55:28 -05:00
//-------------------------------------------------------------------------
// CommandObjectTypeCategoryDisable
//-------------------------------------------------------------------------
class CommandObjectTypeCategoryDisable : public CommandObjectParsed
2013-08-23 13:46:38 -04:00
{
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter )
{
}
2015-12-30 06:55:28 -05:00
~ CommandOptions ( ) override { }
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-08-23 13:46:38 -04:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
2015-12-30 06:55:28 -05:00
case ' l ' :
if ( option_arg )
{
m_language = Language : : GetLanguageTypeFromString ( option_arg ) ;
if ( m_language = = lldb : : eLanguageTypeUnknown )
error . SetErrorStringWithFormat ( " unrecognized language '%s' " , option_arg ) ;
}
2013-08-23 13:46:38 -04:00
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 06:55:28 -05:00
OptionParsingStarting ( ) override
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
m_language = lldb : : eLanguageTypeUnknown ;
2013-08-23 13:46:38 -04:00
}
const OptionDefinition *
2015-12-30 06:55:28 -05:00
GetDefinitions ( ) override
2013-08-23 13:46:38 -04:00
{
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.
2015-12-30 06:55:28 -05:00
lldb : : LanguageType m_language ;
2013-08-23 13:46:38 -04:00
} ;
CommandOptions m_options ;
2015-12-30 06:55:28 -05:00
Options *
GetOptions ( ) override
2013-08-23 13:46:38 -04:00
{
return & m_options ;
}
2015-12-30 06:55:28 -05:00
2013-08-23 13:46:38 -04:00
public :
2015-12-30 06:55:28 -05:00
CommandObjectTypeCategoryDisable ( CommandInterpreter & interpreter ) :
2013-08-23 13:46:38 -04:00
CommandObjectParsed ( interpreter ,
2015-12-30 06:55:28 -05:00
" type category disable " ,
" Disable a category as a source of formatters. " ,
2013-08-23 13:46:38 -04:00
NULL ) ,
m_options ( interpreter )
{
CommandArgumentEntry type_arg ;
CommandArgumentData type_style_arg ;
type_style_arg . arg_type = eArgTypeName ;
2015-12-30 06:55:28 -05:00
type_style_arg . arg_repetition = eArgRepeatPlus ;
2013-08-23 13:46:38 -04:00
type_arg . push_back ( type_style_arg ) ;
m_arguments . push_back ( type_arg ) ;
2015-12-30 06:55:28 -05:00
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeCategoryDisable ( ) override
2013-08-23 13:46:38 -04:00
{
}
protected :
bool
2015-12-30 06:55:28 -05:00
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 13:46:38 -04:00
{
const size_t argc = command . GetArgumentCount ( ) ;
2015-12-30 06:55:28 -05:00
if ( argc < 1 & &
m_options . m_language = = lldb : : eLanguageTypeUnknown )
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
result . AppendErrorWithFormat ( " %s takes arguments and/or a language " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
if ( argc = = 1 & & strcmp ( command . GetArgumentAtIndex ( 0 ) , " * " ) = = 0 )
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
DataVisualization : : Categories : : DisableStar ( ) ;
}
else if ( argc > 0 )
{
// the order is not relevant here
for ( int i = argc - 1 ; i > = 0 ; i - - )
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
const char * typeA = command . GetArgumentAtIndex ( i ) ;
ConstString typeCS ( typeA ) ;
if ( ! typeCS )
{
result . AppendError ( " empty category name not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
DataVisualization : : Categories : : Disable ( typeCS ) ;
2013-08-23 13:46:38 -04:00
}
}
2015-12-30 06:55:28 -05:00
if ( m_options . m_language ! = lldb : : eLanguageTypeUnknown )
DataVisualization : : Categories : : Disable ( m_options . m_language ) ;
2013-08-23 13:46:38 -04:00
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
return result . Succeeded ( ) ;
}
} ;
OptionDefinition
2015-12-30 06:55:28 -05:00
CommandObjectTypeCategoryDisable : : CommandOptions : : g_option_table [ ] =
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
{ LLDB_OPT_SET_ALL , false , " language " , ' l ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeLanguage , " Enable the category for this language. " } ,
2014-11-25 16:00:58 -05:00
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-08-23 13:46:38 -04:00
} ;
//-------------------------------------------------------------------------
// CommandObjectTypeCategoryList
//-------------------------------------------------------------------------
class CommandObjectTypeCategoryList : public CommandObjectParsed
{
public :
CommandObjectTypeCategoryList ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" type category list " ,
" Provide a list of all existing categories. " ,
NULL )
{
CommandArgumentEntry type_arg ;
CommandArgumentData type_style_arg ;
type_style_arg . arg_type = eArgTypeName ;
type_style_arg . arg_repetition = eArgRepeatOptional ;
type_arg . push_back ( type_style_arg ) ;
m_arguments . push_back ( type_arg ) ;
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeCategoryList ( ) override
2013-08-23 13:46:38 -04:00
{
}
protected :
bool
2015-12-30 06:55:28 -05:00
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 13:46:38 -04:00
{
const size_t argc = command . GetArgumentCount ( ) ;
2015-12-30 06:55:28 -05:00
std : : unique_ptr < RegularExpression > regex ;
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
if ( argc = = 1 )
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
regex . reset ( new RegularExpression ( ) ) ;
const char * arg = command . GetArgumentAtIndex ( 0 ) ;
if ( ! regex - > Compile ( arg ) )
{
result . AppendErrorWithFormat ( " syntax error in category regular expression '%s' " , arg ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
else if ( argc ! = 0 )
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
result . AppendErrorWithFormat ( " %s takes 0 or one arg. \n " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
DataVisualization : : Categories : : ForEach ( [ & regex , & result ] ( const lldb : : TypeCategoryImplSP & category_sp ) - > bool {
if ( regex )
{
bool escape = true ;
if ( 0 = = strcmp ( category_sp - > GetName ( ) , regex - > GetText ( ) ) )
{
escape = false ;
}
else if ( regex - > Execute ( category_sp - > GetName ( ) ) )
{
escape = false ;
}
if ( escape )
return true ;
}
result . GetOutputStream ( ) . Printf ( " Category: %s \n " , category_sp - > GetDescription ( ) . c_str ( ) ) ;
return true ;
} ) ;
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
return result . Succeeded ( ) ;
}
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
} ;
//-------------------------------------------------------------------------
// CommandObjectTypeFilterList
//-------------------------------------------------------------------------
class CommandObjectTypeFilterList : public CommandObjectTypeFormatterList < TypeFilterImpl >
{
public :
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
CommandObjectTypeFilterList ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterList ( interpreter ,
" type filter list " ,
" Show a list of current filters. " )
2013-08-23 13:46:38 -04:00
{
}
2015-12-30 06:55:28 -05:00
} ;
# ifndef LLDB_DISABLE_PYTHON
//-------------------------------------------------------------------------
// CommandObjectTypeSynthList
//-------------------------------------------------------------------------
class CommandObjectTypeSynthList : public CommandObjectTypeFormatterList < SyntheticChildren >
{
public :
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
CommandObjectTypeSynthList ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterList ( interpreter ,
" type synthetic list " ,
" Show a list of current synthetic providers. " )
2013-08-23 13:46:38 -04:00
{
}
2015-12-30 06:55:28 -05:00
} ;
# endif // #ifndef LLDB_DISABLE_PYTHON
//-------------------------------------------------------------------------
// CommandObjectTypeFilterDelete
//-------------------------------------------------------------------------
class CommandObjectTypeFilterDelete : public CommandObjectTypeFormatterDelete
{
2013-08-23 13:46:38 -04:00
public :
2015-12-30 06:55:28 -05:00
CommandObjectTypeFilterDelete ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterDelete ( interpreter ,
eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter ,
" type filter delete " ,
" Delete an existing filter for a type. " )
2013-08-23 13:46:38 -04:00
{
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeFilterDelete ( ) override
2013-08-23 13:46:38 -04:00
{
}
2015-12-30 06:55:28 -05:00
} ;
# ifndef LLDB_DISABLE_PYTHON
//-------------------------------------------------------------------------
// CommandObjectTypeSynthDelete
//-------------------------------------------------------------------------
class CommandObjectTypeSynthDelete : public CommandObjectTypeFormatterDelete
{
public :
CommandObjectTypeSynthDelete ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterDelete ( interpreter ,
eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth ,
" type synthetic delete " ,
" Delete an existing synthetic provider for a type. " )
2013-08-23 13:46:38 -04:00
{
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeSynthDelete ( ) override
{
}
2013-08-23 13:46:38 -04:00
} ;
2015-12-30 06:55:28 -05:00
# endif // #ifndef LLDB_DISABLE_PYTHON
//-------------------------------------------------------------------------
// CommandObjectTypeFilterClear
//-------------------------------------------------------------------------
class CommandObjectTypeFilterClear : public CommandObjectTypeFormatterClear
2013-08-23 13:46:38 -04:00
{
2015-12-30 06:55:28 -05:00
public :
CommandObjectTypeFilterClear ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterClear ( interpreter ,
eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter ,
" type filter clear " ,
" Delete all existing filter. " )
{
}
2013-08-23 13:46:38 -04:00
} ;
2015-12-30 06:55:28 -05:00
# ifndef LLDB_DISABLE_PYTHON
//-------------------------------------------------------------------------
// CommandObjectTypeSynthClear
//-------------------------------------------------------------------------
class CommandObjectTypeSynthClear : public CommandObjectTypeFormatterClear
{
public :
CommandObjectTypeSynthClear ( CommandInterpreter & interpreter ) :
CommandObjectTypeFormatterClear ( interpreter ,
eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth ,
" type synthetic clear " ,
" Delete all existing synthetic providers. " )
{
}
} ;
2013-08-23 13:46:38 -04:00
bool
CommandObjectTypeSynthAdd : : Execute_HandwritePython ( Args & command , CommandReturnObject & result )
{
SynthAddOptions * options = new SynthAddOptions ( m_options . m_skip_pointers ,
m_options . m_skip_references ,
m_options . m_cascade ,
m_options . m_regex ,
m_options . m_category ) ;
const size_t argc = command . GetArgumentCount ( ) ;
for ( size_t i = 0 ; i < argc ; i + + )
{
const char * typeA = command . GetArgumentAtIndex ( i ) ;
if ( typeA & & * typeA )
options - > m_target_types < < typeA ;
else
{
result . AppendError ( " empty typenames not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
2014-02-18 11:23:10 -05:00
m_interpreter . GetPythonCommandsFromIOHandler ( " " , // Prompt
* this , // IOHandlerDelegate
true , // Run IOHandler in async mode
options ) ; // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
2013-08-23 13:46:38 -04:00
return result . Succeeded ( ) ;
}
bool
CommandObjectTypeSynthAdd : : Execute_PythonClass ( Args & command , CommandReturnObject & result )
{
const size_t argc = command . GetArgumentCount ( ) ;
if ( argc < 1 )
{
result . AppendErrorWithFormat ( " %s takes one or more args. \n " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( m_options . m_class_name . empty ( ) & & ! m_options . m_input_python )
{
result . AppendErrorWithFormat ( " %s needs either a Python class name or -P to directly input Python code. \n " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
SyntheticChildrenSP entry ;
ScriptedSyntheticChildren * impl = new ScriptedSyntheticChildren ( SyntheticChildren : : Flags ( ) .
SetCascades ( m_options . m_cascade ) .
SetSkipPointers ( m_options . m_skip_pointers ) .
SetSkipReferences ( m_options . m_skip_references ) ,
m_options . m_class_name . c_str ( ) ) ;
entry . reset ( impl ) ;
ScriptInterpreter * interpreter = m_interpreter . GetScriptInterpreter ( ) ;
if ( interpreter & & interpreter - > CheckObjectExists ( impl - > GetPythonClassName ( ) ) = = false )
result . AppendWarning ( " The provided class does not exist - please define it before attempting to use this synthetic provider " ) ;
// now I have a valid provider, let's add it to every type
lldb : : TypeCategoryImplSP category ;
DataVisualization : : Categories : : GetCategory ( ConstString ( m_options . m_category . c_str ( ) ) , category ) ;
Error error ;
for ( size_t i = 0 ; i < argc ; i + + )
{
const char * typeA = command . GetArgumentAtIndex ( i ) ;
ConstString typeCS ( typeA ) ;
if ( typeCS )
{
if ( ! AddSynth ( typeCS ,
entry ,
m_options . m_regex ? eRegexSynth : eRegularSynth ,
m_options . m_category ,
& error ) )
{
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
else
{
result . AppendError ( " empty typenames not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
return result . Succeeded ( ) ;
}
CommandObjectTypeSynthAdd : : CommandObjectTypeSynthAdd ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" type synthetic add " ,
" Add a new synthetic provider for a type. " ,
NULL ) ,
2014-02-18 11:23:10 -05:00
IOHandlerDelegateMultiline ( " DONE " ) ,
2013-08-23 13:46:38 -04:00
m_options ( interpreter )
{
CommandArgumentEntry type_arg ;
CommandArgumentData type_style_arg ;
type_style_arg . arg_type = eArgTypeName ;
type_style_arg . arg_repetition = eArgRepeatPlus ;
type_arg . push_back ( type_style_arg ) ;
m_arguments . push_back ( type_arg ) ;
}
bool
CommandObjectTypeSynthAdd : : AddSynth ( ConstString type_name ,
SyntheticChildrenSP entry ,
SynthFormatType type ,
std : : string category_name ,
Error * error )
{
lldb : : TypeCategoryImplSP category ;
DataVisualization : : Categories : : GetCategory ( ConstString ( category_name . c_str ( ) ) , category ) ;
if ( type = = eRegularSynth )
{
2014-11-25 16:00:58 -05:00
if ( FixArrayTypeNameWithRegex ( type_name ) )
type = eRegexSynth ;
2013-08-23 13:46:38 -04:00
}
if ( category - > AnyMatches ( type_name ,
eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter ,
false ) )
{
if ( error )
error - > SetErrorStringWithFormat ( " cannot add synthetic for type %s when filter is defined in same category! " , type_name . AsCString ( ) ) ;
return false ;
}
if ( type = = eRegexSynth )
{
RegularExpressionSP typeRX ( new RegularExpression ( ) ) ;
if ( ! typeRX - > Compile ( type_name . GetCString ( ) ) )
{
if ( error )
error - > SetErrorString ( " regex format error (maybe this is not really a regex?) " ) ;
return false ;
}
2014-02-18 11:23:10 -05:00
category - > GetRegexTypeSyntheticsContainer ( ) - > Delete ( type_name ) ;
category - > GetRegexTypeSyntheticsContainer ( ) - > Add ( typeRX , entry ) ;
2013-08-23 13:46:38 -04:00
return true ;
}
else
{
2014-02-18 11:23:10 -05:00
category - > GetTypeSyntheticsContainer ( ) - > Add ( type_name , entry ) ;
2013-08-23 13:46:38 -04:00
return true ;
}
}
OptionDefinition
CommandObjectTypeSynthAdd : : CommandOptions : : g_option_table [ ] =
{
2014-11-25 16:00:58 -05:00
{ LLDB_OPT_SET_ALL , false , " cascade " , ' C ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBoolean , " If true, cascade through typedef chains. " } ,
{ LLDB_OPT_SET_ALL , false , " skip-pointers " , ' p ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Don't use this format for pointers-to-type objects. " } ,
2015-12-30 06:55:28 -05:00
{ LLDB_OPT_SET_ALL , false , " skip-references " , ' r ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Don't use this format for references-to-type objects. " } ,
2014-11-25 16:00:58 -05:00
{ LLDB_OPT_SET_ALL , false , " category " , ' w ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeName , " Add this to the given category instead of the default one. " } ,
{ LLDB_OPT_SET_2 , false , " python-class " , ' l ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypePythonClass , " Use this Python class to produce synthetic children. " } ,
2015-12-30 06:55:28 -05:00
{ LLDB_OPT_SET_3 , false , " input-python " , ' P ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Type Python code to generate a class that provides synthetic children. " } ,
2014-11-25 16:00:58 -05:00
{ LLDB_OPT_SET_ALL , false , " regex " , ' x ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Type names are actually regular expressions. " } ,
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-08-23 13:46:38 -04:00
} ;
# endif // #ifndef LLDB_DISABLE_PYTHON
class CommandObjectTypeFilterAdd : public CommandObjectParsed
{
private :
class CommandOptions : public Options
{
typedef std : : vector < std : : string > option_vector ;
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter )
{
}
2015-12-30 06:55:28 -05:00
~ CommandOptions ( ) override { }
2013-08-23 13:46:38 -04:00
2015-12-30 06:55:28 -05:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-08-23 13:46:38 -04:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
bool success ;
switch ( short_option )
{
case ' C ' :
m_cascade = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( ! success )
error . SetErrorStringWithFormat ( " invalid value for cascade: %s " , option_arg ) ;
break ;
case ' c ' :
m_expr_paths . push_back ( option_arg ) ;
has_child_list = true ;
break ;
case ' p ' :
m_skip_pointers = true ;
break ;
case ' r ' :
m_skip_references = true ;
break ;
case ' w ' :
m_category = std : : string ( option_arg ) ;
break ;
case ' x ' :
m_regex = true ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 06:55:28 -05:00
OptionParsingStarting ( ) override
2013-08-23 13:46:38 -04:00
{
m_cascade = true ;
m_skip_pointers = false ;
m_skip_references = false ;
m_category = " default " ;
m_expr_paths . clear ( ) ;
has_child_list = false ;
m_regex = false ;
}
const OptionDefinition *
2015-12-30 06:55:28 -05:00
GetDefinitions ( ) override
2013-08-23 13:46:38 -04:00
{
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_cascade ;
bool m_skip_references ;
bool m_skip_pointers ;
bool m_input_python ;
option_vector m_expr_paths ;
std : : string m_category ;
bool has_child_list ;
bool m_regex ;
typedef option_vector : : iterator ExpressionPathsIterator ;
} ;
CommandOptions m_options ;
2015-12-30 06:55:28 -05:00
Options *
GetOptions ( ) override
2013-08-23 13:46:38 -04:00
{
return & m_options ;
}
enum FilterFormatType
{
eRegularFilter ,
eRegexFilter
} ;
bool
AddFilter ( ConstString type_name ,
2015-12-30 06:55:28 -05:00
TypeFilterImplSP entry ,
2013-08-23 13:46:38 -04:00
FilterFormatType type ,
std : : string category_name ,
Error * error )
{
lldb : : TypeCategoryImplSP category ;
DataVisualization : : Categories : : GetCategory ( ConstString ( category_name . c_str ( ) ) , category ) ;
if ( type = = eRegularFilter )
{
2014-11-25 16:00:58 -05:00
if ( FixArrayTypeNameWithRegex ( type_name ) )
2013-08-23 13:46:38 -04:00
type = eRegexFilter ;
}
if ( category - > AnyMatches ( type_name ,
eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth ,
false ) )
{
if ( error )
error - > SetErrorStringWithFormat ( " cannot add filter for type %s when synthetic is defined in same category! " , type_name . AsCString ( ) ) ;
return false ;
}
if ( type = = eRegexFilter )
{
RegularExpressionSP typeRX ( new RegularExpression ( ) ) ;
if ( ! typeRX - > Compile ( type_name . GetCString ( ) ) )
{
if ( error )
error - > SetErrorString ( " regex format error (maybe this is not really a regex?) " ) ;
return false ;
}
2014-02-18 11:23:10 -05:00
category - > GetRegexTypeFiltersContainer ( ) - > Delete ( type_name ) ;
category - > GetRegexTypeFiltersContainer ( ) - > Add ( typeRX , entry ) ;
2013-08-23 13:46:38 -04:00
return true ;
}
else
{
2014-02-18 11:23:10 -05:00
category - > GetTypeFiltersContainer ( ) - > Add ( type_name , entry ) ;
2013-08-23 13:46:38 -04:00
return true ;
}
}
public :
CommandObjectTypeFilterAdd ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" type filter add " ,
" Add a new filter for a type. " ,
NULL ) ,
m_options ( interpreter )
{
CommandArgumentEntry type_arg ;
CommandArgumentData type_style_arg ;
type_style_arg . arg_type = eArgTypeName ;
type_style_arg . arg_repetition = eArgRepeatPlus ;
type_arg . push_back ( type_style_arg ) ;
m_arguments . push_back ( type_arg ) ;
SetHelpLong (
2015-09-06 10:32:30 -04:00
R " (
The following examples of ' type filter add ' refer to this code snippet for context :
class Foo {
int a ;
int b ;
int c ;
int d ;
int e ;
int f ;
int g ;
int h ;
int i ;
}
Foo my_foo ;
Adding a simple filter :
( lldb ) type filter add - - child a - - child g Foo
( lldb ) frame variable my_foo
) " " Produces output where only a and g are displayed . Other children of my_foo \
( b , c , d , e , f , h and i ) are available by asking for them explicitly : " R " (
( lldb ) frame variable my_foo . b my_foo . c my_foo . i
) " " The formatting option - - raw on frame variable bypasses the filter , showing \
all children of my_foo as if no filter was defined : " R " (
( lldb ) frame variable my_foo - - raw ) "
) ;
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeFilterAdd ( ) override
2013-08-23 13:46:38 -04:00
{
}
protected :
bool
2015-12-30 06:55:28 -05:00
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 13:46:38 -04:00
{
const size_t argc = command . GetArgumentCount ( ) ;
if ( argc < 1 )
{
result . AppendErrorWithFormat ( " %s takes one or more args. \n " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( m_options . m_expr_paths . size ( ) = = 0 )
{
result . AppendErrorWithFormat ( " %s needs one or more children. \n " , m_cmd_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2015-12-30 06:55:28 -05:00
TypeFilterImplSP entry ( new TypeFilterImpl ( SyntheticChildren : : Flags ( ) . SetCascades ( m_options . m_cascade ) .
SetSkipPointers ( m_options . m_skip_pointers ) .
SetSkipReferences ( m_options . m_skip_references ) ) ) ;
2013-08-23 13:46:38 -04:00
// go through the expression paths
CommandOptions : : ExpressionPathsIterator begin , end = m_options . m_expr_paths . end ( ) ;
for ( begin = m_options . m_expr_paths . begin ( ) ; begin ! = end ; begin + + )
2015-12-30 06:55:28 -05:00
entry - > AddExpressionPath ( * begin ) ;
2013-08-23 13:46:38 -04:00
// now I have a valid provider, let's add it to every type
lldb : : TypeCategoryImplSP category ;
DataVisualization : : Categories : : GetCategory ( ConstString ( m_options . m_category . c_str ( ) ) , category ) ;
Error error ;
2014-02-18 11:23:10 -05:00
WarnOnPotentialUnquotedUnsignedType ( command , result ) ;
2013-08-23 13:46:38 -04:00
for ( size_t i = 0 ; i < argc ; i + + )
{
const char * typeA = command . GetArgumentAtIndex ( i ) ;
ConstString typeCS ( typeA ) ;
if ( typeCS )
{
if ( ! AddFilter ( typeCS ,
entry ,
m_options . m_regex ? eRegexFilter : eRegularFilter ,
m_options . m_category ,
& error ) )
{
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
else
{
result . AppendError ( " empty typenames not allowed " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
return result . Succeeded ( ) ;
}
} ;
OptionDefinition
CommandObjectTypeFilterAdd : : CommandOptions : : g_option_table [ ] =
{
2014-11-25 16:00:58 -05:00
{ LLDB_OPT_SET_ALL , false , " cascade " , ' C ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBoolean , " If true, cascade through typedef chains. " } ,
{ LLDB_OPT_SET_ALL , false , " skip-pointers " , ' p ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Don't use this format for pointers-to-type objects. " } ,
{ LLDB_OPT_SET_ALL , false , " skip-references " , ' r ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Don't use this format for references-to-type objects. " } ,
{ LLDB_OPT_SET_ALL , false , " category " , ' w ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeName , " Add this to the given category instead of the default one. " } ,
{ LLDB_OPT_SET_ALL , false , " child " , ' c ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeExpressionPath , " Include this expression path in the synthetic view. " } ,
{ LLDB_OPT_SET_ALL , false , " regex " , ' x ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Type names are actually regular expressions. " } ,
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-08-23 13:46:38 -04:00
} ;
2015-12-30 06:55:28 -05:00
//----------------------------------------------------------------------
// "type lookup"
//----------------------------------------------------------------------
class CommandObjectTypeLookup : public CommandObjectRaw
{
protected :
class CommandOptions : public OptionGroup
{
public :
CommandOptions ( ) :
OptionGroup ( ) ,
m_show_help ( false ) ,
m_language ( eLanguageTypeUnknown )
{ }
~ CommandOptions ( ) override { }
uint32_t
GetNumDefinitions ( ) override
{
return 3 ;
}
const OptionDefinition *
GetDefinitions ( ) override
{
return g_option_table ;
}
Error
SetOptionValue ( CommandInterpreter & interpreter ,
uint32_t option_idx ,
const char * option_value ) override
{
Error error ;
const int short_option = g_option_table [ option_idx ] . short_option ;
switch ( short_option )
{
case ' h ' :
m_show_help = true ;
break ;
case ' l ' :
m_language = Language : : GetLanguageTypeFromString ( option_value ) ;
break ;
default :
error . SetErrorStringWithFormat ( " invalid short option character '%c' " , short_option ) ;
break ;
}
return error ;
}
void
OptionParsingStarting ( CommandInterpreter & interpreter ) override
{
m_show_help = false ;
m_language = eLanguageTypeUnknown ;
}
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
bool m_show_help ;
lldb : : LanguageType m_language ;
} ;
OptionGroupOptions m_option_group ;
CommandOptions m_command_options ;
public :
CommandObjectTypeLookup ( CommandInterpreter & interpreter ) :
CommandObjectRaw ( interpreter ,
" type lookup " ,
" Lookup a type by name in the select target. " ,
" type lookup <typename> " ,
eCommandRequiresTarget ) ,
m_option_group ( interpreter ) ,
m_command_options ( )
{
m_option_group . Append ( & m_command_options ) ;
m_option_group . Finalize ( ) ;
}
~ CommandObjectTypeLookup ( ) override
{
}
Options *
GetOptions ( ) override
{
return & m_option_group ;
}
bool
DoExecute ( const char * raw_command_line , CommandReturnObject & result ) override
{
if ( ! raw_command_line | | ! raw_command_line [ 0 ] )
{
result . SetError ( " type lookup cannot be invoked without a type name as argument " ) ;
return false ;
}
m_option_group . NotifyOptionParsingStarting ( ) ;
const char * name_of_type = NULL ;
if ( raw_command_line [ 0 ] = = ' - ' )
{
// We have some options and these options MUST end with --.
const char * end_options = NULL ;
const char * s = raw_command_line ;
while ( s & & s [ 0 ] )
{
end_options = : : strstr ( s , " -- " ) ;
if ( end_options )
{
end_options + = 2 ; // Get past the "--"
if ( : : isspace ( end_options [ 0 ] ) )
{
name_of_type = end_options ;
while ( : : isspace ( * name_of_type ) )
+ + name_of_type ;
break ;
}
}
s = end_options ;
}
if ( end_options )
{
Args args ( llvm : : StringRef ( raw_command_line , end_options - raw_command_line ) ) ;
if ( ! ParseOptions ( args , result ) )
return false ;
Error error ( m_option_group . NotifyOptionParsingFinished ( ) ) ;
if ( error . Fail ( ) )
{
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
}
if ( nullptr = = name_of_type )
name_of_type = raw_command_line ;
TargetSP target_sp ( GetCommandInterpreter ( ) . GetDebugger ( ) . GetSelectedTarget ( ) ) ;
const bool fill_all_in = true ;
ExecutionContext exe_ctx ( target_sp . get ( ) , fill_all_in ) ;
ExecutionContextScope * best_scope = exe_ctx . GetBestExecutionContextScope ( ) ;
bool any_found = false ;
std : : vector < Language * > languages ;
if ( m_command_options . m_language = = eLanguageTypeUnknown )
{
// FIXME: hardcoding languages is not good
languages . push_back ( Language : : FindPlugin ( eLanguageTypeObjC ) ) ;
languages . push_back ( Language : : FindPlugin ( eLanguageTypeC_plus_plus ) ) ;
}
else
{
languages . push_back ( Language : : FindPlugin ( m_command_options . m_language ) ) ;
}
for ( Language * language : languages )
{
if ( ! language )
continue ;
if ( auto scavenger = language - > GetTypeScavenger ( ) )
{
Language : : TypeScavenger : : ResultSet search_results ;
if ( scavenger - > Find ( best_scope , name_of_type , search_results ) > 0 )
{
for ( const auto & search_result : search_results )
{
if ( search_result & & search_result - > IsValid ( ) )
{
any_found = true ;
search_result - > DumpToStream ( result . GetOutputStream ( ) , this - > m_command_options . m_show_help ) ;
}
}
}
}
}
result . SetStatus ( any_found ? lldb : : eReturnStatusSuccessFinishResult : lldb : : eReturnStatusSuccessFinishNoResult ) ;
return true ;
}
} ;
OptionDefinition
CommandObjectTypeLookup : : CommandOptions : : g_option_table [ ] =
{
{ LLDB_OPT_SET_ALL , false , " show-help " , ' h ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Display available help for types " } ,
{ LLDB_OPT_SET_ALL , false , " language " , ' l ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeLanguage , " Which language's types should the search scope be " } ,
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
} ;
2015-02-06 16:38:51 -05:00
template < typename FormatterType >
class CommandObjectFormatterInfo : public CommandObjectRaw
{
public :
typedef std : : function < typename FormatterType : : SharedPointer ( ValueObject & ) > DiscoveryFunction ;
CommandObjectFormatterInfo ( CommandInterpreter & interpreter ,
const char * formatter_name ,
DiscoveryFunction discovery_func ) :
CommandObjectRaw ( interpreter ,
nullptr ,
nullptr ,
nullptr ,
2015-07-03 12:57:06 -04:00
eCommandRequiresFrame ) ,
2015-02-06 16:38:51 -05:00
m_formatter_name ( formatter_name ? formatter_name : " " ) ,
m_discovery_function ( discovery_func )
{
StreamString name ;
name . Printf ( " type %s info " , formatter_name ) ;
SetCommandName ( name . GetData ( ) ) ;
StreamString help ;
help . Printf ( " This command evaluates the provided expression and shows which %s is applied to the resulting value (if any). " , formatter_name ) ;
SetHelp ( help . GetData ( ) ) ;
StreamString syntax ;
syntax . Printf ( " type %s info <expr> " , formatter_name ) ;
SetSyntax ( syntax . GetData ( ) ) ;
}
2015-12-30 06:55:28 -05:00
~ CommandObjectFormatterInfo ( ) override
2015-02-06 16:38:51 -05:00
{
}
protected :
2015-12-30 06:55:28 -05:00
bool
DoExecute ( const char * command , CommandReturnObject & result ) override
2015-02-06 16:38:51 -05:00
{
auto target_sp = m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) ;
auto frame_sp = target_sp - > GetProcessSP ( ) - > GetThreadList ( ) . GetSelectedThread ( ) - > GetSelectedFrame ( ) ;
ValueObjectSP result_valobj_sp ;
EvaluateExpressionOptions options ;
lldb : : ExpressionResults expr_result = target_sp - > EvaluateExpression ( command , frame_sp . get ( ) , result_valobj_sp , options ) ;
if ( expr_result = = eExpressionCompleted & & result_valobj_sp )
{
result_valobj_sp = result_valobj_sp - > GetQualifiedRepresentationIfAvailable ( target_sp - > GetPreferDynamicValue ( ) , target_sp - > GetEnableSyntheticValue ( ) ) ;
typename FormatterType : : SharedPointer formatter_sp = m_discovery_function ( * result_valobj_sp ) ;
if ( formatter_sp )
{
std : : string description ( formatter_sp - > GetDescription ( ) ) ;
result . AppendMessageWithFormat ( " %s applied to (%s) %s is: %s \n " ,
m_formatter_name . c_str ( ) ,
result_valobj_sp - > GetDisplayTypeName ( ) . AsCString ( " <unknown> " ) ,
command ,
description . c_str ( ) ) ;
result . SetStatus ( lldb : : eReturnStatusSuccessFinishResult ) ;
}
else
{
result . AppendMessageWithFormat ( " no %s applies to (%s) %s \n " ,
m_formatter_name . c_str ( ) ,
result_valobj_sp - > GetDisplayTypeName ( ) . AsCString ( " <unknown> " ) ,
command ) ;
result . SetStatus ( lldb : : eReturnStatusSuccessFinishNoResult ) ;
}
return true ;
}
else
{
result . AppendError ( " failed to evaluate expression " ) ;
result . SetStatus ( lldb : : eReturnStatusFailed ) ;
return false ;
}
}
private :
std : : string m_formatter_name ;
DiscoveryFunction m_discovery_function ;
} ;
2013-08-23 13:46:38 -04:00
class CommandObjectTypeFormat : public CommandObjectMultiword
{
public :
CommandObjectTypeFormat ( CommandInterpreter & interpreter ) :
CommandObjectMultiword ( interpreter ,
" type format " ,
" A set of commands for editing variable value display options " ,
" type format [<sub-command-options>] " )
{
LoadSubCommand ( " add " , CommandObjectSP ( new CommandObjectTypeFormatAdd ( interpreter ) ) ) ;
LoadSubCommand ( " clear " , CommandObjectSP ( new CommandObjectTypeFormatClear ( interpreter ) ) ) ;
LoadSubCommand ( " delete " , CommandObjectSP ( new CommandObjectTypeFormatDelete ( interpreter ) ) ) ;
LoadSubCommand ( " list " , CommandObjectSP ( new CommandObjectTypeFormatList ( interpreter ) ) ) ;
2015-02-06 16:38:51 -05:00
LoadSubCommand ( " info " , CommandObjectSP ( new CommandObjectFormatterInfo < TypeFormatImpl > ( interpreter ,
" format " ,
[ ] ( ValueObject & valobj ) - > TypeFormatImpl : : SharedPointer {
return valobj . GetValueFormat ( ) ;
} ) ) ) ;
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeFormat ( ) override
2013-08-23 13:46:38 -04:00
{
}
} ;
# ifndef LLDB_DISABLE_PYTHON
class CommandObjectTypeSynth : public CommandObjectMultiword
{
public :
CommandObjectTypeSynth ( CommandInterpreter & interpreter ) :
CommandObjectMultiword ( interpreter ,
" type synthetic " ,
" A set of commands for operating on synthetic type representations " ,
" type synthetic [<sub-command-options>] " )
{
LoadSubCommand ( " add " , CommandObjectSP ( new CommandObjectTypeSynthAdd ( interpreter ) ) ) ;
LoadSubCommand ( " clear " , CommandObjectSP ( new CommandObjectTypeSynthClear ( interpreter ) ) ) ;
LoadSubCommand ( " delete " , CommandObjectSP ( new CommandObjectTypeSynthDelete ( interpreter ) ) ) ;
LoadSubCommand ( " list " , CommandObjectSP ( new CommandObjectTypeSynthList ( interpreter ) ) ) ;
2015-02-06 16:38:51 -05:00
LoadSubCommand ( " info " , CommandObjectSP ( new CommandObjectFormatterInfo < SyntheticChildren > ( interpreter ,
" synthetic " ,
[ ] ( ValueObject & valobj ) - > SyntheticChildren : : SharedPointer {
return valobj . GetSyntheticChildren ( ) ;
} ) ) ) ;
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeSynth ( ) override
2013-08-23 13:46:38 -04:00
{
}
} ;
# endif // #ifndef LLDB_DISABLE_PYTHON
class CommandObjectTypeFilter : public CommandObjectMultiword
{
public :
CommandObjectTypeFilter ( CommandInterpreter & interpreter ) :
CommandObjectMultiword ( interpreter ,
" type filter " ,
" A set of commands for operating on type filters " ,
" type synthetic [<sub-command-options>] " )
{
LoadSubCommand ( " add " , CommandObjectSP ( new CommandObjectTypeFilterAdd ( interpreter ) ) ) ;
LoadSubCommand ( " clear " , CommandObjectSP ( new CommandObjectTypeFilterClear ( interpreter ) ) ) ;
LoadSubCommand ( " delete " , CommandObjectSP ( new CommandObjectTypeFilterDelete ( interpreter ) ) ) ;
LoadSubCommand ( " list " , CommandObjectSP ( new CommandObjectTypeFilterList ( interpreter ) ) ) ;
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeFilter ( ) override
2013-08-23 13:46:38 -04:00
{
}
} ;
class CommandObjectTypeCategory : public CommandObjectMultiword
{
public :
CommandObjectTypeCategory ( CommandInterpreter & interpreter ) :
CommandObjectMultiword ( interpreter ,
" type category " ,
" A set of commands for operating on categories " ,
" type category [<sub-command-options>] " )
{
2015-12-30 06:55:28 -05:00
LoadSubCommand ( " define " , CommandObjectSP ( new CommandObjectTypeCategoryDefine ( interpreter ) ) ) ;
2013-08-23 13:46:38 -04:00
LoadSubCommand ( " enable " , CommandObjectSP ( new CommandObjectTypeCategoryEnable ( interpreter ) ) ) ;
LoadSubCommand ( " disable " , CommandObjectSP ( new CommandObjectTypeCategoryDisable ( interpreter ) ) ) ;
LoadSubCommand ( " delete " , CommandObjectSP ( new CommandObjectTypeCategoryDelete ( interpreter ) ) ) ;
LoadSubCommand ( " list " , CommandObjectSP ( new CommandObjectTypeCategoryList ( interpreter ) ) ) ;
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeCategory ( ) override
2013-08-23 13:46:38 -04:00
{
}
} ;
class CommandObjectTypeSummary : public CommandObjectMultiword
{
public :
CommandObjectTypeSummary ( CommandInterpreter & interpreter ) :
CommandObjectMultiword ( interpreter ,
" type summary " ,
" A set of commands for editing variable summary display options " ,
" type summary [<sub-command-options>] " )
{
LoadSubCommand ( " add " , CommandObjectSP ( new CommandObjectTypeSummaryAdd ( interpreter ) ) ) ;
LoadSubCommand ( " clear " , CommandObjectSP ( new CommandObjectTypeSummaryClear ( interpreter ) ) ) ;
LoadSubCommand ( " delete " , CommandObjectSP ( new CommandObjectTypeSummaryDelete ( interpreter ) ) ) ;
LoadSubCommand ( " list " , CommandObjectSP ( new CommandObjectTypeSummaryList ( interpreter ) ) ) ;
2015-02-06 16:38:51 -05:00
LoadSubCommand ( " info " , CommandObjectSP ( new CommandObjectFormatterInfo < TypeSummaryImpl > ( interpreter ,
" summary " ,
[ ] ( ValueObject & valobj ) - > TypeSummaryImpl : : SharedPointer {
return valobj . GetSummaryFormat ( ) ;
} ) ) ) ;
2013-08-23 13:46:38 -04:00
}
2015-12-30 06:55:28 -05:00
~ CommandObjectTypeSummary ( ) override
2013-08-23 13:46:38 -04:00
{
}
} ;
//-------------------------------------------------------------------------
// CommandObjectType
//-------------------------------------------------------------------------
CommandObjectType : : CommandObjectType ( CommandInterpreter & interpreter ) :
CommandObjectMultiword ( interpreter ,
" type " ,
" A set of commands for operating on the type system " ,
" type [<sub-command-options>] " )
{
LoadSubCommand ( " category " , CommandObjectSP ( new CommandObjectTypeCategory ( interpreter ) ) ) ;
LoadSubCommand ( " filter " , CommandObjectSP ( new CommandObjectTypeFilter ( interpreter ) ) ) ;
LoadSubCommand ( " format " , CommandObjectSP ( new CommandObjectTypeFormat ( interpreter ) ) ) ;
LoadSubCommand ( " summary " , CommandObjectSP ( new CommandObjectTypeSummary ( interpreter ) ) ) ;
# ifndef LLDB_DISABLE_PYTHON
LoadSubCommand ( " synthetic " , CommandObjectSP ( new CommandObjectTypeSynth ( interpreter ) ) ) ;
# endif
2015-12-30 06:55:28 -05:00
LoadSubCommand ( " lookup " , CommandObjectSP ( new CommandObjectTypeLookup ( interpreter ) ) ) ;
2013-08-23 13:46:38 -04:00
}
CommandObjectType : : ~ CommandObjectType ( )
{
}