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, ¶m);
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