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