1 //===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "CommandObjectType.h"
11 
12 // C Includes
13 // C++ Includes
14 
15 #include "lldb/Core/ConstString.h"
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/Core/FormatManager.h"
18 #include "lldb/Core/RegularExpression.h"
19 #include "lldb/Core/State.h"
20 #include "lldb/Interpreter/CommandInterpreter.h"
21 #include "lldb/Interpreter/CommandObject.h"
22 #include "lldb/Interpreter/CommandReturnObject.h"
23 #include "lldb/Interpreter/Options.h"
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 
28 //-------------------------------------------------------------------------
29 // CommandObjectTypeFormatAdd
30 //-------------------------------------------------------------------------
31 
32 class CommandObjectTypeFormatAdd : public CommandObject
33 {
34 
35 private:
36 
37     class CommandOptions : public Options
38     {
39     public:
40 
41         CommandOptions (CommandInterpreter &interpreter) :
42         Options (interpreter)
43         {
44         }
45 
46         virtual
47         ~CommandOptions (){}
48 
49         virtual Error
50         SetOptionValue (uint32_t option_idx, const char *option_arg)
51         {
52             Error error;
53             char short_option = (char) m_getopt_table[option_idx].val;
54             bool success;
55 
56             switch (short_option)
57             {
58                 case 'C':
59                     m_cascade = Args::StringToBoolean(option_arg, true, &success);
60                     if (!success)
61                         error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg);
62                     break;
63                 case 'f':
64                     error = Args::StringToFormat(option_arg, m_format, NULL);
65                     break;
66                 case 'p':
67                     m_skip_pointers = true;
68                     break;
69                 case 'r':
70                     m_skip_references = true;
71                     break;
72                 default:
73                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
74                     break;
75             }
76 
77             return error;
78         }
79 
80         void
81         OptionParsingStarting ()
82         {
83             m_cascade = true;
84             m_format = eFormatInvalid;
85             m_skip_pointers = false;
86             m_skip_references = false;
87         }
88 
89         const OptionDefinition*
90         GetDefinitions ()
91         {
92             return g_option_table;
93         }
94 
95         // Options table: Required for subclasses of Options.
96 
97         static OptionDefinition g_option_table[];
98 
99         // Instance variables to hold the values for command options.
100 
101         bool m_cascade;
102         lldb::Format m_format;
103         bool m_skip_references;
104         bool m_skip_pointers;
105     };
106 
107     CommandOptions m_options;
108 
109     virtual Options *
110     GetOptions ()
111     {
112         return &m_options;
113     }
114 
115 public:
116     CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) :
117     CommandObject (interpreter,
118                    "type format add",
119                    "Add a new formatting style for a type.",
120                    NULL), m_options (interpreter)
121     {
122         CommandArgumentEntry type_arg;
123         CommandArgumentData type_style_arg;
124 
125         type_style_arg.arg_type = eArgTypeName;
126         type_style_arg.arg_repetition = eArgRepeatPlus;
127 
128         type_arg.push_back (type_style_arg);
129 
130         m_arguments.push_back (type_arg);
131 
132         SetHelpLong(
133                     "Some examples of using this command.\n"
134                     "We use as reference the following snippet of code:\n"
135                     "\n"
136                     "typedef int Aint;\n"
137                     "typedef float Afloat;\n"
138                     "typedef Aint Bint;\n"
139                     "typedef Afloat Bfloat;\n"
140                     "\n"
141                     "Aint ix = 5;\n"
142                     "Bint iy = 5;\n"
143                     "\n"
144                     "Afloat fx = 3.14;\n"
145                     "BFloat fy = 3.14;\n"
146                     "\n"
147                     "Typing:\n"
148                     "type format add -f hex AInt\n"
149                     "frame variable iy\n"
150                     "will produce an hex display of iy, because no formatter is available for Bint and the one for Aint is used instead\n"
151                     "To prevent this type\n"
152                     "type format add -f hex -C no AInt\n"
153                     "\n"
154                     "A similar reasoning applies to\n"
155                     "type format add -f hex -C no float -p\n"
156                     "which now prints all floats and float&s as hexadecimal, but does not format float*s\n"
157                     "and does not change the default display for Afloat and Bfloat objects.\n"
158                     );
159     }
160 
161     ~CommandObjectTypeFormatAdd ()
162     {
163     }
164 
165     bool
166     Execute (Args& command, CommandReturnObject &result)
167     {
168         const size_t argc = command.GetArgumentCount();
169 
170         if (argc < 1)
171         {
172             result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
173             result.SetStatus(eReturnStatusFailed);
174             return false;
175         }
176 
177         if(m_options.m_format == eFormatInvalid)
178         {
179             result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
180             result.SetStatus(eReturnStatusFailed);
181             return false;
182         }
183 
184         ValueFormatSP entry;
185 
186         entry.reset(new ValueFormat(m_options.m_format,
187                                     m_options.m_cascade,
188                                     m_options.m_skip_pointers,
189                                     m_options.m_skip_references));
190 
191         // now I have a valid format, let's add it to every type
192 
193         for(int i = 0; i < argc; i++) {
194             const char* typeA = command.GetArgumentAtIndex(i);
195             ConstString typeCS(typeA);
196             if (typeCS)
197                 Debugger::ValueFormats::Add(typeCS, entry);
198             else
199             {
200                 result.AppendError("empty typenames not allowed");
201                 result.SetStatus(eReturnStatusFailed);
202                 return false;
203             }
204         }
205 
206         result.SetStatus(eReturnStatusSuccessFinishNoResult);
207         return result.Succeeded();
208     }
209 };
210 
211 OptionDefinition
212 CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
213 {
214     { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean,    "If true, cascade to derived typedefs."},
215     { LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, eArgTypeFormat,    "The format to use to display this type."},
216     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean,         "Don't use this format for pointers-to-type objects."},
217     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeBoolean,         "Don't use this format for references-to-type objects."},
218     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
219 };
220 
221 
222 //-------------------------------------------------------------------------
223 // CommandObjectTypeFormatDelete
224 //-------------------------------------------------------------------------
225 
226 class CommandObjectTypeFormatDelete : public CommandObject
227 {
228 public:
229     CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) :
230     CommandObject (interpreter,
231                    "type format delete",
232                    "Delete an existing formatting style for a type.",
233                    NULL)
234     {
235         CommandArgumentEntry type_arg;
236         CommandArgumentData type_style_arg;
237 
238         type_style_arg.arg_type = eArgTypeName;
239         type_style_arg.arg_repetition = eArgRepeatPlain;
240 
241         type_arg.push_back (type_style_arg);
242 
243         m_arguments.push_back (type_arg);
244 
245     }
246 
247     ~CommandObjectTypeFormatDelete ()
248     {
249     }
250 
251     bool
252     Execute (Args& command, CommandReturnObject &result)
253     {
254         const size_t argc = command.GetArgumentCount();
255 
256         if (argc != 1)
257         {
258             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
259             result.SetStatus(eReturnStatusFailed);
260             return false;
261         }
262 
263         const char* typeA = command.GetArgumentAtIndex(0);
264         ConstString typeCS(typeA);
265 
266         if(!typeCS)
267         {
268             result.AppendError("empty typenames not allowed");
269             result.SetStatus(eReturnStatusFailed);
270             return false;
271         }
272 
273 
274         if (Debugger::ValueFormats::Delete(typeCS))
275         {
276             result.SetStatus(eReturnStatusSuccessFinishNoResult);
277             return result.Succeeded();
278         }
279         else
280         {
281             result.AppendErrorWithFormat ("no custom format for %s.\n", typeA);
282             result.SetStatus(eReturnStatusFailed);
283             return false;
284         }
285 
286     }
287 
288 };
289 
290 //-------------------------------------------------------------------------
291 // CommandObjectTypeFormatClear
292 //-------------------------------------------------------------------------
293 
294 class CommandObjectTypeFormatClear : public CommandObject
295 {
296 public:
297     CommandObjectTypeFormatClear (CommandInterpreter &interpreter) :
298     CommandObject (interpreter,
299                    "type format clear",
300                    "Delete all existing format styles.",
301                    NULL)
302     {
303     }
304 
305     ~CommandObjectTypeFormatClear ()
306     {
307     }
308 
309     bool
310     Execute (Args& command, CommandReturnObject &result)
311     {
312         Debugger::ValueFormats::Clear();
313         result.SetStatus(eReturnStatusSuccessFinishResult);
314         return result.Succeeded();
315     }
316 
317 };
318 
319 //-------------------------------------------------------------------------
320 // CommandObjectTypeFormatList
321 //-------------------------------------------------------------------------
322 
323 bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, const char* type, const ValueFormat::SharedPointer& entry);
324 
325 class CommandObjectTypeFormatList;
326 
327 struct CommandObjectTypeFormatList_LoopCallbackParam {
328     CommandObjectTypeFormatList* self;
329     CommandReturnObject* result;
330     RegularExpression* regex;
331     CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R,
332                                             RegularExpression* X = NULL) : self(S), result(R), regex(X) {}
333 };
334 
335 class CommandObjectTypeFormatList : public CommandObject
336 {
337 public:
338     CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
339     CommandObject (interpreter,
340                    "type format list",
341                    "Show a list of current formatting styles.",
342                    NULL)
343     {
344         CommandArgumentEntry type_arg;
345         CommandArgumentData type_style_arg;
346 
347         type_style_arg.arg_type = eArgTypeName;
348         type_style_arg.arg_repetition = eArgRepeatOptional;
349 
350         type_arg.push_back (type_style_arg);
351 
352         m_arguments.push_back (type_arg);
353     }
354 
355     ~CommandObjectTypeFormatList ()
356     {
357     }
358 
359     bool
360     Execute (Args& command, CommandReturnObject &result)
361     {
362         const size_t argc = command.GetArgumentCount();
363 
364         CommandObjectTypeFormatList_LoopCallbackParam *param;
365 
366         if (argc == 1) {
367             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
368             regex->Compile(command.GetArgumentAtIndex(0));
369             param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex);
370         }
371         else
372             param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result);
373         Debugger::ValueFormats::LoopThrough(CommandObjectTypeFormatList_LoopCallback, param);
374         delete param;
375         result.SetStatus(eReturnStatusSuccessFinishResult);
376         return result.Succeeded();
377     }
378 
379 private:
380 
381     bool
382     LoopCallback (const char* type,
383                   const ValueFormat::SharedPointer& entry,
384                   RegularExpression* regex,
385                   CommandReturnObject *result)
386     {
387         if (regex == NULL || regex->Execute(type))
388         {
389             result->GetOutputStream().Printf ("%s: %s%s%s%s\n", type,
390                                               FormatManager::GetFormatAsCString (entry->m_format),
391                                               entry->m_cascades ? "" : " (not cascading)",
392                                               entry->m_skip_pointers ? " (skip pointers)" : "",
393                                               entry->m_skip_references ? " (skip references)" : "");
394         }
395         return true;
396     }
397 
398     friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, const char* type, const ValueFormat::SharedPointer& entry);
399 
400 };
401 
402 bool
403 CommandObjectTypeFormatList_LoopCallback (
404                                     void* pt2self,
405                                     const char* type,
406                                     const ValueFormat::SharedPointer& entry)
407 {
408     CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;
409     return param->self->LoopCallback(type, entry, param->regex, param->result);
410 }
411 
412 
413 
414 
415 //-------------------------------------------------------------------------
416 // CommandObjectTypeSummaryAdd
417 //-------------------------------------------------------------------------
418 
419 class CommandObjectTypeSummaryAdd : public CommandObject
420 {
421 
422 private:
423 
424     class CommandOptions : public Options
425     {
426     public:
427 
428         CommandOptions (CommandInterpreter &interpreter) :
429         Options (interpreter)
430         {
431         }
432 
433         virtual
434         ~CommandOptions (){}
435 
436         virtual Error
437         SetOptionValue (uint32_t option_idx, const char *option_arg)
438         {
439             Error error;
440             char short_option = (char) m_getopt_table[option_idx].val;
441             bool success;
442 
443             switch (short_option)
444             {
445                 case 'C':
446                     m_cascade = Args::StringToBoolean(option_arg, true, &success);
447                     if (!success)
448                         error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg);
449                     break;
450                 case 'e':
451                     m_no_children = false;
452                     break;
453                 case 'v':
454                     m_no_value = true;
455                     break;
456                 case 'c':
457                     m_one_liner = true;
458                     break;
459                 case 'f':
460                     m_format_string = std::string(option_arg);
461                     break;
462                 case 'p':
463                     m_skip_pointers = true;
464                     break;
465                 case 'r':
466                     m_skip_references = true;
467                     break;
468                 case 'x':
469                     m_regex = true;
470                     break;
471                 case 'n':
472                     m_name = new ConstString(option_arg);
473                     break;
474                 default:
475                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
476                     break;
477             }
478 
479             return error;
480         }
481 
482         void
483         OptionParsingStarting ()
484         {
485             m_cascade = true;
486             m_no_children = true;
487             m_no_value = false;
488             m_one_liner = false;
489             m_skip_references = false;
490             m_skip_pointers = false;
491             m_regex = false;
492             m_name = NULL;
493         }
494 
495         const OptionDefinition*
496         GetDefinitions ()
497         {
498             return g_option_table;
499         }
500 
501         // Options table: Required for subclasses of Options.
502 
503         static OptionDefinition g_option_table[];
504 
505         // Instance variables to hold the values for command options.
506 
507         bool m_cascade;
508         bool m_no_children;
509         bool m_no_value;
510         bool m_one_liner;
511         bool m_skip_references;
512         bool m_skip_pointers;
513         bool m_regex;
514         std::string m_format_string;
515         ConstString* m_name;
516     };
517 
518     CommandOptions m_options;
519 
520     virtual Options *
521     GetOptions ()
522     {
523         return &m_options;
524     }
525 
526 public:
527     CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
528     CommandObject (interpreter,
529                    "type summary add",
530                    "Add a new summary style for a type.",
531                    NULL), m_options (interpreter)
532     {
533         CommandArgumentEntry type_arg;
534         CommandArgumentData type_style_arg;
535 
536         type_style_arg.arg_type = eArgTypeName;
537         type_style_arg.arg_repetition = eArgRepeatPlus;
538 
539         type_arg.push_back (type_style_arg);
540 
541         m_arguments.push_back (type_arg);
542 
543         SetHelpLong(
544                     "Some examples of using this command.\n"
545                     "We use as reference the following snippet of code:\n"
546                     "struct JustADemo\n"
547                     "{\n"
548                     "int* ptr;\n"
549                     "float value;\n"
550                     "JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n"
551                     "};\n"
552                     "JustADemo object(42,3.14);\n"
553                     "struct AnotherDemo : public JustADemo\n"
554                     "{\n"
555                     "uint8_t byte;\n"
556                     "AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n"
557                     "};\n"
558                     "AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n"
559                     "\n"
560                     "type summary add -f \"the answer is ${*var.ptr}\" JustADemo\n"
561                     "when typing frame variable object you will get \"the answer is 42\"\n"
562                     "type summary add -f \"the answer is ${*var.ptr}, and the question is ${var.value}\" JustADemo\n"
563                     "when typing frame variable object you will get \"the answer is 42 and the question is 3.14\"\n"
564                     "\n"
565                     "Alternatively, you could also say\n"
566                     "type summary add -f \"${var%V} -> ${*var}\" \"int *\"\n"
567                     "and replace the above summary string with\n"
568                     "type summary add -f \"the answer is ${var.ptr}, and the question is ${var.value}\" JustADemo\n"
569                     "to obtain a similar result\n"
570                     "\n"
571                     "To add a summary valid for both JustADemo and AnotherDemo you can use the scoping operator, as in:\n"
572                     "type summary add -f \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes\n"
573                     "\n"
574                     "This will be used for both variables of type JustADemo and AnotherDemo. To prevent this, change the -C to read -C no\n"
575                     "If you do not want pointers to be shown using that summary, you can use the -p option, as in:\n"
576                     "type summary add -f \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes -p\n"
577                     "A similar option -r exists for references.\n"
578                     "\n"
579                     "If you simply want a one-line summary of the content of your variable, without typing an explicit string to that effect\n"
580                     "you can use the -c option, without giving any summary string:\n"
581                     "type summary add -c JustADemo\n"
582                     "frame variable object\n"
583                     "the output being similar to (ptr=0xsomeaddress, value=3.14)\n"
584                     "\n"
585                     "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"
586                     "type summary add -e -f \"*ptr = ${*var.ptr}\" JustADemo\n"
587                     "Here the value of the int* is displayed, followed by the standard LLDB sequence of children objects, one per line.\n"
588                     "to get an output like:\n"
589                     "\n"
590                     "*ptr = 42 {\n"
591                     " ptr = 0xsomeaddress\n"
592                     " value = 3.14\n"
593                     "}\n"
594                     "\n"
595                     "A command you may definitely want to try if you're doing C++ debugging is:\n"
596                     "type summary add -f \"${var._M_dataplus._M_p}\" std::string\n"
597         );
598     }
599 
600     ~CommandObjectTypeSummaryAdd ()
601     {
602     }
603 
604     bool
605     Execute (Args& command, CommandReturnObject &result)
606     {
607         const size_t argc = command.GetArgumentCount();
608 
609         if (argc < 1 && !m_options.m_name)
610         {
611             result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
612             result.SetStatus(eReturnStatusFailed);
613             return false;
614         }
615 
616         if(!m_options.m_one_liner && m_options.m_format_string.empty())
617         {
618             result.AppendError("empty summary strings not allowed");
619             result.SetStatus(eReturnStatusFailed);
620             return false;
621         }
622 
623         const char* format_cstr = (m_options.m_one_liner ? "" : m_options.m_format_string.c_str());
624 
625         Error error;
626 
627         SummaryFormat::SharedPointer entry(new SummaryFormat(format_cstr,m_options.m_cascade,
628                                              m_options.m_no_children,m_options.m_no_value,
629                                              m_options.m_one_liner,
630                                              m_options.m_skip_pointers,
631                                              m_options.m_skip_references));
632 
633         if (error.Fail())
634         {
635             result.AppendError(error.AsCString());
636             result.SetStatus(eReturnStatusFailed);
637             return false;
638         }
639 
640         // now I have a valid format, let's add it to every type
641 
642         for(int i = 0; i < argc; i++) {
643             const char* typeA = command.GetArgumentAtIndex(i);
644             if (!typeA || typeA[0] == '\0')
645             {
646                 result.AppendError("empty typenames not allowed");
647                 result.SetStatus(eReturnStatusFailed);
648                 return false;
649             }
650             ConstString typeCS(typeA);
651             if (!m_options.m_regex)
652             {
653                 Debugger::SummaryFormats::Add(typeCS, entry);
654             }
655             else
656             {
657                 RegularExpressionSP typeRX(new RegularExpression());
658                 if(!typeRX->Compile(typeA))
659                 {
660                     result.AppendError("regex format error (maybe this is not really a regex?)");
661                     result.SetStatus(eReturnStatusFailed);
662                     return false;
663                 }
664                 Debugger::RegexSummaryFormats::Delete(typeCS);
665                 Debugger::RegexSummaryFormats::Add(typeRX, entry);
666             }
667         }
668 
669         if (m_options.m_name)
670         {
671             if( (bool)(*(m_options.m_name)) )
672             {
673                 Debugger::NamedSummaryFormats::Add(*(m_options.m_name), entry);
674             }
675             else
676             {
677                 result.AppendError("added to types, but not given a name");
678                 result.SetStatus(eReturnStatusFailed);
679                 return false;
680             }
681         }
682 
683         result.SetStatus(eReturnStatusSuccessFinishNoResult);
684         return result.Succeeded();
685     }
686 
687 };
688 
689 OptionDefinition
690 CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
691 {
692     { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean,    "If true, cascade to derived typedefs."},
693     { LLDB_OPT_SET_ALL, false, "no-value", 'v', no_argument, NULL, 0, eArgTypeBoolean,         "Don't show the value, just show the summary, for this type."},
694     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean,         "Don't use this format for pointers-to-type objects."},
695     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeBoolean,         "Don't use this format for references-to-type objects."},
696     { LLDB_OPT_SET_ALL, false,  "regex", 'x', no_argument, NULL, 0, eArgTypeBoolean,    "Type names are actually regular expressions."},
697     { LLDB_OPT_SET_1  , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeBoolean,    "If true, inline all child values into summary string."},
698     { LLDB_OPT_SET_2  , true, "format-string", 'f', required_argument, NULL, 0, eArgTypeSummaryString,    "Format string used to display text and object contents."},
699     { LLDB_OPT_SET_2,   false, "expand", 'e', no_argument, NULL, 0, eArgTypeBoolean,    "Expand aggregate data types to show children on separate lines."},
700     { LLDB_OPT_SET_2,   false, "name", 'n', required_argument, NULL, 0, eArgTypeName,    "A name for this summary string."},
701     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
702 };
703 
704 
705 //-------------------------------------------------------------------------
706 // CommandObjectTypeSummaryDelete
707 //-------------------------------------------------------------------------
708 
709 class CommandObjectTypeSummaryDelete : public CommandObject
710 {
711 public:
712     CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) :
713     CommandObject (interpreter,
714                    "type summary delete",
715                    "Delete an existing summary style for a type.",
716                    NULL)
717     {
718         CommandArgumentEntry type_arg;
719         CommandArgumentData type_style_arg;
720 
721         type_style_arg.arg_type = eArgTypeName;
722         type_style_arg.arg_repetition = eArgRepeatPlain;
723 
724         type_arg.push_back (type_style_arg);
725 
726         m_arguments.push_back (type_arg);
727 
728     }
729 
730     ~CommandObjectTypeSummaryDelete ()
731     {
732     }
733 
734     bool
735     Execute (Args& command, CommandReturnObject &result)
736     {
737         const size_t argc = command.GetArgumentCount();
738 
739         if (argc != 1)
740         {
741             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
742             result.SetStatus(eReturnStatusFailed);
743             return false;
744         }
745 
746         const char* typeA = command.GetArgumentAtIndex(0);
747         ConstString typeCS(typeA);
748 
749         if(!typeCS)
750         {
751             result.AppendError("empty typenames not allowed");
752             result.SetStatus(eReturnStatusFailed);
753             return false;
754         }
755 
756         bool delete_summary = Debugger::SummaryFormats::Delete(typeCS);
757         bool delete_regex = Debugger::RegexSummaryFormats::Delete(typeCS);
758         bool delete_named = Debugger::NamedSummaryFormats::Delete(typeCS);
759 
760         if (delete_summary || delete_regex || delete_named)
761         {
762             result.SetStatus(eReturnStatusSuccessFinishNoResult);
763             return result.Succeeded();
764         }
765         else
766         {
767             result.AppendErrorWithFormat ("no custom summary for %s.\n", typeA);
768             result.SetStatus(eReturnStatusFailed);
769             return false;
770         }
771 
772     }
773 
774 };
775 
776 //-------------------------------------------------------------------------
777 // CommandObjectTypeSummaryClear
778 //-------------------------------------------------------------------------
779 
780 class CommandObjectTypeSummaryClear : public CommandObject
781 {
782 public:
783     CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) :
784     CommandObject (interpreter,
785                    "type summary clear",
786                    "Delete all existing summary styles.",
787                    NULL)
788     {
789     }
790 
791     ~CommandObjectTypeSummaryClear ()
792     {
793     }
794 
795     bool
796     Execute (Args& command, CommandReturnObject &result)
797     {
798         Debugger::SummaryFormats::Clear();
799         Debugger::RegexSummaryFormats::Clear();
800         Debugger::NamedSummaryFormats::Clear();
801         result.SetStatus(eReturnStatusSuccessFinishResult);
802         return result.Succeeded();
803     }
804 
805 };
806 
807 //-------------------------------------------------------------------------
808 // CommandObjectTypeSummaryList
809 //-------------------------------------------------------------------------
810 
811 bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry);
812 bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SummaryFormat::SharedPointer& entry);
813 
814 class CommandObjectTypeSummaryList;
815 
816 struct CommandObjectTypeSummaryList_LoopCallbackParam {
817     CommandObjectTypeSummaryList* self;
818     CommandReturnObject* result;
819     RegularExpression* regex;
820     CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R,
821                                                   RegularExpression* X = NULL) : self(S), result(R), regex(X) {}
822 };
823 
824 struct CommandObjectTypeRXSummaryList_LoopCallbackParam {
825     CommandObjectTypeSummaryList* self;
826     CommandReturnObject* result;
827     RegularExpression* regex;
828     CommandObjectTypeRXSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R,
829                                                    RegularExpression* X = NULL) : self(S), result(R), regex(X) {}
830 };
831 
832 class CommandObjectTypeSummaryList : public CommandObject
833 {
834 public:
835     CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :
836     CommandObject (interpreter,
837                    "type summary list",
838                    "Show a list of current summary styles.",
839                    NULL)
840     {
841         CommandArgumentEntry type_arg;
842         CommandArgumentData type_style_arg;
843 
844         type_style_arg.arg_type = eArgTypeName;
845         type_style_arg.arg_repetition = eArgRepeatOptional;
846 
847         type_arg.push_back (type_style_arg);
848 
849         m_arguments.push_back (type_arg);
850     }
851 
852     ~CommandObjectTypeSummaryList ()
853     {
854     }
855 
856     bool
857     Execute (Args& command, CommandReturnObject &result)
858     {
859         const size_t argc = command.GetArgumentCount();
860 
861         CommandObjectTypeSummaryList_LoopCallbackParam *param;
862         CommandObjectTypeRXSummaryList_LoopCallbackParam *rxparam;
863 
864         if (argc == 1) {
865             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
866             regex->Compile(command.GetArgumentAtIndex(0));
867             param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex);
868         }
869         else
870             param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);
871         Debugger::SummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
872         delete param;
873 
874         if(Debugger::RegexSummaryFormats::GetCount() > 0)
875         {
876             result.GetOutputStream().Printf("Regex-based summaries (slower):\n");
877             if (argc == 1) {
878                 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
879                 regex->Compile(command.GetArgumentAtIndex(0));
880                 rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result,regex);
881             }
882             else
883                 rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result);
884             Debugger::RegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam);
885             delete rxparam;
886         }
887 
888         if(Debugger::NamedSummaryFormats::GetCount() > 0)
889         {
890             result.GetOutputStream().Printf("Named summaries:\n");
891             if (argc == 1) {
892                 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
893                 regex->Compile(command.GetArgumentAtIndex(0));
894                 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex);
895             }
896             else
897                 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);
898             Debugger::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
899             delete param;
900         }
901 
902         result.SetStatus(eReturnStatusSuccessFinishResult);
903         return result.Succeeded();
904     }
905 
906 private:
907 
908     bool
909     LoopCallback (const char* type,
910                   const SummaryFormat::SharedPointer& entry,
911                   RegularExpression* regex,
912                   CommandReturnObject *result)
913     {
914         if (regex == NULL || regex->Execute(type))
915         {
916                 result->GetOutputStream().Printf ("%s: `%s`%s%s%s%s%s%s\n", type,
917                                                   entry->m_format.c_str(),
918                                                   entry->m_cascades ? "" : " (not cascading)",
919                                                   entry->m_dont_show_children ? "" : " (show children)",
920                                                   entry->m_dont_show_value ? " (hide value)" : "",
921                                                   entry->m_show_members_oneliner ? " (one-line printout)" : "",
922                                                   entry->m_skip_pointers ? " (skip pointers)" : "",
923                                                   entry->m_skip_references ? " (skip references)" : "");
924         }
925         return true;
926     }
927 
928     friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry);
929     friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SummaryFormat::SharedPointer& entry);
930 
931 };
932 
933 bool
934 CommandObjectTypeSummaryList_LoopCallback (
935                                           void* pt2self,
936                                           const char* type,
937                                           const SummaryFormat::SharedPointer& entry)
938 {
939     CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;
940     return param->self->LoopCallback(type, entry, param->regex, param->result);
941 }
942 
943 bool
944 CommandObjectTypeRXSummaryList_LoopCallback (
945                                            void* pt2self,
946                                            lldb::RegularExpressionSP regex,
947                                            const SummaryFormat::SharedPointer& entry)
948 {
949     CommandObjectTypeRXSummaryList_LoopCallbackParam* param = (CommandObjectTypeRXSummaryList_LoopCallbackParam*)pt2self;
950     return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
951 }
952 
953 
954 
955 
956 class CommandObjectTypeFormat : public CommandObjectMultiword
957 {
958 public:
959     CommandObjectTypeFormat (CommandInterpreter &interpreter) :
960         CommandObjectMultiword (interpreter,
961                                 "type format",
962                                 "A set of commands for editing variable value display options",
963                                 "type format [<sub-command-options>] ")
964     {
965         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter)));
966         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectTypeFormatClear (interpreter)));
967         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter)));
968         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectTypeFormatList (interpreter)));
969     }
970 
971 
972     ~CommandObjectTypeFormat ()
973     {
974     }
975 };
976 
977 class CommandObjectTypeSummary : public CommandObjectMultiword
978 {
979 public:
980     CommandObjectTypeSummary (CommandInterpreter &interpreter) :
981     CommandObjectMultiword (interpreter,
982                             "type summary",
983                             "A set of commands for editing variable summary display options",
984                             "type summary [<sub-command-options>] ")
985     {
986         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter)));
987         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter)));
988         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter)));
989         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectTypeSummaryList (interpreter)));
990     }
991 
992 
993     ~CommandObjectTypeSummary ()
994     {
995     }
996 };
997 
998 //-------------------------------------------------------------------------
999 // CommandObjectType
1000 //-------------------------------------------------------------------------
1001 
1002 CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) :
1003     CommandObjectMultiword (interpreter,
1004                             "type",
1005                             "A set of commands for operating on the type system",
1006                             "type [<sub-command-options>]")
1007 {
1008     LoadSubCommand ("format",    CommandObjectSP (new CommandObjectTypeFormat (interpreter)));
1009     LoadSubCommand ("summary",   CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
1010 }
1011 
1012 
1013 CommandObjectType::~CommandObjectType ()
1014 {
1015 }
1016 
1017 
1018