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