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