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