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