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