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