1254721Semaste//===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste#include "CommandObjectType.h"
13254721Semaste
14254721Semaste// C Includes
15254721Semaste
16254721Semaste#include <ctype.h>
17254721Semaste
18254721Semaste// C++ Includes
19254721Semaste
20254721Semaste#include "lldb/Core/ConstString.h"
21254721Semaste#include "lldb/Core/Debugger.h"
22269024Semaste#include "lldb/Core/IOHandler.h"
23254721Semaste#include "lldb/Core/RegularExpression.h"
24254721Semaste#include "lldb/Core/State.h"
25254721Semaste#include "lldb/Core/StringList.h"
26254721Semaste#include "lldb/DataFormatters/DataVisualization.h"
27254721Semaste#include "lldb/Interpreter/CommandInterpreter.h"
28254721Semaste#include "lldb/Interpreter/CommandObject.h"
29254721Semaste#include "lldb/Interpreter/CommandReturnObject.h"
30254721Semaste#include "lldb/Interpreter/Options.h"
31254721Semaste#include "lldb/Interpreter/OptionGroupFormat.h"
32254721Semaste
33254721Semasteusing namespace lldb;
34254721Semasteusing namespace lldb_private;
35254721Semaste
36254721Semaste
37254721Semasteclass ScriptAddOptions
38254721Semaste{
39254721Semaste
40254721Semastepublic:
41254721Semaste
42254721Semaste    TypeSummaryImpl::Flags m_flags;
43254721Semaste
44254721Semaste    StringList m_target_types;
45254721Semaste
46254721Semaste    bool m_regex;
47254721Semaste
48254721Semaste    ConstString m_name;
49254721Semaste
50254721Semaste    std::string m_category;
51254721Semaste
52254721Semaste    ScriptAddOptions(const TypeSummaryImpl::Flags& flags,
53254721Semaste                     bool regx,
54254721Semaste                     const ConstString& name,
55254721Semaste                     std::string catg) :
56254721Semaste        m_flags(flags),
57254721Semaste        m_regex(regx),
58254721Semaste        m_name(name),
59254721Semaste        m_category(catg)
60254721Semaste    {
61254721Semaste    }
62254721Semaste
63254721Semaste    typedef std::shared_ptr<ScriptAddOptions> SharedPointer;
64254721Semaste
65254721Semaste};
66254721Semaste
67254721Semasteclass SynthAddOptions
68254721Semaste{
69254721Semaste
70254721Semastepublic:
71254721Semaste
72254721Semaste    bool m_skip_pointers;
73254721Semaste    bool m_skip_references;
74254721Semaste    bool m_cascade;
75254721Semaste    bool m_regex;
76254721Semaste    StringList m_target_types;
77254721Semaste
78254721Semaste    std::string m_category;
79254721Semaste
80254721Semaste    SynthAddOptions(bool sptr,
81254721Semaste                    bool sref,
82254721Semaste                    bool casc,
83254721Semaste                    bool regx,
84254721Semaste                    std::string catg) :
85254721Semaste    m_skip_pointers(sptr),
86254721Semaste    m_skip_references(sref),
87254721Semaste    m_cascade(casc),
88254721Semaste    m_regex(regx),
89254721Semaste    m_target_types(),
90254721Semaste    m_category(catg)
91254721Semaste    {
92254721Semaste    }
93254721Semaste
94254721Semaste    typedef std::shared_ptr<SynthAddOptions> SharedPointer;
95254721Semaste
96254721Semaste};
97254721Semaste
98269024Semastestatic bool
99269024SemasteWarnOnPotentialUnquotedUnsignedType (Args& command, CommandReturnObject &result)
100269024Semaste{
101269024Semaste    for (int idx = 0; idx < command.GetArgumentCount(); idx++)
102269024Semaste    {
103269024Semaste        const char* arg = command.GetArgumentAtIndex(idx);
104269024Semaste        if (idx+1 < command.GetArgumentCount())
105269024Semaste        {
106269024Semaste            if (arg && 0 == strcmp(arg,"unsigned"))
107269024Semaste            {
108269024Semaste                const char* next = command.GetArgumentAtIndex(idx+1);
109269024Semaste                if (next &&
110269024Semaste                    (0 == strcmp(next, "int") ||
111269024Semaste                     0 == strcmp(next, "short") ||
112269024Semaste                     0 == strcmp(next, "char") ||
113269024Semaste                     0 == strcmp(next, "long")))
114269024Semaste                {
115269024Semaste                    result.AppendWarningWithFormat("%s %s being treated as two types. if you meant the combined type name use quotes, as in \"%s %s\"\n",
116269024Semaste                                                   arg,next,arg,next);
117269024Semaste                    return true;
118269024Semaste                }
119269024Semaste            }
120269024Semaste        }
121269024Semaste    }
122269024Semaste    return false;
123269024Semaste}
124254721Semaste
125269024Semasteclass CommandObjectTypeSummaryAdd :
126269024Semaste    public CommandObjectParsed,
127269024Semaste    public IOHandlerDelegateMultiline
128254721Semaste{
129254721Semaste
130254721Semasteprivate:
131254721Semaste
132254721Semaste    class CommandOptions : public Options
133254721Semaste    {
134254721Semaste    public:
135254721Semaste
136254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
137254721Semaste        Options (interpreter)
138254721Semaste        {
139254721Semaste        }
140254721Semaste
141254721Semaste        virtual
142254721Semaste        ~CommandOptions (){}
143254721Semaste
144254721Semaste        virtual Error
145254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg);
146254721Semaste
147254721Semaste        void
148254721Semaste        OptionParsingStarting ();
149254721Semaste
150254721Semaste        const OptionDefinition*
151254721Semaste        GetDefinitions ()
152254721Semaste        {
153254721Semaste            return g_option_table;
154254721Semaste        }
155254721Semaste
156254721Semaste        // Options table: Required for subclasses of Options.
157254721Semaste
158254721Semaste        static OptionDefinition g_option_table[];
159254721Semaste
160254721Semaste        // Instance variables to hold the values for command options.
161254721Semaste
162254721Semaste        TypeSummaryImpl::Flags m_flags;
163254721Semaste        bool m_regex;
164254721Semaste        std::string m_format_string;
165254721Semaste        ConstString m_name;
166254721Semaste        std::string m_python_script;
167254721Semaste        std::string m_python_function;
168254721Semaste        bool m_is_add_script;
169254721Semaste        std::string m_category;
170254721Semaste    };
171254721Semaste
172254721Semaste    CommandOptions m_options;
173254721Semaste
174254721Semaste    virtual Options *
175254721Semaste    GetOptions ()
176254721Semaste    {
177254721Semaste        return &m_options;
178254721Semaste    }
179254721Semaste
180254721Semaste    bool
181254721Semaste    Execute_ScriptSummary (Args& command, CommandReturnObject &result);
182254721Semaste
183254721Semaste    bool
184254721Semaste    Execute_StringSummary (Args& command, CommandReturnObject &result);
185254721Semaste
186254721Semastepublic:
187254721Semaste
188254721Semaste    enum SummaryFormatType
189254721Semaste    {
190254721Semaste        eRegularSummary,
191254721Semaste        eRegexSummary,
192254721Semaste        eNamedSummary
193254721Semaste    };
194254721Semaste
195254721Semaste    CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter);
196254721Semaste
197254721Semaste    ~CommandObjectTypeSummaryAdd ()
198254721Semaste    {
199254721Semaste    }
200254721Semaste
201269024Semaste    virtual void
202269024Semaste    IOHandlerActivated (IOHandler &io_handler)
203269024Semaste    {
204269024Semaste        static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
205269024Semaste        "def function (valobj,internal_dict):\n"
206269024Semaste        "     \"\"\"valobj: an SBValue which you want to provide a summary for\n"
207269024Semaste        "        internal_dict: an LLDB support object not to be used\"\"\"";
208269024Semaste
209269024Semaste        StreamFileSP output_sp(io_handler.GetOutputStreamFile());
210269024Semaste        if (output_sp)
211269024Semaste        {
212269024Semaste            output_sp->PutCString(g_summary_addreader_instructions);
213269024Semaste            output_sp->Flush();
214269024Semaste        }
215269024Semaste    }
216269024Semaste
217269024Semaste
218269024Semaste    virtual void
219269024Semaste    IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
220269024Semaste    {
221269024Semaste        StreamFileSP error_sp = io_handler.GetErrorStreamFile();
222269024Semaste
223269024Semaste#ifndef LLDB_DISABLE_PYTHON
224269024Semaste        ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
225269024Semaste        if (interpreter)
226269024Semaste        {
227269024Semaste            StringList lines;
228269024Semaste            lines.SplitIntoLines(data);
229269024Semaste            if (lines.GetSize() > 0)
230269024Semaste            {
231269024Semaste                ScriptAddOptions *options_ptr = ((ScriptAddOptions*)io_handler.GetUserData());
232269024Semaste                if (options_ptr)
233269024Semaste                {
234269024Semaste                    ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
235269024Semaste
236269024Semaste                    ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
237269024Semaste                    if (interpreter)
238269024Semaste                    {
239269024Semaste                        std::string funct_name_str;
240269024Semaste                        if (interpreter->GenerateTypeScriptFunction (lines, funct_name_str))
241269024Semaste                        {
242269024Semaste                            if (funct_name_str.empty())
243269024Semaste                            {
244269024Semaste                                error_sp->Printf ("unable to obtain a valid function name from the script interpreter.\n");
245269024Semaste                                error_sp->Flush();
246269024Semaste                            }
247269024Semaste                            else
248269024Semaste                            {
249269024Semaste                                // now I have a valid function name, let's add this as script for every type in the list
250269024Semaste
251269024Semaste                                TypeSummaryImplSP script_format;
252269024Semaste                                script_format.reset(new ScriptSummaryFormat(options->m_flags,
253269024Semaste                                                                            funct_name_str.c_str(),
254269024Semaste                                                                            lines.CopyList("    ").c_str()));
255269024Semaste
256269024Semaste                                Error error;
257269024Semaste
258269024Semaste                                for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
259269024Semaste                                {
260269024Semaste                                    const char *type_name = options->m_target_types.GetStringAtIndex(i);
261269024Semaste                                    CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
262269024Semaste                                                                            script_format,
263269024Semaste                                                                            (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
264269024Semaste                                                                            options->m_category,
265269024Semaste                                                                            &error);
266269024Semaste                                    if (error.Fail())
267269024Semaste                                    {
268269024Semaste                                        error_sp->Printf ("error: %s", error.AsCString());
269269024Semaste                                        error_sp->Flush();
270269024Semaste                                    }
271269024Semaste                                }
272269024Semaste
273269024Semaste                                if (options->m_name)
274269024Semaste                                {
275269024Semaste                                    CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
276269024Semaste                                                                             script_format,
277269024Semaste                                                                             CommandObjectTypeSummaryAdd::eNamedSummary,
278269024Semaste                                                                             options->m_category,
279269024Semaste                                                                             &error);
280269024Semaste                                    if (error.Fail())
281269024Semaste                                    {
282269024Semaste                                        CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
283269024Semaste                                                                                 script_format,
284269024Semaste                                                                                 CommandObjectTypeSummaryAdd::eNamedSummary,
285269024Semaste                                                                                 options->m_category,
286269024Semaste                                                                                 &error);
287269024Semaste                                        if (error.Fail())
288269024Semaste                                        {
289269024Semaste                                            error_sp->Printf ("error: %s", error.AsCString());
290269024Semaste                                            error_sp->Flush();
291269024Semaste                                        }
292269024Semaste                                    }
293269024Semaste                                    else
294269024Semaste                                    {
295269024Semaste                                        error_sp->Printf ("error: %s", error.AsCString());
296269024Semaste                                        error_sp->Flush();
297269024Semaste                                    }
298269024Semaste                                }
299269024Semaste                                else
300269024Semaste                                {
301269024Semaste                                    if (error.AsCString())
302269024Semaste                                    {
303269024Semaste                                        error_sp->Printf ("error: %s", error.AsCString());
304269024Semaste                                        error_sp->Flush();
305269024Semaste                                    }
306269024Semaste                                }
307269024Semaste                            }
308269024Semaste                        }
309269024Semaste                        else
310269024Semaste                        {
311269024Semaste                            error_sp->Printf ("error: unable to generate a function.\n");
312269024Semaste                            error_sp->Flush();
313269024Semaste                        }
314269024Semaste                    }
315269024Semaste                    else
316269024Semaste                    {
317269024Semaste                        error_sp->Printf ("error: no script interpreter.\n");
318269024Semaste                        error_sp->Flush();
319269024Semaste                    }
320269024Semaste                }
321269024Semaste                else
322269024Semaste                {
323269024Semaste                    error_sp->Printf ("error: internal synchronization information missing or invalid.\n");
324269024Semaste                    error_sp->Flush();
325269024Semaste                }
326269024Semaste            }
327269024Semaste            else
328269024Semaste            {
329269024Semaste                error_sp->Printf ("error: empty function, didn't add python command.\n");
330269024Semaste                error_sp->Flush();
331269024Semaste            }
332269024Semaste        }
333269024Semaste        else
334269024Semaste        {
335269024Semaste            error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
336269024Semaste            error_sp->Flush();
337269024Semaste        }
338269024Semaste#endif // #ifndef LLDB_DISABLE_PYTHON
339269024Semaste        io_handler.SetIsDone(true);
340269024Semaste    }
341269024Semaste
342254721Semaste    static bool
343254721Semaste    AddSummary(ConstString type_name,
344254721Semaste               lldb::TypeSummaryImplSP entry,
345254721Semaste               SummaryFormatType type,
346254721Semaste               std::string category,
347254721Semaste               Error* error = NULL);
348254721Semasteprotected:
349254721Semaste    bool
350254721Semaste    DoExecute (Args& command, CommandReturnObject &result);
351254721Semaste
352254721Semaste};
353254721Semaste
354269024Semastestatic const char *g_synth_addreader_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
355269024Semaste"You must define a Python class with these methods:\n"
356269024Semaste"    def __init__(self, valobj, dict):\n"
357269024Semaste"    def num_children(self):\n"
358269024Semaste"    def get_child_at_index(self, index):\n"
359269024Semaste"    def get_child_index(self, name):\n"
360269024Semaste"    def update(self):\n"
361269024Semaste"        '''Optional'''\n"
362269024Semaste"class synthProvider:\n";
363269024Semaste
364269024Semasteclass CommandObjectTypeSynthAdd :
365269024Semaste    public CommandObjectParsed,
366269024Semaste    public IOHandlerDelegateMultiline
367254721Semaste{
368254721Semaste
369254721Semasteprivate:
370254721Semaste
371254721Semaste    class CommandOptions : public Options
372254721Semaste    {
373254721Semaste    public:
374254721Semaste
375254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
376269024Semaste            Options (interpreter)
377254721Semaste        {
378254721Semaste        }
379254721Semaste
380254721Semaste        virtual
381254721Semaste        ~CommandOptions (){}
382254721Semaste
383254721Semaste        virtual Error
384254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
385254721Semaste        {
386254721Semaste            Error error;
387254721Semaste            const int short_option = m_getopt_table[option_idx].val;
388254721Semaste            bool success;
389254721Semaste
390254721Semaste            switch (short_option)
391254721Semaste            {
392254721Semaste                case 'C':
393254721Semaste                    m_cascade = Args::StringToBoolean(option_arg, true, &success);
394254721Semaste                    if (!success)
395254721Semaste                        error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
396254721Semaste                    break;
397254721Semaste                case 'P':
398254721Semaste                    handwrite_python = true;
399254721Semaste                    break;
400254721Semaste                case 'l':
401254721Semaste                    m_class_name = std::string(option_arg);
402254721Semaste                    is_class_based = true;
403254721Semaste                    break;
404254721Semaste                case 'p':
405254721Semaste                    m_skip_pointers = true;
406254721Semaste                    break;
407254721Semaste                case 'r':
408254721Semaste                    m_skip_references = true;
409254721Semaste                    break;
410254721Semaste                case 'w':
411254721Semaste                    m_category = std::string(option_arg);
412254721Semaste                    break;
413254721Semaste                case 'x':
414254721Semaste                    m_regex = true;
415254721Semaste                    break;
416254721Semaste                default:
417254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
418254721Semaste                    break;
419254721Semaste            }
420254721Semaste
421254721Semaste            return error;
422254721Semaste        }
423254721Semaste
424254721Semaste        void
425254721Semaste        OptionParsingStarting ()
426254721Semaste        {
427254721Semaste            m_cascade = true;
428254721Semaste            m_class_name = "";
429254721Semaste            m_skip_pointers = false;
430254721Semaste            m_skip_references = false;
431254721Semaste            m_category = "default";
432254721Semaste            is_class_based = false;
433254721Semaste            handwrite_python = false;
434254721Semaste            m_regex = false;
435254721Semaste        }
436254721Semaste
437254721Semaste        const OptionDefinition*
438254721Semaste        GetDefinitions ()
439254721Semaste        {
440254721Semaste            return g_option_table;
441254721Semaste        }
442254721Semaste
443254721Semaste        // Options table: Required for subclasses of Options.
444254721Semaste
445254721Semaste        static OptionDefinition g_option_table[];
446254721Semaste
447254721Semaste        // Instance variables to hold the values for command options.
448254721Semaste
449254721Semaste        bool m_cascade;
450254721Semaste        bool m_skip_references;
451254721Semaste        bool m_skip_pointers;
452254721Semaste        std::string m_class_name;
453254721Semaste        bool m_input_python;
454254721Semaste        std::string m_category;
455254721Semaste
456254721Semaste        bool is_class_based;
457254721Semaste
458254721Semaste        bool handwrite_python;
459254721Semaste
460254721Semaste        bool m_regex;
461254721Semaste
462254721Semaste    };
463254721Semaste
464254721Semaste    CommandOptions m_options;
465254721Semaste
466254721Semaste    virtual Options *
467254721Semaste    GetOptions ()
468254721Semaste    {
469254721Semaste        return &m_options;
470254721Semaste    }
471254721Semaste
472254721Semaste    bool
473254721Semaste    Execute_HandwritePython (Args& command, CommandReturnObject &result);
474254721Semaste
475254721Semaste    bool
476254721Semaste    Execute_PythonClass (Args& command, CommandReturnObject &result);
477254721Semaste
478254721Semasteprotected:
479254721Semaste    bool
480269024Semaste    DoExecute (Args& command, CommandReturnObject &result)
481269024Semaste    {
482269024Semaste        WarnOnPotentialUnquotedUnsignedType(command, result);
483269024Semaste
484269024Semaste        if (m_options.handwrite_python)
485269024Semaste            return Execute_HandwritePython(command, result);
486269024Semaste        else if (m_options.is_class_based)
487269024Semaste            return Execute_PythonClass(command, result);
488269024Semaste        else
489269024Semaste        {
490269024Semaste            result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
491269024Semaste            result.SetStatus(eReturnStatusFailed);
492269024Semaste            return false;
493269024Semaste        }
494269024Semaste    }
495254721Semaste
496269024Semaste    virtual void
497269024Semaste    IOHandlerActivated (IOHandler &io_handler)
498269024Semaste    {
499269024Semaste        StreamFileSP output_sp(io_handler.GetOutputStreamFile());
500269024Semaste        if (output_sp)
501269024Semaste        {
502269024Semaste            output_sp->PutCString(g_synth_addreader_instructions);
503269024Semaste            output_sp->Flush();
504269024Semaste        }
505269024Semaste    }
506269024Semaste
507269024Semaste
508269024Semaste    virtual void
509269024Semaste    IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
510269024Semaste    {
511269024Semaste        StreamFileSP error_sp = io_handler.GetErrorStreamFile();
512269024Semaste
513269024Semaste#ifndef LLDB_DISABLE_PYTHON
514269024Semaste        ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
515269024Semaste        if (interpreter)
516269024Semaste        {
517269024Semaste            StringList lines;
518269024Semaste            lines.SplitIntoLines(data);
519269024Semaste            if (lines.GetSize() > 0)
520269024Semaste            {
521269024Semaste                SynthAddOptions *options_ptr = ((SynthAddOptions*)io_handler.GetUserData());
522269024Semaste                if (options_ptr)
523269024Semaste                {
524269024Semaste                    SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
525269024Semaste
526269024Semaste                    ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
527269024Semaste                    if (interpreter)
528269024Semaste                    {
529269024Semaste                        std::string class_name_str;
530269024Semaste                        if (interpreter->GenerateTypeSynthClass (lines, class_name_str))
531269024Semaste                        {
532269024Semaste                            if (class_name_str.empty())
533269024Semaste                            {
534269024Semaste                                error_sp->Printf ("error: unable to obtain a proper name for the class.\n");
535269024Semaste                                error_sp->Flush();
536269024Semaste                            }
537269024Semaste                            else
538269024Semaste                            {
539269024Semaste                                // everything should be fine now, let's add the synth provider class
540269024Semaste
541269024Semaste                                SyntheticChildrenSP synth_provider;
542269024Semaste                                synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade).
543269024Semaste                                                                                   SetSkipPointers(options->m_skip_pointers).
544269024Semaste                                                                                   SetSkipReferences(options->m_skip_references),
545269024Semaste                                                                                   class_name_str.c_str()));
546269024Semaste
547269024Semaste
548269024Semaste                                lldb::TypeCategoryImplSP category;
549269024Semaste                                DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category);
550269024Semaste
551269024Semaste                                Error error;
552269024Semaste
553269024Semaste                                for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
554269024Semaste                                {
555269024Semaste                                    const char *type_name = options->m_target_types.GetStringAtIndex(i);
556269024Semaste                                    ConstString const_type_name(type_name);
557269024Semaste                                    if (const_type_name)
558269024Semaste                                    {
559269024Semaste                                        if (!CommandObjectTypeSynthAdd::AddSynth(const_type_name,
560269024Semaste                                                                                 synth_provider,
561269024Semaste                                                                                 options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth,
562269024Semaste                                                                                 options->m_category,
563269024Semaste                                                                                 &error))
564269024Semaste                                        {
565269024Semaste                                            error_sp->Printf("error: %s\n", error.AsCString());
566269024Semaste                                            error_sp->Flush();
567269024Semaste                                            break;
568269024Semaste                                        }
569269024Semaste                                    }
570269024Semaste                                    else
571269024Semaste                                    {
572269024Semaste                                        error_sp->Printf ("error: invalid type name.\n");
573269024Semaste                                        error_sp->Flush();
574269024Semaste                                        break;
575269024Semaste                                    }
576269024Semaste                                }
577269024Semaste                            }
578269024Semaste                        }
579269024Semaste                        else
580269024Semaste                        {
581269024Semaste                            error_sp->Printf ("error: unable to generate a class.\n");
582269024Semaste                            error_sp->Flush();
583269024Semaste                        }
584269024Semaste                    }
585269024Semaste                    else
586269024Semaste                    {
587269024Semaste                        error_sp->Printf ("error: no script interpreter.\n");
588269024Semaste                        error_sp->Flush();
589269024Semaste                    }
590269024Semaste                }
591269024Semaste                else
592269024Semaste                {
593269024Semaste                    error_sp->Printf ("error: internal synchronization data missing.\n");
594269024Semaste                    error_sp->Flush();
595269024Semaste                }
596269024Semaste            }
597269024Semaste            else
598269024Semaste            {
599269024Semaste                error_sp->Printf ("error: empty function, didn't add python command.\n");
600269024Semaste                error_sp->Flush();
601269024Semaste            }
602269024Semaste        }
603269024Semaste        else
604269024Semaste        {
605269024Semaste            error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
606269024Semaste            error_sp->Flush();
607269024Semaste        }
608269024Semaste
609269024Semaste#endif // #ifndef LLDB_DISABLE_PYTHON
610269024Semaste        io_handler.SetIsDone(true);
611269024Semaste    }
612269024Semaste
613254721Semastepublic:
614254721Semaste
615254721Semaste    enum SynthFormatType
616254721Semaste    {
617254721Semaste        eRegularSynth,
618254721Semaste        eRegexSynth
619254721Semaste    };
620254721Semaste
621254721Semaste    CommandObjectTypeSynthAdd (CommandInterpreter &interpreter);
622254721Semaste
623254721Semaste    ~CommandObjectTypeSynthAdd ()
624254721Semaste    {
625254721Semaste    }
626254721Semaste
627254721Semaste    static bool
628254721Semaste    AddSynth(ConstString type_name,
629254721Semaste             lldb::SyntheticChildrenSP entry,
630254721Semaste             SynthFormatType type,
631254721Semaste             std::string category_name,
632254721Semaste             Error* error);
633254721Semaste};
634254721Semaste
635254721Semaste//-------------------------------------------------------------------------
636254721Semaste// CommandObjectTypeFormatAdd
637254721Semaste//-------------------------------------------------------------------------
638254721Semaste
639254721Semasteclass CommandObjectTypeFormatAdd : public CommandObjectParsed
640254721Semaste{
641254721Semaste
642254721Semasteprivate:
643254721Semaste
644254721Semaste    class CommandOptions : public OptionGroup
645254721Semaste    {
646254721Semaste    public:
647254721Semaste
648254721Semaste        CommandOptions () :
649254721Semaste            OptionGroup()
650254721Semaste        {
651254721Semaste        }
652254721Semaste
653254721Semaste        virtual
654254721Semaste        ~CommandOptions ()
655254721Semaste        {
656254721Semaste        }
657254721Semaste
658254721Semaste        virtual uint32_t
659254721Semaste        GetNumDefinitions ();
660254721Semaste
661254721Semaste        virtual const OptionDefinition*
662254721Semaste        GetDefinitions ()
663254721Semaste        {
664254721Semaste            return g_option_table;
665254721Semaste        }
666254721Semaste
667254721Semaste        virtual void
668254721Semaste        OptionParsingStarting (CommandInterpreter &interpreter)
669254721Semaste        {
670254721Semaste            m_cascade = true;
671254721Semaste            m_skip_pointers = false;
672254721Semaste            m_skip_references = false;
673263363Semaste            m_regex = false;
674263363Semaste            m_category.assign("default");
675269024Semaste            m_custom_type_name.clear();
676254721Semaste        }
677254721Semaste        virtual Error
678254721Semaste        SetOptionValue (CommandInterpreter &interpreter,
679254721Semaste                        uint32_t option_idx,
680254721Semaste                        const char *option_value)
681254721Semaste        {
682254721Semaste            Error error;
683254721Semaste            const int short_option = g_option_table[option_idx].short_option;
684254721Semaste            bool success;
685254721Semaste
686254721Semaste            switch (short_option)
687254721Semaste            {
688254721Semaste                case 'C':
689254721Semaste                    m_cascade = Args::StringToBoolean(option_value, true, &success);
690254721Semaste                    if (!success)
691254721Semaste                        error.SetErrorStringWithFormat("invalid value for cascade: %s", option_value);
692254721Semaste                    break;
693254721Semaste                case 'p':
694254721Semaste                    m_skip_pointers = true;
695254721Semaste                    break;
696263363Semaste                case 'w':
697263363Semaste                    m_category.assign(option_value);
698263363Semaste                    break;
699254721Semaste                case 'r':
700254721Semaste                    m_skip_references = true;
701254721Semaste                    break;
702263363Semaste                case 'x':
703263363Semaste                    m_regex = true;
704263363Semaste                    break;
705269024Semaste                case 't':
706269024Semaste                    m_custom_type_name.assign(option_value);
707269024Semaste                    break;
708254721Semaste                default:
709254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
710254721Semaste                    break;
711254721Semaste            }
712254721Semaste
713254721Semaste            return error;
714254721Semaste        }
715254721Semaste
716254721Semaste        // Options table: Required for subclasses of Options.
717254721Semaste
718254721Semaste        static OptionDefinition g_option_table[];
719254721Semaste
720254721Semaste        // Instance variables to hold the values for command options.
721254721Semaste
722254721Semaste        bool m_cascade;
723254721Semaste        bool m_skip_references;
724254721Semaste        bool m_skip_pointers;
725263363Semaste        bool m_regex;
726263363Semaste        std::string m_category;
727269024Semaste        std::string m_custom_type_name;
728254721Semaste    };
729254721Semaste
730254721Semaste    OptionGroupOptions m_option_group;
731254721Semaste    OptionGroupFormat m_format_options;
732254721Semaste    CommandOptions m_command_options;
733254721Semaste
734254721Semaste    virtual Options *
735254721Semaste    GetOptions ()
736254721Semaste    {
737254721Semaste        return &m_option_group;
738254721Semaste    }
739254721Semaste
740254721Semastepublic:
741254721Semaste    CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) :
742254721Semaste        CommandObjectParsed (interpreter,
743254721Semaste                             "type format add",
744254721Semaste                             "Add a new formatting style for a type.",
745254721Semaste                             NULL),
746254721Semaste        m_option_group (interpreter),
747254721Semaste        m_format_options (eFormatInvalid),
748254721Semaste        m_command_options ()
749254721Semaste    {
750254721Semaste        CommandArgumentEntry type_arg;
751254721Semaste        CommandArgumentData type_style_arg;
752254721Semaste
753254721Semaste        type_style_arg.arg_type = eArgTypeName;
754254721Semaste        type_style_arg.arg_repetition = eArgRepeatPlus;
755254721Semaste
756254721Semaste        type_arg.push_back (type_style_arg);
757254721Semaste
758254721Semaste        m_arguments.push_back (type_arg);
759254721Semaste
760254721Semaste        SetHelpLong(
761254721Semaste                    "Some examples of using this command.\n"
762254721Semaste                    "We use as reference the following snippet of code:\n"
763254721Semaste                    "\n"
764254721Semaste                    "typedef int Aint;\n"
765254721Semaste                    "typedef float Afloat;\n"
766254721Semaste                    "typedef Aint Bint;\n"
767254721Semaste                    "typedef Afloat Bfloat;\n"
768254721Semaste                    "\n"
769254721Semaste                    "Aint ix = 5;\n"
770254721Semaste                    "Bint iy = 5;\n"
771254721Semaste                    "\n"
772254721Semaste                    "Afloat fx = 3.14;\n"
773254721Semaste                    "BFloat fy = 3.14;\n"
774254721Semaste                    "\n"
775254721Semaste                    "Typing:\n"
776254721Semaste                    "type format add -f hex AInt\n"
777254721Semaste                    "frame variable iy\n"
778254721Semaste                    "will produce an hex display of iy, because no formatter is available for Bint and the one for Aint is used instead\n"
779254721Semaste                    "To prevent this type\n"
780254721Semaste                    "type format add -f hex -C no AInt\n"
781254721Semaste                    "\n"
782254721Semaste                    "A similar reasoning applies to\n"
783254721Semaste                    "type format add -f hex -C no float -p\n"
784254721Semaste                    "which now prints all floats and float&s as hexadecimal, but does not format float*s\n"
785254721Semaste                    "and does not change the default display for Afloat and Bfloat objects.\n"
786254721Semaste                    );
787254721Semaste
788254721Semaste        // Add the "--format" to all options groups
789269024Semaste        m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
790254721Semaste        m_option_group.Append (&m_command_options);
791254721Semaste        m_option_group.Finalize();
792254721Semaste
793254721Semaste    }
794254721Semaste
795254721Semaste    ~CommandObjectTypeFormatAdd ()
796254721Semaste    {
797254721Semaste    }
798254721Semaste
799254721Semasteprotected:
800254721Semaste    bool
801254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
802254721Semaste    {
803254721Semaste        const size_t argc = command.GetArgumentCount();
804254721Semaste
805254721Semaste        if (argc < 1)
806254721Semaste        {
807254721Semaste            result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
808254721Semaste            result.SetStatus(eReturnStatusFailed);
809254721Semaste            return false;
810254721Semaste        }
811254721Semaste
812254721Semaste        const Format format = m_format_options.GetFormat();
813269024Semaste        if (format == eFormatInvalid && m_command_options.m_custom_type_name.empty())
814254721Semaste        {
815254721Semaste            result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
816254721Semaste            result.SetStatus(eReturnStatusFailed);
817254721Semaste            return false;
818254721Semaste        }
819254721Semaste
820254721Semaste        TypeFormatImplSP entry;
821254721Semaste
822269024Semaste        if (m_command_options.m_custom_type_name.empty())
823269024Semaste            entry.reset(new TypeFormatImpl_Format(format,
824269024Semaste                                                  TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
825269024Semaste                                                  SetSkipPointers(m_command_options.m_skip_pointers).
826269024Semaste                                                  SetSkipReferences(m_command_options.m_skip_references)));
827269024Semaste        else
828269024Semaste            entry.reset(new TypeFormatImpl_EnumType(ConstString(m_command_options.m_custom_type_name.c_str()),
829269024Semaste                                                    TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
830269024Semaste                                                    SetSkipPointers(m_command_options.m_skip_pointers).
831269024Semaste                                                    SetSkipReferences(m_command_options.m_skip_references)));
832254721Semaste
833254721Semaste        // now I have a valid format, let's add it to every type
834254721Semaste
835263363Semaste        TypeCategoryImplSP category_sp;
836263363Semaste        DataVisualization::Categories::GetCategory(ConstString(m_command_options.m_category), category_sp);
837263363Semaste        if (!category_sp)
838263363Semaste            return false;
839263363Semaste
840269024Semaste        WarnOnPotentialUnquotedUnsignedType(command, result);
841269024Semaste
842254721Semaste        for (size_t i = 0; i < argc; i++)
843254721Semaste        {
844254721Semaste            const char* typeA = command.GetArgumentAtIndex(i);
845254721Semaste            ConstString typeCS(typeA);
846254721Semaste            if (typeCS)
847263363Semaste            {
848263363Semaste                if (m_command_options.m_regex)
849263363Semaste                {
850263363Semaste                    RegularExpressionSP typeRX(new RegularExpression());
851263363Semaste                    if (!typeRX->Compile(typeCS.GetCString()))
852263363Semaste                    {
853263363Semaste                        result.AppendError("regex format error (maybe this is not really a regex?)");
854263363Semaste                        result.SetStatus(eReturnStatusFailed);
855263363Semaste                        return false;
856263363Semaste                    }
857269024Semaste                    category_sp->GetRegexTypeSummariesContainer()->Delete(typeCS);
858269024Semaste                    category_sp->GetRegexTypeFormatsContainer()->Add(typeRX, entry);
859263363Semaste                }
860263363Semaste                else
861269024Semaste                    category_sp->GetTypeFormatsContainer()->Add(typeCS, entry);
862263363Semaste            }
863254721Semaste            else
864254721Semaste            {
865254721Semaste                result.AppendError("empty typenames not allowed");
866254721Semaste                result.SetStatus(eReturnStatusFailed);
867254721Semaste                return false;
868254721Semaste            }
869254721Semaste        }
870254721Semaste
871254721Semaste        result.SetStatus(eReturnStatusSuccessFinishNoResult);
872254721Semaste        return result.Succeeded();
873254721Semaste    }
874254721Semaste};
875254721Semaste
876254721SemasteOptionDefinition
877254721SemasteCommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
878254721Semaste{
879269024Semaste    { LLDB_OPT_SET_ALL, false,  "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,    "Add this to the given category instead of the default one."},
880269024Semaste    { LLDB_OPT_SET_ALL, false,  "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
881269024Semaste    { LLDB_OPT_SET_ALL, false,  "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
882269024Semaste    { LLDB_OPT_SET_ALL, false,  "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
883263363Semaste    { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
884269024Semaste    { LLDB_OPT_SET_2,   false,  "type", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,    "Format variables as if they were of this type."},
885263363Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
886254721Semaste};
887254721Semaste
888254721Semaste
889254721Semasteuint32_t
890254721SemasteCommandObjectTypeFormatAdd::CommandOptions::GetNumDefinitions ()
891254721Semaste{
892254721Semaste    return sizeof(g_option_table) / sizeof (OptionDefinition);
893254721Semaste}
894254721Semaste
895254721Semaste
896254721Semaste//-------------------------------------------------------------------------
897254721Semaste// CommandObjectTypeFormatDelete
898254721Semaste//-------------------------------------------------------------------------
899254721Semaste
900254721Semasteclass CommandObjectTypeFormatDelete : public CommandObjectParsed
901254721Semaste{
902263363Semasteprivate:
903263363Semaste    class CommandOptions : public Options
904263363Semaste    {
905263363Semaste    public:
906263363Semaste
907263363Semaste        CommandOptions (CommandInterpreter &interpreter) :
908263363Semaste        Options (interpreter)
909263363Semaste        {
910263363Semaste        }
911263363Semaste
912263363Semaste        virtual
913263363Semaste        ~CommandOptions (){}
914263363Semaste
915263363Semaste        virtual Error
916263363Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
917263363Semaste        {
918263363Semaste            Error error;
919263363Semaste            const int short_option = m_getopt_table[option_idx].val;
920263363Semaste
921263363Semaste            switch (short_option)
922263363Semaste            {
923263363Semaste                case 'a':
924263363Semaste                    m_delete_all = true;
925263363Semaste                    break;
926263363Semaste                case 'w':
927263363Semaste                    m_category = std::string(option_arg);
928263363Semaste                    break;
929263363Semaste                default:
930263363Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
931263363Semaste                    break;
932263363Semaste            }
933263363Semaste
934263363Semaste            return error;
935263363Semaste        }
936263363Semaste
937263363Semaste        void
938263363Semaste        OptionParsingStarting ()
939263363Semaste        {
940263363Semaste            m_delete_all = false;
941263363Semaste            m_category = "default";
942263363Semaste        }
943263363Semaste
944263363Semaste        const OptionDefinition*
945263363Semaste        GetDefinitions ()
946263363Semaste        {
947263363Semaste            return g_option_table;
948263363Semaste        }
949263363Semaste
950263363Semaste        // Options table: Required for subclasses of Options.
951263363Semaste
952263363Semaste        static OptionDefinition g_option_table[];
953263363Semaste
954263363Semaste        // Instance variables to hold the values for command options.
955263363Semaste
956263363Semaste        bool m_delete_all;
957263363Semaste        std::string m_category;
958263363Semaste
959263363Semaste    };
960263363Semaste
961263363Semaste    CommandOptions m_options;
962263363Semaste
963263363Semaste    virtual Options *
964263363Semaste    GetOptions ()
965263363Semaste    {
966263363Semaste        return &m_options;
967263363Semaste    }
968263363Semaste
969263363Semaste    static bool
970263363Semaste    PerCategoryCallback(void* param,
971263363Semaste                        const lldb::TypeCategoryImplSP& category_sp)
972263363Semaste    {
973263363Semaste		ConstString *name = (ConstString*)param;
974263363Semaste		category_sp->Delete(*name, eFormatCategoryItemValue | eFormatCategoryItemRegexValue);
975263363Semaste		return true;
976263363Semaste    }
977263363Semaste
978254721Semastepublic:
979254721Semaste    CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) :
980254721Semaste        CommandObjectParsed (interpreter,
981254721Semaste                             "type format delete",
982254721Semaste                             "Delete an existing formatting style for a type.",
983263363Semaste                             NULL),
984263363Semaste    m_options(interpreter)
985254721Semaste    {
986254721Semaste        CommandArgumentEntry type_arg;
987254721Semaste        CommandArgumentData type_style_arg;
988254721Semaste
989254721Semaste        type_style_arg.arg_type = eArgTypeName;
990254721Semaste        type_style_arg.arg_repetition = eArgRepeatPlain;
991254721Semaste
992254721Semaste        type_arg.push_back (type_style_arg);
993254721Semaste
994254721Semaste        m_arguments.push_back (type_arg);
995254721Semaste
996254721Semaste    }
997254721Semaste
998254721Semaste    ~CommandObjectTypeFormatDelete ()
999254721Semaste    {
1000254721Semaste    }
1001254721Semaste
1002254721Semasteprotected:
1003254721Semaste    bool
1004254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
1005254721Semaste    {
1006254721Semaste        const size_t argc = command.GetArgumentCount();
1007254721Semaste
1008254721Semaste        if (argc != 1)
1009254721Semaste        {
1010254721Semaste            result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
1011254721Semaste            result.SetStatus(eReturnStatusFailed);
1012254721Semaste            return false;
1013254721Semaste        }
1014254721Semaste
1015254721Semaste        const char* typeA = command.GetArgumentAtIndex(0);
1016254721Semaste        ConstString typeCS(typeA);
1017254721Semaste
1018254721Semaste        if (!typeCS)
1019254721Semaste        {
1020254721Semaste            result.AppendError("empty typenames not allowed");
1021254721Semaste            result.SetStatus(eReturnStatusFailed);
1022254721Semaste            return false;
1023254721Semaste        }
1024254721Semaste
1025263363Semaste        if (m_options.m_delete_all)
1026263363Semaste        {
1027263363Semaste            DataVisualization::Categories::LoopThrough(PerCategoryCallback, &typeCS);
1028263363Semaste            result.SetStatus(eReturnStatusSuccessFinishNoResult);
1029263363Semaste            return result.Succeeded();
1030263363Semaste        }
1031254721Semaste
1032263363Semaste        lldb::TypeCategoryImplSP category;
1033263363Semaste        DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
1034263363Semaste
1035263363Semaste        bool delete_category = category->Delete(typeCS,
1036263363Semaste                                                eFormatCategoryItemValue | eFormatCategoryItemRegexValue);
1037263363Semaste
1038263363Semaste        if (delete_category)
1039254721Semaste        {
1040254721Semaste            result.SetStatus(eReturnStatusSuccessFinishNoResult);
1041254721Semaste            return result.Succeeded();
1042254721Semaste        }
1043254721Semaste        else
1044254721Semaste        {
1045254721Semaste            result.AppendErrorWithFormat ("no custom format for %s.\n", typeA);
1046254721Semaste            result.SetStatus(eReturnStatusFailed);
1047254721Semaste            return false;
1048254721Semaste        }
1049254721Semaste
1050254721Semaste    }
1051254721Semaste
1052254721Semaste};
1053254721Semaste
1054263363SemasteOptionDefinition
1055263363SemasteCommandObjectTypeFormatDelete::CommandOptions::g_option_table[] =
1056263363Semaste{
1057263363Semaste    { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,  "Delete from every category."},
1058263363Semaste    { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,  "Delete from given category."},
1059263363Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1060263363Semaste};
1061263363Semaste
1062254721Semaste//-------------------------------------------------------------------------
1063254721Semaste// CommandObjectTypeFormatClear
1064254721Semaste//-------------------------------------------------------------------------
1065254721Semaste
1066254721Semasteclass CommandObjectTypeFormatClear : public CommandObjectParsed
1067254721Semaste{
1068263363Semasteprivate:
1069263363Semaste
1070263363Semaste    class CommandOptions : public Options
1071263363Semaste    {
1072263363Semaste    public:
1073263363Semaste
1074263363Semaste        CommandOptions (CommandInterpreter &interpreter) :
1075263363Semaste        Options (interpreter)
1076263363Semaste        {
1077263363Semaste        }
1078263363Semaste
1079263363Semaste        virtual
1080263363Semaste        ~CommandOptions (){}
1081263363Semaste
1082263363Semaste        virtual Error
1083263363Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
1084263363Semaste        {
1085263363Semaste            Error error;
1086263363Semaste            const int short_option = m_getopt_table[option_idx].val;
1087263363Semaste
1088263363Semaste            switch (short_option)
1089263363Semaste            {
1090263363Semaste                case 'a':
1091263363Semaste                    m_delete_all = true;
1092263363Semaste                    break;
1093263363Semaste                default:
1094263363Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1095263363Semaste                    break;
1096263363Semaste            }
1097263363Semaste
1098263363Semaste            return error;
1099263363Semaste        }
1100263363Semaste
1101263363Semaste        void
1102263363Semaste        OptionParsingStarting ()
1103263363Semaste        {
1104263363Semaste            m_delete_all = false;
1105263363Semaste        }
1106263363Semaste
1107263363Semaste        const OptionDefinition*
1108263363Semaste        GetDefinitions ()
1109263363Semaste        {
1110263363Semaste            return g_option_table;
1111263363Semaste        }
1112263363Semaste
1113263363Semaste        // Options table: Required for subclasses of Options.
1114263363Semaste
1115263363Semaste        static OptionDefinition g_option_table[];
1116263363Semaste
1117263363Semaste        // Instance variables to hold the values for command options.
1118263363Semaste
1119263363Semaste        bool m_delete_all;
1120263363Semaste        bool m_delete_named;
1121263363Semaste    };
1122263363Semaste
1123263363Semaste    CommandOptions m_options;
1124263363Semaste
1125263363Semaste    virtual Options *
1126263363Semaste    GetOptions ()
1127263363Semaste    {
1128263363Semaste        return &m_options;
1129263363Semaste    }
1130263363Semaste
1131263363Semaste    static bool
1132263363Semaste    PerCategoryCallback(void* param,
1133263363Semaste                        const lldb::TypeCategoryImplSP& cate)
1134263363Semaste    {
1135269024Semaste        cate->GetTypeFormatsContainer()->Clear();
1136269024Semaste        cate->GetRegexTypeFormatsContainer()->Clear();
1137263363Semaste        return true;
1138263363Semaste
1139263363Semaste    }
1140263363Semaste
1141254721Semastepublic:
1142254721Semaste    CommandObjectTypeFormatClear (CommandInterpreter &interpreter) :
1143254721Semaste        CommandObjectParsed (interpreter,
1144254721Semaste                             "type format clear",
1145254721Semaste                             "Delete all existing format styles.",
1146263363Semaste                             NULL),
1147263363Semaste    m_options(interpreter)
1148254721Semaste    {
1149254721Semaste    }
1150254721Semaste
1151254721Semaste    ~CommandObjectTypeFormatClear ()
1152254721Semaste    {
1153254721Semaste    }
1154254721Semaste
1155254721Semasteprotected:
1156254721Semaste    bool
1157254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
1158254721Semaste    {
1159263363Semaste        if (m_options.m_delete_all)
1160263363Semaste            DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL);
1161263363Semaste
1162263363Semaste        else
1163263363Semaste        {
1164263363Semaste            lldb::TypeCategoryImplSP category;
1165263363Semaste            if (command.GetArgumentCount() > 0)
1166263363Semaste            {
1167263363Semaste                const char* cat_name = command.GetArgumentAtIndex(0);
1168263363Semaste                ConstString cat_nameCS(cat_name);
1169263363Semaste                DataVisualization::Categories::GetCategory(cat_nameCS, category);
1170263363Semaste            }
1171263363Semaste            else
1172263363Semaste                DataVisualization::Categories::GetCategory(ConstString(NULL), category);
1173263363Semaste            category->Clear(eFormatCategoryItemValue | eFormatCategoryItemRegexValue);
1174263363Semaste        }
1175263363Semaste
1176254721Semaste        result.SetStatus(eReturnStatusSuccessFinishResult);
1177254721Semaste        return result.Succeeded();
1178254721Semaste    }
1179254721Semaste
1180254721Semaste};
1181254721Semaste
1182263363SemasteOptionDefinition
1183263363SemasteCommandObjectTypeFormatClear::CommandOptions::g_option_table[] =
1184263363Semaste{
1185263363Semaste    { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,  "Clear every category."},
1186263363Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1187263363Semaste};
1188263363Semaste
1189254721Semaste//-------------------------------------------------------------------------
1190254721Semaste// CommandObjectTypeFormatList
1191254721Semaste//-------------------------------------------------------------------------
1192254721Semaste
1193254721Semastebool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);
1194263363Semastebool CommandObjectTypeRXFormatList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeFormatImplSP& entry);
1195254721Semaste
1196254721Semasteclass CommandObjectTypeFormatList;
1197254721Semaste
1198254721Semastestruct CommandObjectTypeFormatList_LoopCallbackParam {
1199254721Semaste    CommandObjectTypeFormatList* self;
1200254721Semaste    CommandReturnObject* result;
1201254721Semaste    RegularExpression* regex;
1202263363Semaste    RegularExpression* cate_regex;
1203254721Semaste    CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R,
1204263363Semaste                                            RegularExpression* X = NULL, RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
1205254721Semaste};
1206254721Semaste
1207254721Semasteclass CommandObjectTypeFormatList : public CommandObjectParsed
1208254721Semaste{
1209263363Semaste    class CommandOptions : public Options
1210263363Semaste    {
1211263363Semaste    public:
1212263363Semaste
1213263363Semaste        CommandOptions (CommandInterpreter &interpreter) :
1214263363Semaste        Options (interpreter)
1215263363Semaste        {
1216263363Semaste        }
1217263363Semaste
1218263363Semaste        virtual
1219263363Semaste        ~CommandOptions (){}
1220263363Semaste
1221263363Semaste        virtual Error
1222263363Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
1223263363Semaste        {
1224263363Semaste            Error error;
1225263363Semaste            const int short_option = m_getopt_table[option_idx].val;
1226263363Semaste
1227263363Semaste            switch (short_option)
1228263363Semaste            {
1229263363Semaste                case 'w':
1230263363Semaste                    m_category_regex = std::string(option_arg);
1231263363Semaste                    break;
1232263363Semaste                default:
1233263363Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1234263363Semaste                    break;
1235263363Semaste            }
1236263363Semaste
1237263363Semaste            return error;
1238263363Semaste        }
1239263363Semaste
1240263363Semaste        void
1241263363Semaste        OptionParsingStarting ()
1242263363Semaste        {
1243263363Semaste            m_category_regex = "";
1244263363Semaste        }
1245263363Semaste
1246263363Semaste        const OptionDefinition*
1247263363Semaste        GetDefinitions ()
1248263363Semaste        {
1249263363Semaste            return g_option_table;
1250263363Semaste        }
1251263363Semaste
1252263363Semaste        // Options table: Required for subclasses of Options.
1253263363Semaste
1254263363Semaste        static OptionDefinition g_option_table[];
1255263363Semaste
1256263363Semaste        // Instance variables to hold the values for command options.
1257263363Semaste
1258263363Semaste        std::string m_category_regex;
1259263363Semaste
1260263363Semaste    };
1261263363Semaste
1262263363Semaste    CommandOptions m_options;
1263263363Semaste
1264263363Semaste    virtual Options *
1265263363Semaste    GetOptions ()
1266263363Semaste    {
1267263363Semaste        return &m_options;
1268263363Semaste    }
1269263363Semaste
1270254721Semastepublic:
1271254721Semaste    CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
1272254721Semaste        CommandObjectParsed (interpreter,
1273254721Semaste                             "type format list",
1274254721Semaste                             "Show a list of current formatting styles.",
1275263363Semaste                             NULL),
1276263363Semaste    m_options(interpreter)
1277254721Semaste    {
1278254721Semaste        CommandArgumentEntry type_arg;
1279254721Semaste        CommandArgumentData type_style_arg;
1280254721Semaste
1281254721Semaste        type_style_arg.arg_type = eArgTypeName;
1282254721Semaste        type_style_arg.arg_repetition = eArgRepeatOptional;
1283254721Semaste
1284254721Semaste        type_arg.push_back (type_style_arg);
1285254721Semaste
1286254721Semaste        m_arguments.push_back (type_arg);
1287254721Semaste    }
1288254721Semaste
1289254721Semaste    ~CommandObjectTypeFormatList ()
1290254721Semaste    {
1291254721Semaste    }
1292254721Semaste
1293254721Semasteprotected:
1294254721Semaste    bool
1295254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
1296254721Semaste    {
1297254721Semaste        const size_t argc = command.GetArgumentCount();
1298254721Semaste
1299254721Semaste        CommandObjectTypeFormatList_LoopCallbackParam *param;
1300263363Semaste        RegularExpression* cate_regex =
1301263363Semaste        m_options.m_category_regex.empty() ? NULL :
1302263363Semaste        new RegularExpression(m_options.m_category_regex.c_str());
1303254721Semaste
1304254721Semaste        if (argc == 1)
1305254721Semaste        {
1306254721Semaste            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
1307254721Semaste            regex->Compile(command.GetArgumentAtIndex(0));
1308263363Semaste            param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex,cate_regex);
1309254721Semaste        }
1310254721Semaste        else
1311263363Semaste            param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,NULL,cate_regex);
1312263363Semaste
1313263363Semaste        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
1314269024Semaste        delete param;
1315263363Semaste
1316263363Semaste        if (cate_regex)
1317263363Semaste            delete cate_regex;
1318263363Semaste
1319254721Semaste        result.SetStatus(eReturnStatusSuccessFinishResult);
1320254721Semaste        return result.Succeeded();
1321254721Semaste    }
1322254721Semaste
1323254721Semasteprivate:
1324254721Semaste
1325263363Semaste    static bool
1326263363Semaste    PerCategoryCallback(void* param_vp,
1327263363Semaste                        const lldb::TypeCategoryImplSP& cate)
1328263363Semaste    {
1329263363Semaste
1330263363Semaste        CommandObjectTypeFormatList_LoopCallbackParam* param =
1331263363Semaste        (CommandObjectTypeFormatList_LoopCallbackParam*)param_vp;
1332263363Semaste        CommandReturnObject* result = param->result;
1333263363Semaste
1334263363Semaste        const char* cate_name = cate->GetName();
1335263363Semaste
1336263363Semaste        // if the category is disabled or empty and there is no regex, just skip it
1337263363Semaste        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemValue | eFormatCategoryItemRegexValue) == 0) && param->cate_regex == NULL)
1338263363Semaste            return true;
1339263363Semaste
1340263363Semaste        // if we have a regex and this category does not match it, just skip it
1341263363Semaste        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
1342263363Semaste            return true;
1343263363Semaste
1344263363Semaste        result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n",
1345263363Semaste                                         cate_name,
1346263363Semaste                                         (cate->IsEnabled() ? "enabled" : "disabled"));
1347263363Semaste
1348269024Semaste        cate->GetTypeFormatsContainer()->LoopThrough(CommandObjectTypeFormatList_LoopCallback, param_vp);
1349263363Semaste
1350269024Semaste        if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0)
1351263363Semaste        {
1352263363Semaste            result->GetOutputStream().Printf("Regex-based summaries (slower):\n");
1353269024Semaste            cate->GetRegexTypeFormatsContainer()->LoopThrough(CommandObjectTypeRXFormatList_LoopCallback, param_vp);
1354263363Semaste        }
1355263363Semaste        return true;
1356263363Semaste    }
1357263363Semaste
1358263363Semaste
1359254721Semaste    bool
1360263363Semaste    LoopCallback (const char* type,
1361254721Semaste                  const lldb::TypeFormatImplSP& entry,
1362254721Semaste                  RegularExpression* regex,
1363254721Semaste                  CommandReturnObject *result)
1364254721Semaste    {
1365263363Semaste        if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type))
1366263363Semaste            result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
1367254721Semaste        return true;
1368254721Semaste    }
1369254721Semaste
1370254721Semaste    friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);
1371263363Semaste    friend bool CommandObjectTypeRXFormatList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeFormatImplSP& entry);
1372254721Semaste
1373254721Semaste};
1374254721Semaste
1375254721Semastebool
1376254721SemasteCommandObjectTypeFormatList_LoopCallback (
1377254721Semaste                                    void* pt2self,
1378254721Semaste                                    ConstString type,
1379254721Semaste                                    const lldb::TypeFormatImplSP& entry)
1380254721Semaste{
1381254721Semaste    CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;
1382263363Semaste    return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
1383254721Semaste}
1384254721Semaste
1385263363Semastebool
1386263363SemasteCommandObjectTypeRXFormatList_LoopCallback (
1387263363Semaste                                             void* pt2self,
1388263363Semaste                                             lldb::RegularExpressionSP regex,
1389263363Semaste                                             const lldb::TypeFormatImplSP& entry)
1390263363Semaste{
1391263363Semaste    CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;
1392263363Semaste    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
1393263363Semaste}
1394254721Semaste
1395263363SemasteOptionDefinition
1396263363SemasteCommandObjectTypeFormatList::CommandOptions::g_option_table[] =
1397263363Semaste{
1398263363Semaste    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
1399263363Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1400263363Semaste};
1401263363Semaste
1402254721Semaste#ifndef LLDB_DISABLE_PYTHON
1403254721Semaste
1404254721Semaste//-------------------------------------------------------------------------
1405254721Semaste// CommandObjectTypeSummaryAdd
1406254721Semaste//-------------------------------------------------------------------------
1407254721Semaste
1408254721Semaste#endif // #ifndef LLDB_DISABLE_PYTHON
1409254721Semaste
1410254721SemasteError
1411254721SemasteCommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
1412254721Semaste{
1413254721Semaste    Error error;
1414254721Semaste    const int short_option = m_getopt_table[option_idx].val;
1415254721Semaste    bool success;
1416254721Semaste
1417254721Semaste    switch (short_option)
1418254721Semaste    {
1419254721Semaste        case 'C':
1420254721Semaste            m_flags.SetCascades(Args::StringToBoolean(option_arg, true, &success));
1421254721Semaste            if (!success)
1422254721Semaste                error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
1423254721Semaste            break;
1424254721Semaste        case 'e':
1425254721Semaste            m_flags.SetDontShowChildren(false);
1426254721Semaste            break;
1427254721Semaste        case 'v':
1428254721Semaste            m_flags.SetDontShowValue(true);
1429254721Semaste            break;
1430254721Semaste        case 'c':
1431254721Semaste            m_flags.SetShowMembersOneLiner(true);
1432254721Semaste            break;
1433254721Semaste        case 's':
1434254721Semaste            m_format_string = std::string(option_arg);
1435254721Semaste            break;
1436254721Semaste        case 'p':
1437254721Semaste            m_flags.SetSkipPointers(true);
1438254721Semaste            break;
1439254721Semaste        case 'r':
1440254721Semaste            m_flags.SetSkipReferences(true);
1441254721Semaste            break;
1442254721Semaste        case 'x':
1443254721Semaste            m_regex = true;
1444254721Semaste            break;
1445254721Semaste        case 'n':
1446254721Semaste            m_name.SetCString(option_arg);
1447254721Semaste            break;
1448254721Semaste        case 'o':
1449254721Semaste            m_python_script = std::string(option_arg);
1450254721Semaste            m_is_add_script = true;
1451254721Semaste            break;
1452254721Semaste        case 'F':
1453254721Semaste            m_python_function = std::string(option_arg);
1454254721Semaste            m_is_add_script = true;
1455254721Semaste            break;
1456254721Semaste        case 'P':
1457254721Semaste            m_is_add_script = true;
1458254721Semaste            break;
1459254721Semaste        case 'w':
1460254721Semaste            m_category = std::string(option_arg);
1461254721Semaste            break;
1462254721Semaste        case 'O':
1463254721Semaste            m_flags.SetHideItemNames(true);
1464254721Semaste            break;
1465254721Semaste        default:
1466254721Semaste            error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1467254721Semaste            break;
1468254721Semaste    }
1469254721Semaste
1470254721Semaste    return error;
1471254721Semaste}
1472254721Semaste
1473254721Semastevoid
1474254721SemasteCommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting ()
1475254721Semaste{
1476254721Semaste    m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false);
1477254721Semaste    m_flags.SetShowMembersOneLiner(false).SetSkipPointers(false).SetSkipReferences(false).SetHideItemNames(false);
1478254721Semaste
1479254721Semaste    m_regex = false;
1480254721Semaste    m_name.Clear();
1481254721Semaste    m_python_script = "";
1482254721Semaste    m_python_function = "";
1483254721Semaste    m_format_string = "";
1484254721Semaste    m_is_add_script = false;
1485254721Semaste    m_category = "default";
1486254721Semaste}
1487254721Semaste
1488269024Semaste
1489269024Semaste
1490254721Semaste#ifndef LLDB_DISABLE_PYTHON
1491254721Semaste
1492254721Semastebool
1493254721SemasteCommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result)
1494254721Semaste{
1495254721Semaste    const size_t argc = command.GetArgumentCount();
1496254721Semaste
1497254721Semaste    if (argc < 1 && !m_options.m_name)
1498254721Semaste    {
1499254721Semaste        result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
1500254721Semaste        result.SetStatus(eReturnStatusFailed);
1501254721Semaste        return false;
1502254721Semaste    }
1503254721Semaste
1504254721Semaste    TypeSummaryImplSP script_format;
1505254721Semaste
1506254721Semaste    if (!m_options.m_python_function.empty()) // we have a Python function ready to use
1507254721Semaste    {
1508254721Semaste        const char *funct_name = m_options.m_python_function.c_str();
1509254721Semaste        if (!funct_name || !funct_name[0])
1510254721Semaste        {
1511254721Semaste            result.AppendError ("function name empty.\n");
1512254721Semaste            result.SetStatus (eReturnStatusFailed);
1513254721Semaste            return false;
1514254721Semaste        }
1515254721Semaste
1516269024Semaste        std::string code = ("    " + m_options.m_python_function + "(valobj,internal_dict)");
1517254721Semaste
1518254721Semaste        script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
1519254721Semaste                                                    funct_name,
1520254721Semaste                                                    code.c_str()));
1521254721Semaste
1522254721Semaste        ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1523254721Semaste
1524254721Semaste        if (interpreter && interpreter->CheckObjectExists(funct_name) == false)
1525254721Semaste            result.AppendWarningWithFormat("The provided function \"%s\" does not exist - "
1526254721Semaste                                           "please define it before attempting to use this summary.\n",
1527254721Semaste                                           funct_name);
1528254721Semaste    }
1529254721Semaste    else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it
1530254721Semaste    {
1531254721Semaste        ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1532254721Semaste        if (!interpreter)
1533254721Semaste        {
1534254721Semaste            result.AppendError ("script interpreter missing - unable to generate function wrapper.\n");
1535254721Semaste            result.SetStatus (eReturnStatusFailed);
1536254721Semaste            return false;
1537254721Semaste        }
1538254721Semaste        StringList funct_sl;
1539254721Semaste        funct_sl << m_options.m_python_script.c_str();
1540254721Semaste        std::string funct_name_str;
1541254721Semaste        if (!interpreter->GenerateTypeScriptFunction (funct_sl,
1542254721Semaste                                                      funct_name_str))
1543254721Semaste        {
1544254721Semaste            result.AppendError ("unable to generate function wrapper.\n");
1545254721Semaste            result.SetStatus (eReturnStatusFailed);
1546254721Semaste            return false;
1547254721Semaste        }
1548254721Semaste        if (funct_name_str.empty())
1549254721Semaste        {
1550254721Semaste            result.AppendError ("script interpreter failed to generate a valid function name.\n");
1551254721Semaste            result.SetStatus (eReturnStatusFailed);
1552254721Semaste            return false;
1553254721Semaste        }
1554254721Semaste
1555269024Semaste        std::string code = "    " + m_options.m_python_script;
1556254721Semaste
1557254721Semaste        script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
1558254721Semaste                                                    funct_name_str.c_str(),
1559254721Semaste                                                    code.c_str()));
1560254721Semaste    }
1561269024Semaste    else
1562269024Semaste    {
1563269024Semaste        // Use an IOHandler to grab Python code from the user
1564254721Semaste        ScriptAddOptions *options = new ScriptAddOptions(m_options.m_flags,
1565254721Semaste                                                         m_options.m_regex,
1566254721Semaste                                                         m_options.m_name,
1567254721Semaste                                                         m_options.m_category);
1568254721Semaste
1569254721Semaste        for (size_t i = 0; i < argc; i++)
1570254721Semaste        {
1571254721Semaste            const char* typeA = command.GetArgumentAtIndex(i);
1572254721Semaste            if (typeA && *typeA)
1573254721Semaste                options->m_target_types << typeA;
1574254721Semaste            else
1575254721Semaste            {
1576254721Semaste                result.AppendError("empty typenames not allowed");
1577254721Semaste                result.SetStatus(eReturnStatusFailed);
1578254721Semaste                return false;
1579254721Semaste            }
1580254721Semaste        }
1581254721Semaste
1582269024Semaste        m_interpreter.GetPythonCommandsFromIOHandler ("    ",   // Prompt
1583269024Semaste                                                      *this,    // IOHandlerDelegate
1584269024Semaste                                                      true,     // Run IOHandler in async mode
1585269024Semaste                                                      options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1586269024Semaste        result.SetStatus(eReturnStatusSuccessFinishNoResult);
1587269024Semaste
1588254721Semaste        return result.Succeeded();
1589254721Semaste    }
1590254721Semaste
1591254721Semaste    // if I am here, script_format must point to something good, so I can add that
1592254721Semaste    // as a script summary to all interested parties
1593254721Semaste
1594254721Semaste    Error error;
1595254721Semaste
1596254721Semaste    for (size_t i = 0; i < command.GetArgumentCount(); i++)
1597254721Semaste    {
1598254721Semaste        const char *type_name = command.GetArgumentAtIndex(i);
1599254721Semaste        CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
1600254721Semaste                                                script_format,
1601254721Semaste                                                (m_options.m_regex ? eRegexSummary : eRegularSummary),
1602254721Semaste                                                m_options.m_category,
1603254721Semaste                                                &error);
1604254721Semaste        if (error.Fail())
1605254721Semaste        {
1606254721Semaste            result.AppendError(error.AsCString());
1607254721Semaste            result.SetStatus(eReturnStatusFailed);
1608254721Semaste            return false;
1609254721Semaste        }
1610254721Semaste    }
1611254721Semaste
1612254721Semaste    if (m_options.m_name)
1613254721Semaste    {
1614254721Semaste        AddSummary(m_options.m_name, script_format, eNamedSummary, m_options.m_category, &error);
1615254721Semaste        if (error.Fail())
1616254721Semaste        {
1617254721Semaste            result.AppendError(error.AsCString());
1618254721Semaste            result.AppendError("added to types, but not given a name");
1619254721Semaste            result.SetStatus(eReturnStatusFailed);
1620254721Semaste            return false;
1621254721Semaste        }
1622254721Semaste    }
1623254721Semaste
1624254721Semaste    return result.Succeeded();
1625254721Semaste}
1626254721Semaste
1627254721Semaste#endif
1628254721Semaste
1629254721Semaste
1630254721Semastebool
1631254721SemasteCommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturnObject &result)
1632254721Semaste{
1633254721Semaste    const size_t argc = command.GetArgumentCount();
1634254721Semaste
1635254721Semaste    if (argc < 1 && !m_options.m_name)
1636254721Semaste    {
1637254721Semaste        result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
1638254721Semaste        result.SetStatus(eReturnStatusFailed);
1639254721Semaste        return false;
1640254721Semaste    }
1641254721Semaste
1642254721Semaste    if (!m_options.m_flags.GetShowMembersOneLiner() && m_options.m_format_string.empty())
1643254721Semaste    {
1644254721Semaste        result.AppendError("empty summary strings not allowed");
1645254721Semaste        result.SetStatus(eReturnStatusFailed);
1646254721Semaste        return false;
1647254721Semaste    }
1648254721Semaste
1649254721Semaste    const char* format_cstr = (m_options.m_flags.GetShowMembersOneLiner() ? "" : m_options.m_format_string.c_str());
1650254721Semaste
1651254721Semaste    // ${var%S} is an endless recursion, prevent it
1652254721Semaste    if (strcmp(format_cstr, "${var%S}") == 0)
1653254721Semaste    {
1654254721Semaste        result.AppendError("recursive summary not allowed");
1655254721Semaste        result.SetStatus(eReturnStatusFailed);
1656254721Semaste        return false;
1657254721Semaste    }
1658254721Semaste
1659254721Semaste    Error error;
1660254721Semaste
1661254721Semaste    lldb::TypeSummaryImplSP entry(new StringSummaryFormat(m_options.m_flags,
1662254721Semaste                                                        format_cstr));
1663254721Semaste
1664254721Semaste    if (error.Fail())
1665254721Semaste    {
1666254721Semaste        result.AppendError(error.AsCString());
1667254721Semaste        result.SetStatus(eReturnStatusFailed);
1668254721Semaste        return false;
1669254721Semaste    }
1670254721Semaste
1671254721Semaste    // now I have a valid format, let's add it to every type
1672254721Semaste
1673254721Semaste    for (size_t i = 0; i < argc; i++)
1674254721Semaste    {
1675254721Semaste        const char* typeA = command.GetArgumentAtIndex(i);
1676254721Semaste        if (!typeA || typeA[0] == '\0')
1677254721Semaste        {
1678254721Semaste            result.AppendError("empty typenames not allowed");
1679254721Semaste            result.SetStatus(eReturnStatusFailed);
1680254721Semaste            return false;
1681254721Semaste        }
1682254721Semaste        ConstString typeCS(typeA);
1683254721Semaste
1684254721Semaste        AddSummary(typeCS,
1685254721Semaste                   entry,
1686254721Semaste                   (m_options.m_regex ? eRegexSummary : eRegularSummary),
1687254721Semaste                   m_options.m_category,
1688254721Semaste                   &error);
1689254721Semaste
1690254721Semaste        if (error.Fail())
1691254721Semaste        {
1692254721Semaste            result.AppendError(error.AsCString());
1693254721Semaste            result.SetStatus(eReturnStatusFailed);
1694254721Semaste            return false;
1695254721Semaste        }
1696254721Semaste    }
1697254721Semaste
1698254721Semaste    if (m_options.m_name)
1699254721Semaste    {
1700254721Semaste        AddSummary(m_options.m_name, entry, eNamedSummary, m_options.m_category, &error);
1701254721Semaste        if (error.Fail())
1702254721Semaste        {
1703254721Semaste            result.AppendError(error.AsCString());
1704254721Semaste            result.AppendError("added to types, but not given a name");
1705254721Semaste            result.SetStatus(eReturnStatusFailed);
1706254721Semaste            return false;
1707254721Semaste        }
1708254721Semaste    }
1709254721Semaste
1710254721Semaste    result.SetStatus(eReturnStatusSuccessFinishNoResult);
1711254721Semaste    return result.Succeeded();
1712254721Semaste}
1713254721Semaste
1714254721SemasteCommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
1715254721Semaste    CommandObjectParsed (interpreter,
1716254721Semaste                         "type summary add",
1717254721Semaste                         "Add a new summary style for a type.",
1718254721Semaste                         NULL),
1719269024Semaste    IOHandlerDelegateMultiline ("DONE"),
1720254721Semaste    m_options (interpreter)
1721254721Semaste{
1722254721Semaste    CommandArgumentEntry type_arg;
1723254721Semaste    CommandArgumentData type_style_arg;
1724254721Semaste
1725254721Semaste    type_style_arg.arg_type = eArgTypeName;
1726254721Semaste    type_style_arg.arg_repetition = eArgRepeatPlus;
1727254721Semaste
1728254721Semaste    type_arg.push_back (type_style_arg);
1729254721Semaste
1730254721Semaste    m_arguments.push_back (type_arg);
1731254721Semaste
1732254721Semaste    SetHelpLong(
1733254721Semaste                "Some examples of using this command.\n"
1734254721Semaste                "We use as reference the following snippet of code:\n"
1735254721Semaste                "struct JustADemo\n"
1736254721Semaste                "{\n"
1737254721Semaste                "int* ptr;\n"
1738254721Semaste                "float value;\n"
1739254721Semaste                "JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n"
1740254721Semaste                "};\n"
1741254721Semaste                "JustADemo object(42,3.14);\n"
1742254721Semaste                "struct AnotherDemo : public JustADemo\n"
1743254721Semaste                "{\n"
1744254721Semaste                "uint8_t byte;\n"
1745254721Semaste                "AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n"
1746254721Semaste                "};\n"
1747254721Semaste                "AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n"
1748254721Semaste                "\n"
1749254721Semaste                "type summary add --summary-string \"the answer is ${*var.ptr}\" JustADemo\n"
1750254721Semaste                "when typing frame variable object you will get \"the answer is 42\"\n"
1751254721Semaste                "type summary add --summary-string \"the answer is ${*var.ptr}, and the question is ${var.value}\" JustADemo\n"
1752254721Semaste                "when typing frame variable object you will get \"the answer is 42 and the question is 3.14\"\n"
1753254721Semaste                "\n"
1754254721Semaste                "Alternatively, you could also say\n"
1755254721Semaste                "type summary add --summary-string \"${var%V} -> ${*var}\" \"int *\"\n"
1756254721Semaste                "and replace the above summary string with\n"
1757254721Semaste                "type summary add --summary-string \"the answer is ${var.ptr}, and the question is ${var.value}\" JustADemo\n"
1758254721Semaste                "to obtain a similar result\n"
1759254721Semaste                "\n"
1760254721Semaste                "To add a summary valid for both JustADemo and AnotherDemo you can use the scoping operator, as in:\n"
1761254721Semaste                "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes\n"
1762254721Semaste                "\n"
1763254721Semaste                "This will be used for both variables of type JustADemo and AnotherDemo. To prevent this, change the -C to read -C no\n"
1764254721Semaste                "If you do not want pointers to be shown using that summary, you can use the -p option, as in:\n"
1765254721Semaste                "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes -p\n"
1766254721Semaste                "A similar option -r exists for references.\n"
1767254721Semaste                "\n"
1768254721Semaste                "If you simply want a one-line summary of the content of your variable, without typing an explicit string to that effect\n"
1769254721Semaste                "you can use the -c option, without giving any summary string:\n"
1770254721Semaste                "type summary add -c JustADemo\n"
1771254721Semaste                "frame variable object\n"
1772254721Semaste                "the output being similar to (ptr=0xsomeaddress, value=3.14)\n"
1773254721Semaste                "\n"
1774254721Semaste                "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"
1775254721Semaste                "type summary add -e --summary-string \"*ptr = ${*var.ptr}\" JustADemo\n"
1776254721Semaste                "Here the value of the int* is displayed, followed by the standard LLDB sequence of children objects, one per line.\n"
1777254721Semaste                "to get an output like:\n"
1778254721Semaste                "\n"
1779254721Semaste                "*ptr = 42 {\n"
1780254721Semaste                " ptr = 0xsomeaddress\n"
1781254721Semaste                " value = 3.14\n"
1782254721Semaste                "}\n"
1783254721Semaste                "\n"
1784254721Semaste                "You can also add Python summaries, in which case you will use lldb public API to gather information from your variables"
1785254721Semaste                "and elaborate them to a meaningful summary inside a script written in Python. The variable object will be passed to your"
1786254721Semaste                "script as an SBValue object. The following example might help you when starting to use the Python summaries feature:\n"
1787254721Semaste                "type summary add JustADemo -o \"value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();\"\n"
1788254721Semaste                "If you prefer to type your scripts on multiple lines, you will use the -P option and then type your script, ending it with "
1789254721Semaste                "the word DONE on a line by itself to mark you're finished editing your code:\n"
1790254721Semaste                "(lldb)type summary add JustADemo -P\n"
1791254721Semaste                "     value = valobj.GetChildMemberWithName('value');\n"
1792254721Semaste                "     return 'My value is ' + value.GetValue();\n"
1793254721Semaste                "DONE\n"
1794254721Semaste                "(lldb) <-- type further LLDB commands here\n"
1795254721Semaste                );
1796254721Semaste}
1797254721Semaste
1798254721Semastebool
1799254721SemasteCommandObjectTypeSummaryAdd::DoExecute (Args& command, CommandReturnObject &result)
1800254721Semaste{
1801269024Semaste    WarnOnPotentialUnquotedUnsignedType(command, result);
1802269024Semaste
1803254721Semaste    if (m_options.m_is_add_script)
1804254721Semaste    {
1805254721Semaste#ifndef LLDB_DISABLE_PYTHON
1806254721Semaste        return Execute_ScriptSummary(command, result);
1807254721Semaste#else
1808254721Semaste        result.AppendError ("python is disabled");
1809254721Semaste        result.SetStatus(eReturnStatusFailed);
1810254721Semaste        return false;
1811254721Semaste#endif
1812254721Semaste    }
1813254721Semaste
1814254721Semaste    return Execute_StringSummary(command, result);
1815254721Semaste}
1816254721Semaste
1817254721Semastebool
1818254721SemasteCommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
1819254721Semaste                                        TypeSummaryImplSP entry,
1820254721Semaste                                        SummaryFormatType type,
1821254721Semaste                                        std::string category_name,
1822254721Semaste                                        Error* error)
1823254721Semaste{
1824254721Semaste    lldb::TypeCategoryImplSP category;
1825254721Semaste    DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
1826254721Semaste
1827254721Semaste    if (type == eRegularSummary)
1828254721Semaste    {
1829254721Semaste        std::string type_name_str(type_name.GetCString());
1830254721Semaste        if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0)
1831254721Semaste        {
1832254721Semaste            type_name_str.resize(type_name_str.length()-2);
1833254721Semaste            if (type_name_str.back() != ' ')
1834254721Semaste                type_name_str.append(" \\[[0-9]+\\]");
1835254721Semaste            else
1836254721Semaste                type_name_str.append("\\[[0-9]+\\]");
1837254721Semaste            type_name.SetCString(type_name_str.c_str());
1838254721Semaste            type = eRegexSummary;
1839254721Semaste        }
1840254721Semaste    }
1841254721Semaste
1842254721Semaste    if (type == eRegexSummary)
1843254721Semaste    {
1844254721Semaste        RegularExpressionSP typeRX(new RegularExpression());
1845254721Semaste        if (!typeRX->Compile(type_name.GetCString()))
1846254721Semaste        {
1847254721Semaste            if (error)
1848254721Semaste                error->SetErrorString("regex format error (maybe this is not really a regex?)");
1849254721Semaste            return false;
1850254721Semaste        }
1851254721Semaste
1852269024Semaste        category->GetRegexTypeSummariesContainer()->Delete(type_name);
1853269024Semaste        category->GetRegexTypeSummariesContainer()->Add(typeRX, entry);
1854254721Semaste
1855254721Semaste        return true;
1856254721Semaste    }
1857254721Semaste    else if (type == eNamedSummary)
1858254721Semaste    {
1859254721Semaste        // system named summaries do not exist (yet?)
1860254721Semaste        DataVisualization::NamedSummaryFormats::Add(type_name,entry);
1861254721Semaste        return true;
1862254721Semaste    }
1863254721Semaste    else
1864254721Semaste    {
1865269024Semaste        category->GetTypeSummariesContainer()->Add(type_name, entry);
1866254721Semaste        return true;
1867254721Semaste    }
1868254721Semaste}
1869254721Semaste
1870254721SemasteOptionDefinition
1871254721SemasteCommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
1872254721Semaste{
1873263363Semaste    { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,    "Add this to the given category instead of the default one."},
1874263363Semaste    { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
1875263363Semaste    { 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."},
1876263363Semaste    { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
1877263363Semaste    { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
1878263363Semaste    { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
1879263363Semaste    { LLDB_OPT_SET_1  , true, "inline-children", 'c', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,    "If true, inline all child values into summary string."},
1880263363Semaste    { LLDB_OPT_SET_1  , false, "omit-names", 'O', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,    "If true, omit value names in the summary display."},
1881263363Semaste    { LLDB_OPT_SET_2  , true, "summary-string", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeSummaryString,    "Summary string used to display text and object contents."},
1882263363Semaste    { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."},
1883263363Semaste    { 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."},
1884263363Semaste    { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."},
1885263363Semaste    { 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."},
1886263363Semaste    { LLDB_OPT_SET_2 | LLDB_OPT_SET_3,   false, "name", 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,    "A name for this summary string."},
1887254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1888254721Semaste};
1889254721Semaste
1890254721Semaste
1891254721Semaste//-------------------------------------------------------------------------
1892254721Semaste// CommandObjectTypeSummaryDelete
1893254721Semaste//-------------------------------------------------------------------------
1894254721Semaste
1895254721Semasteclass CommandObjectTypeSummaryDelete : public CommandObjectParsed
1896254721Semaste{
1897254721Semasteprivate:
1898254721Semaste    class CommandOptions : public Options
1899254721Semaste    {
1900254721Semaste    public:
1901254721Semaste
1902254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
1903254721Semaste        Options (interpreter)
1904254721Semaste        {
1905254721Semaste        }
1906254721Semaste
1907254721Semaste        virtual
1908254721Semaste        ~CommandOptions (){}
1909254721Semaste
1910254721Semaste        virtual Error
1911254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
1912254721Semaste        {
1913254721Semaste            Error error;
1914254721Semaste            const int short_option = m_getopt_table[option_idx].val;
1915254721Semaste
1916254721Semaste            switch (short_option)
1917254721Semaste            {
1918254721Semaste                case 'a':
1919254721Semaste                    m_delete_all = true;
1920254721Semaste                    break;
1921254721Semaste                case 'w':
1922254721Semaste                    m_category = std::string(option_arg);
1923254721Semaste                    break;
1924254721Semaste                default:
1925254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1926254721Semaste                    break;
1927254721Semaste            }
1928254721Semaste
1929254721Semaste            return error;
1930254721Semaste        }
1931254721Semaste
1932254721Semaste        void
1933254721Semaste        OptionParsingStarting ()
1934254721Semaste        {
1935254721Semaste            m_delete_all = false;
1936254721Semaste            m_category = "default";
1937254721Semaste        }
1938254721Semaste
1939254721Semaste        const OptionDefinition*
1940254721Semaste        GetDefinitions ()
1941254721Semaste        {
1942254721Semaste            return g_option_table;
1943254721Semaste        }
1944254721Semaste
1945254721Semaste        // Options table: Required for subclasses of Options.
1946254721Semaste
1947254721Semaste        static OptionDefinition g_option_table[];
1948254721Semaste
1949254721Semaste        // Instance variables to hold the values for command options.
1950254721Semaste
1951254721Semaste        bool m_delete_all;
1952254721Semaste        std::string m_category;
1953254721Semaste
1954254721Semaste    };
1955254721Semaste
1956254721Semaste    CommandOptions m_options;
1957254721Semaste
1958254721Semaste    virtual Options *
1959254721Semaste    GetOptions ()
1960254721Semaste    {
1961254721Semaste        return &m_options;
1962254721Semaste    }
1963254721Semaste
1964254721Semaste    static bool
1965254721Semaste    PerCategoryCallback(void* param,
1966254721Semaste                        const lldb::TypeCategoryImplSP& category_sp)
1967254721Semaste    {
1968254721Semaste		ConstString *name = (ConstString*)param;
1969254721Semaste		category_sp->Delete(*name, eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
1970254721Semaste		return true;
1971254721Semaste    }
1972254721Semaste
1973254721Semastepublic:
1974254721Semaste    CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) :
1975254721Semaste        CommandObjectParsed (interpreter,
1976254721Semaste                             "type summary delete",
1977254721Semaste                             "Delete an existing summary style for a type.",
1978254721Semaste                             NULL),
1979254721Semaste        m_options(interpreter)
1980254721Semaste    {
1981254721Semaste        CommandArgumentEntry type_arg;
1982254721Semaste        CommandArgumentData type_style_arg;
1983254721Semaste
1984254721Semaste        type_style_arg.arg_type = eArgTypeName;
1985254721Semaste        type_style_arg.arg_repetition = eArgRepeatPlain;
1986254721Semaste
1987254721Semaste        type_arg.push_back (type_style_arg);
1988254721Semaste
1989254721Semaste        m_arguments.push_back (type_arg);
1990254721Semaste
1991254721Semaste    }
1992254721Semaste
1993254721Semaste    ~CommandObjectTypeSummaryDelete ()
1994254721Semaste    {
1995254721Semaste    }
1996254721Semaste
1997254721Semasteprotected:
1998254721Semaste    bool
1999254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
2000254721Semaste    {
2001254721Semaste        const size_t argc = command.GetArgumentCount();
2002254721Semaste
2003254721Semaste        if (argc != 1)
2004254721Semaste        {
2005254721Semaste            result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
2006254721Semaste            result.SetStatus(eReturnStatusFailed);
2007254721Semaste            return false;
2008254721Semaste        }
2009254721Semaste
2010254721Semaste        const char* typeA = command.GetArgumentAtIndex(0);
2011254721Semaste        ConstString typeCS(typeA);
2012254721Semaste
2013254721Semaste        if (!typeCS)
2014254721Semaste        {
2015254721Semaste            result.AppendError("empty typenames not allowed");
2016254721Semaste            result.SetStatus(eReturnStatusFailed);
2017254721Semaste            return false;
2018254721Semaste        }
2019254721Semaste
2020254721Semaste        if (m_options.m_delete_all)
2021254721Semaste        {
2022254721Semaste            DataVisualization::Categories::LoopThrough(PerCategoryCallback, &typeCS);
2023254721Semaste            result.SetStatus(eReturnStatusSuccessFinishNoResult);
2024254721Semaste            return result.Succeeded();
2025254721Semaste        }
2026254721Semaste
2027254721Semaste        lldb::TypeCategoryImplSP category;
2028254721Semaste        DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
2029254721Semaste
2030254721Semaste        bool delete_category = category->Delete(typeCS,
2031254721Semaste                                                eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
2032254721Semaste        bool delete_named = DataVisualization::NamedSummaryFormats::Delete(typeCS);
2033254721Semaste
2034254721Semaste        if (delete_category || delete_named)
2035254721Semaste        {
2036254721Semaste            result.SetStatus(eReturnStatusSuccessFinishNoResult);
2037254721Semaste            return result.Succeeded();
2038254721Semaste        }
2039254721Semaste        else
2040254721Semaste        {
2041254721Semaste            result.AppendErrorWithFormat ("no custom summary for %s.\n", typeA);
2042254721Semaste            result.SetStatus(eReturnStatusFailed);
2043254721Semaste            return false;
2044254721Semaste        }
2045254721Semaste
2046254721Semaste    }
2047254721Semaste};
2048254721Semaste
2049254721SemasteOptionDefinition
2050254721SemasteCommandObjectTypeSummaryDelete::CommandOptions::g_option_table[] =
2051254721Semaste{
2052263363Semaste    { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,  "Delete from every category."},
2053263363Semaste    { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,  "Delete from given category."},
2054254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2055254721Semaste};
2056254721Semaste
2057254721Semasteclass CommandObjectTypeSummaryClear : public CommandObjectParsed
2058254721Semaste{
2059254721Semasteprivate:
2060254721Semaste
2061254721Semaste    class CommandOptions : public Options
2062254721Semaste    {
2063254721Semaste    public:
2064254721Semaste
2065254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
2066254721Semaste        Options (interpreter)
2067254721Semaste        {
2068254721Semaste        }
2069254721Semaste
2070254721Semaste        virtual
2071254721Semaste        ~CommandOptions (){}
2072254721Semaste
2073254721Semaste        virtual Error
2074254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
2075254721Semaste        {
2076254721Semaste            Error error;
2077254721Semaste            const int short_option = m_getopt_table[option_idx].val;
2078254721Semaste
2079254721Semaste            switch (short_option)
2080254721Semaste            {
2081254721Semaste                case 'a':
2082254721Semaste                    m_delete_all = true;
2083254721Semaste                    break;
2084254721Semaste                default:
2085254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2086254721Semaste                    break;
2087254721Semaste            }
2088254721Semaste
2089254721Semaste            return error;
2090254721Semaste        }
2091254721Semaste
2092254721Semaste        void
2093254721Semaste        OptionParsingStarting ()
2094254721Semaste        {
2095254721Semaste            m_delete_all = false;
2096254721Semaste        }
2097254721Semaste
2098254721Semaste        const OptionDefinition*
2099254721Semaste        GetDefinitions ()
2100254721Semaste        {
2101254721Semaste            return g_option_table;
2102254721Semaste        }
2103254721Semaste
2104254721Semaste        // Options table: Required for subclasses of Options.
2105254721Semaste
2106254721Semaste        static OptionDefinition g_option_table[];
2107254721Semaste
2108254721Semaste        // Instance variables to hold the values for command options.
2109254721Semaste
2110254721Semaste        bool m_delete_all;
2111254721Semaste        bool m_delete_named;
2112254721Semaste    };
2113254721Semaste
2114254721Semaste    CommandOptions m_options;
2115254721Semaste
2116254721Semaste    virtual Options *
2117254721Semaste    GetOptions ()
2118254721Semaste    {
2119254721Semaste        return &m_options;
2120254721Semaste    }
2121254721Semaste
2122254721Semaste    static bool
2123254721Semaste    PerCategoryCallback(void* param,
2124254721Semaste                        const lldb::TypeCategoryImplSP& cate)
2125254721Semaste    {
2126269024Semaste        cate->GetTypeSummariesContainer()->Clear();
2127269024Semaste        cate->GetRegexTypeSummariesContainer()->Clear();
2128254721Semaste        return true;
2129254721Semaste
2130254721Semaste    }
2131254721Semaste
2132254721Semastepublic:
2133254721Semaste    CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) :
2134254721Semaste        CommandObjectParsed (interpreter,
2135254721Semaste                             "type summary clear",
2136254721Semaste                             "Delete all existing summary styles.",
2137254721Semaste                             NULL),
2138254721Semaste        m_options(interpreter)
2139254721Semaste    {
2140254721Semaste    }
2141254721Semaste
2142254721Semaste    ~CommandObjectTypeSummaryClear ()
2143254721Semaste    {
2144254721Semaste    }
2145254721Semaste
2146254721Semasteprotected:
2147254721Semaste    bool
2148254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
2149254721Semaste    {
2150254721Semaste
2151254721Semaste        if (m_options.m_delete_all)
2152254721Semaste            DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL);
2153254721Semaste
2154254721Semaste        else
2155254721Semaste        {
2156254721Semaste            lldb::TypeCategoryImplSP category;
2157254721Semaste            if (command.GetArgumentCount() > 0)
2158254721Semaste            {
2159254721Semaste                const char* cat_name = command.GetArgumentAtIndex(0);
2160254721Semaste                ConstString cat_nameCS(cat_name);
2161254721Semaste                DataVisualization::Categories::GetCategory(cat_nameCS, category);
2162254721Semaste            }
2163254721Semaste            else
2164254721Semaste                DataVisualization::Categories::GetCategory(ConstString(NULL), category);
2165254721Semaste            category->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
2166254721Semaste        }
2167254721Semaste
2168254721Semaste        DataVisualization::NamedSummaryFormats::Clear();
2169254721Semaste
2170254721Semaste        result.SetStatus(eReturnStatusSuccessFinishResult);
2171254721Semaste        return result.Succeeded();
2172254721Semaste    }
2173254721Semaste
2174254721Semaste};
2175254721Semaste
2176254721SemasteOptionDefinition
2177254721SemasteCommandObjectTypeSummaryClear::CommandOptions::g_option_table[] =
2178254721Semaste{
2179263363Semaste    { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,  "Clear every category."},
2180254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2181254721Semaste};
2182254721Semaste
2183254721Semaste//-------------------------------------------------------------------------
2184254721Semaste// CommandObjectTypeSummaryList
2185254721Semaste//-------------------------------------------------------------------------
2186254721Semaste
2187254721Semastebool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const StringSummaryFormat::SharedPointer& entry);
2188254721Semastebool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const StringSummaryFormat::SharedPointer& entry);
2189254721Semaste
2190254721Semasteclass CommandObjectTypeSummaryList;
2191254721Semaste
2192254721Semastestruct CommandObjectTypeSummaryList_LoopCallbackParam {
2193254721Semaste    CommandObjectTypeSummaryList* self;
2194254721Semaste    CommandReturnObject* result;
2195254721Semaste    RegularExpression* regex;
2196254721Semaste    RegularExpression* cate_regex;
2197254721Semaste    CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R,
2198254721Semaste                                                  RegularExpression* X = NULL,
2199254721Semaste                                                  RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
2200254721Semaste};
2201254721Semaste
2202254721Semasteclass CommandObjectTypeSummaryList : public CommandObjectParsed
2203254721Semaste{
2204254721Semaste
2205254721Semaste    class CommandOptions : public Options
2206254721Semaste    {
2207254721Semaste    public:
2208254721Semaste
2209254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
2210254721Semaste        Options (interpreter)
2211254721Semaste        {
2212254721Semaste        }
2213254721Semaste
2214254721Semaste        virtual
2215254721Semaste        ~CommandOptions (){}
2216254721Semaste
2217254721Semaste        virtual Error
2218254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
2219254721Semaste        {
2220254721Semaste            Error error;
2221254721Semaste            const int short_option = m_getopt_table[option_idx].val;
2222254721Semaste
2223254721Semaste            switch (short_option)
2224254721Semaste            {
2225254721Semaste                case 'w':
2226254721Semaste                    m_category_regex = std::string(option_arg);
2227254721Semaste                    break;
2228254721Semaste                default:
2229254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2230254721Semaste                    break;
2231254721Semaste            }
2232254721Semaste
2233254721Semaste            return error;
2234254721Semaste        }
2235254721Semaste
2236254721Semaste        void
2237254721Semaste        OptionParsingStarting ()
2238254721Semaste        {
2239254721Semaste            m_category_regex = "";
2240254721Semaste        }
2241254721Semaste
2242254721Semaste        const OptionDefinition*
2243254721Semaste        GetDefinitions ()
2244254721Semaste        {
2245254721Semaste            return g_option_table;
2246254721Semaste        }
2247254721Semaste
2248254721Semaste        // Options table: Required for subclasses of Options.
2249254721Semaste
2250254721Semaste        static OptionDefinition g_option_table[];
2251254721Semaste
2252254721Semaste        // Instance variables to hold the values for command options.
2253254721Semaste
2254254721Semaste        std::string m_category_regex;
2255254721Semaste
2256254721Semaste    };
2257254721Semaste
2258254721Semaste    CommandOptions m_options;
2259254721Semaste
2260254721Semaste    virtual Options *
2261254721Semaste    GetOptions ()
2262254721Semaste    {
2263254721Semaste        return &m_options;
2264254721Semaste    }
2265254721Semaste
2266254721Semastepublic:
2267254721Semaste    CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :
2268254721Semaste        CommandObjectParsed (interpreter,
2269254721Semaste                             "type summary list",
2270254721Semaste                             "Show a list of current summary styles.",
2271254721Semaste                             NULL),
2272254721Semaste        m_options(interpreter)
2273254721Semaste    {
2274254721Semaste        CommandArgumentEntry type_arg;
2275254721Semaste        CommandArgumentData type_style_arg;
2276254721Semaste
2277254721Semaste        type_style_arg.arg_type = eArgTypeName;
2278254721Semaste        type_style_arg.arg_repetition = eArgRepeatOptional;
2279254721Semaste
2280254721Semaste        type_arg.push_back (type_style_arg);
2281254721Semaste
2282254721Semaste        m_arguments.push_back (type_arg);
2283254721Semaste    }
2284254721Semaste
2285254721Semaste    ~CommandObjectTypeSummaryList ()
2286254721Semaste    {
2287254721Semaste    }
2288254721Semaste
2289254721Semasteprotected:
2290254721Semaste    bool
2291254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
2292254721Semaste    {
2293254721Semaste        const size_t argc = command.GetArgumentCount();
2294254721Semaste
2295254721Semaste        CommandObjectTypeSummaryList_LoopCallbackParam *param;
2296254721Semaste        RegularExpression* cate_regex =
2297254721Semaste        m_options.m_category_regex.empty() ? NULL :
2298254721Semaste        new RegularExpression(m_options.m_category_regex.c_str());
2299254721Semaste
2300254721Semaste        if (argc == 1)
2301254721Semaste        {
2302254721Semaste            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
2303254721Semaste            regex->Compile(command.GetArgumentAtIndex(0));
2304254721Semaste            param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex,cate_regex);
2305254721Semaste        }
2306254721Semaste        else
2307254721Semaste            param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,NULL,cate_regex);
2308254721Semaste
2309254721Semaste        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
2310269024Semaste        delete param;
2311269024Semaste
2312254721Semaste        if (DataVisualization::NamedSummaryFormats::GetCount() > 0)
2313254721Semaste        {
2314254721Semaste            result.GetOutputStream().Printf("Named summaries:\n");
2315254721Semaste            if (argc == 1)
2316254721Semaste            {
2317254721Semaste                RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
2318254721Semaste                regex->Compile(command.GetArgumentAtIndex(0));
2319254721Semaste                param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex);
2320254721Semaste            }
2321254721Semaste            else
2322254721Semaste                param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);
2323254721Semaste            DataVisualization::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
2324254721Semaste            delete param;
2325254721Semaste        }
2326254721Semaste
2327254721Semaste        if (cate_regex)
2328254721Semaste            delete cate_regex;
2329254721Semaste
2330254721Semaste        result.SetStatus(eReturnStatusSuccessFinishResult);
2331254721Semaste        return result.Succeeded();
2332254721Semaste    }
2333254721Semaste
2334254721Semasteprivate:
2335254721Semaste
2336254721Semaste    static bool
2337254721Semaste    PerCategoryCallback(void* param_vp,
2338254721Semaste                        const lldb::TypeCategoryImplSP& cate)
2339254721Semaste    {
2340254721Semaste
2341254721Semaste        CommandObjectTypeSummaryList_LoopCallbackParam* param =
2342254721Semaste            (CommandObjectTypeSummaryList_LoopCallbackParam*)param_vp;
2343254721Semaste        CommandReturnObject* result = param->result;
2344254721Semaste
2345254721Semaste        const char* cate_name = cate->GetName();
2346254721Semaste
2347254721Semaste        // if the category is disabled or empty and there is no regex, just skip it
2348254721Semaste        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary) == 0) && param->cate_regex == NULL)
2349254721Semaste            return true;
2350254721Semaste
2351254721Semaste        // if we have a regex and this category does not match it, just skip it
2352254721Semaste        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
2353254721Semaste            return true;
2354254721Semaste
2355254721Semaste        result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n",
2356254721Semaste                                         cate_name,
2357254721Semaste                                         (cate->IsEnabled() ? "enabled" : "disabled"));
2358254721Semaste
2359269024Semaste        cate->GetTypeSummariesContainer()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param_vp);
2360254721Semaste
2361269024Semaste        if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0)
2362254721Semaste        {
2363254721Semaste            result->GetOutputStream().Printf("Regex-based summaries (slower):\n");
2364269024Semaste            cate->GetRegexTypeSummariesContainer()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param_vp);
2365254721Semaste        }
2366254721Semaste        return true;
2367254721Semaste    }
2368254721Semaste
2369254721Semaste
2370254721Semaste    bool
2371254721Semaste    LoopCallback (const char* type,
2372254721Semaste                  const lldb::TypeSummaryImplSP& entry,
2373254721Semaste                  RegularExpression* regex,
2374254721Semaste                  CommandReturnObject *result)
2375254721Semaste    {
2376254721Semaste        if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type))
2377254721Semaste                result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
2378254721Semaste        return true;
2379254721Semaste    }
2380254721Semaste
2381254721Semaste    friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeSummaryImplSP& entry);
2382254721Semaste    friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeSummaryImplSP& entry);
2383254721Semaste};
2384254721Semaste
2385254721Semastebool
2386254721SemasteCommandObjectTypeSummaryList_LoopCallback (
2387254721Semaste                                          void* pt2self,
2388254721Semaste                                          ConstString type,
2389254721Semaste                                          const lldb::TypeSummaryImplSP& entry)
2390254721Semaste{
2391254721Semaste    CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;
2392254721Semaste    return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
2393254721Semaste}
2394254721Semaste
2395254721Semastebool
2396254721SemasteCommandObjectTypeRXSummaryList_LoopCallback (
2397254721Semaste                                           void* pt2self,
2398254721Semaste                                           lldb::RegularExpressionSP regex,
2399254721Semaste                                           const lldb::TypeSummaryImplSP& entry)
2400254721Semaste{
2401254721Semaste    CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;
2402254721Semaste    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
2403254721Semaste}
2404254721Semaste
2405254721SemasteOptionDefinition
2406254721SemasteCommandObjectTypeSummaryList::CommandOptions::g_option_table[] =
2407254721Semaste{
2408263363Semaste    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
2409254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2410254721Semaste};
2411254721Semaste
2412254721Semaste//-------------------------------------------------------------------------
2413254721Semaste// CommandObjectTypeCategoryEnable
2414254721Semaste//-------------------------------------------------------------------------
2415254721Semaste
2416254721Semasteclass CommandObjectTypeCategoryEnable : public CommandObjectParsed
2417254721Semaste{
2418254721Semastepublic:
2419254721Semaste    CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) :
2420254721Semaste        CommandObjectParsed (interpreter,
2421254721Semaste                             "type category enable",
2422254721Semaste                             "Enable a category as a source of formatters.",
2423254721Semaste                             NULL)
2424254721Semaste    {
2425254721Semaste        CommandArgumentEntry type_arg;
2426254721Semaste        CommandArgumentData type_style_arg;
2427254721Semaste
2428254721Semaste        type_style_arg.arg_type = eArgTypeName;
2429254721Semaste        type_style_arg.arg_repetition = eArgRepeatPlus;
2430254721Semaste
2431254721Semaste        type_arg.push_back (type_style_arg);
2432254721Semaste
2433254721Semaste        m_arguments.push_back (type_arg);
2434254721Semaste
2435254721Semaste    }
2436254721Semaste
2437254721Semaste    ~CommandObjectTypeCategoryEnable ()
2438254721Semaste    {
2439254721Semaste    }
2440254721Semaste
2441254721Semasteprotected:
2442254721Semaste    bool
2443254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
2444254721Semaste    {
2445254721Semaste        const size_t argc = command.GetArgumentCount();
2446254721Semaste
2447254721Semaste        if (argc < 1)
2448254721Semaste        {
2449254721Semaste            result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
2450254721Semaste            result.SetStatus(eReturnStatusFailed);
2451254721Semaste            return false;
2452254721Semaste        }
2453254721Semaste
2454254721Semaste        if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
2455254721Semaste        {
2456254721Semaste            // we want to make sure to enable "system" last and "default" first
2457254721Semaste            DataVisualization::Categories::Enable(ConstString("default"), TypeCategoryMap::First);
2458254721Semaste            uint32_t num_categories = DataVisualization::Categories::GetCount();
2459254721Semaste            for (uint32_t i = 0; i < num_categories; i++)
2460254721Semaste            {
2461254721Semaste                lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i);
2462254721Semaste                if (category_sp)
2463254721Semaste                {
2464254721Semaste                    if ( ::strcmp(category_sp->GetName(), "system") == 0 ||
2465254721Semaste                         ::strcmp(category_sp->GetName(), "default") == 0 )
2466254721Semaste                        continue;
2467254721Semaste                    else
2468254721Semaste                        DataVisualization::Categories::Enable(category_sp, TypeCategoryMap::Default);
2469254721Semaste                }
2470254721Semaste            }
2471254721Semaste            DataVisualization::Categories::Enable(ConstString("system"), TypeCategoryMap::Last);
2472254721Semaste        }
2473254721Semaste        else
2474254721Semaste        {
2475254721Semaste            for (int i = argc - 1; i >= 0; i--)
2476254721Semaste            {
2477254721Semaste                const char* typeA = command.GetArgumentAtIndex(i);
2478254721Semaste                ConstString typeCS(typeA);
2479254721Semaste
2480254721Semaste                if (!typeCS)
2481254721Semaste                {
2482254721Semaste                    result.AppendError("empty category name not allowed");
2483254721Semaste                    result.SetStatus(eReturnStatusFailed);
2484254721Semaste                    return false;
2485254721Semaste                }
2486254721Semaste                DataVisualization::Categories::Enable(typeCS);
2487254721Semaste                lldb::TypeCategoryImplSP cate;
2488254721Semaste                if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get())
2489254721Semaste                {
2490254721Semaste                    if (cate->GetCount() == 0)
2491254721Semaste                    {
2492254721Semaste                        result.AppendWarning("empty category enabled (typo?)");
2493254721Semaste                    }
2494254721Semaste                }
2495254721Semaste            }
2496254721Semaste        }
2497254721Semaste
2498254721Semaste        result.SetStatus(eReturnStatusSuccessFinishResult);
2499254721Semaste        return result.Succeeded();
2500254721Semaste    }
2501254721Semaste
2502254721Semaste};
2503254721Semaste
2504254721Semaste//-------------------------------------------------------------------------
2505254721Semaste// CommandObjectTypeCategoryDelete
2506254721Semaste//-------------------------------------------------------------------------
2507254721Semaste
2508254721Semasteclass CommandObjectTypeCategoryDelete : public CommandObjectParsed
2509254721Semaste{
2510254721Semastepublic:
2511254721Semaste    CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) :
2512254721Semaste        CommandObjectParsed (interpreter,
2513254721Semaste                             "type category delete",
2514254721Semaste                             "Delete a category and all associated formatters.",
2515254721Semaste                             NULL)
2516254721Semaste    {
2517254721Semaste        CommandArgumentEntry type_arg;
2518254721Semaste        CommandArgumentData type_style_arg;
2519254721Semaste
2520254721Semaste        type_style_arg.arg_type = eArgTypeName;
2521254721Semaste        type_style_arg.arg_repetition = eArgRepeatPlus;
2522254721Semaste
2523254721Semaste        type_arg.push_back (type_style_arg);
2524254721Semaste
2525254721Semaste        m_arguments.push_back (type_arg);
2526254721Semaste
2527254721Semaste    }
2528254721Semaste
2529254721Semaste    ~CommandObjectTypeCategoryDelete ()
2530254721Semaste    {
2531254721Semaste    }
2532254721Semaste
2533254721Semasteprotected:
2534254721Semaste    bool
2535254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
2536254721Semaste    {
2537254721Semaste        const size_t argc = command.GetArgumentCount();
2538254721Semaste
2539254721Semaste        if (argc < 1)
2540254721Semaste        {
2541254721Semaste            result.AppendErrorWithFormat ("%s takes 1 or more arg.\n", m_cmd_name.c_str());
2542254721Semaste            result.SetStatus(eReturnStatusFailed);
2543254721Semaste            return false;
2544254721Semaste        }
2545254721Semaste
2546254721Semaste        bool success = true;
2547254721Semaste
2548254721Semaste        // the order is not relevant here
2549254721Semaste        for (int i = argc - 1; i >= 0; i--)
2550254721Semaste        {
2551254721Semaste            const char* typeA = command.GetArgumentAtIndex(i);
2552254721Semaste            ConstString typeCS(typeA);
2553254721Semaste
2554254721Semaste            if (!typeCS)
2555254721Semaste            {
2556254721Semaste                result.AppendError("empty category name not allowed");
2557254721Semaste                result.SetStatus(eReturnStatusFailed);
2558254721Semaste                return false;
2559254721Semaste            }
2560254721Semaste            if (!DataVisualization::Categories::Delete(typeCS))
2561254721Semaste                success = false; // keep deleting even if we hit an error
2562254721Semaste        }
2563254721Semaste        if (success)
2564254721Semaste        {
2565254721Semaste            result.SetStatus(eReturnStatusSuccessFinishResult);
2566254721Semaste            return result.Succeeded();
2567254721Semaste        }
2568254721Semaste        else
2569254721Semaste        {
2570254721Semaste            result.AppendError("cannot delete one or more categories\n");
2571254721Semaste            result.SetStatus(eReturnStatusFailed);
2572254721Semaste            return false;
2573254721Semaste        }
2574254721Semaste    }
2575254721Semaste};
2576254721Semaste
2577254721Semaste//-------------------------------------------------------------------------
2578254721Semaste// CommandObjectTypeCategoryDisable
2579254721Semaste//-------------------------------------------------------------------------
2580254721Semaste
2581254721Semasteclass CommandObjectTypeCategoryDisable : public CommandObjectParsed
2582254721Semaste{
2583254721Semastepublic:
2584254721Semaste    CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
2585254721Semaste        CommandObjectParsed (interpreter,
2586254721Semaste                             "type category disable",
2587254721Semaste                             "Disable a category as a source of formatters.",
2588254721Semaste                             NULL)
2589254721Semaste    {
2590254721Semaste        CommandArgumentEntry type_arg;
2591254721Semaste        CommandArgumentData type_style_arg;
2592254721Semaste
2593254721Semaste        type_style_arg.arg_type = eArgTypeName;
2594254721Semaste        type_style_arg.arg_repetition = eArgRepeatPlus;
2595254721Semaste
2596254721Semaste        type_arg.push_back (type_style_arg);
2597254721Semaste
2598254721Semaste        m_arguments.push_back (type_arg);
2599254721Semaste
2600254721Semaste    }
2601254721Semaste
2602254721Semaste    ~CommandObjectTypeCategoryDisable ()
2603254721Semaste    {
2604254721Semaste    }
2605254721Semaste
2606254721Semasteprotected:
2607254721Semaste    bool
2608254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
2609254721Semaste    {
2610254721Semaste        const size_t argc = command.GetArgumentCount();
2611254721Semaste
2612254721Semaste        if (argc < 1)
2613254721Semaste        {
2614254721Semaste            result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
2615254721Semaste            result.SetStatus(eReturnStatusFailed);
2616254721Semaste            return false;
2617254721Semaste        }
2618254721Semaste
2619254721Semaste        if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
2620254721Semaste        {
2621254721Semaste            uint32_t num_categories = DataVisualization::Categories::GetCount();
2622254721Semaste            for (uint32_t i = 0; i < num_categories; i++)
2623254721Semaste            {
2624254721Semaste                lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i);
2625254721Semaste                // no need to check if the category is enabled - disabling a disabled category has no effect
2626254721Semaste                if (category_sp)
2627254721Semaste                    DataVisualization::Categories::Disable(category_sp);
2628254721Semaste            }
2629254721Semaste        }
2630254721Semaste        else
2631254721Semaste        {
2632254721Semaste            // the order is not relevant here
2633254721Semaste            for (int i = argc - 1; i >= 0; i--)
2634254721Semaste            {
2635254721Semaste                const char* typeA = command.GetArgumentAtIndex(i);
2636254721Semaste                ConstString typeCS(typeA);
2637254721Semaste
2638254721Semaste                if (!typeCS)
2639254721Semaste                {
2640254721Semaste                    result.AppendError("empty category name not allowed");
2641254721Semaste                    result.SetStatus(eReturnStatusFailed);
2642254721Semaste                    return false;
2643254721Semaste                }
2644254721Semaste                DataVisualization::Categories::Disable(typeCS);
2645254721Semaste            }
2646254721Semaste        }
2647254721Semaste
2648254721Semaste        result.SetStatus(eReturnStatusSuccessFinishResult);
2649254721Semaste        return result.Succeeded();
2650254721Semaste    }
2651254721Semaste
2652254721Semaste};
2653254721Semaste
2654254721Semaste//-------------------------------------------------------------------------
2655254721Semaste// CommandObjectTypeCategoryList
2656254721Semaste//-------------------------------------------------------------------------
2657254721Semaste
2658254721Semasteclass CommandObjectTypeCategoryList : public CommandObjectParsed
2659254721Semaste{
2660254721Semasteprivate:
2661254721Semaste
2662254721Semaste    struct CommandObjectTypeCategoryList_CallbackParam
2663254721Semaste    {
2664254721Semaste        CommandReturnObject* result;
2665254721Semaste        RegularExpression* regex;
2666254721Semaste
2667254721Semaste        CommandObjectTypeCategoryList_CallbackParam(CommandReturnObject* res,
2668254721Semaste                                                    RegularExpression* rex = NULL) :
2669254721Semaste        result(res),
2670254721Semaste        regex(rex)
2671254721Semaste        {
2672254721Semaste        }
2673254721Semaste
2674254721Semaste    };
2675254721Semaste
2676254721Semaste    static bool
2677254721Semaste    PerCategoryCallback(void* param_vp,
2678254721Semaste                        const lldb::TypeCategoryImplSP& cate)
2679254721Semaste    {
2680254721Semaste        CommandObjectTypeCategoryList_CallbackParam* param =
2681254721Semaste            (CommandObjectTypeCategoryList_CallbackParam*)param_vp;
2682254721Semaste        CommandReturnObject* result = param->result;
2683254721Semaste        RegularExpression* regex = param->regex;
2684254721Semaste
2685254721Semaste        const char* cate_name = cate->GetName();
2686254721Semaste
2687254721Semaste        if (regex == NULL || strcmp(cate_name, regex->GetText()) == 0 || regex->Execute(cate_name))
2688254721Semaste            result->GetOutputStream().Printf("Category %s is%s enabled\n",
2689254721Semaste                                       cate_name,
2690254721Semaste                                       (cate->IsEnabled() ? "" : " not"));
2691254721Semaste        return true;
2692254721Semaste    }
2693254721Semastepublic:
2694254721Semaste    CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :
2695254721Semaste        CommandObjectParsed (interpreter,
2696254721Semaste                             "type category list",
2697254721Semaste                             "Provide a list of all existing categories.",
2698254721Semaste                             NULL)
2699254721Semaste    {
2700254721Semaste        CommandArgumentEntry type_arg;
2701254721Semaste        CommandArgumentData type_style_arg;
2702254721Semaste
2703254721Semaste        type_style_arg.arg_type = eArgTypeName;
2704254721Semaste        type_style_arg.arg_repetition = eArgRepeatOptional;
2705254721Semaste
2706254721Semaste        type_arg.push_back (type_style_arg);
2707254721Semaste
2708254721Semaste        m_arguments.push_back (type_arg);
2709254721Semaste    }
2710254721Semaste
2711254721Semaste    ~CommandObjectTypeCategoryList ()
2712254721Semaste    {
2713254721Semaste    }
2714254721Semaste
2715254721Semasteprotected:
2716254721Semaste    bool
2717254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
2718254721Semaste    {
2719254721Semaste        const size_t argc = command.GetArgumentCount();
2720254721Semaste        RegularExpression* regex = NULL;
2721254721Semaste
2722254721Semaste        if (argc == 0)
2723254721Semaste            ;
2724254721Semaste        else if (argc == 1)
2725254721Semaste            regex = new RegularExpression(command.GetArgumentAtIndex(0));
2726254721Semaste        else
2727254721Semaste        {
2728254721Semaste            result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str());
2729254721Semaste            result.SetStatus(eReturnStatusFailed);
2730254721Semaste            return false;
2731254721Semaste        }
2732254721Semaste
2733254721Semaste        CommandObjectTypeCategoryList_CallbackParam param(&result,
2734254721Semaste                                                          regex);
2735254721Semaste
2736254721Semaste        DataVisualization::Categories::LoopThrough(PerCategoryCallback, &param);
2737254721Semaste
2738254721Semaste        if (regex)
2739254721Semaste            delete regex;
2740254721Semaste
2741254721Semaste        result.SetStatus(eReturnStatusSuccessFinishResult);
2742254721Semaste        return result.Succeeded();
2743254721Semaste    }
2744254721Semaste
2745254721Semaste};
2746254721Semaste
2747254721Semaste//-------------------------------------------------------------------------
2748254721Semaste// CommandObjectTypeFilterList
2749254721Semaste//-------------------------------------------------------------------------
2750254721Semaste
2751254721Semastebool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
2752254721Semastebool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
2753254721Semaste
2754254721Semasteclass CommandObjectTypeFilterList;
2755254721Semaste
2756254721Semastestruct CommandObjectTypeFilterList_LoopCallbackParam {
2757254721Semaste    CommandObjectTypeFilterList* self;
2758254721Semaste    CommandReturnObject* result;
2759254721Semaste    RegularExpression* regex;
2760254721Semaste    RegularExpression* cate_regex;
2761254721Semaste    CommandObjectTypeFilterList_LoopCallbackParam(CommandObjectTypeFilterList* S, CommandReturnObject* R,
2762254721Semaste                                                  RegularExpression* X = NULL,
2763254721Semaste                                                  RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
2764254721Semaste};
2765254721Semaste
2766254721Semasteclass CommandObjectTypeFilterList : public CommandObjectParsed
2767254721Semaste{
2768254721Semaste
2769254721Semaste    class CommandOptions : public Options
2770254721Semaste    {
2771254721Semaste    public:
2772254721Semaste
2773254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
2774254721Semaste        Options (interpreter)
2775254721Semaste        {
2776254721Semaste        }
2777254721Semaste
2778254721Semaste        virtual
2779254721Semaste        ~CommandOptions (){}
2780254721Semaste
2781254721Semaste        virtual Error
2782254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
2783254721Semaste        {
2784254721Semaste            Error error;
2785254721Semaste            const int short_option = m_getopt_table[option_idx].val;
2786254721Semaste
2787254721Semaste            switch (short_option)
2788254721Semaste            {
2789254721Semaste                case 'w':
2790254721Semaste                    m_category_regex = std::string(option_arg);
2791254721Semaste                    break;
2792254721Semaste                default:
2793254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2794254721Semaste                    break;
2795254721Semaste            }
2796254721Semaste
2797254721Semaste            return error;
2798254721Semaste        }
2799254721Semaste
2800254721Semaste        void
2801254721Semaste        OptionParsingStarting ()
2802254721Semaste        {
2803254721Semaste            m_category_regex = "";
2804254721Semaste        }
2805254721Semaste
2806254721Semaste        const OptionDefinition*
2807254721Semaste        GetDefinitions ()
2808254721Semaste        {
2809254721Semaste            return g_option_table;
2810254721Semaste        }
2811254721Semaste
2812254721Semaste        // Options table: Required for subclasses of Options.
2813254721Semaste
2814254721Semaste        static OptionDefinition g_option_table[];
2815254721Semaste
2816254721Semaste        // Instance variables to hold the values for command options.
2817254721Semaste
2818254721Semaste        std::string m_category_regex;
2819254721Semaste
2820254721Semaste    };
2821254721Semaste
2822254721Semaste    CommandOptions m_options;
2823254721Semaste
2824254721Semaste    virtual Options *
2825254721Semaste    GetOptions ()
2826254721Semaste    {
2827254721Semaste        return &m_options;
2828254721Semaste    }
2829254721Semaste
2830254721Semastepublic:
2831254721Semaste    CommandObjectTypeFilterList (CommandInterpreter &interpreter) :
2832254721Semaste        CommandObjectParsed (interpreter,
2833254721Semaste                             "type filter list",
2834254721Semaste                             "Show a list of current filters.",
2835254721Semaste                             NULL),
2836254721Semaste        m_options(interpreter)
2837254721Semaste    {
2838254721Semaste        CommandArgumentEntry type_arg;
2839254721Semaste        CommandArgumentData type_style_arg;
2840254721Semaste
2841254721Semaste        type_style_arg.arg_type = eArgTypeName;
2842254721Semaste        type_style_arg.arg_repetition = eArgRepeatOptional;
2843254721Semaste
2844254721Semaste        type_arg.push_back (type_style_arg);
2845254721Semaste
2846254721Semaste        m_arguments.push_back (type_arg);
2847254721Semaste    }
2848254721Semaste
2849254721Semaste    ~CommandObjectTypeFilterList ()
2850254721Semaste    {
2851254721Semaste    }
2852254721Semaste
2853254721Semasteprotected:
2854254721Semaste    bool
2855254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
2856254721Semaste    {
2857254721Semaste        const size_t argc = command.GetArgumentCount();
2858254721Semaste
2859254721Semaste        CommandObjectTypeFilterList_LoopCallbackParam *param;
2860254721Semaste        RegularExpression* cate_regex =
2861254721Semaste        m_options.m_category_regex.empty() ? NULL :
2862254721Semaste        new RegularExpression(m_options.m_category_regex.c_str());
2863254721Semaste
2864254721Semaste        if (argc == 1)
2865254721Semaste        {
2866254721Semaste            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
2867254721Semaste            regex->Compile(command.GetArgumentAtIndex(0));
2868254721Semaste            param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex);
2869254721Semaste        }
2870254721Semaste        else
2871254721Semaste            param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex);
2872254721Semaste
2873254721Semaste        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
2874269024Semaste        delete param;
2875254721Semaste
2876254721Semaste        if (cate_regex)
2877254721Semaste            delete cate_regex;
2878254721Semaste
2879254721Semaste        result.SetStatus(eReturnStatusSuccessFinishResult);
2880254721Semaste        return result.Succeeded();
2881254721Semaste    }
2882254721Semaste
2883254721Semasteprivate:
2884254721Semaste
2885254721Semaste    static bool
2886254721Semaste    PerCategoryCallback(void* param_vp,
2887254721Semaste                        const lldb::TypeCategoryImplSP& cate)
2888254721Semaste    {
2889254721Semaste
2890254721Semaste        const char* cate_name = cate->GetName();
2891254721Semaste
2892254721Semaste        CommandObjectTypeFilterList_LoopCallbackParam* param =
2893254721Semaste        (CommandObjectTypeFilterList_LoopCallbackParam*)param_vp;
2894254721Semaste        CommandReturnObject* result = param->result;
2895254721Semaste
2896254721Semaste        // if the category is disabled or empty and there is no regex, just skip it
2897254721Semaste        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter) == 0) && param->cate_regex == NULL)
2898254721Semaste            return true;
2899254721Semaste
2900254721Semaste        // if we have a regex and this category does not match it, just skip it
2901254721Semaste        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
2902254721Semaste            return true;
2903254721Semaste
2904254721Semaste        result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n",
2905254721Semaste                                         cate_name,
2906254721Semaste                                         (cate->IsEnabled() ? "enabled" : "disabled"));
2907254721Semaste
2908269024Semaste        cate->GetTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp);
2909254721Semaste
2910269024Semaste        if (cate->GetRegexTypeFiltersContainer()->GetCount() > 0)
2911254721Semaste        {
2912254721Semaste            result->GetOutputStream().Printf("Regex-based filters (slower):\n");
2913269024Semaste            cate->GetRegexTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp);
2914254721Semaste        }
2915254721Semaste
2916254721Semaste        return true;
2917254721Semaste    }
2918254721Semaste
2919254721Semaste    bool
2920254721Semaste    LoopCallback (const char* type,
2921254721Semaste                  const SyntheticChildren::SharedPointer& entry,
2922254721Semaste                  RegularExpression* regex,
2923254721Semaste                  CommandReturnObject *result)
2924254721Semaste    {
2925254721Semaste        if (regex == NULL || regex->Execute(type))
2926254721Semaste            result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
2927254721Semaste        return true;
2928254721Semaste    }
2929254721Semaste
2930254721Semaste    friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
2931254721Semaste    friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
2932254721Semaste};
2933254721Semaste
2934254721Semastebool
2935254721SemasteCommandObjectTypeFilterList_LoopCallback (void* pt2self,
2936254721Semaste                                         ConstString type,
2937254721Semaste                                         const SyntheticChildren::SharedPointer& entry)
2938254721Semaste{
2939254721Semaste    CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self;
2940254721Semaste    return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
2941254721Semaste}
2942254721Semaste
2943254721Semastebool
2944254721SemasteCommandObjectTypeFilterRXList_LoopCallback (void* pt2self,
2945254721Semaste                                           lldb::RegularExpressionSP regex,
2946254721Semaste                                           const SyntheticChildren::SharedPointer& entry)
2947254721Semaste{
2948254721Semaste    CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self;
2949254721Semaste    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
2950254721Semaste}
2951254721Semaste
2952254721Semaste
2953254721SemasteOptionDefinition
2954254721SemasteCommandObjectTypeFilterList::CommandOptions::g_option_table[] =
2955254721Semaste{
2956263363Semaste    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
2957254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2958254721Semaste};
2959254721Semaste
2960254721Semaste#ifndef LLDB_DISABLE_PYTHON
2961254721Semaste
2962254721Semaste//-------------------------------------------------------------------------
2963254721Semaste// CommandObjectTypeSynthList
2964254721Semaste//-------------------------------------------------------------------------
2965254721Semaste
2966254721Semastebool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
2967254721Semastebool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
2968254721Semaste
2969254721Semasteclass CommandObjectTypeSynthList;
2970254721Semaste
2971254721Semastestruct CommandObjectTypeSynthList_LoopCallbackParam {
2972254721Semaste    CommandObjectTypeSynthList* self;
2973254721Semaste    CommandReturnObject* result;
2974254721Semaste    RegularExpression* regex;
2975254721Semaste    RegularExpression* cate_regex;
2976254721Semaste    CommandObjectTypeSynthList_LoopCallbackParam(CommandObjectTypeSynthList* S, CommandReturnObject* R,
2977254721Semaste                                                 RegularExpression* X = NULL,
2978254721Semaste                                                 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
2979254721Semaste};
2980254721Semaste
2981254721Semasteclass CommandObjectTypeSynthList : public CommandObjectParsed
2982254721Semaste{
2983254721Semaste
2984254721Semaste    class CommandOptions : public Options
2985254721Semaste    {
2986254721Semaste    public:
2987254721Semaste
2988254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
2989254721Semaste        Options (interpreter)
2990254721Semaste        {
2991254721Semaste        }
2992254721Semaste
2993254721Semaste        virtual
2994254721Semaste        ~CommandOptions (){}
2995254721Semaste
2996254721Semaste        virtual Error
2997254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
2998254721Semaste        {
2999254721Semaste            Error error;
3000254721Semaste            const int short_option = m_getopt_table[option_idx].val;
3001254721Semaste
3002254721Semaste            switch (short_option)
3003254721Semaste            {
3004254721Semaste                case 'w':
3005254721Semaste                    m_category_regex = std::string(option_arg);
3006254721Semaste                    break;
3007254721Semaste                default:
3008254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3009254721Semaste                    break;
3010254721Semaste            }
3011254721Semaste
3012254721Semaste            return error;
3013254721Semaste        }
3014254721Semaste
3015254721Semaste        void
3016254721Semaste        OptionParsingStarting ()
3017254721Semaste        {
3018254721Semaste            m_category_regex = "";
3019254721Semaste        }
3020254721Semaste
3021254721Semaste        const OptionDefinition*
3022254721Semaste        GetDefinitions ()
3023254721Semaste        {
3024254721Semaste            return g_option_table;
3025254721Semaste        }
3026254721Semaste
3027254721Semaste        // Options table: Required for subclasses of Options.
3028254721Semaste
3029254721Semaste        static OptionDefinition g_option_table[];
3030254721Semaste
3031254721Semaste        // Instance variables to hold the values for command options.
3032254721Semaste
3033254721Semaste        std::string m_category_regex;
3034254721Semaste
3035254721Semaste    };
3036254721Semaste
3037254721Semaste    CommandOptions m_options;
3038254721Semaste
3039254721Semaste    virtual Options *
3040254721Semaste    GetOptions ()
3041254721Semaste    {
3042254721Semaste        return &m_options;
3043254721Semaste    }
3044254721Semaste
3045254721Semastepublic:
3046254721Semaste    CommandObjectTypeSynthList (CommandInterpreter &interpreter) :
3047254721Semaste        CommandObjectParsed (interpreter,
3048254721Semaste                             "type synthetic list",
3049254721Semaste                             "Show a list of current synthetic providers.",
3050254721Semaste                             NULL),
3051254721Semaste        m_options(interpreter)
3052254721Semaste    {
3053254721Semaste        CommandArgumentEntry type_arg;
3054254721Semaste        CommandArgumentData type_style_arg;
3055254721Semaste
3056254721Semaste        type_style_arg.arg_type = eArgTypeName;
3057254721Semaste        type_style_arg.arg_repetition = eArgRepeatOptional;
3058254721Semaste
3059254721Semaste        type_arg.push_back (type_style_arg);
3060254721Semaste
3061254721Semaste        m_arguments.push_back (type_arg);
3062254721Semaste    }
3063254721Semaste
3064254721Semaste    ~CommandObjectTypeSynthList ()
3065254721Semaste    {
3066254721Semaste    }
3067254721Semaste
3068254721Semasteprotected:
3069254721Semaste    bool
3070254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
3071254721Semaste    {
3072254721Semaste        const size_t argc = command.GetArgumentCount();
3073254721Semaste
3074254721Semaste        CommandObjectTypeSynthList_LoopCallbackParam *param;
3075254721Semaste        RegularExpression* cate_regex =
3076254721Semaste        m_options.m_category_regex.empty() ? NULL :
3077254721Semaste        new RegularExpression(m_options.m_category_regex.c_str());
3078254721Semaste
3079254721Semaste        if (argc == 1)
3080254721Semaste        {
3081254721Semaste            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
3082254721Semaste            regex->Compile(command.GetArgumentAtIndex(0));
3083254721Semaste            param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,regex,cate_regex);
3084254721Semaste        }
3085254721Semaste        else
3086254721Semaste            param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex);
3087254721Semaste
3088254721Semaste        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
3089269024Semaste        delete param;
3090269024Semaste
3091254721Semaste        if (cate_regex)
3092254721Semaste            delete cate_regex;
3093254721Semaste
3094254721Semaste        result.SetStatus(eReturnStatusSuccessFinishResult);
3095254721Semaste        return result.Succeeded();
3096254721Semaste    }
3097254721Semaste
3098254721Semasteprivate:
3099254721Semaste
3100254721Semaste    static bool
3101254721Semaste    PerCategoryCallback(void* param_vp,
3102254721Semaste                        const lldb::TypeCategoryImplSP& cate)
3103254721Semaste    {
3104254721Semaste
3105254721Semaste        CommandObjectTypeSynthList_LoopCallbackParam* param =
3106254721Semaste        (CommandObjectTypeSynthList_LoopCallbackParam*)param_vp;
3107254721Semaste        CommandReturnObject* result = param->result;
3108254721Semaste
3109254721Semaste        const char* cate_name = cate->GetName();
3110254721Semaste
3111254721Semaste        // if the category is disabled or empty and there is no regex, just skip it
3112254721Semaste        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth) == 0) && param->cate_regex == NULL)
3113254721Semaste            return true;
3114254721Semaste
3115254721Semaste        // if we have a regex and this category does not match it, just skip it
3116254721Semaste        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
3117254721Semaste            return true;
3118254721Semaste
3119254721Semaste        result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n",
3120254721Semaste                                         cate_name,
3121254721Semaste                                         (cate->IsEnabled() ? "enabled" : "disabled"));
3122254721Semaste
3123269024Semaste        cate->GetTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp);
3124254721Semaste
3125269024Semaste        if (cate->GetRegexTypeSyntheticsContainer()->GetCount() > 0)
3126254721Semaste        {
3127254721Semaste            result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n");
3128269024Semaste            cate->GetRegexTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp);
3129254721Semaste        }
3130254721Semaste
3131254721Semaste        return true;
3132254721Semaste    }
3133254721Semaste
3134254721Semaste    bool
3135254721Semaste    LoopCallback (const char* type,
3136254721Semaste                  const SyntheticChildren::SharedPointer& entry,
3137254721Semaste                  RegularExpression* regex,
3138254721Semaste                  CommandReturnObject *result)
3139254721Semaste    {
3140254721Semaste        if (regex == NULL || regex->Execute(type))
3141254721Semaste            result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
3142254721Semaste        return true;
3143254721Semaste    }
3144254721Semaste
3145254721Semaste    friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
3146254721Semaste    friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
3147254721Semaste};
3148254721Semaste
3149254721Semastebool
3150254721SemasteCommandObjectTypeSynthList_LoopCallback (void* pt2self,
3151254721Semaste                                         ConstString type,
3152254721Semaste                                         const SyntheticChildren::SharedPointer& entry)
3153254721Semaste{
3154254721Semaste    CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
3155254721Semaste    return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
3156254721Semaste}
3157254721Semaste
3158254721Semastebool
3159254721SemasteCommandObjectTypeSynthRXList_LoopCallback (void* pt2self,
3160254721Semaste                                         lldb::RegularExpressionSP regex,
3161254721Semaste                                         const SyntheticChildren::SharedPointer& entry)
3162254721Semaste{
3163254721Semaste    CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
3164254721Semaste    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
3165254721Semaste}
3166254721Semaste
3167254721Semaste
3168254721SemasteOptionDefinition
3169254721SemasteCommandObjectTypeSynthList::CommandOptions::g_option_table[] =
3170254721Semaste{
3171263363Semaste    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
3172254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3173254721Semaste};
3174254721Semaste
3175254721Semaste#endif // #ifndef LLDB_DISABLE_PYTHON
3176254721Semaste//-------------------------------------------------------------------------
3177254721Semaste// CommandObjectTypeFilterDelete
3178254721Semaste//-------------------------------------------------------------------------
3179254721Semaste
3180254721Semasteclass CommandObjectTypeFilterDelete : public CommandObjectParsed
3181254721Semaste{
3182254721Semasteprivate:
3183254721Semaste    class CommandOptions : public Options
3184254721Semaste    {
3185254721Semaste    public:
3186254721Semaste
3187254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
3188254721Semaste        Options (interpreter)
3189254721Semaste        {
3190254721Semaste        }
3191254721Semaste
3192254721Semaste        virtual
3193254721Semaste        ~CommandOptions (){}
3194254721Semaste
3195254721Semaste        virtual Error
3196254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
3197254721Semaste        {
3198254721Semaste            Error error;
3199254721Semaste            const int short_option = m_getopt_table[option_idx].val;
3200254721Semaste
3201254721Semaste            switch (short_option)
3202254721Semaste            {
3203254721Semaste                case 'a':
3204254721Semaste                    m_delete_all = true;
3205254721Semaste                    break;
3206254721Semaste                case 'w':
3207254721Semaste                    m_category = std::string(option_arg);
3208254721Semaste                    break;
3209254721Semaste                default:
3210254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3211254721Semaste                    break;
3212254721Semaste            }
3213254721Semaste
3214254721Semaste            return error;
3215254721Semaste        }
3216254721Semaste
3217254721Semaste        void
3218254721Semaste        OptionParsingStarting ()
3219254721Semaste        {
3220254721Semaste            m_delete_all = false;
3221254721Semaste            m_category = "default";
3222254721Semaste        }
3223254721Semaste
3224254721Semaste        const OptionDefinition*
3225254721Semaste        GetDefinitions ()
3226254721Semaste        {
3227254721Semaste            return g_option_table;
3228254721Semaste        }
3229254721Semaste
3230254721Semaste        // Options table: Required for subclasses of Options.
3231254721Semaste
3232254721Semaste        static OptionDefinition g_option_table[];
3233254721Semaste
3234254721Semaste        // Instance variables to hold the values for command options.
3235254721Semaste
3236254721Semaste        bool m_delete_all;
3237254721Semaste        std::string m_category;
3238254721Semaste
3239254721Semaste    };
3240254721Semaste
3241254721Semaste    CommandOptions m_options;
3242254721Semaste
3243254721Semaste    virtual Options *
3244254721Semaste    GetOptions ()
3245254721Semaste    {
3246254721Semaste        return &m_options;
3247254721Semaste    }
3248254721Semaste
3249254721Semaste    static bool
3250254721Semaste    PerCategoryCallback(void* param,
3251254721Semaste                        const lldb::TypeCategoryImplSP& cate)
3252254721Semaste    {
3253254721Semaste        ConstString *name = (ConstString*)param;
3254254721Semaste        return cate->Delete(*name, eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter);
3255254721Semaste    }
3256254721Semaste
3257254721Semastepublic:
3258254721Semaste    CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) :
3259254721Semaste        CommandObjectParsed (interpreter,
3260254721Semaste                             "type filter delete",
3261254721Semaste                             "Delete an existing filter for a type.",
3262254721Semaste                             NULL),
3263254721Semaste        m_options(interpreter)
3264254721Semaste    {
3265254721Semaste        CommandArgumentEntry type_arg;
3266254721Semaste        CommandArgumentData type_style_arg;
3267254721Semaste
3268254721Semaste        type_style_arg.arg_type = eArgTypeName;
3269254721Semaste        type_style_arg.arg_repetition = eArgRepeatPlain;
3270254721Semaste
3271254721Semaste        type_arg.push_back (type_style_arg);
3272254721Semaste
3273254721Semaste        m_arguments.push_back (type_arg);
3274254721Semaste
3275254721Semaste    }
3276254721Semaste
3277254721Semaste    ~CommandObjectTypeFilterDelete ()
3278254721Semaste    {
3279254721Semaste    }
3280254721Semaste
3281254721Semasteprotected:
3282254721Semaste    bool
3283254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
3284254721Semaste    {
3285254721Semaste        const size_t argc = command.GetArgumentCount();
3286254721Semaste
3287254721Semaste        if (argc != 1)
3288254721Semaste        {
3289254721Semaste            result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
3290254721Semaste            result.SetStatus(eReturnStatusFailed);
3291254721Semaste            return false;
3292254721Semaste        }
3293254721Semaste
3294254721Semaste        const char* typeA = command.GetArgumentAtIndex(0);
3295254721Semaste        ConstString typeCS(typeA);
3296254721Semaste
3297254721Semaste        if (!typeCS)
3298254721Semaste        {
3299254721Semaste            result.AppendError("empty typenames not allowed");
3300254721Semaste            result.SetStatus(eReturnStatusFailed);
3301254721Semaste            return false;
3302254721Semaste        }
3303254721Semaste
3304254721Semaste        if (m_options.m_delete_all)
3305254721Semaste        {
3306254721Semaste            DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS);
3307254721Semaste            result.SetStatus(eReturnStatusSuccessFinishNoResult);
3308254721Semaste            return result.Succeeded();
3309254721Semaste        }
3310254721Semaste
3311254721Semaste        lldb::TypeCategoryImplSP category;
3312254721Semaste        DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
3313254721Semaste
3314269024Semaste        bool delete_category = category->GetTypeFiltersContainer()->Delete(typeCS);
3315269024Semaste        delete_category = category->GetRegexTypeFiltersContainer()->Delete(typeCS) || delete_category;
3316254721Semaste
3317254721Semaste        if (delete_category)
3318254721Semaste        {
3319254721Semaste            result.SetStatus(eReturnStatusSuccessFinishNoResult);
3320254721Semaste            return result.Succeeded();
3321254721Semaste        }
3322254721Semaste        else
3323254721Semaste        {
3324254721Semaste            result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA);
3325254721Semaste            result.SetStatus(eReturnStatusFailed);
3326254721Semaste            return false;
3327254721Semaste        }
3328254721Semaste
3329254721Semaste    }
3330254721Semaste};
3331254721Semaste
3332254721SemasteOptionDefinition
3333254721SemasteCommandObjectTypeFilterDelete::CommandOptions::g_option_table[] =
3334254721Semaste{
3335263363Semaste    { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,  "Delete from every category."},
3336263363Semaste    { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,  "Delete from given category."},
3337254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3338254721Semaste};
3339254721Semaste
3340254721Semaste#ifndef LLDB_DISABLE_PYTHON
3341254721Semaste
3342254721Semaste//-------------------------------------------------------------------------
3343254721Semaste// CommandObjectTypeSynthDelete
3344254721Semaste//-------------------------------------------------------------------------
3345254721Semaste
3346254721Semasteclass CommandObjectTypeSynthDelete : public CommandObjectParsed
3347254721Semaste{
3348254721Semasteprivate:
3349254721Semaste    class CommandOptions : public Options
3350254721Semaste    {
3351254721Semaste    public:
3352254721Semaste
3353254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
3354254721Semaste        Options (interpreter)
3355254721Semaste        {
3356254721Semaste        }
3357254721Semaste
3358254721Semaste        virtual
3359254721Semaste        ~CommandOptions (){}
3360254721Semaste
3361254721Semaste        virtual Error
3362254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
3363254721Semaste        {
3364254721Semaste            Error error;
3365254721Semaste            const int short_option = m_getopt_table[option_idx].val;
3366254721Semaste
3367254721Semaste            switch (short_option)
3368254721Semaste            {
3369254721Semaste                case 'a':
3370254721Semaste                    m_delete_all = true;
3371254721Semaste                    break;
3372254721Semaste                case 'w':
3373254721Semaste                    m_category = std::string(option_arg);
3374254721Semaste                    break;
3375254721Semaste                default:
3376254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3377254721Semaste                    break;
3378254721Semaste            }
3379254721Semaste
3380254721Semaste            return error;
3381254721Semaste        }
3382254721Semaste
3383254721Semaste        void
3384254721Semaste        OptionParsingStarting ()
3385254721Semaste        {
3386254721Semaste            m_delete_all = false;
3387254721Semaste            m_category = "default";
3388254721Semaste        }
3389254721Semaste
3390254721Semaste        const OptionDefinition*
3391254721Semaste        GetDefinitions ()
3392254721Semaste        {
3393254721Semaste            return g_option_table;
3394254721Semaste        }
3395254721Semaste
3396254721Semaste        // Options table: Required for subclasses of Options.
3397254721Semaste
3398254721Semaste        static OptionDefinition g_option_table[];
3399254721Semaste
3400254721Semaste        // Instance variables to hold the values for command options.
3401254721Semaste
3402254721Semaste        bool m_delete_all;
3403254721Semaste        std::string m_category;
3404254721Semaste
3405254721Semaste    };
3406254721Semaste
3407254721Semaste    CommandOptions m_options;
3408254721Semaste
3409254721Semaste    virtual Options *
3410254721Semaste    GetOptions ()
3411254721Semaste    {
3412254721Semaste        return &m_options;
3413254721Semaste    }
3414254721Semaste
3415254721Semaste    static bool
3416254721Semaste    PerCategoryCallback(void* param,
3417254721Semaste                        const lldb::TypeCategoryImplSP& cate)
3418254721Semaste    {
3419254721Semaste        ConstString* name = (ConstString*)param;
3420254721Semaste        return cate->Delete(*name, eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth);
3421254721Semaste    }
3422254721Semaste
3423254721Semastepublic:
3424254721Semaste    CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) :
3425254721Semaste        CommandObjectParsed (interpreter,
3426254721Semaste                             "type synthetic delete",
3427254721Semaste                             "Delete an existing synthetic provider for a type.",
3428254721Semaste                             NULL),
3429254721Semaste        m_options(interpreter)
3430254721Semaste    {
3431254721Semaste        CommandArgumentEntry type_arg;
3432254721Semaste        CommandArgumentData type_style_arg;
3433254721Semaste
3434254721Semaste        type_style_arg.arg_type = eArgTypeName;
3435254721Semaste        type_style_arg.arg_repetition = eArgRepeatPlain;
3436254721Semaste
3437254721Semaste        type_arg.push_back (type_style_arg);
3438254721Semaste
3439254721Semaste        m_arguments.push_back (type_arg);
3440254721Semaste
3441254721Semaste    }
3442254721Semaste
3443254721Semaste    ~CommandObjectTypeSynthDelete ()
3444254721Semaste    {
3445254721Semaste    }
3446254721Semaste
3447254721Semasteprotected:
3448254721Semaste    bool
3449254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
3450254721Semaste    {
3451254721Semaste        const size_t argc = command.GetArgumentCount();
3452254721Semaste
3453254721Semaste        if (argc != 1)
3454254721Semaste        {
3455254721Semaste            result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
3456254721Semaste            result.SetStatus(eReturnStatusFailed);
3457254721Semaste            return false;
3458254721Semaste        }
3459254721Semaste
3460254721Semaste        const char* typeA = command.GetArgumentAtIndex(0);
3461254721Semaste        ConstString typeCS(typeA);
3462254721Semaste
3463254721Semaste        if (!typeCS)
3464254721Semaste        {
3465254721Semaste            result.AppendError("empty typenames not allowed");
3466254721Semaste            result.SetStatus(eReturnStatusFailed);
3467254721Semaste            return false;
3468254721Semaste        }
3469254721Semaste
3470254721Semaste        if (m_options.m_delete_all)
3471254721Semaste        {
3472254721Semaste            DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS);
3473254721Semaste            result.SetStatus(eReturnStatusSuccessFinishNoResult);
3474254721Semaste            return result.Succeeded();
3475254721Semaste        }
3476254721Semaste
3477254721Semaste        lldb::TypeCategoryImplSP category;
3478254721Semaste        DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
3479254721Semaste
3480269024Semaste        bool delete_category = category->GetTypeSyntheticsContainer()->Delete(typeCS);
3481269024Semaste        delete_category = category->GetRegexTypeSyntheticsContainer()->Delete(typeCS) || delete_category;
3482254721Semaste
3483254721Semaste        if (delete_category)
3484254721Semaste        {
3485254721Semaste            result.SetStatus(eReturnStatusSuccessFinishNoResult);
3486254721Semaste            return result.Succeeded();
3487254721Semaste        }
3488254721Semaste        else
3489254721Semaste        {
3490254721Semaste            result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA);
3491254721Semaste            result.SetStatus(eReturnStatusFailed);
3492254721Semaste            return false;
3493254721Semaste        }
3494254721Semaste
3495254721Semaste    }
3496254721Semaste};
3497254721Semaste
3498254721SemasteOptionDefinition
3499254721SemasteCommandObjectTypeSynthDelete::CommandOptions::g_option_table[] =
3500254721Semaste{
3501263363Semaste    { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,  "Delete from every category."},
3502263363Semaste    { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,  "Delete from given category."},
3503254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3504254721Semaste};
3505254721Semaste
3506254721Semaste#endif // #ifndef LLDB_DISABLE_PYTHON
3507254721Semaste
3508254721Semaste//-------------------------------------------------------------------------
3509254721Semaste// CommandObjectTypeFilterClear
3510254721Semaste//-------------------------------------------------------------------------
3511254721Semaste
3512254721Semasteclass CommandObjectTypeFilterClear : public CommandObjectParsed
3513254721Semaste{
3514254721Semasteprivate:
3515254721Semaste
3516254721Semaste    class CommandOptions : public Options
3517254721Semaste    {
3518254721Semaste    public:
3519254721Semaste
3520254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
3521254721Semaste        Options (interpreter)
3522254721Semaste        {
3523254721Semaste        }
3524254721Semaste
3525254721Semaste        virtual
3526254721Semaste        ~CommandOptions (){}
3527254721Semaste
3528254721Semaste        virtual Error
3529254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
3530254721Semaste        {
3531254721Semaste            Error error;
3532254721Semaste            const int short_option = m_getopt_table[option_idx].val;
3533254721Semaste
3534254721Semaste            switch (short_option)
3535254721Semaste            {
3536254721Semaste                case 'a':
3537254721Semaste                    m_delete_all = true;
3538254721Semaste                    break;
3539254721Semaste                default:
3540254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3541254721Semaste                    break;
3542254721Semaste            }
3543254721Semaste
3544254721Semaste            return error;
3545254721Semaste        }
3546254721Semaste
3547254721Semaste        void
3548254721Semaste        OptionParsingStarting ()
3549254721Semaste        {
3550254721Semaste            m_delete_all = false;
3551254721Semaste        }
3552254721Semaste
3553254721Semaste        const OptionDefinition*
3554254721Semaste        GetDefinitions ()
3555254721Semaste        {
3556254721Semaste            return g_option_table;
3557254721Semaste        }
3558254721Semaste
3559254721Semaste        // Options table: Required for subclasses of Options.
3560254721Semaste
3561254721Semaste        static OptionDefinition g_option_table[];
3562254721Semaste
3563254721Semaste        // Instance variables to hold the values for command options.
3564254721Semaste
3565254721Semaste        bool m_delete_all;
3566254721Semaste        bool m_delete_named;
3567254721Semaste    };
3568254721Semaste
3569254721Semaste    CommandOptions m_options;
3570254721Semaste
3571254721Semaste    virtual Options *
3572254721Semaste    GetOptions ()
3573254721Semaste    {
3574254721Semaste        return &m_options;
3575254721Semaste    }
3576254721Semaste
3577254721Semaste    static bool
3578254721Semaste    PerCategoryCallback(void* param,
3579254721Semaste                        const lldb::TypeCategoryImplSP& cate)
3580254721Semaste    {
3581254721Semaste        cate->Clear(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter);
3582254721Semaste        return true;
3583254721Semaste
3584254721Semaste    }
3585254721Semaste
3586254721Semastepublic:
3587254721Semaste    CommandObjectTypeFilterClear (CommandInterpreter &interpreter) :
3588254721Semaste        CommandObjectParsed (interpreter,
3589254721Semaste                             "type filter clear",
3590254721Semaste                             "Delete all existing filters.",
3591254721Semaste                             NULL),
3592254721Semaste        m_options(interpreter)
3593254721Semaste    {
3594254721Semaste    }
3595254721Semaste
3596254721Semaste    ~CommandObjectTypeFilterClear ()
3597254721Semaste    {
3598254721Semaste    }
3599254721Semaste
3600254721Semasteprotected:
3601254721Semaste    bool
3602254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
3603254721Semaste    {
3604254721Semaste
3605254721Semaste        if (m_options.m_delete_all)
3606254721Semaste            DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL);
3607254721Semaste
3608254721Semaste        else
3609254721Semaste        {
3610254721Semaste            lldb::TypeCategoryImplSP category;
3611254721Semaste            if (command.GetArgumentCount() > 0)
3612254721Semaste            {
3613254721Semaste                const char* cat_name = command.GetArgumentAtIndex(0);
3614254721Semaste                ConstString cat_nameCS(cat_name);
3615254721Semaste                DataVisualization::Categories::GetCategory(cat_nameCS, category);
3616254721Semaste            }
3617254721Semaste            else
3618254721Semaste                DataVisualization::Categories::GetCategory(ConstString(NULL), category);
3619269024Semaste            category->GetTypeFiltersContainer()->Clear();
3620269024Semaste            category->GetRegexTypeFiltersContainer()->Clear();
3621254721Semaste        }
3622254721Semaste
3623254721Semaste        result.SetStatus(eReturnStatusSuccessFinishResult);
3624254721Semaste        return result.Succeeded();
3625254721Semaste    }
3626254721Semaste
3627254721Semaste};
3628254721Semaste
3629254721SemasteOptionDefinition
3630254721SemasteCommandObjectTypeFilterClear::CommandOptions::g_option_table[] =
3631254721Semaste{
3632263363Semaste    { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,  "Clear every category."},
3633254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3634254721Semaste};
3635254721Semaste
3636254721Semaste#ifndef LLDB_DISABLE_PYTHON
3637254721Semaste//-------------------------------------------------------------------------
3638254721Semaste// CommandObjectTypeSynthClear
3639254721Semaste//-------------------------------------------------------------------------
3640254721Semaste
3641254721Semasteclass CommandObjectTypeSynthClear : public CommandObjectParsed
3642254721Semaste{
3643254721Semasteprivate:
3644254721Semaste
3645254721Semaste    class CommandOptions : public Options
3646254721Semaste    {
3647254721Semaste    public:
3648254721Semaste
3649254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
3650254721Semaste        Options (interpreter)
3651254721Semaste        {
3652254721Semaste        }
3653254721Semaste
3654254721Semaste        virtual
3655254721Semaste        ~CommandOptions (){}
3656254721Semaste
3657254721Semaste        virtual Error
3658254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
3659254721Semaste        {
3660254721Semaste            Error error;
3661254721Semaste            const int short_option = m_getopt_table[option_idx].val;
3662254721Semaste
3663254721Semaste            switch (short_option)
3664254721Semaste            {
3665254721Semaste                case 'a':
3666254721Semaste                    m_delete_all = true;
3667254721Semaste                    break;
3668254721Semaste                default:
3669254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3670254721Semaste                    break;
3671254721Semaste            }
3672254721Semaste
3673254721Semaste            return error;
3674254721Semaste        }
3675254721Semaste
3676254721Semaste        void
3677254721Semaste        OptionParsingStarting ()
3678254721Semaste        {
3679254721Semaste            m_delete_all = false;
3680254721Semaste        }
3681254721Semaste
3682254721Semaste        const OptionDefinition*
3683254721Semaste        GetDefinitions ()
3684254721Semaste        {
3685254721Semaste            return g_option_table;
3686254721Semaste        }
3687254721Semaste
3688254721Semaste        // Options table: Required for subclasses of Options.
3689254721Semaste
3690254721Semaste        static OptionDefinition g_option_table[];
3691254721Semaste
3692254721Semaste        // Instance variables to hold the values for command options.
3693254721Semaste
3694254721Semaste        bool m_delete_all;
3695254721Semaste        bool m_delete_named;
3696254721Semaste    };
3697254721Semaste
3698254721Semaste    CommandOptions m_options;
3699254721Semaste
3700254721Semaste    virtual Options *
3701254721Semaste    GetOptions ()
3702254721Semaste    {
3703254721Semaste        return &m_options;
3704254721Semaste    }
3705254721Semaste
3706254721Semaste    static bool
3707254721Semaste    PerCategoryCallback(void* param,
3708254721Semaste                        const lldb::TypeCategoryImplSP& cate)
3709254721Semaste    {
3710254721Semaste        cate->Clear(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth);
3711254721Semaste        return true;
3712254721Semaste
3713254721Semaste    }
3714254721Semaste
3715254721Semastepublic:
3716254721Semaste    CommandObjectTypeSynthClear (CommandInterpreter &interpreter) :
3717254721Semaste        CommandObjectParsed (interpreter,
3718254721Semaste                             "type synthetic clear",
3719254721Semaste                             "Delete all existing synthetic providers.",
3720254721Semaste                             NULL),
3721254721Semaste        m_options(interpreter)
3722254721Semaste    {
3723254721Semaste    }
3724254721Semaste
3725254721Semaste    ~CommandObjectTypeSynthClear ()
3726254721Semaste    {
3727254721Semaste    }
3728254721Semaste
3729254721Semasteprotected:
3730254721Semaste    bool
3731254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
3732254721Semaste    {
3733254721Semaste
3734254721Semaste        if (m_options.m_delete_all)
3735254721Semaste            DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL);
3736254721Semaste
3737254721Semaste        else
3738254721Semaste        {
3739254721Semaste            lldb::TypeCategoryImplSP category;
3740254721Semaste            if (command.GetArgumentCount() > 0)
3741254721Semaste            {
3742254721Semaste                const char* cat_name = command.GetArgumentAtIndex(0);
3743254721Semaste                ConstString cat_nameCS(cat_name);
3744254721Semaste                DataVisualization::Categories::GetCategory(cat_nameCS, category);
3745254721Semaste            }
3746254721Semaste            else
3747254721Semaste                DataVisualization::Categories::GetCategory(ConstString(NULL), category);
3748269024Semaste            category->GetTypeSyntheticsContainer()->Clear();
3749269024Semaste            category->GetRegexTypeSyntheticsContainer()->Clear();
3750254721Semaste        }
3751254721Semaste
3752254721Semaste        result.SetStatus(eReturnStatusSuccessFinishResult);
3753254721Semaste        return result.Succeeded();
3754254721Semaste    }
3755254721Semaste
3756254721Semaste};
3757254721Semaste
3758254721SemasteOptionDefinition
3759254721SemasteCommandObjectTypeSynthClear::CommandOptions::g_option_table[] =
3760254721Semaste{
3761263363Semaste    { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,  "Clear every category."},
3762254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3763254721Semaste};
3764254721Semaste
3765254721Semaste
3766254721Semastebool
3767254721SemasteCommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result)
3768254721Semaste{
3769254721Semaste    SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers,
3770254721Semaste                                                     m_options.m_skip_references,
3771254721Semaste                                                     m_options.m_cascade,
3772254721Semaste                                                     m_options.m_regex,
3773254721Semaste                                                     m_options.m_category);
3774254721Semaste
3775254721Semaste    const size_t argc = command.GetArgumentCount();
3776254721Semaste
3777254721Semaste    for (size_t i = 0; i < argc; i++)
3778254721Semaste    {
3779254721Semaste        const char* typeA = command.GetArgumentAtIndex(i);
3780254721Semaste        if (typeA && *typeA)
3781254721Semaste            options->m_target_types << typeA;
3782254721Semaste        else
3783254721Semaste        {
3784254721Semaste            result.AppendError("empty typenames not allowed");
3785254721Semaste            result.SetStatus(eReturnStatusFailed);
3786254721Semaste            return false;
3787254721Semaste        }
3788254721Semaste    }
3789254721Semaste
3790269024Semaste    m_interpreter.GetPythonCommandsFromIOHandler ("    ",   // Prompt
3791269024Semaste                                                  *this,    // IOHandlerDelegate
3792269024Semaste                                                  true,     // Run IOHandler in async mode
3793269024Semaste                                                  options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
3794269024Semaste    result.SetStatus(eReturnStatusSuccessFinishNoResult);
3795254721Semaste    return result.Succeeded();
3796254721Semaste}
3797254721Semaste
3798254721Semastebool
3799254721SemasteCommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result)
3800254721Semaste{
3801254721Semaste    const size_t argc = command.GetArgumentCount();
3802254721Semaste
3803254721Semaste    if (argc < 1)
3804254721Semaste    {
3805254721Semaste        result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
3806254721Semaste        result.SetStatus(eReturnStatusFailed);
3807254721Semaste        return false;
3808254721Semaste    }
3809254721Semaste
3810254721Semaste    if (m_options.m_class_name.empty() && !m_options.m_input_python)
3811254721Semaste    {
3812254721Semaste        result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str());
3813254721Semaste        result.SetStatus(eReturnStatusFailed);
3814254721Semaste        return false;
3815254721Semaste    }
3816254721Semaste
3817254721Semaste    SyntheticChildrenSP entry;
3818254721Semaste
3819254721Semaste    ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(SyntheticChildren::Flags().
3820254721Semaste                                                                    SetCascades(m_options.m_cascade).
3821254721Semaste                                                                    SetSkipPointers(m_options.m_skip_pointers).
3822254721Semaste                                                                    SetSkipReferences(m_options.m_skip_references),
3823254721Semaste                                                                    m_options.m_class_name.c_str());
3824254721Semaste
3825254721Semaste    entry.reset(impl);
3826254721Semaste
3827254721Semaste    ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
3828254721Semaste
3829254721Semaste    if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false)
3830254721Semaste        result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider");
3831254721Semaste
3832254721Semaste    // now I have a valid provider, let's add it to every type
3833254721Semaste
3834254721Semaste    lldb::TypeCategoryImplSP category;
3835254721Semaste    DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
3836254721Semaste
3837254721Semaste    Error error;
3838254721Semaste
3839254721Semaste    for (size_t i = 0; i < argc; i++)
3840254721Semaste    {
3841254721Semaste        const char* typeA = command.GetArgumentAtIndex(i);
3842254721Semaste        ConstString typeCS(typeA);
3843254721Semaste        if (typeCS)
3844254721Semaste        {
3845254721Semaste            if (!AddSynth(typeCS,
3846254721Semaste                          entry,
3847254721Semaste                          m_options.m_regex ? eRegexSynth : eRegularSynth,
3848254721Semaste                          m_options.m_category,
3849254721Semaste                          &error))
3850254721Semaste            {
3851254721Semaste                result.AppendError(error.AsCString());
3852254721Semaste                result.SetStatus(eReturnStatusFailed);
3853254721Semaste                return false;
3854254721Semaste            }
3855254721Semaste        }
3856254721Semaste        else
3857254721Semaste        {
3858254721Semaste            result.AppendError("empty typenames not allowed");
3859254721Semaste            result.SetStatus(eReturnStatusFailed);
3860254721Semaste            return false;
3861254721Semaste        }
3862254721Semaste    }
3863254721Semaste
3864254721Semaste    result.SetStatus(eReturnStatusSuccessFinishNoResult);
3865254721Semaste    return result.Succeeded();
3866254721Semaste}
3867254721Semaste
3868254721SemasteCommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
3869254721Semaste    CommandObjectParsed (interpreter,
3870254721Semaste                         "type synthetic add",
3871254721Semaste                         "Add a new synthetic provider for a type.",
3872254721Semaste                         NULL),
3873269024Semaste    IOHandlerDelegateMultiline ("DONE"),
3874254721Semaste    m_options (interpreter)
3875254721Semaste{
3876254721Semaste    CommandArgumentEntry type_arg;
3877254721Semaste    CommandArgumentData type_style_arg;
3878254721Semaste
3879254721Semaste    type_style_arg.arg_type = eArgTypeName;
3880254721Semaste    type_style_arg.arg_repetition = eArgRepeatPlus;
3881254721Semaste
3882254721Semaste    type_arg.push_back (type_style_arg);
3883254721Semaste
3884254721Semaste    m_arguments.push_back (type_arg);
3885254721Semaste
3886254721Semaste}
3887254721Semaste
3888254721Semastebool
3889254721SemasteCommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
3890254721Semaste                                    SyntheticChildrenSP entry,
3891254721Semaste                                    SynthFormatType type,
3892254721Semaste                                    std::string category_name,
3893254721Semaste                                    Error* error)
3894254721Semaste{
3895254721Semaste    lldb::TypeCategoryImplSP category;
3896254721Semaste    DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
3897254721Semaste
3898254721Semaste    if (type == eRegularSynth)
3899254721Semaste    {
3900254721Semaste        std::string type_name_str(type_name.GetCString());
3901254721Semaste        if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0)
3902254721Semaste        {
3903254721Semaste            type_name_str.resize(type_name_str.length()-2);
3904254721Semaste            if (type_name_str.back() != ' ')
3905254721Semaste                type_name_str.append(" \\[[0-9]+\\]");
3906254721Semaste            else
3907254721Semaste                type_name_str.append("\\[[0-9]+\\]");
3908254721Semaste            type_name.SetCString(type_name_str.c_str());
3909254721Semaste            type = eRegularSynth;
3910254721Semaste        }
3911254721Semaste    }
3912254721Semaste
3913254721Semaste    if (category->AnyMatches(type_name,
3914254721Semaste                             eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
3915254721Semaste                             false))
3916254721Semaste    {
3917254721Semaste        if (error)
3918254721Semaste            error->SetErrorStringWithFormat("cannot add synthetic for type %s when filter is defined in same category!", type_name.AsCString());
3919254721Semaste        return false;
3920254721Semaste    }
3921254721Semaste
3922254721Semaste    if (type == eRegexSynth)
3923254721Semaste    {
3924254721Semaste        RegularExpressionSP typeRX(new RegularExpression());
3925254721Semaste        if (!typeRX->Compile(type_name.GetCString()))
3926254721Semaste        {
3927254721Semaste            if (error)
3928254721Semaste                error->SetErrorString("regex format error (maybe this is not really a regex?)");
3929254721Semaste            return false;
3930254721Semaste        }
3931254721Semaste
3932269024Semaste        category->GetRegexTypeSyntheticsContainer()->Delete(type_name);
3933269024Semaste        category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry);
3934254721Semaste
3935254721Semaste        return true;
3936254721Semaste    }
3937254721Semaste    else
3938254721Semaste    {
3939269024Semaste        category->GetTypeSyntheticsContainer()->Add(type_name, entry);
3940254721Semaste        return true;
3941254721Semaste    }
3942254721Semaste}
3943254721Semaste
3944254721SemasteOptionDefinition
3945254721SemasteCommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
3946254721Semaste{
3947263363Semaste    { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
3948263363Semaste    { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
3949263363Semaste    { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
3950263363Semaste    { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
3951263363Semaste    { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonClass,    "Use this Python class to produce synthetic children."},
3952263363Semaste    { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,    "Type Python code to generate a class that provides synthetic children."},
3953263363Semaste    { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
3954254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3955254721Semaste};
3956254721Semaste
3957254721Semaste#endif // #ifndef LLDB_DISABLE_PYTHON
3958254721Semaste
3959254721Semasteclass CommandObjectTypeFilterAdd : public CommandObjectParsed
3960254721Semaste{
3961254721Semaste
3962254721Semasteprivate:
3963254721Semaste
3964254721Semaste    class CommandOptions : public Options
3965254721Semaste    {
3966254721Semaste        typedef std::vector<std::string> option_vector;
3967254721Semaste    public:
3968254721Semaste
3969254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
3970254721Semaste        Options (interpreter)
3971254721Semaste        {
3972254721Semaste        }
3973254721Semaste
3974254721Semaste        virtual
3975254721Semaste        ~CommandOptions (){}
3976254721Semaste
3977254721Semaste        virtual Error
3978254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
3979254721Semaste        {
3980254721Semaste            Error error;
3981254721Semaste            const int short_option = m_getopt_table[option_idx].val;
3982254721Semaste            bool success;
3983254721Semaste
3984254721Semaste            switch (short_option)
3985254721Semaste            {
3986254721Semaste                case 'C':
3987254721Semaste                    m_cascade = Args::StringToBoolean(option_arg, true, &success);
3988254721Semaste                    if (!success)
3989254721Semaste                        error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
3990254721Semaste                    break;
3991254721Semaste                case 'c':
3992254721Semaste                    m_expr_paths.push_back(option_arg);
3993254721Semaste                    has_child_list = true;
3994254721Semaste                    break;
3995254721Semaste                case 'p':
3996254721Semaste                    m_skip_pointers = true;
3997254721Semaste                    break;
3998254721Semaste                case 'r':
3999254721Semaste                    m_skip_references = true;
4000254721Semaste                    break;
4001254721Semaste                case 'w':
4002254721Semaste                    m_category = std::string(option_arg);
4003254721Semaste                    break;
4004254721Semaste                case 'x':
4005254721Semaste                    m_regex = true;
4006254721Semaste                    break;
4007254721Semaste                default:
4008254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
4009254721Semaste                    break;
4010254721Semaste            }
4011254721Semaste
4012254721Semaste            return error;
4013254721Semaste        }
4014254721Semaste
4015254721Semaste        void
4016254721Semaste        OptionParsingStarting ()
4017254721Semaste        {
4018254721Semaste            m_cascade = true;
4019254721Semaste            m_skip_pointers = false;
4020254721Semaste            m_skip_references = false;
4021254721Semaste            m_category = "default";
4022254721Semaste            m_expr_paths.clear();
4023254721Semaste            has_child_list = false;
4024254721Semaste            m_regex = false;
4025254721Semaste        }
4026254721Semaste
4027254721Semaste        const OptionDefinition*
4028254721Semaste        GetDefinitions ()
4029254721Semaste        {
4030254721Semaste            return g_option_table;
4031254721Semaste        }
4032254721Semaste
4033254721Semaste        // Options table: Required for subclasses of Options.
4034254721Semaste
4035254721Semaste        static OptionDefinition g_option_table[];
4036254721Semaste
4037254721Semaste        // Instance variables to hold the values for command options.
4038254721Semaste
4039254721Semaste        bool m_cascade;
4040254721Semaste        bool m_skip_references;
4041254721Semaste        bool m_skip_pointers;
4042254721Semaste        bool m_input_python;
4043254721Semaste        option_vector m_expr_paths;
4044254721Semaste        std::string m_category;
4045254721Semaste
4046254721Semaste        bool has_child_list;
4047254721Semaste
4048254721Semaste        bool m_regex;
4049254721Semaste
4050254721Semaste        typedef option_vector::iterator ExpressionPathsIterator;
4051254721Semaste    };
4052254721Semaste
4053254721Semaste    CommandOptions m_options;
4054254721Semaste
4055254721Semaste    virtual Options *
4056254721Semaste    GetOptions ()
4057254721Semaste    {
4058254721Semaste        return &m_options;
4059254721Semaste    }
4060254721Semaste
4061254721Semaste    enum FilterFormatType
4062254721Semaste    {
4063254721Semaste        eRegularFilter,
4064254721Semaste        eRegexFilter
4065254721Semaste    };
4066254721Semaste
4067254721Semaste    bool
4068254721Semaste    AddFilter(ConstString type_name,
4069254721Semaste              SyntheticChildrenSP entry,
4070254721Semaste              FilterFormatType type,
4071254721Semaste              std::string category_name,
4072254721Semaste              Error* error)
4073254721Semaste    {
4074254721Semaste        lldb::TypeCategoryImplSP category;
4075254721Semaste        DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
4076254721Semaste
4077254721Semaste        if (type == eRegularFilter)
4078254721Semaste        {
4079254721Semaste            std::string type_name_str(type_name.GetCString());
4080254721Semaste            if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0)
4081254721Semaste            {
4082254721Semaste                type_name_str.resize(type_name_str.length()-2);
4083254721Semaste                if (type_name_str.back() != ' ')
4084254721Semaste                    type_name_str.append(" \\[[0-9]+\\]");
4085254721Semaste                else
4086254721Semaste                    type_name_str.append("\\[[0-9]+\\]");
4087254721Semaste                type_name.SetCString(type_name_str.c_str());
4088254721Semaste                type = eRegexFilter;
4089254721Semaste            }
4090254721Semaste        }
4091254721Semaste
4092254721Semaste        if (category->AnyMatches(type_name,
4093254721Semaste                                 eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
4094254721Semaste                                 false))
4095254721Semaste        {
4096254721Semaste            if (error)
4097254721Semaste                error->SetErrorStringWithFormat("cannot add filter for type %s when synthetic is defined in same category!", type_name.AsCString());
4098254721Semaste            return false;
4099254721Semaste        }
4100254721Semaste
4101254721Semaste        if (type == eRegexFilter)
4102254721Semaste        {
4103254721Semaste            RegularExpressionSP typeRX(new RegularExpression());
4104254721Semaste            if (!typeRX->Compile(type_name.GetCString()))
4105254721Semaste            {
4106254721Semaste                if (error)
4107254721Semaste                    error->SetErrorString("regex format error (maybe this is not really a regex?)");
4108254721Semaste                return false;
4109254721Semaste            }
4110254721Semaste
4111269024Semaste            category->GetRegexTypeFiltersContainer()->Delete(type_name);
4112269024Semaste            category->GetRegexTypeFiltersContainer()->Add(typeRX, entry);
4113254721Semaste
4114254721Semaste            return true;
4115254721Semaste        }
4116254721Semaste        else
4117254721Semaste        {
4118269024Semaste            category->GetTypeFiltersContainer()->Add(type_name, entry);
4119254721Semaste            return true;
4120254721Semaste        }
4121254721Semaste    }
4122254721Semaste
4123254721Semaste
4124254721Semastepublic:
4125254721Semaste
4126254721Semaste    CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) :
4127254721Semaste        CommandObjectParsed (interpreter,
4128254721Semaste                             "type filter add",
4129254721Semaste                             "Add a new filter for a type.",
4130254721Semaste                             NULL),
4131254721Semaste        m_options (interpreter)
4132254721Semaste    {
4133254721Semaste        CommandArgumentEntry type_arg;
4134254721Semaste        CommandArgumentData type_style_arg;
4135254721Semaste
4136254721Semaste        type_style_arg.arg_type = eArgTypeName;
4137254721Semaste        type_style_arg.arg_repetition = eArgRepeatPlus;
4138254721Semaste
4139254721Semaste        type_arg.push_back (type_style_arg);
4140254721Semaste
4141254721Semaste        m_arguments.push_back (type_arg);
4142254721Semaste
4143254721Semaste        SetHelpLong(
4144254721Semaste                    "Some examples of using this command.\n"
4145254721Semaste                    "We use as reference the following snippet of code:\n"
4146254721Semaste                    "\n"
4147254721Semaste                    "class Foo {;\n"
4148254721Semaste                    "    int a;\n"
4149254721Semaste                    "    int b;\n"
4150254721Semaste                    "    int c;\n"
4151254721Semaste                    "    int d;\n"
4152254721Semaste                    "    int e;\n"
4153254721Semaste                    "    int f;\n"
4154254721Semaste                    "    int g;\n"
4155254721Semaste                    "    int h;\n"
4156254721Semaste                    "    int i;\n"
4157254721Semaste                    "} \n"
4158254721Semaste                    "Typing:\n"
4159254721Semaste                    "type filter add --child a --child g Foo\n"
4160254721Semaste                    "frame variable a_foo\n"
4161254721Semaste                    "will produce an output where only a and g are displayed\n"
4162254721Semaste                    "Other children of a_foo (b,c,d,e,f,h and i) are available by asking for them, as in:\n"
4163254721Semaste                    "frame variable a_foo.b a_foo.c ... a_foo.i\n"
4164254721Semaste                    "\n"
4165254721Semaste                    "Use option --raw to frame variable prevails on the filter\n"
4166254721Semaste                    "frame variable a_foo --raw\n"
4167254721Semaste                    "shows all the children of a_foo (a thru i) as if no filter was defined\n"
4168254721Semaste                    );
4169254721Semaste    }
4170254721Semaste
4171254721Semaste    ~CommandObjectTypeFilterAdd ()
4172254721Semaste    {
4173254721Semaste    }
4174254721Semaste
4175254721Semasteprotected:
4176254721Semaste    bool
4177254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
4178254721Semaste    {
4179254721Semaste        const size_t argc = command.GetArgumentCount();
4180254721Semaste
4181254721Semaste        if (argc < 1)
4182254721Semaste        {
4183254721Semaste            result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
4184254721Semaste            result.SetStatus(eReturnStatusFailed);
4185254721Semaste            return false;
4186254721Semaste        }
4187254721Semaste
4188254721Semaste        if (m_options.m_expr_paths.size() == 0)
4189254721Semaste        {
4190254721Semaste            result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
4191254721Semaste            result.SetStatus(eReturnStatusFailed);
4192254721Semaste            return false;
4193254721Semaste        }
4194254721Semaste
4195254721Semaste        SyntheticChildrenSP entry;
4196254721Semaste
4197254721Semaste        TypeFilterImpl* impl = new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade).
4198254721Semaste                                                    SetSkipPointers(m_options.m_skip_pointers).
4199254721Semaste                                                    SetSkipReferences(m_options.m_skip_references));
4200254721Semaste
4201254721Semaste        entry.reset(impl);
4202254721Semaste
4203254721Semaste        // go through the expression paths
4204254721Semaste        CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end();
4205254721Semaste
4206254721Semaste        for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
4207254721Semaste            impl->AddExpressionPath(*begin);
4208254721Semaste
4209254721Semaste
4210254721Semaste        // now I have a valid provider, let's add it to every type
4211254721Semaste
4212254721Semaste        lldb::TypeCategoryImplSP category;
4213254721Semaste        DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
4214254721Semaste
4215254721Semaste        Error error;
4216254721Semaste
4217269024Semaste        WarnOnPotentialUnquotedUnsignedType(command, result);
4218269024Semaste
4219254721Semaste        for (size_t i = 0; i < argc; i++)
4220254721Semaste        {
4221254721Semaste            const char* typeA = command.GetArgumentAtIndex(i);
4222254721Semaste            ConstString typeCS(typeA);
4223254721Semaste            if (typeCS)
4224254721Semaste            {
4225254721Semaste                if (!AddFilter(typeCS,
4226254721Semaste                          entry,
4227254721Semaste                          m_options.m_regex ? eRegexFilter : eRegularFilter,
4228254721Semaste                          m_options.m_category,
4229254721Semaste                          &error))
4230254721Semaste                {
4231254721Semaste                    result.AppendError(error.AsCString());
4232254721Semaste                    result.SetStatus(eReturnStatusFailed);
4233254721Semaste                    return false;
4234254721Semaste                }
4235254721Semaste            }
4236254721Semaste            else
4237254721Semaste            {
4238254721Semaste                result.AppendError("empty typenames not allowed");
4239254721Semaste                result.SetStatus(eReturnStatusFailed);
4240254721Semaste                return false;
4241254721Semaste            }
4242254721Semaste        }
4243254721Semaste
4244254721Semaste        result.SetStatus(eReturnStatusSuccessFinishNoResult);
4245254721Semaste        return result.Succeeded();
4246254721Semaste    }
4247254721Semaste
4248254721Semaste};
4249254721Semaste
4250254721SemasteOptionDefinition
4251254721SemasteCommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
4252254721Semaste{
4253263363Semaste    { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
4254263363Semaste    { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
4255263363Semaste    { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
4256263363Semaste    { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
4257263363Semaste    { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpressionPath,    "Include this expression path in the synthetic view."},
4258263363Semaste    { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
4259254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
4260254721Semaste};
4261254721Semaste
4262254721Semasteclass CommandObjectTypeFormat : public CommandObjectMultiword
4263254721Semaste{
4264254721Semastepublic:
4265254721Semaste    CommandObjectTypeFormat (CommandInterpreter &interpreter) :
4266254721Semaste        CommandObjectMultiword (interpreter,
4267254721Semaste                                "type format",
4268254721Semaste                                "A set of commands for editing variable value display options",
4269254721Semaste                                "type format [<sub-command-options>] ")
4270254721Semaste    {
4271254721Semaste        LoadSubCommand ("add",    CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter)));
4272254721Semaste        LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectTypeFormatClear (interpreter)));
4273254721Semaste        LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter)));
4274254721Semaste        LoadSubCommand ("list",   CommandObjectSP (new CommandObjectTypeFormatList (interpreter)));
4275254721Semaste    }
4276254721Semaste
4277254721Semaste
4278254721Semaste    ~CommandObjectTypeFormat ()
4279254721Semaste    {
4280254721Semaste    }
4281254721Semaste};
4282254721Semaste
4283254721Semaste#ifndef LLDB_DISABLE_PYTHON
4284254721Semaste
4285254721Semasteclass CommandObjectTypeSynth : public CommandObjectMultiword
4286254721Semaste{
4287254721Semastepublic:
4288254721Semaste    CommandObjectTypeSynth (CommandInterpreter &interpreter) :
4289254721Semaste    CommandObjectMultiword (interpreter,
4290254721Semaste                            "type synthetic",
4291254721Semaste                            "A set of commands for operating on synthetic type representations",
4292254721Semaste                            "type synthetic [<sub-command-options>] ")
4293254721Semaste    {
4294254721Semaste        LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter)));
4295254721Semaste        LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeSynthClear (interpreter)));
4296254721Semaste        LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter)));
4297254721Semaste        LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeSynthList (interpreter)));
4298254721Semaste    }
4299254721Semaste
4300254721Semaste
4301254721Semaste    ~CommandObjectTypeSynth ()
4302254721Semaste    {
4303254721Semaste    }
4304254721Semaste};
4305254721Semaste
4306254721Semaste#endif // #ifndef LLDB_DISABLE_PYTHON
4307254721Semaste
4308254721Semasteclass CommandObjectTypeFilter : public CommandObjectMultiword
4309254721Semaste{
4310254721Semastepublic:
4311254721Semaste    CommandObjectTypeFilter (CommandInterpreter &interpreter) :
4312254721Semaste    CommandObjectMultiword (interpreter,
4313254721Semaste                            "type filter",
4314254721Semaste                            "A set of commands for operating on type filters",
4315254721Semaste                            "type synthetic [<sub-command-options>] ")
4316254721Semaste    {
4317254721Semaste        LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter)));
4318254721Semaste        LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeFilterClear (interpreter)));
4319254721Semaste        LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter)));
4320254721Semaste        LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeFilterList (interpreter)));
4321254721Semaste    }
4322254721Semaste
4323254721Semaste
4324254721Semaste    ~CommandObjectTypeFilter ()
4325254721Semaste    {
4326254721Semaste    }
4327254721Semaste};
4328254721Semaste
4329254721Semasteclass CommandObjectTypeCategory : public CommandObjectMultiword
4330254721Semaste{
4331254721Semastepublic:
4332254721Semaste    CommandObjectTypeCategory (CommandInterpreter &interpreter) :
4333254721Semaste    CommandObjectMultiword (interpreter,
4334254721Semaste                            "type category",
4335254721Semaste                            "A set of commands for operating on categories",
4336254721Semaste                            "type category [<sub-command-options>] ")
4337254721Semaste    {
4338254721Semaste        LoadSubCommand ("enable",        CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter)));
4339254721Semaste        LoadSubCommand ("disable",       CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter)));
4340254721Semaste        LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter)));
4341254721Semaste        LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeCategoryList (interpreter)));
4342254721Semaste    }
4343254721Semaste
4344254721Semaste
4345254721Semaste    ~CommandObjectTypeCategory ()
4346254721Semaste    {
4347254721Semaste    }
4348254721Semaste};
4349254721Semaste
4350254721Semasteclass CommandObjectTypeSummary : public CommandObjectMultiword
4351254721Semaste{
4352254721Semastepublic:
4353254721Semaste    CommandObjectTypeSummary (CommandInterpreter &interpreter) :
4354254721Semaste    CommandObjectMultiword (interpreter,
4355254721Semaste                            "type summary",
4356254721Semaste                            "A set of commands for editing variable summary display options",
4357254721Semaste                            "type summary [<sub-command-options>] ")
4358254721Semaste    {
4359254721Semaste        LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter)));
4360254721Semaste        LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter)));
4361254721Semaste        LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter)));
4362254721Semaste        LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeSummaryList (interpreter)));
4363254721Semaste    }
4364254721Semaste
4365254721Semaste
4366254721Semaste    ~CommandObjectTypeSummary ()
4367254721Semaste    {
4368254721Semaste    }
4369254721Semaste};
4370254721Semaste
4371254721Semaste//-------------------------------------------------------------------------
4372254721Semaste// CommandObjectType
4373254721Semaste//-------------------------------------------------------------------------
4374254721Semaste
4375254721SemasteCommandObjectType::CommandObjectType (CommandInterpreter &interpreter) :
4376254721Semaste    CommandObjectMultiword (interpreter,
4377254721Semaste                            "type",
4378254721Semaste                            "A set of commands for operating on the type system",
4379254721Semaste                            "type [<sub-command-options>]")
4380254721Semaste{
4381254721Semaste    LoadSubCommand ("category",  CommandObjectSP (new CommandObjectTypeCategory (interpreter)));
4382254721Semaste    LoadSubCommand ("filter",    CommandObjectSP (new CommandObjectTypeFilter (interpreter)));
4383254721Semaste    LoadSubCommand ("format",    CommandObjectSP (new CommandObjectTypeFormat (interpreter)));
4384254721Semaste    LoadSubCommand ("summary",   CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
4385254721Semaste#ifndef LLDB_DISABLE_PYTHON
4386254721Semaste    LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter)));
4387254721Semaste#endif
4388254721Semaste}
4389254721Semaste
4390254721Semaste
4391254721SemasteCommandObjectType::~CommandObjectType ()
4392254721Semaste{
4393254721Semaste}
4394254721Semaste
4395254721Semaste
4396