Home | History | Annotate | Download | only in Commands
      1 //===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "lldb/lldb-python.h"
     11 
     12 #include "CommandObjectType.h"
     13 
     14 // C Includes
     15 
     16 #include <ctype.h>
     17 
     18 // C++ Includes
     19 
     20 #include "lldb/Core/ConstString.h"
     21 #include "lldb/Core/Debugger.h"
     22 #include "lldb/Core/InputReaderEZ.h"
     23 #include "lldb/Core/RegularExpression.h"
     24 #include "lldb/Core/State.h"
     25 #include "lldb/Core/StringList.h"
     26 #include "lldb/DataFormatters/DataVisualization.h"
     27 #include "lldb/Interpreter/CommandInterpreter.h"
     28 #include "lldb/Interpreter/CommandObject.h"
     29 #include "lldb/Interpreter/CommandReturnObject.h"
     30 #include "lldb/Interpreter/Options.h"
     31 #include "lldb/Interpreter/OptionGroupFormat.h"
     32 
     33 using namespace lldb;
     34 using namespace lldb_private;
     35 
     36 
     37 class ScriptAddOptions
     38 {
     39 
     40 public:
     41 
     42     TypeSummaryImpl::Flags m_flags;
     43 
     44     StringList m_target_types;
     45     StringList m_user_source;
     46 
     47     bool m_regex;
     48 
     49     ConstString m_name;
     50 
     51     std::string m_category;
     52 
     53     ScriptAddOptions(const TypeSummaryImpl::Flags& flags,
     54                      bool regx,
     55                      const ConstString& name,
     56                      std::string catg) :
     57         m_flags(flags),
     58         m_regex(regx),
     59         m_name(name),
     60         m_category(catg)
     61     {
     62     }
     63 
     64     typedef std::shared_ptr<ScriptAddOptions> SharedPointer;
     65 
     66 };
     67 
     68 class SynthAddOptions
     69 {
     70 
     71 public:
     72 
     73     bool m_skip_pointers;
     74     bool m_skip_references;
     75     bool m_cascade;
     76     bool m_regex;
     77     StringList m_user_source;
     78     StringList m_target_types;
     79 
     80     std::string m_category;
     81 
     82     SynthAddOptions(bool sptr,
     83                     bool sref,
     84                     bool casc,
     85                     bool regx,
     86                     std::string catg) :
     87     m_skip_pointers(sptr),
     88     m_skip_references(sref),
     89     m_cascade(casc),
     90     m_regex(regx),
     91     m_user_source(),
     92     m_target_types(),
     93     m_category(catg)
     94     {
     95     }
     96 
     97     typedef std::shared_ptr<SynthAddOptions> SharedPointer;
     98 
     99 };
    100 
    101 
    102 
    103 class CommandObjectTypeSummaryAdd : public CommandObjectParsed
    104 {
    105 
    106 private:
    107 
    108     class CommandOptions : public Options
    109     {
    110     public:
    111 
    112         CommandOptions (CommandInterpreter &interpreter) :
    113         Options (interpreter)
    114         {
    115         }
    116 
    117         virtual
    118         ~CommandOptions (){}
    119 
    120         virtual Error
    121         SetOptionValue (uint32_t option_idx, const char *option_arg);
    122 
    123         void
    124         OptionParsingStarting ();
    125 
    126         const OptionDefinition*
    127         GetDefinitions ()
    128         {
    129             return g_option_table;
    130         }
    131 
    132         // Options table: Required for subclasses of Options.
    133 
    134         static OptionDefinition g_option_table[];
    135 
    136         // Instance variables to hold the values for command options.
    137 
    138         TypeSummaryImpl::Flags m_flags;
    139         bool m_regex;
    140         std::string m_format_string;
    141         ConstString m_name;
    142         std::string m_python_script;
    143         std::string m_python_function;
    144         bool m_is_add_script;
    145         std::string m_category;
    146     };
    147 
    148     CommandOptions m_options;
    149 
    150     virtual Options *
    151     GetOptions ()
    152     {
    153         return &m_options;
    154     }
    155 
    156     void
    157     CollectPythonScript(ScriptAddOptions *options,
    158                         CommandReturnObject &result);
    159 
    160     bool
    161     Execute_ScriptSummary (Args& command, CommandReturnObject &result);
    162 
    163     bool
    164     Execute_StringSummary (Args& command, CommandReturnObject &result);
    165 
    166 public:
    167 
    168     enum SummaryFormatType
    169     {
    170         eRegularSummary,
    171         eRegexSummary,
    172         eNamedSummary
    173     };
    174 
    175     CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter);
    176 
    177     ~CommandObjectTypeSummaryAdd ()
    178     {
    179     }
    180 
    181     static bool
    182     AddSummary(ConstString type_name,
    183                lldb::TypeSummaryImplSP entry,
    184                SummaryFormatType type,
    185                std::string category,
    186                Error* error = NULL);
    187 protected:
    188     bool
    189     DoExecute (Args& command, CommandReturnObject &result);
    190 
    191 };
    192 
    193 class CommandObjectTypeSynthAdd : public CommandObjectParsed
    194 {
    195 
    196 private:
    197 
    198     class CommandOptions : public Options
    199     {
    200     public:
    201 
    202         CommandOptions (CommandInterpreter &interpreter) :
    203         Options (interpreter)
    204         {
    205         }
    206 
    207         virtual
    208         ~CommandOptions (){}
    209 
    210         virtual Error
    211         SetOptionValue (uint32_t option_idx, const char *option_arg)
    212         {
    213             Error error;
    214             const int short_option = m_getopt_table[option_idx].val;
    215             bool success;
    216 
    217             switch (short_option)
    218             {
    219                 case 'C':
    220                     m_cascade = Args::StringToBoolean(option_arg, true, &success);
    221                     if (!success)
    222                         error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
    223                     break;
    224                 case 'P':
    225                     handwrite_python = true;
    226                     break;
    227                 case 'l':
    228                     m_class_name = std::string(option_arg);
    229                     is_class_based = true;
    230                     break;
    231                 case 'p':
    232                     m_skip_pointers = true;
    233                     break;
    234                 case 'r':
    235                     m_skip_references = true;
    236                     break;
    237                 case 'w':
    238                     m_category = std::string(option_arg);
    239                     break;
    240                 case 'x':
    241                     m_regex = true;
    242                     break;
    243                 default:
    244                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
    245                     break;
    246             }
    247 
    248             return error;
    249         }
    250 
    251         void
    252         OptionParsingStarting ()
    253         {
    254             m_cascade = true;
    255             m_class_name = "";
    256             m_skip_pointers = false;
    257             m_skip_references = false;
    258             m_category = "default";
    259             is_class_based = false;
    260             handwrite_python = false;
    261             m_regex = false;
    262         }
    263 
    264         const OptionDefinition*
    265         GetDefinitions ()
    266         {
    267             return g_option_table;
    268         }
    269 
    270         // Options table: Required for subclasses of Options.
    271 
    272         static OptionDefinition g_option_table[];
    273 
    274         // Instance variables to hold the values for command options.
    275 
    276         bool m_cascade;
    277         bool m_skip_references;
    278         bool m_skip_pointers;
    279         std::string m_class_name;
    280         bool m_input_python;
    281         std::string m_category;
    282 
    283         bool is_class_based;
    284 
    285         bool handwrite_python;
    286 
    287         bool m_regex;
    288 
    289     };
    290 
    291     CommandOptions m_options;
    292 
    293     virtual Options *
    294     GetOptions ()
    295     {
    296         return &m_options;
    297     }
    298 
    299     void
    300     CollectPythonScript (SynthAddOptions *options,
    301                          CommandReturnObject &result);
    302     bool
    303     Execute_HandwritePython (Args& command, CommandReturnObject &result);
    304 
    305     bool
    306     Execute_PythonClass (Args& command, CommandReturnObject &result);
    307 
    308 protected:
    309     bool
    310     DoExecute (Args& command, CommandReturnObject &result);
    311 
    312 public:
    313 
    314     enum SynthFormatType
    315     {
    316         eRegularSynth,
    317         eRegexSynth
    318     };
    319 
    320     CommandObjectTypeSynthAdd (CommandInterpreter &interpreter);
    321 
    322     ~CommandObjectTypeSynthAdd ()
    323     {
    324     }
    325 
    326     static bool
    327     AddSynth(ConstString type_name,
    328              lldb::SyntheticChildrenSP entry,
    329              SynthFormatType type,
    330              std::string category_name,
    331              Error* error);
    332 };
    333 
    334 //-------------------------------------------------------------------------
    335 // CommandObjectTypeFormatAdd
    336 //-------------------------------------------------------------------------
    337 
    338 class CommandObjectTypeFormatAdd : public CommandObjectParsed
    339 {
    340 
    341 private:
    342 
    343     class CommandOptions : public OptionGroup
    344     {
    345     public:
    346 
    347         CommandOptions () :
    348             OptionGroup()
    349         {
    350         }
    351 
    352         virtual
    353         ~CommandOptions ()
    354         {
    355         }
    356 
    357         virtual uint32_t
    358         GetNumDefinitions ();
    359 
    360         virtual const OptionDefinition*
    361         GetDefinitions ()
    362         {
    363             return g_option_table;
    364         }
    365 
    366         virtual void
    367         OptionParsingStarting (CommandInterpreter &interpreter)
    368         {
    369             m_cascade = true;
    370             m_skip_pointers = false;
    371             m_skip_references = false;
    372         }
    373         virtual Error
    374         SetOptionValue (CommandInterpreter &interpreter,
    375                         uint32_t option_idx,
    376                         const char *option_value)
    377         {
    378             Error error;
    379             const int short_option = g_option_table[option_idx].short_option;
    380             bool success;
    381 
    382             switch (short_option)
    383             {
    384                 case 'C':
    385                     m_cascade = Args::StringToBoolean(option_value, true, &success);
    386                     if (!success)
    387                         error.SetErrorStringWithFormat("invalid value for cascade: %s", option_value);
    388                     break;
    389                 case 'p':
    390                     m_skip_pointers = true;
    391                     break;
    392                 case 'r':
    393                     m_skip_references = true;
    394                     break;
    395                 default:
    396                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
    397                     break;
    398             }
    399 
    400             return error;
    401         }
    402 
    403         // Options table: Required for subclasses of Options.
    404 
    405         static OptionDefinition g_option_table[];
    406 
    407         // Instance variables to hold the values for command options.
    408 
    409         bool m_cascade;
    410         bool m_skip_references;
    411         bool m_skip_pointers;
    412     };
    413 
    414     OptionGroupOptions m_option_group;
    415     OptionGroupFormat m_format_options;
    416     CommandOptions m_command_options;
    417 
    418     virtual Options *
    419     GetOptions ()
    420     {
    421         return &m_option_group;
    422     }
    423 
    424 public:
    425     CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) :
    426         CommandObjectParsed (interpreter,
    427                              "type format add",
    428                              "Add a new formatting style for a type.",
    429                              NULL),
    430         m_option_group (interpreter),
    431         m_format_options (eFormatInvalid),
    432         m_command_options ()
    433     {
    434         CommandArgumentEntry type_arg;
    435         CommandArgumentData type_style_arg;
    436 
    437         type_style_arg.arg_type = eArgTypeName;
    438         type_style_arg.arg_repetition = eArgRepeatPlus;
    439 
    440         type_arg.push_back (type_style_arg);
    441 
    442         m_arguments.push_back (type_arg);
    443 
    444         SetHelpLong(
    445                     "Some examples of using this command.\n"
    446                     "We use as reference the following snippet of code:\n"
    447                     "\n"
    448                     "typedef int Aint;\n"
    449                     "typedef float Afloat;\n"
    450                     "typedef Aint Bint;\n"
    451                     "typedef Afloat Bfloat;\n"
    452                     "\n"
    453                     "Aint ix = 5;\n"
    454                     "Bint iy = 5;\n"
    455                     "\n"
    456                     "Afloat fx = 3.14;\n"
    457                     "BFloat fy = 3.14;\n"
    458                     "\n"
    459                     "Typing:\n"
    460                     "type format add -f hex AInt\n"
    461                     "frame variable iy\n"
    462                     "will produce an hex display of iy, because no formatter is available for Bint and the one for Aint is used instead\n"
    463                     "To prevent this type\n"
    464                     "type format add -f hex -C no AInt\n"
    465                     "\n"
    466                     "A similar reasoning applies to\n"
    467                     "type format add -f hex -C no float -p\n"
    468                     "which now prints all floats and float&s as hexadecimal, but does not format float*s\n"
    469                     "and does not change the default display for Afloat and Bfloat objects.\n"
    470                     );
    471 
    472         // Add the "--format" to all options groups
    473         m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_ALL);
    474         m_option_group.Append (&m_command_options);
    475         m_option_group.Finalize();
    476 
    477     }
    478 
    479     ~CommandObjectTypeFormatAdd ()
    480     {
    481     }
    482 
    483 protected:
    484     bool
    485     DoExecute (Args& command, CommandReturnObject &result)
    486     {
    487         const size_t argc = command.GetArgumentCount();
    488 
    489         if (argc < 1)
    490         {
    491             result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
    492             result.SetStatus(eReturnStatusFailed);
    493             return false;
    494         }
    495 
    496         const Format format = m_format_options.GetFormat();
    497         if (format == eFormatInvalid)
    498         {
    499             result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
    500             result.SetStatus(eReturnStatusFailed);
    501             return false;
    502         }
    503 
    504         TypeFormatImplSP entry;
    505 
    506         entry.reset(new TypeFormatImpl(format,
    507                                     TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
    508                                     SetSkipPointers(m_command_options.m_skip_pointers).
    509                                     SetSkipReferences(m_command_options.m_skip_references)));
    510 
    511         // now I have a valid format, let's add it to every type
    512 
    513         for (size_t i = 0; i < argc; i++)
    514         {
    515             const char* typeA = command.GetArgumentAtIndex(i);
    516             ConstString typeCS(typeA);
    517             if (typeCS)
    518                 DataVisualization::ValueFormats::Add(typeCS, entry);
    519             else
    520             {
    521                 result.AppendError("empty typenames not allowed");
    522                 result.SetStatus(eReturnStatusFailed);
    523                 return false;
    524             }
    525         }
    526 
    527         result.SetStatus(eReturnStatusSuccessFinishNoResult);
    528         return result.Succeeded();
    529     }
    530 };
    531 
    532 OptionDefinition
    533 CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
    534 {
    535     { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
    536     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
    537     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
    538 };
    539 
    540 
    541 uint32_t
    542 CommandObjectTypeFormatAdd::CommandOptions::GetNumDefinitions ()
    543 {
    544     return sizeof(g_option_table) / sizeof (OptionDefinition);
    545 }
    546 
    547 
    548 //-------------------------------------------------------------------------
    549 // CommandObjectTypeFormatDelete
    550 //-------------------------------------------------------------------------
    551 
    552 class CommandObjectTypeFormatDelete : public CommandObjectParsed
    553 {
    554 public:
    555     CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) :
    556         CommandObjectParsed (interpreter,
    557                              "type format delete",
    558                              "Delete an existing formatting style for a type.",
    559                              NULL)
    560     {
    561         CommandArgumentEntry type_arg;
    562         CommandArgumentData type_style_arg;
    563 
    564         type_style_arg.arg_type = eArgTypeName;
    565         type_style_arg.arg_repetition = eArgRepeatPlain;
    566 
    567         type_arg.push_back (type_style_arg);
    568 
    569         m_arguments.push_back (type_arg);
    570 
    571     }
    572 
    573     ~CommandObjectTypeFormatDelete ()
    574     {
    575     }
    576 
    577 protected:
    578     bool
    579     DoExecute (Args& command, CommandReturnObject &result)
    580     {
    581         const size_t argc = command.GetArgumentCount();
    582 
    583         if (argc != 1)
    584         {
    585             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
    586             result.SetStatus(eReturnStatusFailed);
    587             return false;
    588         }
    589 
    590         const char* typeA = command.GetArgumentAtIndex(0);
    591         ConstString typeCS(typeA);
    592 
    593         if (!typeCS)
    594         {
    595             result.AppendError("empty typenames not allowed");
    596             result.SetStatus(eReturnStatusFailed);
    597             return false;
    598         }
    599 
    600 
    601         if (DataVisualization::ValueFormats::Delete(typeCS))
    602         {
    603             result.SetStatus(eReturnStatusSuccessFinishNoResult);
    604             return result.Succeeded();
    605         }
    606         else
    607         {
    608             result.AppendErrorWithFormat ("no custom format for %s.\n", typeA);
    609             result.SetStatus(eReturnStatusFailed);
    610             return false;
    611         }
    612 
    613     }
    614 
    615 };
    616 
    617 //-------------------------------------------------------------------------
    618 // CommandObjectTypeFormatClear
    619 //-------------------------------------------------------------------------
    620 
    621 class CommandObjectTypeFormatClear : public CommandObjectParsed
    622 {
    623 public:
    624     CommandObjectTypeFormatClear (CommandInterpreter &interpreter) :
    625         CommandObjectParsed (interpreter,
    626                              "type format clear",
    627                              "Delete all existing format styles.",
    628                              NULL)
    629     {
    630     }
    631 
    632     ~CommandObjectTypeFormatClear ()
    633     {
    634     }
    635 
    636 protected:
    637     bool
    638     DoExecute (Args& command, CommandReturnObject &result)
    639     {
    640         DataVisualization::ValueFormats::Clear();
    641         result.SetStatus(eReturnStatusSuccessFinishResult);
    642         return result.Succeeded();
    643     }
    644 
    645 };
    646 
    647 //-------------------------------------------------------------------------
    648 // CommandObjectTypeFormatList
    649 //-------------------------------------------------------------------------
    650 
    651 bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);
    652 
    653 class CommandObjectTypeFormatList;
    654 
    655 struct CommandObjectTypeFormatList_LoopCallbackParam {
    656     CommandObjectTypeFormatList* self;
    657     CommandReturnObject* result;
    658     RegularExpression* regex;
    659     CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R,
    660                                             RegularExpression* X = NULL) : self(S), result(R), regex(X) {}
    661 };
    662 
    663 class CommandObjectTypeFormatList : public CommandObjectParsed
    664 {
    665 public:
    666     CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
    667         CommandObjectParsed (interpreter,
    668                              "type format list",
    669                              "Show a list of current formatting styles.",
    670                              NULL)
    671     {
    672         CommandArgumentEntry type_arg;
    673         CommandArgumentData type_style_arg;
    674 
    675         type_style_arg.arg_type = eArgTypeName;
    676         type_style_arg.arg_repetition = eArgRepeatOptional;
    677 
    678         type_arg.push_back (type_style_arg);
    679 
    680         m_arguments.push_back (type_arg);
    681     }
    682 
    683     ~CommandObjectTypeFormatList ()
    684     {
    685     }
    686 
    687 protected:
    688     bool
    689     DoExecute (Args& command, CommandReturnObject &result)
    690     {
    691         const size_t argc = command.GetArgumentCount();
    692 
    693         CommandObjectTypeFormatList_LoopCallbackParam *param;
    694 
    695         if (argc == 1)
    696         {
    697             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
    698             regex->Compile(command.GetArgumentAtIndex(0));
    699             param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex);
    700         }
    701         else
    702             param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result);
    703         DataVisualization::ValueFormats::LoopThrough(CommandObjectTypeFormatList_LoopCallback, param);
    704         delete param;
    705         result.SetStatus(eReturnStatusSuccessFinishResult);
    706         return result.Succeeded();
    707     }
    708 
    709 private:
    710 
    711     bool
    712     LoopCallback (ConstString type,
    713                   const lldb::TypeFormatImplSP& entry,
    714                   RegularExpression* regex,
    715                   CommandReturnObject *result)
    716     {
    717         if (regex == NULL || regex->Execute(type.AsCString()))
    718         {
    719             result->GetOutputStream().Printf ("%s: %s\n", type.AsCString(),
    720                                               entry->GetDescription().c_str());
    721         }
    722         return true;
    723     }
    724 
    725     friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);
    726 
    727 };
    728 
    729 bool
    730 CommandObjectTypeFormatList_LoopCallback (
    731                                     void* pt2self,
    732                                     ConstString type,
    733                                     const lldb::TypeFormatImplSP& entry)
    734 {
    735     CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;
    736     return param->self->LoopCallback(type, entry, param->regex, param->result);
    737 }
    738 
    739 
    740 #ifndef LLDB_DISABLE_PYTHON
    741 
    742 //-------------------------------------------------------------------------
    743 // CommandObjectTypeSummaryAdd
    744 //-------------------------------------------------------------------------
    745 
    746 static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
    747                                                        "def function (valobj,internal_dict):\n"
    748                                                        "     \"\"\"valobj: an SBValue which you want to provide a summary for\n"
    749                                                        "        internal_dict: an LLDB support object not to be used\"\"\"";
    750 
    751 class TypeScriptAddInputReader : public InputReaderEZ
    752 {
    753 private:
    754     DISALLOW_COPY_AND_ASSIGN (TypeScriptAddInputReader);
    755 public:
    756     TypeScriptAddInputReader(Debugger& debugger) :
    757     InputReaderEZ(debugger)
    758     {}
    759 
    760     virtual
    761     ~TypeScriptAddInputReader()
    762     {
    763     }
    764 
    765     virtual void ActivateHandler(HandlerData& data)
    766     {
    767         StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
    768         bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
    769         if (!batch_mode)
    770         {
    771             out_stream->Printf ("%s\n", g_summary_addreader_instructions);
    772             if (data.reader.GetPrompt())
    773                 out_stream->Printf ("%s", data.reader.GetPrompt());
    774             out_stream->Flush();
    775         }
    776     }
    777 
    778     virtual void ReactivateHandler(HandlerData& data)
    779     {
    780         StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
    781         bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
    782         if (data.reader.GetPrompt() && !batch_mode)
    783         {
    784             out_stream->Printf ("%s", data.reader.GetPrompt());
    785             out_stream->Flush();
    786         }
    787     }
    788     virtual void GotTokenHandler(HandlerData& data)
    789     {
    790         StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
    791         bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
    792         if (data.bytes && data.bytes_len && data.baton)
    793         {
    794             ((ScriptAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len);
    795         }
    796         if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
    797         {
    798             out_stream->Printf ("%s", data.reader.GetPrompt());
    799             out_stream->Flush();
    800         }
    801     }
    802     virtual void InterruptHandler(HandlerData& data)
    803     {
    804         StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
    805         bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
    806         data.reader.SetIsDone (true);
    807         if (!batch_mode)
    808         {
    809             out_stream->Printf ("Warning: No command attached to breakpoint.\n");
    810             out_stream->Flush();
    811         }
    812     }
    813     virtual void EOFHandler(HandlerData& data)
    814     {
    815         data.reader.SetIsDone (true);
    816     }
    817     virtual void DoneHandler(HandlerData& data)
    818     {
    819         StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
    820         ScriptAddOptions *options_ptr = ((ScriptAddOptions*)data.baton);
    821         if (!options_ptr)
    822         {
    823             out_stream->Printf ("internal synchronization information missing or invalid.\n");
    824             out_stream->Flush();
    825             return;
    826         }
    827 
    828         ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
    829 
    830         ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
    831         if (!interpreter)
    832         {
    833             out_stream->Printf ("no script interpreter.\n");
    834             out_stream->Flush();
    835             return;
    836         }
    837         std::string funct_name_str;
    838         if (!interpreter->GenerateTypeScriptFunction (options->m_user_source,
    839                                                       funct_name_str))
    840         {
    841             out_stream->Printf ("unable to generate a function.\n");
    842             out_stream->Flush();
    843             return;
    844         }
    845         if (funct_name_str.empty())
    846         {
    847             out_stream->Printf ("unable to obtain a valid function name from the script interpreter.\n");
    848             out_stream->Flush();
    849             return;
    850         }
    851         // now I have a valid function name, let's add this as script for every type in the list
    852 
    853         TypeSummaryImplSP script_format;
    854         script_format.reset(new ScriptSummaryFormat(options->m_flags,
    855                                                     funct_name_str.c_str(),
    856                                                     options->m_user_source.CopyList("     ").c_str()));
    857 
    858         Error error;
    859 
    860         for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
    861         {
    862             const char *type_name = options->m_target_types.GetStringAtIndex(i);
    863             CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
    864                                                     script_format,
    865                                                     (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
    866                                                     options->m_category,
    867                                                     &error);
    868             if (error.Fail())
    869             {
    870                 out_stream->Printf ("%s", error.AsCString());
    871                 out_stream->Flush();
    872                 return;
    873             }
    874         }
    875 
    876         if (options->m_name)
    877         {
    878             CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
    879                                                      script_format,
    880                                                      CommandObjectTypeSummaryAdd::eNamedSummary,
    881                                                      options->m_category,
    882                                                      &error);
    883             if (error.Fail())
    884             {
    885                 CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
    886                                                          script_format,
    887                                                          CommandObjectTypeSummaryAdd::eNamedSummary,
    888                                                          options->m_category,
    889                                                          &error);
    890                 if (error.Fail())
    891                 {
    892                     out_stream->Printf ("%s", error.AsCString());
    893                     out_stream->Flush();
    894                     return;
    895                 }
    896             }
    897             else
    898             {
    899                 out_stream->Printf ("%s", error.AsCString());
    900                 out_stream->Flush();
    901                 return;
    902             }
    903         }
    904         else
    905         {
    906             if (error.AsCString())
    907             {
    908                 out_stream->PutCString (error.AsCString());
    909                 out_stream->Flush();
    910             }
    911             return;
    912         }
    913     }
    914 };
    915 
    916 #endif // #ifndef LLDB_DISABLE_PYTHON
    917 
    918 Error
    919 CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
    920 {
    921     Error error;
    922     const int short_option = m_getopt_table[option_idx].val;
    923     bool success;
    924 
    925     switch (short_option)
    926     {
    927         case 'C':
    928             m_flags.SetCascades(Args::StringToBoolean(option_arg, true, &success));
    929             if (!success)
    930                 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
    931             break;
    932         case 'e':
    933             m_flags.SetDontShowChildren(false);
    934             break;
    935         case 'v':
    936             m_flags.SetDontShowValue(true);
    937             break;
    938         case 'c':
    939             m_flags.SetShowMembersOneLiner(true);
    940             break;
    941         case 's':
    942             m_format_string = std::string(option_arg);
    943             break;
    944         case 'p':
    945             m_flags.SetSkipPointers(true);
    946             break;
    947         case 'r':
    948             m_flags.SetSkipReferences(true);
    949             break;
    950         case 'x':
    951             m_regex = true;
    952             break;
    953         case 'n':
    954             m_name.SetCString(option_arg);
    955             break;
    956         case 'o':
    957             m_python_script = std::string(option_arg);
    958             m_is_add_script = true;
    959             break;
    960         case 'F':
    961             m_python_function = std::string(option_arg);
    962             m_is_add_script = true;
    963             break;
    964         case 'P':
    965             m_is_add_script = true;
    966             break;
    967         case 'w':
    968             m_category = std::string(option_arg);
    969             break;
    970         case 'O':
    971             m_flags.SetHideItemNames(true);
    972             break;
    973         default:
    974             error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
    975             break;
    976     }
    977 
    978     return error;
    979 }
    980 
    981 void
    982 CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting ()
    983 {
    984     m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false);
    985     m_flags.SetShowMembersOneLiner(false).SetSkipPointers(false).SetSkipReferences(false).SetHideItemNames(false);
    986 
    987     m_regex = false;
    988     m_name.Clear();
    989     m_python_script = "";
    990     m_python_function = "";
    991     m_format_string = "";
    992     m_is_add_script = false;
    993     m_category = "default";
    994 }
    995 
    996 #ifndef LLDB_DISABLE_PYTHON
    997 void
    998 CommandObjectTypeSummaryAdd::CollectPythonScript (ScriptAddOptions *options,
    999                                                   CommandReturnObject &result)
   1000 {
   1001     InputReaderSP reader_sp (new TypeScriptAddInputReader(m_interpreter.GetDebugger()));
   1002     if (reader_sp && options)
   1003     {
   1004 
   1005         InputReaderEZ::InitializationParameters ipr;
   1006 
   1007         Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt("     ")));
   1008         if (err.Success())
   1009         {
   1010             m_interpreter.GetDebugger().PushInputReader (reader_sp);
   1011             result.SetStatus (eReturnStatusSuccessFinishNoResult);
   1012         }
   1013         else
   1014         {
   1015             result.AppendError (err.AsCString());
   1016             result.SetStatus (eReturnStatusFailed);
   1017         }
   1018     }
   1019     else
   1020     {
   1021         result.AppendError("out of memory");
   1022         result.SetStatus (eReturnStatusFailed);
   1023     }
   1024 }
   1025 
   1026 bool
   1027 CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result)
   1028 {
   1029     const size_t argc = command.GetArgumentCount();
   1030 
   1031     if (argc < 1 && !m_options.m_name)
   1032     {
   1033         result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
   1034         result.SetStatus(eReturnStatusFailed);
   1035         return false;
   1036     }
   1037 
   1038     TypeSummaryImplSP script_format;
   1039 
   1040     if (!m_options.m_python_function.empty()) // we have a Python function ready to use
   1041     {
   1042         const char *funct_name = m_options.m_python_function.c_str();
   1043         if (!funct_name || !funct_name[0])
   1044         {
   1045             result.AppendError ("function name empty.\n");
   1046             result.SetStatus (eReturnStatusFailed);
   1047             return false;
   1048         }
   1049 
   1050         std::string code = ("     " + m_options.m_python_function + "(valobj,internal_dict)");
   1051 
   1052         script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
   1053                                                     funct_name,
   1054                                                     code.c_str()));
   1055 
   1056         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
   1057 
   1058         if (interpreter && interpreter->CheckObjectExists(funct_name) == false)
   1059             result.AppendWarningWithFormat("The provided function \"%s\" does not exist - "
   1060                                            "please define it before attempting to use this summary.\n",
   1061                                            funct_name);
   1062     }
   1063     else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it
   1064     {
   1065         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
   1066         if (!interpreter)
   1067         {
   1068             result.AppendError ("script interpreter missing - unable to generate function wrapper.\n");
   1069             result.SetStatus (eReturnStatusFailed);
   1070             return false;
   1071         }
   1072         StringList funct_sl;
   1073         funct_sl << m_options.m_python_script.c_str();
   1074         std::string funct_name_str;
   1075         if (!interpreter->GenerateTypeScriptFunction (funct_sl,
   1076                                                       funct_name_str))
   1077         {
   1078             result.AppendError ("unable to generate function wrapper.\n");
   1079             result.SetStatus (eReturnStatusFailed);
   1080             return false;
   1081         }
   1082         if (funct_name_str.empty())
   1083         {
   1084             result.AppendError ("script interpreter failed to generate a valid function name.\n");
   1085             result.SetStatus (eReturnStatusFailed);
   1086             return false;
   1087         }
   1088 
   1089         std::string code = "     " + m_options.m_python_script;
   1090 
   1091         script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
   1092                                                     funct_name_str.c_str(),
   1093                                                     code.c_str()));
   1094     }
   1095     else // use an InputReader to grab Python code from the user
   1096     {
   1097         ScriptAddOptions *options = new ScriptAddOptions(m_options.m_flags,
   1098                                                          m_options.m_regex,
   1099                                                          m_options.m_name,
   1100                                                          m_options.m_category);
   1101 
   1102         for (size_t i = 0; i < argc; i++)
   1103         {
   1104             const char* typeA = command.GetArgumentAtIndex(i);
   1105             if (typeA && *typeA)
   1106                 options->m_target_types << typeA;
   1107             else
   1108             {
   1109                 result.AppendError("empty typenames not allowed");
   1110                 result.SetStatus(eReturnStatusFailed);
   1111                 return false;
   1112             }
   1113         }
   1114 
   1115         CollectPythonScript(options,result);
   1116         return result.Succeeded();
   1117     }
   1118 
   1119     // if I am here, script_format must point to something good, so I can add that
   1120     // as a script summary to all interested parties
   1121 
   1122     Error error;
   1123 
   1124     for (size_t i = 0; i < command.GetArgumentCount(); i++)
   1125     {
   1126         const char *type_name = command.GetArgumentAtIndex(i);
   1127         CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
   1128                                                 script_format,
   1129                                                 (m_options.m_regex ? eRegexSummary : eRegularSummary),
   1130                                                 m_options.m_category,
   1131                                                 &error);
   1132         if (error.Fail())
   1133         {
   1134             result.AppendError(error.AsCString());
   1135             result.SetStatus(eReturnStatusFailed);
   1136             return false;
   1137         }
   1138     }
   1139 
   1140     if (m_options.m_name)
   1141     {
   1142         AddSummary(m_options.m_name, script_format, eNamedSummary, m_options.m_category, &error);
   1143         if (error.Fail())
   1144         {
   1145             result.AppendError(error.AsCString());
   1146             result.AppendError("added to types, but not given a name");
   1147             result.SetStatus(eReturnStatusFailed);
   1148             return false;
   1149         }
   1150     }
   1151 
   1152     return result.Succeeded();
   1153 }
   1154 
   1155 #endif
   1156 
   1157 
   1158 bool
   1159 CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturnObject &result)
   1160 {
   1161     const size_t argc = command.GetArgumentCount();
   1162 
   1163     if (argc < 1 && !m_options.m_name)
   1164     {
   1165         result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
   1166         result.SetStatus(eReturnStatusFailed);
   1167         return false;
   1168     }
   1169 
   1170     if (!m_options.m_flags.GetShowMembersOneLiner() && m_options.m_format_string.empty())
   1171     {
   1172         result.AppendError("empty summary strings not allowed");
   1173         result.SetStatus(eReturnStatusFailed);
   1174         return false;
   1175     }
   1176 
   1177     const char* format_cstr = (m_options.m_flags.GetShowMembersOneLiner() ? "" : m_options.m_format_string.c_str());
   1178 
   1179     // ${var%S} is an endless recursion, prevent it
   1180     if (strcmp(format_cstr, "${var%S}") == 0)
   1181     {
   1182         result.AppendError("recursive summary not allowed");
   1183         result.SetStatus(eReturnStatusFailed);
   1184         return false;
   1185     }
   1186 
   1187     Error error;
   1188 
   1189     lldb::TypeSummaryImplSP entry(new StringSummaryFormat(m_options.m_flags,
   1190                                                         format_cstr));
   1191 
   1192     if (error.Fail())
   1193     {
   1194         result.AppendError(error.AsCString());
   1195         result.SetStatus(eReturnStatusFailed);
   1196         return false;
   1197     }
   1198 
   1199     // now I have a valid format, let's add it to every type
   1200 
   1201     for (size_t i = 0; i < argc; i++)
   1202     {
   1203         const char* typeA = command.GetArgumentAtIndex(i);
   1204         if (!typeA || typeA[0] == '\0')
   1205         {
   1206             result.AppendError("empty typenames not allowed");
   1207             result.SetStatus(eReturnStatusFailed);
   1208             return false;
   1209         }
   1210         ConstString typeCS(typeA);
   1211 
   1212         AddSummary(typeCS,
   1213                    entry,
   1214                    (m_options.m_regex ? eRegexSummary : eRegularSummary),
   1215                    m_options.m_category,
   1216                    &error);
   1217 
   1218         if (error.Fail())
   1219         {
   1220             result.AppendError(error.AsCString());
   1221             result.SetStatus(eReturnStatusFailed);
   1222             return false;
   1223         }
   1224     }
   1225 
   1226     if (m_options.m_name)
   1227     {
   1228         AddSummary(m_options.m_name, entry, eNamedSummary, m_options.m_category, &error);
   1229         if (error.Fail())
   1230         {
   1231             result.AppendError(error.AsCString());
   1232             result.AppendError("added to types, but not given a name");
   1233             result.SetStatus(eReturnStatusFailed);
   1234             return false;
   1235         }
   1236     }
   1237 
   1238     result.SetStatus(eReturnStatusSuccessFinishNoResult);
   1239     return result.Succeeded();
   1240 }
   1241 
   1242 CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
   1243     CommandObjectParsed (interpreter,
   1244                          "type summary add",
   1245                          "Add a new summary style for a type.",
   1246                          NULL),
   1247     m_options (interpreter)
   1248 {
   1249     CommandArgumentEntry type_arg;
   1250     CommandArgumentData type_style_arg;
   1251 
   1252     type_style_arg.arg_type = eArgTypeName;
   1253     type_style_arg.arg_repetition = eArgRepeatPlus;
   1254 
   1255     type_arg.push_back (type_style_arg);
   1256 
   1257     m_arguments.push_back (type_arg);
   1258 
   1259     SetHelpLong(
   1260                 "Some examples of using this command.\n"
   1261                 "We use as reference the following snippet of code:\n"
   1262                 "struct JustADemo\n"
   1263                 "{\n"
   1264                 "int* ptr;\n"
   1265                 "float value;\n"
   1266                 "JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n"
   1267                 "};\n"
   1268                 "JustADemo object(42,3.14);\n"
   1269                 "struct AnotherDemo : public JustADemo\n"
   1270                 "{\n"
   1271                 "uint8_t byte;\n"
   1272                 "AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n"
   1273                 "};\n"
   1274                 "AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n"
   1275                 "\n"
   1276                 "type summary add --summary-string \"the answer is ${*var.ptr}\" JustADemo\n"
   1277                 "when typing frame variable object you will get \"the answer is 42\"\n"
   1278                 "type summary add --summary-string \"the answer is ${*var.ptr}, and the question is ${var.value}\" JustADemo\n"
   1279                 "when typing frame variable object you will get \"the answer is 42 and the question is 3.14\"\n"
   1280                 "\n"
   1281                 "Alternatively, you could also say\n"
   1282                 "type summary add --summary-string \"${var%V} -> ${*var}\" \"int *\"\n"
   1283                 "and replace the above summary string with\n"
   1284                 "type summary add --summary-string \"the answer is ${var.ptr}, and the question is ${var.value}\" JustADemo\n"
   1285                 "to obtain a similar result\n"
   1286                 "\n"
   1287                 "To add a summary valid for both JustADemo and AnotherDemo you can use the scoping operator, as in:\n"
   1288                 "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes\n"
   1289                 "\n"
   1290                 "This will be used for both variables of type JustADemo and AnotherDemo. To prevent this, change the -C to read -C no\n"
   1291                 "If you do not want pointers to be shown using that summary, you can use the -p option, as in:\n"
   1292                 "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes -p\n"
   1293                 "A similar option -r exists for references.\n"
   1294                 "\n"
   1295                 "If you simply want a one-line summary of the content of your variable, without typing an explicit string to that effect\n"
   1296                 "you can use the -c option, without giving any summary string:\n"
   1297                 "type summary add -c JustADemo\n"
   1298                 "frame variable object\n"
   1299                 "the output being similar to (ptr=0xsomeaddress, value=3.14)\n"
   1300                 "\n"
   1301                 "If you want to display some summary text, but also expand the structure of your object, you can add the -e option, as in:\n"
   1302                 "type summary add -e --summary-string \"*ptr = ${*var.ptr}\" JustADemo\n"
   1303                 "Here the value of the int* is displayed, followed by the standard LLDB sequence of children objects, one per line.\n"
   1304                 "to get an output like:\n"
   1305                 "\n"
   1306                 "*ptr = 42 {\n"
   1307                 " ptr = 0xsomeaddress\n"
   1308                 " value = 3.14\n"
   1309                 "}\n"
   1310                 "\n"
   1311                 "You can also add Python summaries, in which case you will use lldb public API to gather information from your variables"
   1312                 "and elaborate them to a meaningful summary inside a script written in Python. The variable object will be passed to your"
   1313                 "script as an SBValue object. The following example might help you when starting to use the Python summaries feature:\n"
   1314                 "type summary add JustADemo -o \"value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();\"\n"
   1315                 "If you prefer to type your scripts on multiple lines, you will use the -P option and then type your script, ending it with "
   1316                 "the word DONE on a line by itself to mark you're finished editing your code:\n"
   1317                 "(lldb)type summary add JustADemo -P\n"
   1318                 "     value = valobj.GetChildMemberWithName('value');\n"
   1319                 "     return 'My value is ' + value.GetValue();\n"
   1320                 "DONE\n"
   1321                 "(lldb) <-- type further LLDB commands here\n"
   1322                 );
   1323 }
   1324 
   1325 bool
   1326 CommandObjectTypeSummaryAdd::DoExecute (Args& command, CommandReturnObject &result)
   1327 {
   1328     if (m_options.m_is_add_script)
   1329     {
   1330 #ifndef LLDB_DISABLE_PYTHON
   1331         return Execute_ScriptSummary(command, result);
   1332 #else
   1333         result.AppendError ("python is disabled");
   1334         result.SetStatus(eReturnStatusFailed);
   1335         return false;
   1336 #endif
   1337     }
   1338 
   1339     return Execute_StringSummary(command, result);
   1340 }
   1341 
   1342 bool
   1343 CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
   1344                                         TypeSummaryImplSP entry,
   1345                                         SummaryFormatType type,
   1346                                         std::string category_name,
   1347                                         Error* error)
   1348 {
   1349     lldb::TypeCategoryImplSP category;
   1350     DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
   1351 
   1352     if (type == eRegularSummary)
   1353     {
   1354         std::string type_name_str(type_name.GetCString());
   1355         if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0)
   1356         {
   1357             type_name_str.resize(type_name_str.length()-2);
   1358             if (type_name_str.back() != ' ')
   1359                 type_name_str.append(" \\[[0-9]+\\]");
   1360             else
   1361                 type_name_str.append("\\[[0-9]+\\]");
   1362             type_name.SetCString(type_name_str.c_str());
   1363             type = eRegexSummary;
   1364         }
   1365     }
   1366 
   1367     if (type == eRegexSummary)
   1368     {
   1369         RegularExpressionSP typeRX(new RegularExpression());
   1370         if (!typeRX->Compile(type_name.GetCString()))
   1371         {
   1372             if (error)
   1373                 error->SetErrorString("regex format error (maybe this is not really a regex?)");
   1374             return false;
   1375         }
   1376 
   1377         category->GetRegexSummaryNavigator()->Delete(type_name);
   1378         category->GetRegexSummaryNavigator()->Add(typeRX, entry);
   1379 
   1380         return true;
   1381     }
   1382     else if (type == eNamedSummary)
   1383     {
   1384         // system named summaries do not exist (yet?)
   1385         DataVisualization::NamedSummaryFormats::Add(type_name,entry);
   1386         return true;
   1387     }
   1388     else
   1389     {
   1390         category->GetSummaryNavigator()->Add(type_name, entry);
   1391         return true;
   1392     }
   1393 }
   1394 
   1395 OptionDefinition
   1396 CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
   1397 {
   1398     { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,    "Add this to the given category instead of the default one."},
   1399     { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
   1400     { LLDB_OPT_SET_ALL, false, "no-value", 'v', no_argument, NULL, 0, eArgTypeNone,         "Don't show the value, just show the summary, for this type."},
   1401     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
   1402     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
   1403     { LLDB_OPT_SET_ALL, false,  "regex", 'x', no_argument, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
   1404     { LLDB_OPT_SET_1  , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeNone,    "If true, inline all child values into summary string."},
   1405     { LLDB_OPT_SET_1  , false, "omit-names", 'O', no_argument, NULL, 0, eArgTypeNone,    "If true, omit value names in the summary display."},
   1406     { LLDB_OPT_SET_2  , true, "summary-string", 's', required_argument, NULL, 0, eArgTypeSummaryString,    "Summary string used to display text and object contents."},
   1407     { LLDB_OPT_SET_3, false, "python-script", 'o', required_argument, NULL, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."},
   1408     { LLDB_OPT_SET_3, false, "python-function", 'F', required_argument, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."},
   1409     { LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."},
   1410     { LLDB_OPT_SET_2 | LLDB_OPT_SET_3,   false, "expand", 'e', no_argument, NULL, 0, eArgTypeNone,    "Expand aggregate data types to show children on separate lines."},
   1411     { LLDB_OPT_SET_2 | LLDB_OPT_SET_3,   false, "name", 'n', required_argument, NULL, 0, eArgTypeName,    "A name for this summary string."},
   1412     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   1413 };
   1414 
   1415 
   1416 //-------------------------------------------------------------------------
   1417 // CommandObjectTypeSummaryDelete
   1418 //-------------------------------------------------------------------------
   1419 
   1420 class CommandObjectTypeSummaryDelete : public CommandObjectParsed
   1421 {
   1422 private:
   1423     class CommandOptions : public Options
   1424     {
   1425     public:
   1426 
   1427         CommandOptions (CommandInterpreter &interpreter) :
   1428         Options (interpreter)
   1429         {
   1430         }
   1431 
   1432         virtual
   1433         ~CommandOptions (){}
   1434 
   1435         virtual Error
   1436         SetOptionValue (uint32_t option_idx, const char *option_arg)
   1437         {
   1438             Error error;
   1439             const int short_option = m_getopt_table[option_idx].val;
   1440 
   1441             switch (short_option)
   1442             {
   1443                 case 'a':
   1444                     m_delete_all = true;
   1445                     break;
   1446                 case 'w':
   1447                     m_category = std::string(option_arg);
   1448                     break;
   1449                 default:
   1450                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
   1451                     break;
   1452             }
   1453 
   1454             return error;
   1455         }
   1456 
   1457         void
   1458         OptionParsingStarting ()
   1459         {
   1460             m_delete_all = false;
   1461             m_category = "default";
   1462         }
   1463 
   1464         const OptionDefinition*
   1465         GetDefinitions ()
   1466         {
   1467             return g_option_table;
   1468         }
   1469 
   1470         // Options table: Required for subclasses of Options.
   1471 
   1472         static OptionDefinition g_option_table[];
   1473 
   1474         // Instance variables to hold the values for command options.
   1475 
   1476         bool m_delete_all;
   1477         std::string m_category;
   1478 
   1479     };
   1480 
   1481     CommandOptions m_options;
   1482 
   1483     virtual Options *
   1484     GetOptions ()
   1485     {
   1486         return &m_options;
   1487     }
   1488 
   1489     static bool
   1490     PerCategoryCallback(void* param,
   1491                         const lldb::TypeCategoryImplSP& category_sp)
   1492     {
   1493 		ConstString *name = (ConstString*)param;
   1494 		category_sp->Delete(*name, eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
   1495 		return true;
   1496     }
   1497 
   1498 public:
   1499     CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) :
   1500         CommandObjectParsed (interpreter,
   1501                              "type summary delete",
   1502                              "Delete an existing summary style for a type.",
   1503                              NULL),
   1504         m_options(interpreter)
   1505     {
   1506         CommandArgumentEntry type_arg;
   1507         CommandArgumentData type_style_arg;
   1508 
   1509         type_style_arg.arg_type = eArgTypeName;
   1510         type_style_arg.arg_repetition = eArgRepeatPlain;
   1511 
   1512         type_arg.push_back (type_style_arg);
   1513 
   1514         m_arguments.push_back (type_arg);
   1515 
   1516     }
   1517 
   1518     ~CommandObjectTypeSummaryDelete ()
   1519     {
   1520     }
   1521 
   1522 protected:
   1523     bool
   1524     DoExecute (Args& command, CommandReturnObject &result)
   1525     {
   1526         const size_t argc = command.GetArgumentCount();
   1527 
   1528         if (argc != 1)
   1529         {
   1530             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
   1531             result.SetStatus(eReturnStatusFailed);
   1532             return false;
   1533         }
   1534 
   1535         const char* typeA = command.GetArgumentAtIndex(0);
   1536         ConstString typeCS(typeA);
   1537 
   1538         if (!typeCS)
   1539         {
   1540             result.AppendError("empty typenames not allowed");
   1541             result.SetStatus(eReturnStatusFailed);
   1542             return false;
   1543         }
   1544 
   1545         if (m_options.m_delete_all)
   1546         {
   1547             DataVisualization::Categories::LoopThrough(PerCategoryCallback, &typeCS);
   1548             result.SetStatus(eReturnStatusSuccessFinishNoResult);
   1549             return result.Succeeded();
   1550         }
   1551 
   1552         lldb::TypeCategoryImplSP category;
   1553         DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
   1554 
   1555         bool delete_category = category->Delete(typeCS,
   1556                                                 eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
   1557         bool delete_named = DataVisualization::NamedSummaryFormats::Delete(typeCS);
   1558 
   1559         if (delete_category || delete_named)
   1560         {
   1561             result.SetStatus(eReturnStatusSuccessFinishNoResult);
   1562             return result.Succeeded();
   1563         }
   1564         else
   1565         {
   1566             result.AppendErrorWithFormat ("no custom summary for %s.\n", typeA);
   1567             result.SetStatus(eReturnStatusFailed);
   1568             return false;
   1569         }
   1570 
   1571     }
   1572 };
   1573 
   1574 OptionDefinition
   1575 CommandObjectTypeSummaryDelete::CommandOptions::g_option_table[] =
   1576 {
   1577     { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone,  "Delete from every category."},
   1578     { LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,  "Delete from given category."},
   1579     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   1580 };
   1581 
   1582 class CommandObjectTypeSummaryClear : public CommandObjectParsed
   1583 {
   1584 private:
   1585 
   1586     class CommandOptions : public Options
   1587     {
   1588     public:
   1589 
   1590         CommandOptions (CommandInterpreter &interpreter) :
   1591         Options (interpreter)
   1592         {
   1593         }
   1594 
   1595         virtual
   1596         ~CommandOptions (){}
   1597 
   1598         virtual Error
   1599         SetOptionValue (uint32_t option_idx, const char *option_arg)
   1600         {
   1601             Error error;
   1602             const int short_option = m_getopt_table[option_idx].val;
   1603 
   1604             switch (short_option)
   1605             {
   1606                 case 'a':
   1607                     m_delete_all = true;
   1608                     break;
   1609                 default:
   1610                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
   1611                     break;
   1612             }
   1613 
   1614             return error;
   1615         }
   1616 
   1617         void
   1618         OptionParsingStarting ()
   1619         {
   1620             m_delete_all = false;
   1621         }
   1622 
   1623         const OptionDefinition*
   1624         GetDefinitions ()
   1625         {
   1626             return g_option_table;
   1627         }
   1628 
   1629         // Options table: Required for subclasses of Options.
   1630 
   1631         static OptionDefinition g_option_table[];
   1632 
   1633         // Instance variables to hold the values for command options.
   1634 
   1635         bool m_delete_all;
   1636         bool m_delete_named;
   1637     };
   1638 
   1639     CommandOptions m_options;
   1640 
   1641     virtual Options *
   1642     GetOptions ()
   1643     {
   1644         return &m_options;
   1645     }
   1646 
   1647     static bool
   1648     PerCategoryCallback(void* param,
   1649                         const lldb::TypeCategoryImplSP& cate)
   1650     {
   1651         cate->GetSummaryNavigator()->Clear();
   1652         cate->GetRegexSummaryNavigator()->Clear();
   1653         return true;
   1654 
   1655     }
   1656 
   1657 public:
   1658     CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) :
   1659         CommandObjectParsed (interpreter,
   1660                              "type summary clear",
   1661                              "Delete all existing summary styles.",
   1662                              NULL),
   1663         m_options(interpreter)
   1664     {
   1665     }
   1666 
   1667     ~CommandObjectTypeSummaryClear ()
   1668     {
   1669     }
   1670 
   1671 protected:
   1672     bool
   1673     DoExecute (Args& command, CommandReturnObject &result)
   1674     {
   1675 
   1676         if (m_options.m_delete_all)
   1677             DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL);
   1678 
   1679         else
   1680         {
   1681             lldb::TypeCategoryImplSP category;
   1682             if (command.GetArgumentCount() > 0)
   1683             {
   1684                 const char* cat_name = command.GetArgumentAtIndex(0);
   1685                 ConstString cat_nameCS(cat_name);
   1686                 DataVisualization::Categories::GetCategory(cat_nameCS, category);
   1687             }
   1688             else
   1689                 DataVisualization::Categories::GetCategory(ConstString(NULL), category);
   1690             category->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
   1691         }
   1692 
   1693         DataVisualization::NamedSummaryFormats::Clear();
   1694 
   1695         result.SetStatus(eReturnStatusSuccessFinishResult);
   1696         return result.Succeeded();
   1697     }
   1698 
   1699 };
   1700 
   1701 OptionDefinition
   1702 CommandObjectTypeSummaryClear::CommandOptions::g_option_table[] =
   1703 {
   1704     { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone,  "Clear every category."},
   1705     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   1706 };
   1707 
   1708 //-------------------------------------------------------------------------
   1709 // CommandObjectTypeSummaryList
   1710 //-------------------------------------------------------------------------
   1711 
   1712 bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const StringSummaryFormat::SharedPointer& entry);
   1713 bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const StringSummaryFormat::SharedPointer& entry);
   1714 
   1715 class CommandObjectTypeSummaryList;
   1716 
   1717 struct CommandObjectTypeSummaryList_LoopCallbackParam {
   1718     CommandObjectTypeSummaryList* self;
   1719     CommandReturnObject* result;
   1720     RegularExpression* regex;
   1721     RegularExpression* cate_regex;
   1722     CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R,
   1723                                                   RegularExpression* X = NULL,
   1724                                                   RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
   1725 };
   1726 
   1727 class CommandObjectTypeSummaryList : public CommandObjectParsed
   1728 {
   1729 
   1730     class CommandOptions : public Options
   1731     {
   1732     public:
   1733 
   1734         CommandOptions (CommandInterpreter &interpreter) :
   1735         Options (interpreter)
   1736         {
   1737         }
   1738 
   1739         virtual
   1740         ~CommandOptions (){}
   1741 
   1742         virtual Error
   1743         SetOptionValue (uint32_t option_idx, const char *option_arg)
   1744         {
   1745             Error error;
   1746             const int short_option = m_getopt_table[option_idx].val;
   1747 
   1748             switch (short_option)
   1749             {
   1750                 case 'w':
   1751                     m_category_regex = std::string(option_arg);
   1752                     break;
   1753                 default:
   1754                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
   1755                     break;
   1756             }
   1757 
   1758             return error;
   1759         }
   1760 
   1761         void
   1762         OptionParsingStarting ()
   1763         {
   1764             m_category_regex = "";
   1765         }
   1766 
   1767         const OptionDefinition*
   1768         GetDefinitions ()
   1769         {
   1770             return g_option_table;
   1771         }
   1772 
   1773         // Options table: Required for subclasses of Options.
   1774 
   1775         static OptionDefinition g_option_table[];
   1776 
   1777         // Instance variables to hold the values for command options.
   1778 
   1779         std::string m_category_regex;
   1780 
   1781     };
   1782 
   1783     CommandOptions m_options;
   1784 
   1785     virtual Options *
   1786     GetOptions ()
   1787     {
   1788         return &m_options;
   1789     }
   1790 
   1791 public:
   1792     CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :
   1793         CommandObjectParsed (interpreter,
   1794                              "type summary list",
   1795                              "Show a list of current summary styles.",
   1796                              NULL),
   1797         m_options(interpreter)
   1798     {
   1799         CommandArgumentEntry type_arg;
   1800         CommandArgumentData type_style_arg;
   1801 
   1802         type_style_arg.arg_type = eArgTypeName;
   1803         type_style_arg.arg_repetition = eArgRepeatOptional;
   1804 
   1805         type_arg.push_back (type_style_arg);
   1806 
   1807         m_arguments.push_back (type_arg);
   1808     }
   1809 
   1810     ~CommandObjectTypeSummaryList ()
   1811     {
   1812     }
   1813 
   1814 protected:
   1815     bool
   1816     DoExecute (Args& command, CommandReturnObject &result)
   1817     {
   1818         const size_t argc = command.GetArgumentCount();
   1819 
   1820         CommandObjectTypeSummaryList_LoopCallbackParam *param;
   1821         RegularExpression* cate_regex =
   1822         m_options.m_category_regex.empty() ? NULL :
   1823         new RegularExpression(m_options.m_category_regex.c_str());
   1824 
   1825         if (argc == 1)
   1826         {
   1827             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
   1828             regex->Compile(command.GetArgumentAtIndex(0));
   1829             param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex,cate_regex);
   1830         }
   1831         else
   1832             param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,NULL,cate_regex);
   1833 
   1834         DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
   1835 
   1836         if (DataVisualization::NamedSummaryFormats::GetCount() > 0)
   1837         {
   1838             result.GetOutputStream().Printf("Named summaries:\n");
   1839             if (argc == 1)
   1840             {
   1841                 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
   1842                 regex->Compile(command.GetArgumentAtIndex(0));
   1843                 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex);
   1844             }
   1845             else
   1846                 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);
   1847             DataVisualization::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
   1848             delete param;
   1849         }
   1850 
   1851         if (cate_regex)
   1852             delete cate_regex;
   1853 
   1854         result.SetStatus(eReturnStatusSuccessFinishResult);
   1855         return result.Succeeded();
   1856     }
   1857 
   1858 private:
   1859 
   1860     static bool
   1861     PerCategoryCallback(void* param_vp,
   1862                         const lldb::TypeCategoryImplSP& cate)
   1863     {
   1864 
   1865         CommandObjectTypeSummaryList_LoopCallbackParam* param =
   1866             (CommandObjectTypeSummaryList_LoopCallbackParam*)param_vp;
   1867         CommandReturnObject* result = param->result;
   1868 
   1869         const char* cate_name = cate->GetName();
   1870 
   1871         // if the category is disabled or empty and there is no regex, just skip it
   1872         if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary) == 0) && param->cate_regex == NULL)
   1873             return true;
   1874 
   1875         // if we have a regex and this category does not match it, just skip it
   1876         if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
   1877             return true;
   1878 
   1879         result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n",
   1880                                          cate_name,
   1881                                          (cate->IsEnabled() ? "enabled" : "disabled"));
   1882 
   1883         cate->GetSummaryNavigator()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param_vp);
   1884 
   1885         if (cate->GetRegexSummaryNavigator()->GetCount() > 0)
   1886         {
   1887             result->GetOutputStream().Printf("Regex-based summaries (slower):\n");
   1888             cate->GetRegexSummaryNavigator()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param_vp);
   1889         }
   1890         return true;
   1891     }
   1892 
   1893 
   1894     bool
   1895     LoopCallback (const char* type,
   1896                   const lldb::TypeSummaryImplSP& entry,
   1897                   RegularExpression* regex,
   1898                   CommandReturnObject *result)
   1899     {
   1900         if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type))
   1901                 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
   1902         return true;
   1903     }
   1904 
   1905     friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeSummaryImplSP& entry);
   1906     friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeSummaryImplSP& entry);
   1907 };
   1908 
   1909 bool
   1910 CommandObjectTypeSummaryList_LoopCallback (
   1911                                           void* pt2self,
   1912                                           ConstString type,
   1913                                           const lldb::TypeSummaryImplSP& entry)
   1914 {
   1915     CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;
   1916     return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
   1917 }
   1918 
   1919 bool
   1920 CommandObjectTypeRXSummaryList_LoopCallback (
   1921                                            void* pt2self,
   1922                                            lldb::RegularExpressionSP regex,
   1923                                            const lldb::TypeSummaryImplSP& entry)
   1924 {
   1925     CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;
   1926     return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
   1927 }
   1928 
   1929 OptionDefinition
   1930 CommandObjectTypeSummaryList::CommandOptions::g_option_table[] =
   1931 {
   1932     { LLDB_OPT_SET_ALL, false, "category-regex", 'w', required_argument, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
   1933     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   1934 };
   1935 
   1936 //-------------------------------------------------------------------------
   1937 // CommandObjectTypeCategoryEnable
   1938 //-------------------------------------------------------------------------
   1939 
   1940 class CommandObjectTypeCategoryEnable : public CommandObjectParsed
   1941 {
   1942 public:
   1943     CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) :
   1944         CommandObjectParsed (interpreter,
   1945                              "type category enable",
   1946                              "Enable a category as a source of formatters.",
   1947                              NULL)
   1948     {
   1949         CommandArgumentEntry type_arg;
   1950         CommandArgumentData type_style_arg;
   1951 
   1952         type_style_arg.arg_type = eArgTypeName;
   1953         type_style_arg.arg_repetition = eArgRepeatPlus;
   1954 
   1955         type_arg.push_back (type_style_arg);
   1956 
   1957         m_arguments.push_back (type_arg);
   1958 
   1959     }
   1960 
   1961     ~CommandObjectTypeCategoryEnable ()
   1962     {
   1963     }
   1964 
   1965 protected:
   1966     bool
   1967     DoExecute (Args& command, CommandReturnObject &result)
   1968     {
   1969         const size_t argc = command.GetArgumentCount();
   1970 
   1971         if (argc < 1)
   1972         {
   1973             result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
   1974             result.SetStatus(eReturnStatusFailed);
   1975             return false;
   1976         }
   1977 
   1978         if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
   1979         {
   1980             // we want to make sure to enable "system" last and "default" first
   1981             DataVisualization::Categories::Enable(ConstString("default"), TypeCategoryMap::First);
   1982             uint32_t num_categories = DataVisualization::Categories::GetCount();
   1983             for (uint32_t i = 0; i < num_categories; i++)
   1984             {
   1985                 lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i);
   1986                 if (category_sp)
   1987                 {
   1988                     if ( ::strcmp(category_sp->GetName(), "system") == 0 ||
   1989                          ::strcmp(category_sp->GetName(), "default") == 0 )
   1990                         continue;
   1991                     else
   1992                         DataVisualization::Categories::Enable(category_sp, TypeCategoryMap::Default);
   1993                 }
   1994             }
   1995             DataVisualization::Categories::Enable(ConstString("system"), TypeCategoryMap::Last);
   1996         }
   1997         else
   1998         {
   1999             for (int i = argc - 1; i >= 0; i--)
   2000             {
   2001                 const char* typeA = command.GetArgumentAtIndex(i);
   2002                 ConstString typeCS(typeA);
   2003 
   2004                 if (!typeCS)
   2005                 {
   2006                     result.AppendError("empty category name not allowed");
   2007                     result.SetStatus(eReturnStatusFailed);
   2008                     return false;
   2009                 }
   2010                 DataVisualization::Categories::Enable(typeCS);
   2011                 lldb::TypeCategoryImplSP cate;
   2012                 if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get())
   2013                 {
   2014                     if (cate->GetCount() == 0)
   2015                     {
   2016                         result.AppendWarning("empty category enabled (typo?)");
   2017                     }
   2018                 }
   2019             }
   2020         }
   2021 
   2022         result.SetStatus(eReturnStatusSuccessFinishResult);
   2023         return result.Succeeded();
   2024     }
   2025 
   2026 };
   2027 
   2028 //-------------------------------------------------------------------------
   2029 // CommandObjectTypeCategoryDelete
   2030 //-------------------------------------------------------------------------
   2031 
   2032 class CommandObjectTypeCategoryDelete : public CommandObjectParsed
   2033 {
   2034 public:
   2035     CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) :
   2036         CommandObjectParsed (interpreter,
   2037                              "type category delete",
   2038                              "Delete a category and all associated formatters.",
   2039                              NULL)
   2040     {
   2041         CommandArgumentEntry type_arg;
   2042         CommandArgumentData type_style_arg;
   2043 
   2044         type_style_arg.arg_type = eArgTypeName;
   2045         type_style_arg.arg_repetition = eArgRepeatPlus;
   2046 
   2047         type_arg.push_back (type_style_arg);
   2048 
   2049         m_arguments.push_back (type_arg);
   2050 
   2051     }
   2052 
   2053     ~CommandObjectTypeCategoryDelete ()
   2054     {
   2055     }
   2056 
   2057 protected:
   2058     bool
   2059     DoExecute (Args& command, CommandReturnObject &result)
   2060     {
   2061         const size_t argc = command.GetArgumentCount();
   2062 
   2063         if (argc < 1)
   2064         {
   2065             result.AppendErrorWithFormat ("%s takes 1 or more arg.\n", m_cmd_name.c_str());
   2066             result.SetStatus(eReturnStatusFailed);
   2067             return false;
   2068         }
   2069 
   2070         bool success = true;
   2071 
   2072         // the order is not relevant here
   2073         for (int i = argc - 1; i >= 0; i--)
   2074         {
   2075             const char* typeA = command.GetArgumentAtIndex(i);
   2076             ConstString typeCS(typeA);
   2077 
   2078             if (!typeCS)
   2079             {
   2080                 result.AppendError("empty category name not allowed");
   2081                 result.SetStatus(eReturnStatusFailed);
   2082                 return false;
   2083             }
   2084             if (!DataVisualization::Categories::Delete(typeCS))
   2085                 success = false; // keep deleting even if we hit an error
   2086         }
   2087         if (success)
   2088         {
   2089             result.SetStatus(eReturnStatusSuccessFinishResult);
   2090             return result.Succeeded();
   2091         }
   2092         else
   2093         {
   2094             result.AppendError("cannot delete one or more categories\n");
   2095             result.SetStatus(eReturnStatusFailed);
   2096             return false;
   2097         }
   2098     }
   2099 };
   2100 
   2101 //-------------------------------------------------------------------------
   2102 // CommandObjectTypeCategoryDisable
   2103 //-------------------------------------------------------------------------
   2104 
   2105 class CommandObjectTypeCategoryDisable : public CommandObjectParsed
   2106 {
   2107 public:
   2108     CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
   2109         CommandObjectParsed (interpreter,
   2110                              "type category disable",
   2111                              "Disable a category as a source of formatters.",
   2112                              NULL)
   2113     {
   2114         CommandArgumentEntry type_arg;
   2115         CommandArgumentData type_style_arg;
   2116 
   2117         type_style_arg.arg_type = eArgTypeName;
   2118         type_style_arg.arg_repetition = eArgRepeatPlus;
   2119 
   2120         type_arg.push_back (type_style_arg);
   2121 
   2122         m_arguments.push_back (type_arg);
   2123 
   2124     }
   2125 
   2126     ~CommandObjectTypeCategoryDisable ()
   2127     {
   2128     }
   2129 
   2130 protected:
   2131     bool
   2132     DoExecute (Args& command, CommandReturnObject &result)
   2133     {
   2134         const size_t argc = command.GetArgumentCount();
   2135 
   2136         if (argc < 1)
   2137         {
   2138             result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
   2139             result.SetStatus(eReturnStatusFailed);
   2140             return false;
   2141         }
   2142 
   2143         if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
   2144         {
   2145             uint32_t num_categories = DataVisualization::Categories::GetCount();
   2146             for (uint32_t i = 0; i < num_categories; i++)
   2147             {
   2148                 lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i);
   2149                 // no need to check if the category is enabled - disabling a disabled category has no effect
   2150                 if (category_sp)
   2151                     DataVisualization::Categories::Disable(category_sp);
   2152             }
   2153         }
   2154         else
   2155         {
   2156             // the order is not relevant here
   2157             for (int i = argc - 1; i >= 0; i--)
   2158             {
   2159                 const char* typeA = command.GetArgumentAtIndex(i);
   2160                 ConstString typeCS(typeA);
   2161 
   2162                 if (!typeCS)
   2163                 {
   2164                     result.AppendError("empty category name not allowed");
   2165                     result.SetStatus(eReturnStatusFailed);
   2166                     return false;
   2167                 }
   2168                 DataVisualization::Categories::Disable(typeCS);
   2169             }
   2170         }
   2171 
   2172         result.SetStatus(eReturnStatusSuccessFinishResult);
   2173         return result.Succeeded();
   2174     }
   2175 
   2176 };
   2177 
   2178 //-------------------------------------------------------------------------
   2179 // CommandObjectTypeCategoryList
   2180 //-------------------------------------------------------------------------
   2181 
   2182 class CommandObjectTypeCategoryList : public CommandObjectParsed
   2183 {
   2184 private:
   2185 
   2186     struct CommandObjectTypeCategoryList_CallbackParam
   2187     {
   2188         CommandReturnObject* result;
   2189         RegularExpression* regex;
   2190 
   2191         CommandObjectTypeCategoryList_CallbackParam(CommandReturnObject* res,
   2192                                                     RegularExpression* rex = NULL) :
   2193         result(res),
   2194         regex(rex)
   2195         {
   2196         }
   2197 
   2198     };
   2199 
   2200     static bool
   2201     PerCategoryCallback(void* param_vp,
   2202                         const lldb::TypeCategoryImplSP& cate)
   2203     {
   2204         CommandObjectTypeCategoryList_CallbackParam* param =
   2205             (CommandObjectTypeCategoryList_CallbackParam*)param_vp;
   2206         CommandReturnObject* result = param->result;
   2207         RegularExpression* regex = param->regex;
   2208 
   2209         const char* cate_name = cate->GetName();
   2210 
   2211         if (regex == NULL || strcmp(cate_name, regex->GetText()) == 0 || regex->Execute(cate_name))
   2212             result->GetOutputStream().Printf("Category %s is%s enabled\n",
   2213                                        cate_name,
   2214                                        (cate->IsEnabled() ? "" : " not"));
   2215         return true;
   2216     }
   2217 public:
   2218     CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :
   2219         CommandObjectParsed (interpreter,
   2220                              "type category list",
   2221                              "Provide a list of all existing categories.",
   2222                              NULL)
   2223     {
   2224         CommandArgumentEntry type_arg;
   2225         CommandArgumentData type_style_arg;
   2226 
   2227         type_style_arg.arg_type = eArgTypeName;
   2228         type_style_arg.arg_repetition = eArgRepeatOptional;
   2229 
   2230         type_arg.push_back (type_style_arg);
   2231 
   2232         m_arguments.push_back (type_arg);
   2233     }
   2234 
   2235     ~CommandObjectTypeCategoryList ()
   2236     {
   2237     }
   2238 
   2239 protected:
   2240     bool
   2241     DoExecute (Args& command, CommandReturnObject &result)
   2242     {
   2243         const size_t argc = command.GetArgumentCount();
   2244         RegularExpression* regex = NULL;
   2245 
   2246         if (argc == 0)
   2247             ;
   2248         else if (argc == 1)
   2249             regex = new RegularExpression(command.GetArgumentAtIndex(0));
   2250         else
   2251         {
   2252             result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str());
   2253             result.SetStatus(eReturnStatusFailed);
   2254             return false;
   2255         }
   2256 
   2257         CommandObjectTypeCategoryList_CallbackParam param(&result,
   2258                                                           regex);
   2259 
   2260         DataVisualization::Categories::LoopThrough(PerCategoryCallback, &param);
   2261 
   2262         if (regex)
   2263             delete regex;
   2264 
   2265         result.SetStatus(eReturnStatusSuccessFinishResult);
   2266         return result.Succeeded();
   2267     }
   2268 
   2269 };
   2270 
   2271 //-------------------------------------------------------------------------
   2272 // CommandObjectTypeFilterList
   2273 //-------------------------------------------------------------------------
   2274 
   2275 bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
   2276 bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
   2277 
   2278 class CommandObjectTypeFilterList;
   2279 
   2280 struct CommandObjectTypeFilterList_LoopCallbackParam {
   2281     CommandObjectTypeFilterList* self;
   2282     CommandReturnObject* result;
   2283     RegularExpression* regex;
   2284     RegularExpression* cate_regex;
   2285     CommandObjectTypeFilterList_LoopCallbackParam(CommandObjectTypeFilterList* S, CommandReturnObject* R,
   2286                                                   RegularExpression* X = NULL,
   2287                                                   RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
   2288 };
   2289 
   2290 class CommandObjectTypeFilterList : public CommandObjectParsed
   2291 {
   2292 
   2293     class CommandOptions : public Options
   2294     {
   2295     public:
   2296 
   2297         CommandOptions (CommandInterpreter &interpreter) :
   2298         Options (interpreter)
   2299         {
   2300         }
   2301 
   2302         virtual
   2303         ~CommandOptions (){}
   2304 
   2305         virtual Error
   2306         SetOptionValue (uint32_t option_idx, const char *option_arg)
   2307         {
   2308             Error error;
   2309             const int short_option = m_getopt_table[option_idx].val;
   2310 
   2311             switch (short_option)
   2312             {
   2313                 case 'w':
   2314                     m_category_regex = std::string(option_arg);
   2315                     break;
   2316                 default:
   2317                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
   2318                     break;
   2319             }
   2320 
   2321             return error;
   2322         }
   2323 
   2324         void
   2325         OptionParsingStarting ()
   2326         {
   2327             m_category_regex = "";
   2328         }
   2329 
   2330         const OptionDefinition*
   2331         GetDefinitions ()
   2332         {
   2333             return g_option_table;
   2334         }
   2335 
   2336         // Options table: Required for subclasses of Options.
   2337 
   2338         static OptionDefinition g_option_table[];
   2339 
   2340         // Instance variables to hold the values for command options.
   2341 
   2342         std::string m_category_regex;
   2343 
   2344     };
   2345 
   2346     CommandOptions m_options;
   2347 
   2348     virtual Options *
   2349     GetOptions ()
   2350     {
   2351         return &m_options;
   2352     }
   2353 
   2354 public:
   2355     CommandObjectTypeFilterList (CommandInterpreter &interpreter) :
   2356         CommandObjectParsed (interpreter,
   2357                              "type filter list",
   2358                              "Show a list of current filters.",
   2359                              NULL),
   2360         m_options(interpreter)
   2361     {
   2362         CommandArgumentEntry type_arg;
   2363         CommandArgumentData type_style_arg;
   2364 
   2365         type_style_arg.arg_type = eArgTypeName;
   2366         type_style_arg.arg_repetition = eArgRepeatOptional;
   2367 
   2368         type_arg.push_back (type_style_arg);
   2369 
   2370         m_arguments.push_back (type_arg);
   2371     }
   2372 
   2373     ~CommandObjectTypeFilterList ()
   2374     {
   2375     }
   2376 
   2377 protected:
   2378     bool
   2379     DoExecute (Args& command, CommandReturnObject &result)
   2380     {
   2381         const size_t argc = command.GetArgumentCount();
   2382 
   2383         CommandObjectTypeFilterList_LoopCallbackParam *param;
   2384         RegularExpression* cate_regex =
   2385         m_options.m_category_regex.empty() ? NULL :
   2386         new RegularExpression(m_options.m_category_regex.c_str());
   2387 
   2388         if (argc == 1)
   2389         {
   2390             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
   2391             regex->Compile(command.GetArgumentAtIndex(0));
   2392             param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex);
   2393         }
   2394         else
   2395             param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex);
   2396 
   2397         DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
   2398 
   2399         if (cate_regex)
   2400             delete cate_regex;
   2401 
   2402         result.SetStatus(eReturnStatusSuccessFinishResult);
   2403         return result.Succeeded();
   2404     }
   2405 
   2406 private:
   2407 
   2408     static bool
   2409     PerCategoryCallback(void* param_vp,
   2410                         const lldb::TypeCategoryImplSP& cate)
   2411     {
   2412 
   2413         const char* cate_name = cate->GetName();
   2414 
   2415         CommandObjectTypeFilterList_LoopCallbackParam* param =
   2416         (CommandObjectTypeFilterList_LoopCallbackParam*)param_vp;
   2417         CommandReturnObject* result = param->result;
   2418 
   2419         // if the category is disabled or empty and there is no regex, just skip it
   2420         if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter) == 0) && param->cate_regex == NULL)
   2421             return true;
   2422 
   2423         // if we have a regex and this category does not match it, just skip it
   2424         if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
   2425             return true;
   2426 
   2427         result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n",
   2428                                          cate_name,
   2429                                          (cate->IsEnabled() ? "enabled" : "disabled"));
   2430 
   2431         cate->GetFilterNavigator()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp);
   2432 
   2433         if (cate->GetRegexFilterNavigator()->GetCount() > 0)
   2434         {
   2435             result->GetOutputStream().Printf("Regex-based filters (slower):\n");
   2436             cate->GetRegexFilterNavigator()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp);
   2437         }
   2438 
   2439         return true;
   2440     }
   2441 
   2442     bool
   2443     LoopCallback (const char* type,
   2444                   const SyntheticChildren::SharedPointer& entry,
   2445                   RegularExpression* regex,
   2446                   CommandReturnObject *result)
   2447     {
   2448         if (regex == NULL || regex->Execute(type))
   2449             result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
   2450         return true;
   2451     }
   2452 
   2453     friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
   2454     friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
   2455 };
   2456 
   2457 bool
   2458 CommandObjectTypeFilterList_LoopCallback (void* pt2self,
   2459                                          ConstString type,
   2460                                          const SyntheticChildren::SharedPointer& entry)
   2461 {
   2462     CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self;
   2463     return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
   2464 }
   2465 
   2466 bool
   2467 CommandObjectTypeFilterRXList_LoopCallback (void* pt2self,
   2468                                            lldb::RegularExpressionSP regex,
   2469                                            const SyntheticChildren::SharedPointer& entry)
   2470 {
   2471     CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self;
   2472     return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
   2473 }
   2474 
   2475 
   2476 OptionDefinition
   2477 CommandObjectTypeFilterList::CommandOptions::g_option_table[] =
   2478 {
   2479     { LLDB_OPT_SET_ALL, false, "category-regex", 'w', required_argument, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
   2480     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   2481 };
   2482 
   2483 #ifndef LLDB_DISABLE_PYTHON
   2484 
   2485 //-------------------------------------------------------------------------
   2486 // CommandObjectTypeSynthList
   2487 //-------------------------------------------------------------------------
   2488 
   2489 bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
   2490 bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
   2491 
   2492 class CommandObjectTypeSynthList;
   2493 
   2494 struct CommandObjectTypeSynthList_LoopCallbackParam {
   2495     CommandObjectTypeSynthList* self;
   2496     CommandReturnObject* result;
   2497     RegularExpression* regex;
   2498     RegularExpression* cate_regex;
   2499     CommandObjectTypeSynthList_LoopCallbackParam(CommandObjectTypeSynthList* S, CommandReturnObject* R,
   2500                                                  RegularExpression* X = NULL,
   2501                                                  RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
   2502 };
   2503 
   2504 class CommandObjectTypeSynthList : public CommandObjectParsed
   2505 {
   2506 
   2507     class CommandOptions : public Options
   2508     {
   2509     public:
   2510 
   2511         CommandOptions (CommandInterpreter &interpreter) :
   2512         Options (interpreter)
   2513         {
   2514         }
   2515 
   2516         virtual
   2517         ~CommandOptions (){}
   2518 
   2519         virtual Error
   2520         SetOptionValue (uint32_t option_idx, const char *option_arg)
   2521         {
   2522             Error error;
   2523             const int short_option = m_getopt_table[option_idx].val;
   2524 
   2525             switch (short_option)
   2526             {
   2527                 case 'w':
   2528                     m_category_regex = std::string(option_arg);
   2529                     break;
   2530                 default:
   2531                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
   2532                     break;
   2533             }
   2534 
   2535             return error;
   2536         }
   2537 
   2538         void
   2539         OptionParsingStarting ()
   2540         {
   2541             m_category_regex = "";
   2542         }
   2543 
   2544         const OptionDefinition*
   2545         GetDefinitions ()
   2546         {
   2547             return g_option_table;
   2548         }
   2549 
   2550         // Options table: Required for subclasses of Options.
   2551 
   2552         static OptionDefinition g_option_table[];
   2553 
   2554         // Instance variables to hold the values for command options.
   2555 
   2556         std::string m_category_regex;
   2557 
   2558     };
   2559 
   2560     CommandOptions m_options;
   2561 
   2562     virtual Options *
   2563     GetOptions ()
   2564     {
   2565         return &m_options;
   2566     }
   2567 
   2568 public:
   2569     CommandObjectTypeSynthList (CommandInterpreter &interpreter) :
   2570         CommandObjectParsed (interpreter,
   2571                              "type synthetic list",
   2572                              "Show a list of current synthetic providers.",
   2573                              NULL),
   2574         m_options(interpreter)
   2575     {
   2576         CommandArgumentEntry type_arg;
   2577         CommandArgumentData type_style_arg;
   2578 
   2579         type_style_arg.arg_type = eArgTypeName;
   2580         type_style_arg.arg_repetition = eArgRepeatOptional;
   2581 
   2582         type_arg.push_back (type_style_arg);
   2583 
   2584         m_arguments.push_back (type_arg);
   2585     }
   2586 
   2587     ~CommandObjectTypeSynthList ()
   2588     {
   2589     }
   2590 
   2591 protected:
   2592     bool
   2593     DoExecute (Args& command, CommandReturnObject &result)
   2594     {
   2595         const size_t argc = command.GetArgumentCount();
   2596 
   2597         CommandObjectTypeSynthList_LoopCallbackParam *param;
   2598         RegularExpression* cate_regex =
   2599         m_options.m_category_regex.empty() ? NULL :
   2600         new RegularExpression(m_options.m_category_regex.c_str());
   2601 
   2602         if (argc == 1)
   2603         {
   2604             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
   2605             regex->Compile(command.GetArgumentAtIndex(0));
   2606             param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,regex,cate_regex);
   2607         }
   2608         else
   2609             param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex);
   2610 
   2611         DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
   2612 
   2613         if (cate_regex)
   2614             delete cate_regex;
   2615 
   2616         result.SetStatus(eReturnStatusSuccessFinishResult);
   2617         return result.Succeeded();
   2618     }
   2619 
   2620 private:
   2621 
   2622     static bool
   2623     PerCategoryCallback(void* param_vp,
   2624                         const lldb::TypeCategoryImplSP& cate)
   2625     {
   2626 
   2627         CommandObjectTypeSynthList_LoopCallbackParam* param =
   2628         (CommandObjectTypeSynthList_LoopCallbackParam*)param_vp;
   2629         CommandReturnObject* result = param->result;
   2630 
   2631         const char* cate_name = cate->GetName();
   2632 
   2633         // if the category is disabled or empty and there is no regex, just skip it
   2634         if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth) == 0) && param->cate_regex == NULL)
   2635             return true;
   2636 
   2637         // if we have a regex and this category does not match it, just skip it
   2638         if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
   2639             return true;
   2640 
   2641         result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n",
   2642                                          cate_name,
   2643                                          (cate->IsEnabled() ? "enabled" : "disabled"));
   2644 
   2645         cate->GetSyntheticNavigator()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp);
   2646 
   2647         if (cate->GetRegexSyntheticNavigator()->GetCount() > 0)
   2648         {
   2649             result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n");
   2650             cate->GetRegexSyntheticNavigator()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp);
   2651         }
   2652 
   2653         return true;
   2654     }
   2655 
   2656     bool
   2657     LoopCallback (const char* type,
   2658                   const SyntheticChildren::SharedPointer& entry,
   2659                   RegularExpression* regex,
   2660                   CommandReturnObject *result)
   2661     {
   2662         if (regex == NULL || regex->Execute(type))
   2663             result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
   2664         return true;
   2665     }
   2666 
   2667     friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
   2668     friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
   2669 };
   2670 
   2671 bool
   2672 CommandObjectTypeSynthList_LoopCallback (void* pt2self,
   2673                                          ConstString type,
   2674                                          const SyntheticChildren::SharedPointer& entry)
   2675 {
   2676     CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
   2677     return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
   2678 }
   2679 
   2680 bool
   2681 CommandObjectTypeSynthRXList_LoopCallback (void* pt2self,
   2682                                          lldb::RegularExpressionSP regex,
   2683                                          const SyntheticChildren::SharedPointer& entry)
   2684 {
   2685     CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
   2686     return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
   2687 }
   2688 
   2689 
   2690 OptionDefinition
   2691 CommandObjectTypeSynthList::CommandOptions::g_option_table[] =
   2692 {
   2693     { LLDB_OPT_SET_ALL, false, "category-regex", 'w', required_argument, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
   2694     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   2695 };
   2696 
   2697 #endif // #ifndef LLDB_DISABLE_PYTHON
   2698 //-------------------------------------------------------------------------
   2699 // CommandObjectTypeFilterDelete
   2700 //-------------------------------------------------------------------------
   2701 
   2702 class CommandObjectTypeFilterDelete : public CommandObjectParsed
   2703 {
   2704 private:
   2705     class CommandOptions : public Options
   2706     {
   2707     public:
   2708 
   2709         CommandOptions (CommandInterpreter &interpreter) :
   2710         Options (interpreter)
   2711         {
   2712         }
   2713 
   2714         virtual
   2715         ~CommandOptions (){}
   2716 
   2717         virtual Error
   2718         SetOptionValue (uint32_t option_idx, const char *option_arg)
   2719         {
   2720             Error error;
   2721             const int short_option = m_getopt_table[option_idx].val;
   2722 
   2723             switch (short_option)
   2724             {
   2725                 case 'a':
   2726                     m_delete_all = true;
   2727                     break;
   2728                 case 'w':
   2729                     m_category = std::string(option_arg);
   2730                     break;
   2731                 default:
   2732                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
   2733                     break;
   2734             }
   2735 
   2736             return error;
   2737         }
   2738 
   2739         void
   2740         OptionParsingStarting ()
   2741         {
   2742             m_delete_all = false;
   2743             m_category = "default";
   2744         }
   2745 
   2746         const OptionDefinition*
   2747         GetDefinitions ()
   2748         {
   2749             return g_option_table;
   2750         }
   2751 
   2752         // Options table: Required for subclasses of Options.
   2753 
   2754         static OptionDefinition g_option_table[];
   2755 
   2756         // Instance variables to hold the values for command options.
   2757 
   2758         bool m_delete_all;
   2759         std::string m_category;
   2760 
   2761     };
   2762 
   2763     CommandOptions m_options;
   2764 
   2765     virtual Options *
   2766     GetOptions ()
   2767     {
   2768         return &m_options;
   2769     }
   2770 
   2771     static bool
   2772     PerCategoryCallback(void* param,
   2773                         const lldb::TypeCategoryImplSP& cate)
   2774     {
   2775         ConstString *name = (ConstString*)param;
   2776         return cate->Delete(*name, eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter);
   2777     }
   2778 
   2779 public:
   2780     CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) :
   2781         CommandObjectParsed (interpreter,
   2782                              "type filter delete",
   2783                              "Delete an existing filter for a type.",
   2784                              NULL),
   2785         m_options(interpreter)
   2786     {
   2787         CommandArgumentEntry type_arg;
   2788         CommandArgumentData type_style_arg;
   2789 
   2790         type_style_arg.arg_type = eArgTypeName;
   2791         type_style_arg.arg_repetition = eArgRepeatPlain;
   2792 
   2793         type_arg.push_back (type_style_arg);
   2794 
   2795         m_arguments.push_back (type_arg);
   2796 
   2797     }
   2798 
   2799     ~CommandObjectTypeFilterDelete ()
   2800     {
   2801     }
   2802 
   2803 protected:
   2804     bool
   2805     DoExecute (Args& command, CommandReturnObject &result)
   2806     {
   2807         const size_t argc = command.GetArgumentCount();
   2808 
   2809         if (argc != 1)
   2810         {
   2811             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
   2812             result.SetStatus(eReturnStatusFailed);
   2813             return false;
   2814         }
   2815 
   2816         const char* typeA = command.GetArgumentAtIndex(0);
   2817         ConstString typeCS(typeA);
   2818 
   2819         if (!typeCS)
   2820         {
   2821             result.AppendError("empty typenames not allowed");
   2822             result.SetStatus(eReturnStatusFailed);
   2823             return false;
   2824         }
   2825 
   2826         if (m_options.m_delete_all)
   2827         {
   2828             DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS);
   2829             result.SetStatus(eReturnStatusSuccessFinishNoResult);
   2830             return result.Succeeded();
   2831         }
   2832 
   2833         lldb::TypeCategoryImplSP category;
   2834         DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
   2835 
   2836         bool delete_category = category->GetFilterNavigator()->Delete(typeCS);
   2837         delete_category = category->GetRegexFilterNavigator()->Delete(typeCS) || delete_category;
   2838 
   2839         if (delete_category)
   2840         {
   2841             result.SetStatus(eReturnStatusSuccessFinishNoResult);
   2842             return result.Succeeded();
   2843         }
   2844         else
   2845         {
   2846             result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA);
   2847             result.SetStatus(eReturnStatusFailed);
   2848             return false;
   2849         }
   2850 
   2851     }
   2852 };
   2853 
   2854 OptionDefinition
   2855 CommandObjectTypeFilterDelete::CommandOptions::g_option_table[] =
   2856 {
   2857     { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone,  "Delete from every category."},
   2858     { LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,  "Delete from given category."},
   2859     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   2860 };
   2861 
   2862 #ifndef LLDB_DISABLE_PYTHON
   2863 
   2864 //-------------------------------------------------------------------------
   2865 // CommandObjectTypeSynthDelete
   2866 //-------------------------------------------------------------------------
   2867 
   2868 class CommandObjectTypeSynthDelete : public CommandObjectParsed
   2869 {
   2870 private:
   2871     class CommandOptions : public Options
   2872     {
   2873     public:
   2874 
   2875         CommandOptions (CommandInterpreter &interpreter) :
   2876         Options (interpreter)
   2877         {
   2878         }
   2879 
   2880         virtual
   2881         ~CommandOptions (){}
   2882 
   2883         virtual Error
   2884         SetOptionValue (uint32_t option_idx, const char *option_arg)
   2885         {
   2886             Error error;
   2887             const int short_option = m_getopt_table[option_idx].val;
   2888 
   2889             switch (short_option)
   2890             {
   2891                 case 'a':
   2892                     m_delete_all = true;
   2893                     break;
   2894                 case 'w':
   2895                     m_category = std::string(option_arg);
   2896                     break;
   2897                 default:
   2898                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
   2899                     break;
   2900             }
   2901 
   2902             return error;
   2903         }
   2904 
   2905         void
   2906         OptionParsingStarting ()
   2907         {
   2908             m_delete_all = false;
   2909             m_category = "default";
   2910         }
   2911 
   2912         const OptionDefinition*
   2913         GetDefinitions ()
   2914         {
   2915             return g_option_table;
   2916         }
   2917 
   2918         // Options table: Required for subclasses of Options.
   2919 
   2920         static OptionDefinition g_option_table[];
   2921 
   2922         // Instance variables to hold the values for command options.
   2923 
   2924         bool m_delete_all;
   2925         std::string m_category;
   2926 
   2927     };
   2928 
   2929     CommandOptions m_options;
   2930 
   2931     virtual Options *
   2932     GetOptions ()
   2933     {
   2934         return &m_options;
   2935     }
   2936 
   2937     static bool
   2938     PerCategoryCallback(void* param,
   2939                         const lldb::TypeCategoryImplSP& cate)
   2940     {
   2941         ConstString* name = (ConstString*)param;
   2942         return cate->Delete(*name, eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth);
   2943     }
   2944 
   2945 public:
   2946     CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) :
   2947         CommandObjectParsed (interpreter,
   2948                              "type synthetic delete",
   2949                              "Delete an existing synthetic provider for a type.",
   2950                              NULL),
   2951         m_options(interpreter)
   2952     {
   2953         CommandArgumentEntry type_arg;
   2954         CommandArgumentData type_style_arg;
   2955 
   2956         type_style_arg.arg_type = eArgTypeName;
   2957         type_style_arg.arg_repetition = eArgRepeatPlain;
   2958 
   2959         type_arg.push_back (type_style_arg);
   2960 
   2961         m_arguments.push_back (type_arg);
   2962 
   2963     }
   2964 
   2965     ~CommandObjectTypeSynthDelete ()
   2966     {
   2967     }
   2968 
   2969 protected:
   2970     bool
   2971     DoExecute (Args& command, CommandReturnObject &result)
   2972     {
   2973         const size_t argc = command.GetArgumentCount();
   2974 
   2975         if (argc != 1)
   2976         {
   2977             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
   2978             result.SetStatus(eReturnStatusFailed);
   2979             return false;
   2980         }
   2981 
   2982         const char* typeA = command.GetArgumentAtIndex(0);
   2983         ConstString typeCS(typeA);
   2984 
   2985         if (!typeCS)
   2986         {
   2987             result.AppendError("empty typenames not allowed");
   2988             result.SetStatus(eReturnStatusFailed);
   2989             return false;
   2990         }
   2991 
   2992         if (m_options.m_delete_all)
   2993         {
   2994             DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS);
   2995             result.SetStatus(eReturnStatusSuccessFinishNoResult);
   2996             return result.Succeeded();
   2997         }
   2998 
   2999         lldb::TypeCategoryImplSP category;
   3000         DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
   3001 
   3002         bool delete_category = category->GetSyntheticNavigator()->Delete(typeCS);
   3003         delete_category = category->GetRegexSyntheticNavigator()->Delete(typeCS) || delete_category;
   3004 
   3005         if (delete_category)
   3006         {
   3007             result.SetStatus(eReturnStatusSuccessFinishNoResult);
   3008             return result.Succeeded();
   3009         }
   3010         else
   3011         {
   3012             result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA);
   3013             result.SetStatus(eReturnStatusFailed);
   3014             return false;
   3015         }
   3016 
   3017     }
   3018 };
   3019 
   3020 OptionDefinition
   3021 CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] =
   3022 {
   3023     { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone,  "Delete from every category."},
   3024     { LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,  "Delete from given category."},
   3025     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   3026 };
   3027 
   3028 #endif // #ifndef LLDB_DISABLE_PYTHON
   3029 
   3030 //-------------------------------------------------------------------------
   3031 // CommandObjectTypeFilterClear
   3032 //-------------------------------------------------------------------------
   3033 
   3034 class CommandObjectTypeFilterClear : public CommandObjectParsed
   3035 {
   3036 private:
   3037 
   3038     class CommandOptions : public Options
   3039     {
   3040     public:
   3041 
   3042         CommandOptions (CommandInterpreter &interpreter) :
   3043         Options (interpreter)
   3044         {
   3045         }
   3046 
   3047         virtual
   3048         ~CommandOptions (){}
   3049 
   3050         virtual Error
   3051         SetOptionValue (uint32_t option_idx, const char *option_arg)
   3052         {
   3053             Error error;
   3054             const int short_option = m_getopt_table[option_idx].val;
   3055 
   3056             switch (short_option)
   3057             {
   3058                 case 'a':
   3059                     m_delete_all = true;
   3060                     break;
   3061                 default:
   3062                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
   3063                     break;
   3064             }
   3065 
   3066             return error;
   3067         }
   3068 
   3069         void
   3070         OptionParsingStarting ()
   3071         {
   3072             m_delete_all = false;
   3073         }
   3074 
   3075         const OptionDefinition*
   3076         GetDefinitions ()
   3077         {
   3078             return g_option_table;
   3079         }
   3080 
   3081         // Options table: Required for subclasses of Options.
   3082 
   3083         static OptionDefinition g_option_table[];
   3084 
   3085         // Instance variables to hold the values for command options.
   3086 
   3087         bool m_delete_all;
   3088         bool m_delete_named;
   3089     };
   3090 
   3091     CommandOptions m_options;
   3092 
   3093     virtual Options *
   3094     GetOptions ()
   3095     {
   3096         return &m_options;
   3097     }
   3098 
   3099     static bool
   3100     PerCategoryCallback(void* param,
   3101                         const lldb::TypeCategoryImplSP& cate)
   3102     {
   3103         cate->Clear(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter);
   3104         return true;
   3105 
   3106     }
   3107 
   3108 public:
   3109     CommandObjectTypeFilterClear (CommandInterpreter &interpreter) :
   3110         CommandObjectParsed (interpreter,
   3111                              "type filter clear",
   3112                              "Delete all existing filters.",
   3113                              NULL),
   3114         m_options(interpreter)
   3115     {
   3116     }
   3117 
   3118     ~CommandObjectTypeFilterClear ()
   3119     {
   3120     }
   3121 
   3122 protected:
   3123     bool
   3124     DoExecute (Args& command, CommandReturnObject &result)
   3125     {
   3126 
   3127         if (m_options.m_delete_all)
   3128             DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL);
   3129 
   3130         else
   3131         {
   3132             lldb::TypeCategoryImplSP category;
   3133             if (command.GetArgumentCount() > 0)
   3134             {
   3135                 const char* cat_name = command.GetArgumentAtIndex(0);
   3136                 ConstString cat_nameCS(cat_name);
   3137                 DataVisualization::Categories::GetCategory(cat_nameCS, category);
   3138             }
   3139             else
   3140                 DataVisualization::Categories::GetCategory(ConstString(NULL), category);
   3141             category->GetFilterNavigator()->Clear();
   3142             category->GetRegexFilterNavigator()->Clear();
   3143         }
   3144 
   3145         result.SetStatus(eReturnStatusSuccessFinishResult);
   3146         return result.Succeeded();
   3147     }
   3148 
   3149 };
   3150 
   3151 OptionDefinition
   3152 CommandObjectTypeFilterClear::CommandOptions::g_option_table[] =
   3153 {
   3154     { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone,  "Clear every category."},
   3155     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   3156 };
   3157 
   3158 #ifndef LLDB_DISABLE_PYTHON
   3159 //-------------------------------------------------------------------------
   3160 // CommandObjectTypeSynthClear
   3161 //-------------------------------------------------------------------------
   3162 
   3163 class CommandObjectTypeSynthClear : public CommandObjectParsed
   3164 {
   3165 private:
   3166 
   3167     class CommandOptions : public Options
   3168     {
   3169     public:
   3170 
   3171         CommandOptions (CommandInterpreter &interpreter) :
   3172         Options (interpreter)
   3173         {
   3174         }
   3175 
   3176         virtual
   3177         ~CommandOptions (){}
   3178 
   3179         virtual Error
   3180         SetOptionValue (uint32_t option_idx, const char *option_arg)
   3181         {
   3182             Error error;
   3183             const int short_option = m_getopt_table[option_idx].val;
   3184 
   3185             switch (short_option)
   3186             {
   3187                 case 'a':
   3188                     m_delete_all = true;
   3189                     break;
   3190                 default:
   3191                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
   3192                     break;
   3193             }
   3194 
   3195             return error;
   3196         }
   3197 
   3198         void
   3199         OptionParsingStarting ()
   3200         {
   3201             m_delete_all = false;
   3202         }
   3203 
   3204         const OptionDefinition*
   3205         GetDefinitions ()
   3206         {
   3207             return g_option_table;
   3208         }
   3209 
   3210         // Options table: Required for subclasses of Options.
   3211 
   3212         static OptionDefinition g_option_table[];
   3213 
   3214         // Instance variables to hold the values for command options.
   3215 
   3216         bool m_delete_all;
   3217         bool m_delete_named;
   3218     };
   3219 
   3220     CommandOptions m_options;
   3221 
   3222     virtual Options *
   3223     GetOptions ()
   3224     {
   3225         return &m_options;
   3226     }
   3227 
   3228     static bool
   3229     PerCategoryCallback(void* param,
   3230                         const lldb::TypeCategoryImplSP& cate)
   3231     {
   3232         cate->Clear(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth);
   3233         return true;
   3234 
   3235     }
   3236 
   3237 public:
   3238     CommandObjectTypeSynthClear (CommandInterpreter &interpreter) :
   3239         CommandObjectParsed (interpreter,
   3240                              "type synthetic clear",
   3241                              "Delete all existing synthetic providers.",
   3242                              NULL),
   3243         m_options(interpreter)
   3244     {
   3245     }
   3246 
   3247     ~CommandObjectTypeSynthClear ()
   3248     {
   3249     }
   3250 
   3251 protected:
   3252     bool
   3253     DoExecute (Args& command, CommandReturnObject &result)
   3254     {
   3255 
   3256         if (m_options.m_delete_all)
   3257             DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL);
   3258 
   3259         else
   3260         {
   3261             lldb::TypeCategoryImplSP category;
   3262             if (command.GetArgumentCount() > 0)
   3263             {
   3264                 const char* cat_name = command.GetArgumentAtIndex(0);
   3265                 ConstString cat_nameCS(cat_name);
   3266                 DataVisualization::Categories::GetCategory(cat_nameCS, category);
   3267             }
   3268             else
   3269                 DataVisualization::Categories::GetCategory(ConstString(NULL), category);
   3270             category->GetSyntheticNavigator()->Clear();
   3271             category->GetRegexSyntheticNavigator()->Clear();
   3272         }
   3273 
   3274         result.SetStatus(eReturnStatusSuccessFinishResult);
   3275         return result.Succeeded();
   3276     }
   3277 
   3278 };
   3279 
   3280 OptionDefinition
   3281 CommandObjectTypeSynthClear::CommandOptions::g_option_table[] =
   3282 {
   3283     { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone,  "Clear every category."},
   3284     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   3285 };
   3286 
   3287 
   3288 //-------------------------------------------------------------------------
   3289 // TypeSynthAddInputReader
   3290 //-------------------------------------------------------------------------
   3291 
   3292 static const char *g_synth_addreader_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
   3293                                                       "You must define a Python class with these methods:\n"
   3294                                                       "     def __init__(self, valobj, dict):\n"
   3295                                                       "     def num_children(self):\n"
   3296                                                       "     def get_child_at_index(self, index):\n"
   3297                                                       "     def get_child_index(self, name):\n"
   3298                                                       "Optionally, you can also define a method:\n"
   3299                                                       "     def update(self):\n"
   3300                                                       "if your synthetic provider is holding on to any per-object state variables (currently, this is not implemented because of the way LLDB handles instances of SBValue and you should not rely on object persistence and per-object state)\n"
   3301                                                       "class synthProvider:";
   3302 
   3303 class TypeSynthAddInputReader : public InputReaderEZ
   3304 {
   3305 public:
   3306     TypeSynthAddInputReader(Debugger& debugger) :
   3307         InputReaderEZ(debugger)
   3308     {}
   3309 
   3310     virtual
   3311     ~TypeSynthAddInputReader()
   3312     {
   3313     }
   3314 
   3315     virtual void ActivateHandler(HandlerData& data)
   3316     {
   3317         StreamSP out_stream = data.GetOutStream();
   3318         bool batch_mode = data.GetBatchMode();
   3319         if (!batch_mode)
   3320         {
   3321             out_stream->Printf ("%s\n", g_synth_addreader_instructions);
   3322             if (data.reader.GetPrompt())
   3323                 out_stream->Printf ("%s", data.reader.GetPrompt());
   3324             out_stream->Flush();
   3325         }
   3326     }
   3327 
   3328     virtual void ReactivateHandler(HandlerData& data)
   3329     {
   3330         StreamSP out_stream = data.GetOutStream();
   3331         bool batch_mode = data.GetBatchMode();
   3332         if (data.reader.GetPrompt() && !batch_mode)
   3333         {
   3334             out_stream->Printf ("%s", data.reader.GetPrompt());
   3335             out_stream->Flush();
   3336         }
   3337     }
   3338     virtual void GotTokenHandler(HandlerData& data)
   3339     {
   3340         StreamSP out_stream = data.GetOutStream();
   3341         bool batch_mode = data.GetBatchMode();
   3342         if (data.bytes && data.bytes_len && data.baton)
   3343         {
   3344             ((SynthAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len);
   3345         }
   3346         if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
   3347         {
   3348             out_stream->Printf ("%s", data.reader.GetPrompt());
   3349             out_stream->Flush();
   3350         }
   3351     }
   3352     virtual void InterruptHandler(HandlerData& data)
   3353     {
   3354         StreamSP out_stream = data.GetOutStream();
   3355         bool batch_mode = data.GetBatchMode();
   3356         data.reader.SetIsDone (true);
   3357         if (!batch_mode)
   3358         {
   3359             out_stream->Printf ("Warning: No command attached to breakpoint.\n");
   3360             out_stream->Flush();
   3361         }
   3362     }
   3363     virtual void EOFHandler(HandlerData& data)
   3364     {
   3365         data.reader.SetIsDone (true);
   3366     }
   3367     virtual void DoneHandler(HandlerData& data)
   3368     {
   3369         StreamSP out_stream = data.GetOutStream();
   3370         SynthAddOptions *options_ptr = ((SynthAddOptions*)data.baton);
   3371         if (!options_ptr)
   3372         {
   3373             out_stream->Printf ("internal synchronization data missing.\n");
   3374             out_stream->Flush();
   3375             return;
   3376         }
   3377 
   3378         SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
   3379 
   3380         ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
   3381         if (!interpreter)
   3382         {
   3383             out_stream->Printf ("no script interpreter.\n");
   3384             out_stream->Flush();
   3385             return;
   3386         }
   3387         std::string class_name_str;
   3388         if (!interpreter->GenerateTypeSynthClass (options->m_user_source,
   3389                                                   class_name_str))
   3390         {
   3391             out_stream->Printf ("unable to generate a class.\n");
   3392             out_stream->Flush();
   3393             return;
   3394         }
   3395         if (class_name_str.empty())
   3396         {
   3397             out_stream->Printf ("unable to obtain a proper name for the class.\n");
   3398             out_stream->Flush();
   3399             return;
   3400         }
   3401 
   3402         // everything should be fine now, let's add the synth provider class
   3403 
   3404         SyntheticChildrenSP synth_provider;
   3405         synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade).
   3406                                                            SetSkipPointers(options->m_skip_pointers).
   3407                                                            SetSkipReferences(options->m_skip_references),
   3408                                                            class_name_str.c_str()));
   3409 
   3410 
   3411         lldb::TypeCategoryImplSP category;
   3412         DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category);
   3413 
   3414         Error error;
   3415 
   3416         for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
   3417         {
   3418             const char *type_name = options->m_target_types.GetStringAtIndex(i);
   3419             ConstString typeCS(type_name);
   3420             if (typeCS)
   3421             {
   3422                 if (!CommandObjectTypeSynthAdd::AddSynth(typeCS,
   3423                                                         synth_provider,
   3424                                                         options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth,
   3425                                                         options->m_category,
   3426                                                         &error))
   3427                 {
   3428                     out_stream->Printf("%s\n", error.AsCString());
   3429                     out_stream->Flush();
   3430                     return;
   3431                 }
   3432             }
   3433             else
   3434             {
   3435                 out_stream->Printf ("invalid type name.\n");
   3436                 out_stream->Flush();
   3437                 return;
   3438             }
   3439         }
   3440     }
   3441 
   3442 private:
   3443     DISALLOW_COPY_AND_ASSIGN (TypeSynthAddInputReader);
   3444 };
   3445 
   3446 void
   3447 CommandObjectTypeSynthAdd::CollectPythonScript (SynthAddOptions *options,
   3448                                                 CommandReturnObject &result)
   3449 {
   3450     InputReaderSP reader_sp (new TypeSynthAddInputReader(m_interpreter.GetDebugger()));
   3451     if (reader_sp && options)
   3452     {
   3453 
   3454         InputReaderEZ::InitializationParameters ipr;
   3455 
   3456         Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt("     ")));
   3457         if (err.Success())
   3458         {
   3459             m_interpreter.GetDebugger().PushInputReader (reader_sp);
   3460             result.SetStatus (eReturnStatusSuccessFinishNoResult);
   3461         }
   3462         else
   3463         {
   3464             result.AppendError (err.AsCString());
   3465             result.SetStatus (eReturnStatusFailed);
   3466         }
   3467     }
   3468     else
   3469     {
   3470         result.AppendError("out of memory");
   3471         result.SetStatus (eReturnStatusFailed);
   3472     }
   3473 }
   3474 
   3475 bool
   3476 CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result)
   3477 {
   3478     SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers,
   3479                                                      m_options.m_skip_references,
   3480                                                      m_options.m_cascade,
   3481                                                      m_options.m_regex,
   3482                                                      m_options.m_category);
   3483 
   3484     const size_t argc = command.GetArgumentCount();
   3485 
   3486     for (size_t i = 0; i < argc; i++)
   3487     {
   3488         const char* typeA = command.GetArgumentAtIndex(i);
   3489         if (typeA && *typeA)
   3490             options->m_target_types << typeA;
   3491         else
   3492         {
   3493             result.AppendError("empty typenames not allowed");
   3494             result.SetStatus(eReturnStatusFailed);
   3495             return false;
   3496         }
   3497     }
   3498 
   3499     CollectPythonScript(options,result);
   3500     return result.Succeeded();
   3501 }
   3502 
   3503 bool
   3504 CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result)
   3505 {
   3506     const size_t argc = command.GetArgumentCount();
   3507 
   3508     if (argc < 1)
   3509     {
   3510         result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
   3511         result.SetStatus(eReturnStatusFailed);
   3512         return false;
   3513     }
   3514 
   3515     if (m_options.m_class_name.empty() && !m_options.m_input_python)
   3516     {
   3517         result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str());
   3518         result.SetStatus(eReturnStatusFailed);
   3519         return false;
   3520     }
   3521 
   3522     SyntheticChildrenSP entry;
   3523 
   3524     ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(SyntheticChildren::Flags().
   3525                                                                     SetCascades(m_options.m_cascade).
   3526                                                                     SetSkipPointers(m_options.m_skip_pointers).
   3527                                                                     SetSkipReferences(m_options.m_skip_references),
   3528                                                                     m_options.m_class_name.c_str());
   3529 
   3530     entry.reset(impl);
   3531 
   3532     ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
   3533 
   3534     if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false)
   3535         result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider");
   3536 
   3537     // now I have a valid provider, let's add it to every type
   3538 
   3539     lldb::TypeCategoryImplSP category;
   3540     DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
   3541 
   3542     Error error;
   3543 
   3544     for (size_t i = 0; i < argc; i++)
   3545     {
   3546         const char* typeA = command.GetArgumentAtIndex(i);
   3547         ConstString typeCS(typeA);
   3548         if (typeCS)
   3549         {
   3550             if (!AddSynth(typeCS,
   3551                           entry,
   3552                           m_options.m_regex ? eRegexSynth : eRegularSynth,
   3553                           m_options.m_category,
   3554                           &error))
   3555             {
   3556                 result.AppendError(error.AsCString());
   3557                 result.SetStatus(eReturnStatusFailed);
   3558                 return false;
   3559             }
   3560         }
   3561         else
   3562         {
   3563             result.AppendError("empty typenames not allowed");
   3564             result.SetStatus(eReturnStatusFailed);
   3565             return false;
   3566         }
   3567     }
   3568 
   3569     result.SetStatus(eReturnStatusSuccessFinishNoResult);
   3570     return result.Succeeded();
   3571 }
   3572 
   3573 CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
   3574     CommandObjectParsed (interpreter,
   3575                          "type synthetic add",
   3576                          "Add a new synthetic provider for a type.",
   3577                          NULL),
   3578     m_options (interpreter)
   3579 {
   3580     CommandArgumentEntry type_arg;
   3581     CommandArgumentData type_style_arg;
   3582 
   3583     type_style_arg.arg_type = eArgTypeName;
   3584     type_style_arg.arg_repetition = eArgRepeatPlus;
   3585 
   3586     type_arg.push_back (type_style_arg);
   3587 
   3588     m_arguments.push_back (type_arg);
   3589 
   3590 }
   3591 
   3592 bool
   3593 CommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
   3594                                     SyntheticChildrenSP entry,
   3595                                     SynthFormatType type,
   3596                                     std::string category_name,
   3597                                     Error* error)
   3598 {
   3599     lldb::TypeCategoryImplSP category;
   3600     DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
   3601 
   3602     if (type == eRegularSynth)
   3603     {
   3604         std::string type_name_str(type_name.GetCString());
   3605         if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0)
   3606         {
   3607             type_name_str.resize(type_name_str.length()-2);
   3608             if (type_name_str.back() != ' ')
   3609                 type_name_str.append(" \\[[0-9]+\\]");
   3610             else
   3611                 type_name_str.append("\\[[0-9]+\\]");
   3612             type_name.SetCString(type_name_str.c_str());
   3613             type = eRegularSynth;
   3614         }
   3615     }
   3616 
   3617     if (category->AnyMatches(type_name,
   3618                              eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
   3619                              false))
   3620     {
   3621         if (error)
   3622             error->SetErrorStringWithFormat("cannot add synthetic for type %s when filter is defined in same category!", type_name.AsCString());
   3623         return false;
   3624     }
   3625 
   3626     if (type == eRegexSynth)
   3627     {
   3628         RegularExpressionSP typeRX(new RegularExpression());
   3629         if (!typeRX->Compile(type_name.GetCString()))
   3630         {
   3631             if (error)
   3632                 error->SetErrorString("regex format error (maybe this is not really a regex?)");
   3633             return false;
   3634         }
   3635 
   3636         category->GetRegexSyntheticNavigator()->Delete(type_name);
   3637         category->GetRegexSyntheticNavigator()->Add(typeRX, entry);
   3638 
   3639         return true;
   3640     }
   3641     else
   3642     {
   3643         category->GetSyntheticNavigator()->Add(type_name, entry);
   3644         return true;
   3645     }
   3646 }
   3647 
   3648 bool
   3649 CommandObjectTypeSynthAdd::DoExecute (Args& command, CommandReturnObject &result)
   3650 {
   3651     if (m_options.handwrite_python)
   3652         return Execute_HandwritePython(command, result);
   3653     else if (m_options.is_class_based)
   3654         return Execute_PythonClass(command, result);
   3655     else
   3656     {
   3657         result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
   3658         result.SetStatus(eReturnStatusFailed);
   3659         return false;
   3660     }
   3661 }
   3662 
   3663 OptionDefinition
   3664 CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
   3665 {
   3666     { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
   3667     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
   3668     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
   3669     { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
   3670     { LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypePythonClass,    "Use this Python class to produce synthetic children."},
   3671     { LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone,    "Type Python code to generate a class that provides synthetic children."},
   3672     { LLDB_OPT_SET_ALL, false,  "regex", 'x', no_argument, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
   3673     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   3674 };
   3675 
   3676 #endif // #ifndef LLDB_DISABLE_PYTHON
   3677 
   3678 class CommandObjectTypeFilterAdd : public CommandObjectParsed
   3679 {
   3680 
   3681 private:
   3682 
   3683     class CommandOptions : public Options
   3684     {
   3685         typedef std::vector<std::string> option_vector;
   3686     public:
   3687 
   3688         CommandOptions (CommandInterpreter &interpreter) :
   3689         Options (interpreter)
   3690         {
   3691         }
   3692 
   3693         virtual
   3694         ~CommandOptions (){}
   3695 
   3696         virtual Error
   3697         SetOptionValue (uint32_t option_idx, const char *option_arg)
   3698         {
   3699             Error error;
   3700             const int short_option = m_getopt_table[option_idx].val;
   3701             bool success;
   3702 
   3703             switch (short_option)
   3704             {
   3705                 case 'C':
   3706                     m_cascade = Args::StringToBoolean(option_arg, true, &success);
   3707                     if (!success)
   3708                         error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
   3709                     break;
   3710                 case 'c':
   3711                     m_expr_paths.push_back(option_arg);
   3712                     has_child_list = true;
   3713                     break;
   3714                 case 'p':
   3715                     m_skip_pointers = true;
   3716                     break;
   3717                 case 'r':
   3718                     m_skip_references = true;
   3719                     break;
   3720                 case 'w':
   3721                     m_category = std::string(option_arg);
   3722                     break;
   3723                 case 'x':
   3724                     m_regex = true;
   3725                     break;
   3726                 default:
   3727                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
   3728                     break;
   3729             }
   3730 
   3731             return error;
   3732         }
   3733 
   3734         void
   3735         OptionParsingStarting ()
   3736         {
   3737             m_cascade = true;
   3738             m_skip_pointers = false;
   3739             m_skip_references = false;
   3740             m_category = "default";
   3741             m_expr_paths.clear();
   3742             has_child_list = false;
   3743             m_regex = false;
   3744         }
   3745 
   3746         const OptionDefinition*
   3747         GetDefinitions ()
   3748         {
   3749             return g_option_table;
   3750         }
   3751 
   3752         // Options table: Required for subclasses of Options.
   3753 
   3754         static OptionDefinition g_option_table[];
   3755 
   3756         // Instance variables to hold the values for command options.
   3757 
   3758         bool m_cascade;
   3759         bool m_skip_references;
   3760         bool m_skip_pointers;
   3761         bool m_input_python;
   3762         option_vector m_expr_paths;
   3763         std::string m_category;
   3764 
   3765         bool has_child_list;
   3766 
   3767         bool m_regex;
   3768 
   3769         typedef option_vector::iterator ExpressionPathsIterator;
   3770     };
   3771 
   3772     CommandOptions m_options;
   3773 
   3774     virtual Options *
   3775     GetOptions ()
   3776     {
   3777         return &m_options;
   3778     }
   3779 
   3780     enum FilterFormatType
   3781     {
   3782         eRegularFilter,
   3783         eRegexFilter
   3784     };
   3785 
   3786     bool
   3787     AddFilter(ConstString type_name,
   3788               SyntheticChildrenSP entry,
   3789               FilterFormatType type,
   3790               std::string category_name,
   3791               Error* error)
   3792     {
   3793         lldb::TypeCategoryImplSP category;
   3794         DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
   3795 
   3796         if (type == eRegularFilter)
   3797         {
   3798             std::string type_name_str(type_name.GetCString());
   3799             if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0)
   3800             {
   3801                 type_name_str.resize(type_name_str.length()-2);
   3802                 if (type_name_str.back() != ' ')
   3803                     type_name_str.append(" \\[[0-9]+\\]");
   3804                 else
   3805                     type_name_str.append("\\[[0-9]+\\]");
   3806                 type_name.SetCString(type_name_str.c_str());
   3807                 type = eRegexFilter;
   3808             }
   3809         }
   3810 
   3811         if (category->AnyMatches(type_name,
   3812                                  eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
   3813                                  false))
   3814         {
   3815             if (error)
   3816                 error->SetErrorStringWithFormat("cannot add filter for type %s when synthetic is defined in same category!", type_name.AsCString());
   3817             return false;
   3818         }
   3819 
   3820         if (type == eRegexFilter)
   3821         {
   3822             RegularExpressionSP typeRX(new RegularExpression());
   3823             if (!typeRX->Compile(type_name.GetCString()))
   3824             {
   3825                 if (error)
   3826                     error->SetErrorString("regex format error (maybe this is not really a regex?)");
   3827                 return false;
   3828             }
   3829 
   3830             category->GetRegexFilterNavigator()->Delete(type_name);
   3831             category->GetRegexFilterNavigator()->Add(typeRX, entry);
   3832 
   3833             return true;
   3834         }
   3835         else
   3836         {
   3837             category->GetFilterNavigator()->Add(type_name, entry);
   3838             return true;
   3839         }
   3840     }
   3841 
   3842 
   3843 public:
   3844 
   3845     CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) :
   3846         CommandObjectParsed (interpreter,
   3847                              "type filter add",
   3848                              "Add a new filter for a type.",
   3849                              NULL),
   3850         m_options (interpreter)
   3851     {
   3852         CommandArgumentEntry type_arg;
   3853         CommandArgumentData type_style_arg;
   3854 
   3855         type_style_arg.arg_type = eArgTypeName;
   3856         type_style_arg.arg_repetition = eArgRepeatPlus;
   3857 
   3858         type_arg.push_back (type_style_arg);
   3859 
   3860         m_arguments.push_back (type_arg);
   3861 
   3862         SetHelpLong(
   3863                     "Some examples of using this command.\n"
   3864                     "We use as reference the following snippet of code:\n"
   3865                     "\n"
   3866                     "class Foo {;\n"
   3867                     "    int a;\n"
   3868                     "    int b;\n"
   3869                     "    int c;\n"
   3870                     "    int d;\n"
   3871                     "    int e;\n"
   3872                     "    int f;\n"
   3873                     "    int g;\n"
   3874                     "    int h;\n"
   3875                     "    int i;\n"
   3876                     "} \n"
   3877                     "Typing:\n"
   3878                     "type filter add --child a --child g Foo\n"
   3879                     "frame variable a_foo\n"
   3880                     "will produce an output where only a and g are displayed\n"
   3881                     "Other children of a_foo (b,c,d,e,f,h and i) are available by asking for them, as in:\n"
   3882                     "frame variable a_foo.b a_foo.c ... a_foo.i\n"
   3883                     "\n"
   3884                     "Use option --raw to frame variable prevails on the filter\n"
   3885                     "frame variable a_foo --raw\n"
   3886                     "shows all the children of a_foo (a thru i) as if no filter was defined\n"
   3887                     );
   3888     }
   3889 
   3890     ~CommandObjectTypeFilterAdd ()
   3891     {
   3892     }
   3893 
   3894 protected:
   3895     bool
   3896     DoExecute (Args& command, CommandReturnObject &result)
   3897     {
   3898         const size_t argc = command.GetArgumentCount();
   3899 
   3900         if (argc < 1)
   3901         {
   3902             result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
   3903             result.SetStatus(eReturnStatusFailed);
   3904             return false;
   3905         }
   3906 
   3907         if (m_options.m_expr_paths.size() == 0)
   3908         {
   3909             result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
   3910             result.SetStatus(eReturnStatusFailed);
   3911             return false;
   3912         }
   3913 
   3914         SyntheticChildrenSP entry;
   3915 
   3916         TypeFilterImpl* impl = new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade).
   3917                                                     SetSkipPointers(m_options.m_skip_pointers).
   3918                                                     SetSkipReferences(m_options.m_skip_references));
   3919 
   3920         entry.reset(impl);
   3921 
   3922         // go through the expression paths
   3923         CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end();
   3924 
   3925         for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
   3926             impl->AddExpressionPath(*begin);
   3927 
   3928 
   3929         // now I have a valid provider, let's add it to every type
   3930 
   3931         lldb::TypeCategoryImplSP category;
   3932         DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
   3933 
   3934         Error error;
   3935 
   3936         for (size_t i = 0; i < argc; i++)
   3937         {
   3938             const char* typeA = command.GetArgumentAtIndex(i);
   3939             ConstString typeCS(typeA);
   3940             if (typeCS)
   3941             {
   3942                 if (!AddFilter(typeCS,
   3943                           entry,
   3944                           m_options.m_regex ? eRegexFilter : eRegularFilter,
   3945                           m_options.m_category,
   3946                           &error))
   3947                 {
   3948                     result.AppendError(error.AsCString());
   3949                     result.SetStatus(eReturnStatusFailed);
   3950                     return false;
   3951                 }
   3952             }
   3953             else
   3954             {
   3955                 result.AppendError("empty typenames not allowed");
   3956                 result.SetStatus(eReturnStatusFailed);
   3957                 return false;
   3958             }
   3959         }
   3960 
   3961         result.SetStatus(eReturnStatusSuccessFinishNoResult);
   3962         return result.Succeeded();
   3963     }
   3964 
   3965 };
   3966 
   3967 OptionDefinition
   3968 CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
   3969 {
   3970     { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
   3971     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
   3972     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
   3973     { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
   3974     { LLDB_OPT_SET_ALL, false, "child", 'c', required_argument, NULL, 0, eArgTypeExpressionPath,    "Include this expression path in the synthetic view."},
   3975     { LLDB_OPT_SET_ALL, false,  "regex", 'x', no_argument, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
   3976     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   3977 };
   3978 
   3979 class CommandObjectTypeFormat : public CommandObjectMultiword
   3980 {
   3981 public:
   3982     CommandObjectTypeFormat (CommandInterpreter &interpreter) :
   3983         CommandObjectMultiword (interpreter,
   3984                                 "type format",
   3985                                 "A set of commands for editing variable value display options",
   3986                                 "type format [<sub-command-options>] ")
   3987     {
   3988         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter)));
   3989         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectTypeFormatClear (interpreter)));
   3990         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter)));
   3991         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectTypeFormatList (interpreter)));
   3992     }
   3993 
   3994 
   3995     ~CommandObjectTypeFormat ()
   3996     {
   3997     }
   3998 };
   3999 
   4000 #ifndef LLDB_DISABLE_PYTHON
   4001 
   4002 class CommandObjectTypeSynth : public CommandObjectMultiword
   4003 {
   4004 public:
   4005     CommandObjectTypeSynth (CommandInterpreter &interpreter) :
   4006     CommandObjectMultiword (interpreter,
   4007                             "type synthetic",
   4008                             "A set of commands for operating on synthetic type representations",
   4009                             "type synthetic [<sub-command-options>] ")
   4010     {
   4011         LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter)));
   4012         LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeSynthClear (interpreter)));
   4013         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter)));
   4014         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeSynthList (interpreter)));
   4015     }
   4016 
   4017 
   4018     ~CommandObjectTypeSynth ()
   4019     {
   4020     }
   4021 };
   4022 
   4023 #endif // #ifndef LLDB_DISABLE_PYTHON
   4024 
   4025 class CommandObjectTypeFilter : public CommandObjectMultiword
   4026 {
   4027 public:
   4028     CommandObjectTypeFilter (CommandInterpreter &interpreter) :
   4029     CommandObjectMultiword (interpreter,
   4030                             "type filter",
   4031                             "A set of commands for operating on type filters",
   4032                             "type synthetic [<sub-command-options>] ")
   4033     {
   4034         LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter)));
   4035         LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeFilterClear (interpreter)));
   4036         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter)));
   4037         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeFilterList (interpreter)));
   4038     }
   4039 
   4040 
   4041     ~CommandObjectTypeFilter ()
   4042     {
   4043     }
   4044 };
   4045 
   4046 class CommandObjectTypeCategory : public CommandObjectMultiword
   4047 {
   4048 public:
   4049     CommandObjectTypeCategory (CommandInterpreter &interpreter) :
   4050     CommandObjectMultiword (interpreter,
   4051                             "type category",
   4052                             "A set of commands for operating on categories",
   4053                             "type category [<sub-command-options>] ")
   4054     {
   4055         LoadSubCommand ("enable",        CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter)));
   4056         LoadSubCommand ("disable",       CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter)));
   4057         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter)));
   4058         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeCategoryList (interpreter)));
   4059     }
   4060 
   4061 
   4062     ~CommandObjectTypeCategory ()
   4063     {
   4064     }
   4065 };
   4066 
   4067 class CommandObjectTypeSummary : public CommandObjectMultiword
   4068 {
   4069 public:
   4070     CommandObjectTypeSummary (CommandInterpreter &interpreter) :
   4071     CommandObjectMultiword (interpreter,
   4072                             "type summary",
   4073                             "A set of commands for editing variable summary display options",
   4074                             "type summary [<sub-command-options>] ")
   4075     {
   4076         LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter)));
   4077         LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter)));
   4078         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter)));
   4079         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeSummaryList (interpreter)));
   4080     }
   4081 
   4082 
   4083     ~CommandObjectTypeSummary ()
   4084     {
   4085     }
   4086 };
   4087 
   4088 //-------------------------------------------------------------------------
   4089 // CommandObjectType
   4090 //-------------------------------------------------------------------------
   4091 
   4092 CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) :
   4093     CommandObjectMultiword (interpreter,
   4094                             "type",
   4095                             "A set of commands for operating on the type system",
   4096                             "type [<sub-command-options>]")
   4097 {
   4098     LoadSubCommand ("category",  CommandObjectSP (new CommandObjectTypeCategory (interpreter)));
   4099     LoadSubCommand ("filter",    CommandObjectSP (new CommandObjectTypeFilter (interpreter)));
   4100     LoadSubCommand ("format",    CommandObjectSP (new CommandObjectTypeFormat (interpreter)));
   4101     LoadSubCommand ("summary",   CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
   4102 #ifndef LLDB_DISABLE_PYTHON
   4103     LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter)));
   4104 #endif
   4105 }
   4106 
   4107 
   4108 CommandObjectType::~CommandObjectType ()
   4109 {
   4110 }
   4111 
   4112 
   4113