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