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