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