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