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