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