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