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