]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectType.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / source / Commands / CommandObjectType.cpp
1 //===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/lldb-python.h"
11
12 #include "CommandObjectType.h"
13
14 // C Includes
15
16 #include <ctype.h>
17
18 // C++ Includes
19
20 #include "lldb/Core/ConstString.h"
21 #include "lldb/Core/Debugger.h"
22 #include "lldb/Core/InputReaderEZ.h"
23 #include "lldb/Core/RegularExpression.h"
24 #include "lldb/Core/State.h"
25 #include "lldb/Core/StringList.h"
26 #include "lldb/DataFormatters/DataVisualization.h"
27 #include "lldb/Interpreter/CommandInterpreter.h"
28 #include "lldb/Interpreter/CommandObject.h"
29 #include "lldb/Interpreter/CommandReturnObject.h"
30 #include "lldb/Interpreter/Options.h"
31 #include "lldb/Interpreter/OptionGroupFormat.h"
32
33 using namespace lldb;
34 using namespace lldb_private;
35
36
37 class ScriptAddOptions
38 {
39     
40 public:
41     
42     TypeSummaryImpl::Flags m_flags;
43     
44     StringList m_target_types;
45     StringList m_user_source;
46     
47     bool m_regex;
48         
49     ConstString m_name;
50     
51     std::string m_category;
52     
53     ScriptAddOptions(const TypeSummaryImpl::Flags& flags,
54                      bool regx,
55                      const ConstString& name,
56                      std::string catg) :
57         m_flags(flags),
58         m_regex(regx),
59         m_name(name),
60         m_category(catg)
61     {
62     }
63     
64     typedef std::shared_ptr<ScriptAddOptions> SharedPointer;
65     
66 };
67
68 class SynthAddOptions
69 {
70     
71 public:
72     
73     bool m_skip_pointers;
74     bool m_skip_references;
75     bool m_cascade;
76     bool m_regex;
77     StringList m_user_source;
78     StringList m_target_types;
79     
80     std::string m_category;
81     
82     SynthAddOptions(bool sptr,
83                     bool sref,
84                     bool casc,
85                     bool regx,
86                     std::string catg) :
87     m_skip_pointers(sptr),
88     m_skip_references(sref),
89     m_cascade(casc),
90     m_regex(regx),
91     m_user_source(),
92     m_target_types(),
93     m_category(catg)
94     {
95     }
96     
97     typedef std::shared_ptr<SynthAddOptions> SharedPointer;
98     
99 };
100
101
102
103 class CommandObjectTypeSummaryAdd : public CommandObjectParsed
104 {
105     
106 private:
107     
108     class CommandOptions : public Options
109     {
110     public:
111         
112         CommandOptions (CommandInterpreter &interpreter) :
113         Options (interpreter)
114         {
115         }
116         
117         virtual
118         ~CommandOptions (){}
119         
120         virtual Error
121         SetOptionValue (uint32_t option_idx, const char *option_arg);
122         
123         void
124         OptionParsingStarting ();
125         
126         const OptionDefinition*
127         GetDefinitions ()
128         {
129             return g_option_table;
130         }
131         
132         // Options table: Required for subclasses of Options.
133         
134         static OptionDefinition g_option_table[];
135         
136         // Instance variables to hold the values for command options.
137         
138         TypeSummaryImpl::Flags m_flags;
139         bool m_regex;
140         std::string m_format_string;
141         ConstString m_name;
142         std::string m_python_script;
143         std::string m_python_function;
144         bool m_is_add_script;
145         std::string m_category;
146     };
147     
148     CommandOptions m_options;
149     
150     virtual Options *
151     GetOptions ()
152     {
153         return &m_options;
154     }
155     
156     void
157     CollectPythonScript(ScriptAddOptions *options,
158                         CommandReturnObject &result);
159     
160     bool
161     Execute_ScriptSummary (Args& command, CommandReturnObject &result);
162     
163     bool
164     Execute_StringSummary (Args& command, CommandReturnObject &result);
165     
166 public:
167     
168     enum SummaryFormatType
169     {
170         eRegularSummary,
171         eRegexSummary,
172         eNamedSummary
173     };
174     
175     CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter);
176     
177     ~CommandObjectTypeSummaryAdd ()
178     {
179     }
180     
181     static bool
182     AddSummary(ConstString type_name,
183                lldb::TypeSummaryImplSP entry,
184                SummaryFormatType type,
185                std::string category,
186                Error* error = NULL);
187 protected:
188     bool
189     DoExecute (Args& command, CommandReturnObject &result);
190     
191 };
192
193 class CommandObjectTypeSynthAdd : public CommandObjectParsed
194 {
195     
196 private:
197     
198     class CommandOptions : public Options
199     {
200     public:
201         
202         CommandOptions (CommandInterpreter &interpreter) :
203         Options (interpreter)
204         {
205         }
206         
207         virtual
208         ~CommandOptions (){}
209         
210         virtual Error
211         SetOptionValue (uint32_t option_idx, const char *option_arg)
212         {
213             Error error;
214             const int short_option = m_getopt_table[option_idx].val;
215             bool success;
216             
217             switch (short_option)
218             {
219                 case 'C':
220                     m_cascade = Args::StringToBoolean(option_arg, true, &success);
221                     if (!success)
222                         error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
223                     break;
224                 case 'P':
225                     handwrite_python = true;
226                     break;
227                 case 'l':
228                     m_class_name = std::string(option_arg);
229                     is_class_based = true;
230                     break;
231                 case 'p':
232                     m_skip_pointers = true;
233                     break;
234                 case 'r':
235                     m_skip_references = true;
236                     break;
237                 case 'w':
238                     m_category = std::string(option_arg);
239                     break;
240                 case 'x':
241                     m_regex = true;
242                     break;
243                 default:
244                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
245                     break;
246             }
247             
248             return error;
249         }
250         
251         void
252         OptionParsingStarting ()
253         {
254             m_cascade = true;
255             m_class_name = "";
256             m_skip_pointers = false;
257             m_skip_references = false;
258             m_category = "default";
259             is_class_based = false;
260             handwrite_python = false;
261             m_regex = false;
262         }
263         
264         const OptionDefinition*
265         GetDefinitions ()
266         {
267             return g_option_table;
268         }
269         
270         // Options table: Required for subclasses of Options.
271         
272         static OptionDefinition g_option_table[];
273         
274         // Instance variables to hold the values for command options.
275         
276         bool m_cascade;
277         bool m_skip_references;
278         bool m_skip_pointers;
279         std::string m_class_name;
280         bool m_input_python;
281         std::string m_category;
282         
283         bool is_class_based;
284         
285         bool handwrite_python;
286         
287         bool m_regex;
288         
289     };
290     
291     CommandOptions m_options;
292     
293     virtual Options *
294     GetOptions ()
295     {
296         return &m_options;
297     }
298     
299     void
300     CollectPythonScript (SynthAddOptions *options,
301                          CommandReturnObject &result);    
302     bool
303     Execute_HandwritePython (Args& command, CommandReturnObject &result);
304     
305     bool
306     Execute_PythonClass (Args& command, CommandReturnObject &result);
307     
308 protected:
309     bool
310     DoExecute (Args& command, CommandReturnObject &result);
311     
312 public:
313     
314     enum SynthFormatType
315     {
316         eRegularSynth,
317         eRegexSynth
318     };
319     
320     CommandObjectTypeSynthAdd (CommandInterpreter &interpreter);
321     
322     ~CommandObjectTypeSynthAdd ()
323     {
324     }
325     
326     static bool
327     AddSynth(ConstString type_name,
328              lldb::SyntheticChildrenSP entry,
329              SynthFormatType type,
330              std::string category_name,
331              Error* error);
332 };
333
334 //-------------------------------------------------------------------------
335 // CommandObjectTypeFormatAdd
336 //-------------------------------------------------------------------------
337
338 class CommandObjectTypeFormatAdd : public CommandObjectParsed
339 {
340     
341 private:
342     
343     class CommandOptions : public OptionGroup
344     {
345     public:
346         
347         CommandOptions () :
348             OptionGroup()
349         {
350         }
351         
352         virtual
353         ~CommandOptions ()
354         {
355         }
356         
357         virtual uint32_t
358         GetNumDefinitions ();
359         
360         virtual const OptionDefinition*
361         GetDefinitions ()
362         {
363             return g_option_table;
364         }
365         
366         virtual void
367         OptionParsingStarting (CommandInterpreter &interpreter)
368         {
369             m_cascade = true;
370             m_skip_pointers = false;
371             m_skip_references = false;
372         }
373         virtual Error
374         SetOptionValue (CommandInterpreter &interpreter,
375                         uint32_t option_idx,
376                         const char *option_value)
377         {
378             Error error;
379             const int short_option = g_option_table[option_idx].short_option;
380             bool success;
381             
382             switch (short_option)
383             {
384                 case 'C':
385                     m_cascade = Args::StringToBoolean(option_value, true, &success);
386                     if (!success)
387                         error.SetErrorStringWithFormat("invalid value for cascade: %s", option_value);
388                     break;
389                 case 'p':
390                     m_skip_pointers = true;
391                     break;
392                 case 'r':
393                     m_skip_references = true;
394                     break;
395                 default:
396                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
397                     break;
398             }
399             
400             return error;
401         }
402         
403         // Options table: Required for subclasses of Options.
404         
405         static OptionDefinition g_option_table[];
406         
407         // Instance variables to hold the values for command options.
408         
409         bool m_cascade;
410         bool m_skip_references;
411         bool m_skip_pointers;
412     };
413     
414     OptionGroupOptions m_option_group;
415     OptionGroupFormat m_format_options;
416     CommandOptions m_command_options;
417     
418     virtual Options *
419     GetOptions ()
420     {
421         return &m_option_group;
422     }
423     
424 public:
425     CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) :
426         CommandObjectParsed (interpreter,
427                              "type format add",
428                              "Add a new formatting style for a type.",
429                              NULL), 
430         m_option_group (interpreter),
431         m_format_options (eFormatInvalid),
432         m_command_options ()
433     {
434         CommandArgumentEntry type_arg;
435         CommandArgumentData type_style_arg;
436         
437         type_style_arg.arg_type = eArgTypeName;
438         type_style_arg.arg_repetition = eArgRepeatPlus;
439         
440         type_arg.push_back (type_style_arg);
441
442         m_arguments.push_back (type_arg);
443         
444         SetHelpLong(
445                     "Some examples of using this command.\n"
446                     "We use as reference the following snippet of code:\n"
447                     "\n"
448                     "typedef int Aint;\n"
449                     "typedef float Afloat;\n"
450                     "typedef Aint Bint;\n"
451                     "typedef Afloat Bfloat;\n"
452                     "\n"
453                     "Aint ix = 5;\n"
454                     "Bint iy = 5;\n"
455                     "\n"
456                     "Afloat fx = 3.14;\n"
457                     "BFloat fy = 3.14;\n"
458                     "\n"
459                     "Typing:\n"
460                     "type format add -f hex AInt\n"
461                     "frame variable iy\n"
462                     "will produce an hex display of iy, because no formatter is available for Bint and the one for Aint is used instead\n"
463                     "To prevent this type\n"
464                     "type format add -f hex -C no AInt\n"
465                     "\n"
466                     "A similar reasoning applies to\n"
467                     "type format add -f hex -C no float -p\n"
468                     "which now prints all floats and float&s as hexadecimal, but does not format float*s\n"
469                     "and does not change the default display for Afloat and Bfloat objects.\n"
470                     );
471     
472         // Add the "--format" to all options groups
473         m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_ALL);
474         m_option_group.Append (&m_command_options);
475         m_option_group.Finalize();
476
477     }
478     
479     ~CommandObjectTypeFormatAdd ()
480     {
481     }
482     
483 protected:
484     bool
485     DoExecute (Args& command, CommandReturnObject &result)
486     {
487         const size_t argc = command.GetArgumentCount();
488         
489         if (argc < 1)
490         {
491             result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
492             result.SetStatus(eReturnStatusFailed);
493             return false;
494         }
495         
496         const Format format = m_format_options.GetFormat();
497         if (format == eFormatInvalid)
498         {
499             result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
500             result.SetStatus(eReturnStatusFailed);
501             return false;
502         }
503         
504         TypeFormatImplSP entry;
505         
506         entry.reset(new TypeFormatImpl(format,
507                                     TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
508                                     SetSkipPointers(m_command_options.m_skip_pointers).
509                                     SetSkipReferences(m_command_options.m_skip_references)));
510
511         // now I have a valid format, let's add it to every type
512         
513         for (size_t i = 0; i < argc; i++)
514         {
515             const char* typeA = command.GetArgumentAtIndex(i);
516             ConstString typeCS(typeA);
517             if (typeCS)
518                 DataVisualization::ValueFormats::Add(typeCS, entry);
519             else
520             {
521                 result.AppendError("empty typenames not allowed");
522                 result.SetStatus(eReturnStatusFailed);
523                 return false;
524             }
525         }
526         
527         result.SetStatus(eReturnStatusSuccessFinishNoResult);
528         return result.Succeeded();
529     }
530 };
531
532 OptionDefinition
533 CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
534 {
535     { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
536     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
537     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
538 };
539
540
541 uint32_t
542 CommandObjectTypeFormatAdd::CommandOptions::GetNumDefinitions ()
543 {
544     return sizeof(g_option_table) / sizeof (OptionDefinition);
545 }
546
547
548 //-------------------------------------------------------------------------
549 // CommandObjectTypeFormatDelete
550 //-------------------------------------------------------------------------
551
552 class CommandObjectTypeFormatDelete : public CommandObjectParsed
553 {
554 public:
555     CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) :
556         CommandObjectParsed (interpreter,
557                              "type format delete",
558                              "Delete an existing formatting style for a type.",
559                              NULL)
560     {
561         CommandArgumentEntry type_arg;
562         CommandArgumentData type_style_arg;
563         
564         type_style_arg.arg_type = eArgTypeName;
565         type_style_arg.arg_repetition = eArgRepeatPlain;
566         
567         type_arg.push_back (type_style_arg);
568         
569         m_arguments.push_back (type_arg);
570         
571     }
572     
573     ~CommandObjectTypeFormatDelete ()
574     {
575     }
576     
577 protected:
578     bool
579     DoExecute (Args& command, CommandReturnObject &result)
580     {
581         const size_t argc = command.GetArgumentCount();
582         
583         if (argc != 1)
584         {
585             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
586             result.SetStatus(eReturnStatusFailed);
587             return false;
588         }
589         
590         const char* typeA = command.GetArgumentAtIndex(0);
591         ConstString typeCS(typeA);
592         
593         if (!typeCS)
594         {
595             result.AppendError("empty typenames not allowed");
596             result.SetStatus(eReturnStatusFailed);
597             return false;
598         }
599         
600         
601         if (DataVisualization::ValueFormats::Delete(typeCS))
602         {
603             result.SetStatus(eReturnStatusSuccessFinishNoResult);
604             return result.Succeeded();
605         }
606         else
607         {
608             result.AppendErrorWithFormat ("no custom format for %s.\n", typeA);
609             result.SetStatus(eReturnStatusFailed);
610             return false;
611         }
612         
613     }
614     
615 };
616
617 //-------------------------------------------------------------------------
618 // CommandObjectTypeFormatClear
619 //-------------------------------------------------------------------------
620
621 class CommandObjectTypeFormatClear : public CommandObjectParsed
622 {
623 public:
624     CommandObjectTypeFormatClear (CommandInterpreter &interpreter) :
625         CommandObjectParsed (interpreter,
626                              "type format clear",
627                              "Delete all existing format styles.",
628                              NULL)
629     {
630     }
631     
632     ~CommandObjectTypeFormatClear ()
633     {
634     }
635     
636 protected:
637     bool
638     DoExecute (Args& command, CommandReturnObject &result)
639     {
640         DataVisualization::ValueFormats::Clear();
641         result.SetStatus(eReturnStatusSuccessFinishResult);
642         return result.Succeeded();
643     }
644     
645 };
646
647 //-------------------------------------------------------------------------
648 // CommandObjectTypeFormatList
649 //-------------------------------------------------------------------------
650
651 bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);
652
653 class CommandObjectTypeFormatList;
654
655 struct CommandObjectTypeFormatList_LoopCallbackParam {
656     CommandObjectTypeFormatList* self;
657     CommandReturnObject* result;
658     RegularExpression* regex;
659     CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R,
660                                             RegularExpression* X = NULL) : self(S), result(R), regex(X) {}
661 };
662
663 class CommandObjectTypeFormatList : public CommandObjectParsed
664 {
665 public:
666     CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
667         CommandObjectParsed (interpreter,
668                              "type format list",
669                              "Show a list of current formatting styles.",
670                              NULL)
671     {
672         CommandArgumentEntry type_arg;
673         CommandArgumentData type_style_arg;
674         
675         type_style_arg.arg_type = eArgTypeName;
676         type_style_arg.arg_repetition = eArgRepeatOptional;
677         
678         type_arg.push_back (type_style_arg);
679         
680         m_arguments.push_back (type_arg);
681     }
682     
683     ~CommandObjectTypeFormatList ()
684     {
685     }
686     
687 protected:
688     bool
689     DoExecute (Args& command, CommandReturnObject &result)
690     {
691         const size_t argc = command.GetArgumentCount();
692         
693         CommandObjectTypeFormatList_LoopCallbackParam *param;
694         
695         if (argc == 1)
696         {
697             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
698             regex->Compile(command.GetArgumentAtIndex(0));
699             param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex);
700         }
701         else
702             param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result);
703         DataVisualization::ValueFormats::LoopThrough(CommandObjectTypeFormatList_LoopCallback, param);
704         delete param;
705         result.SetStatus(eReturnStatusSuccessFinishResult);
706         return result.Succeeded();
707     }
708     
709 private:
710     
711     bool
712     LoopCallback (ConstString type,
713                   const lldb::TypeFormatImplSP& entry,
714                   RegularExpression* regex,
715                   CommandReturnObject *result)
716     {
717         if (regex == NULL || regex->Execute(type.AsCString())) 
718         {
719             result->GetOutputStream().Printf ("%s: %s\n", type.AsCString(), 
720                                               entry->GetDescription().c_str());
721         }
722         return true;
723     }
724     
725     friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);
726     
727 };
728
729 bool
730 CommandObjectTypeFormatList_LoopCallback (
731                                     void* pt2self,
732                                     ConstString type,
733                                     const lldb::TypeFormatImplSP& entry)
734 {
735     CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;
736     return param->self->LoopCallback(type, entry, param->regex, param->result);
737 }
738
739
740 #ifndef LLDB_DISABLE_PYTHON
741
742 //-------------------------------------------------------------------------
743 // CommandObjectTypeSummaryAdd
744 //-------------------------------------------------------------------------
745
746 static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
747                                                        "def function (valobj,internal_dict):\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:
756     TypeScriptAddInputReader(Debugger& debugger) : 
757     InputReaderEZ(debugger)
758     {}
759     
760     virtual
761     ~TypeScriptAddInputReader()
762     {
763     }
764     
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     
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     }
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     }
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     }
813     virtual void EOFHandler(HandlerData& data)
814     {
815         data.reader.SetIsDone (true);
816     }
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
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
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
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
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
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
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
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
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         
1427         CommandOptions (CommandInterpreter &interpreter) :
1428         Options (interpreter)
1429         {
1430         }
1431         
1432         virtual
1433         ~CommandOptions (){}
1434         
1435         virtual Error
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
1458         OptionParsingStarting ()
1459         {
1460             m_delete_all = false;
1461             m_category = "default";
1462         }
1463         
1464         const OptionDefinition*
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 *
1484     GetOptions ()
1485     {
1486         return &m_options;
1487     }
1488     
1489     static bool
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:
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     
1518     ~CommandObjectTypeSummaryDelete ()
1519     {
1520     }
1521     
1522 protected:
1523     bool
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         
1590         CommandOptions (CommandInterpreter &interpreter) :
1591         Options (interpreter)
1592         {
1593         }
1594         
1595         virtual
1596         ~CommandOptions (){}
1597         
1598         virtual Error
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
1618         OptionParsingStarting ()
1619         {
1620             m_delete_all = false;
1621         }
1622         
1623         const OptionDefinition*
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 *
1642     GetOptions ()
1643     {
1644         return &m_options;
1645     }
1646     
1647     static bool
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:
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     
1667     ~CommandObjectTypeSummaryClear ()
1668     {
1669     }
1670     
1671 protected:
1672     bool
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;
1722     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         
1734         CommandOptions (CommandInterpreter &interpreter) :
1735         Options (interpreter)
1736         {
1737         }
1738         
1739         virtual
1740         ~CommandOptions (){}
1741         
1742         virtual Error
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
1762         OptionParsingStarting ()
1763         {
1764             m_category_regex = "";
1765         }
1766         
1767         const OptionDefinition*
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 *
1786     GetOptions ()
1787     {
1788         return &m_options;
1789     }
1790     
1791 public:
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     
1810     ~CommandObjectTypeSummaryList ()
1811     {
1812     }
1813     
1814 protected:
1815     bool
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
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
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
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
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:
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     
1961     ~CommandObjectTypeCategoryEnable ()
1962     {
1963     }
1964     
1965 protected:
1966     bool
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:
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     
2053     ~CommandObjectTypeCategoryDelete ()
2054     {
2055     }
2056     
2057 protected:
2058     bool
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:
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     
2126     ~CommandObjectTypeCategoryDisable ()
2127     {
2128     }
2129     
2130 protected:
2131     bool
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         
2191         CommandObjectTypeCategoryList_CallbackParam(CommandReturnObject* res,
2192                                                     RegularExpression* rex = NULL) :
2193         result(res),
2194         regex(rex)
2195         {
2196         }
2197         
2198     };
2199     
2200     static bool
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:
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     
2235     ~CommandObjectTypeCategoryList ()
2236     {
2237     }
2238     
2239 protected:
2240     bool
2241     DoExecute (Args& command, CommandReturnObject &result)
2242     {
2243         const size_t argc = command.GetArgumentCount();
2244         RegularExpression* regex = NULL;
2245         
2246         if (argc == 0)
2247             ;
2248         else if (argc == 1)
2249             regex = new RegularExpression(command.GetArgumentAtIndex(0));
2250         else
2251         {
2252             result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str());
2253             result.SetStatus(eReturnStatusFailed);
2254             return false;
2255         }
2256         
2257         CommandObjectTypeCategoryList_CallbackParam param(&result,
2258                                                           regex);
2259         
2260         DataVisualization::Categories::LoopThrough(PerCategoryCallback, &param);
2261         
2262         if (regex)
2263             delete regex;
2264         
2265         result.SetStatus(eReturnStatusSuccessFinishResult);
2266         return result.Succeeded();
2267     }
2268     
2269 };
2270
2271 //-------------------------------------------------------------------------
2272 // CommandObjectTypeFilterList
2273 //-------------------------------------------------------------------------
2274
2275 bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
2276 bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
2277
2278 class CommandObjectTypeFilterList;
2279
2280 struct CommandObjectTypeFilterList_LoopCallbackParam {
2281     CommandObjectTypeFilterList* self;
2282     CommandReturnObject* result;
2283     RegularExpression* regex;
2284     RegularExpression* cate_regex;
2285     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         
2297         CommandOptions (CommandInterpreter &interpreter) :
2298         Options (interpreter)
2299         {
2300         }
2301         
2302         virtual
2303         ~CommandOptions (){}
2304         
2305         virtual Error
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
2325         OptionParsingStarting ()
2326         {
2327             m_category_regex = "";
2328         }
2329         
2330         const OptionDefinition*
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 *
2349     GetOptions ()
2350     {
2351         return &m_options;
2352     }
2353     
2354 public:
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     
2373     ~CommandObjectTypeFilterList ()
2374     {
2375     }
2376     
2377 protected:
2378     bool
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
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
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
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
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;
2499     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         
2511         CommandOptions (CommandInterpreter &interpreter) :
2512         Options (interpreter)
2513         {
2514         }
2515         
2516         virtual
2517         ~CommandOptions (){}
2518         
2519         virtual Error
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
2539         OptionParsingStarting ()
2540         {
2541             m_category_regex = "";
2542         }
2543         
2544         const OptionDefinition*
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 *
2563     GetOptions ()
2564     {
2565         return &m_options;
2566     }
2567     
2568 public:
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     
2587     ~CommandObjectTypeSynthList ()
2588     {
2589     }
2590     
2591 protected:
2592     bool
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
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
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
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
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         
2709         CommandOptions (CommandInterpreter &interpreter) :
2710         Options (interpreter)
2711         {
2712         }
2713         
2714         virtual
2715         ~CommandOptions (){}
2716         
2717         virtual Error
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
2740         OptionParsingStarting ()
2741         {
2742             m_delete_all = false;
2743             m_category = "default";
2744         }
2745         
2746         const OptionDefinition*
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 *
2766     GetOptions ()
2767     {
2768         return &m_options;
2769     }
2770     
2771     static bool
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:
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     
2799     ~CommandObjectTypeFilterDelete ()
2800     {
2801     }
2802     
2803 protected:
2804     bool
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         
2875         CommandOptions (CommandInterpreter &interpreter) :
2876         Options (interpreter)
2877         {
2878         }
2879         
2880         virtual
2881         ~CommandOptions (){}
2882         
2883         virtual Error
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
2906         OptionParsingStarting ()
2907         {
2908             m_delete_all = false;
2909             m_category = "default";
2910         }
2911         
2912         const OptionDefinition*
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 *
2932     GetOptions ()
2933     {
2934         return &m_options;
2935     }
2936     
2937     static bool
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:
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     
2965     ~CommandObjectTypeSynthDelete ()
2966     {
2967     }
2968     
2969 protected:
2970     bool
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         
3042         CommandOptions (CommandInterpreter &interpreter) :
3043         Options (interpreter)
3044         {
3045         }
3046         
3047         virtual
3048         ~CommandOptions (){}
3049         
3050         virtual Error
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
3070         OptionParsingStarting ()
3071         {
3072             m_delete_all = false;
3073         }
3074         
3075         const OptionDefinition*
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 *
3094     GetOptions ()
3095     {
3096         return &m_options;
3097     }
3098     
3099     static bool
3100     PerCategoryCallback(void* param,
3101                         const lldb::TypeCategoryImplSP& cate)
3102     {
3103         cate->Clear(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter);
3104         return true;
3105         
3106     }
3107     
3108 public:
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     
3118     ~CommandObjectTypeFilterClear ()
3119     {
3120     }
3121     
3122 protected:
3123     bool
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         
3171         CommandOptions (CommandInterpreter &interpreter) :
3172         Options (interpreter)
3173         {
3174         }
3175         
3176         virtual
3177         ~CommandOptions (){}
3178         
3179         virtual Error
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
3199         OptionParsingStarting ()
3200         {
3201             m_delete_all = false;
3202         }
3203         
3204         const OptionDefinition*
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 *
3223     GetOptions ()
3224     {
3225         return &m_options;
3226     }
3227     
3228     static bool
3229     PerCategoryCallback(void* param,
3230                         const lldb::TypeCategoryImplSP& cate)
3231     {
3232         cate->Clear(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth);
3233         return true;
3234         
3235     }
3236     
3237 public:
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     
3247     ~CommandObjectTypeSynthClear ()
3248     {
3249     }
3250     
3251 protected:
3252     bool
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:
3306     TypeSynthAddInputReader(Debugger& debugger) : 
3307         InputReaderEZ(debugger)
3308     {}
3309     
3310     virtual
3311     ~TypeSynthAddInputReader()
3312     {
3313     }
3314     
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     
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     }
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     }
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     }
3363     virtual void EOFHandler(HandlerData& data)
3364     {
3365         data.reader.SetIsDone (true);
3366     }
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
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
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
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     
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
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
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         
3688         CommandOptions (CommandInterpreter &interpreter) :
3689         Options (interpreter)
3690         {
3691         }
3692         
3693         virtual
3694         ~CommandOptions (){}
3695         
3696         virtual Error
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
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*
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 *
3775     GetOptions ()
3776     {
3777         return &m_options;
3778     }
3779     
3780     enum FilterFormatType
3781     {
3782         eRegularFilter,
3783         eRegexFilter
3784     };
3785     
3786     bool
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     
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     
3890     ~CommandObjectTypeFilterAdd ()
3891     {
3892     }
3893     
3894 protected:
3895     bool
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:
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
3995     ~CommandObjectTypeFormat ()
3996     {
3997     }
3998 };
3999
4000 #ifndef LLDB_DISABLE_PYTHON
4001
4002 class CommandObjectTypeSynth : public CommandObjectMultiword
4003 {
4004 public:
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     
4018     ~CommandObjectTypeSynth ()
4019     {
4020     }
4021 };
4022
4023 #endif // #ifndef LLDB_DISABLE_PYTHON
4024
4025 class CommandObjectTypeFilter : public CommandObjectMultiword
4026 {
4027 public:
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     
4041     ~CommandObjectTypeFilter ()
4042     {
4043     }
4044 };
4045
4046 class CommandObjectTypeCategory : public CommandObjectMultiword
4047 {
4048 public:
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     
4062     ~CommandObjectTypeCategory ()
4063     {
4064     }
4065 };
4066
4067 class CommandObjectTypeSummary : public CommandObjectMultiword
4068 {
4069 public:
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     
4083     ~CommandObjectTypeSummary ()
4084     {
4085     }
4086 };
4087
4088 //-------------------------------------------------------------------------
4089 // CommandObjectType
4090 //-------------------------------------------------------------------------
4091
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
4108 CommandObjectType::~CommandObjectType ()
4109 {
4110 }
4111
4112