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