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