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