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