130fdc8d8SChris Lattner //===-- CommandObjectLog.cpp ------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "CommandObjectLog.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
1630fdc8d8SChris Lattner #include "lldb/lldb-private-log.h"
1730fdc8d8SChris Lattner 
1840af72e1SJim Ingham #include "lldb/Interpreter/Args.h"
1930fdc8d8SChris Lattner #include "lldb/Core/Debugger.h"
2053239f00SGreg Clayton #include "lldb/Host/FileSpec.h"
2130fdc8d8SChris Lattner #include "lldb/Core/Log.h"
2230fdc8d8SChris Lattner #include "lldb/Core/Module.h"
2340af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
2430fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
2530fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
2630fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
2730fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
2830fdc8d8SChris Lattner 
296611103cSGreg Clayton #include "lldb/Core/Debugger.h"
304be3990fSSean Callanan #include "lldb/Interpreter/CommandInterpreter.h"
3130fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
3230fdc8d8SChris Lattner 
3330fdc8d8SChris Lattner #include "lldb/Symbol/LineTable.h"
3430fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
3530fdc8d8SChris Lattner #include "lldb/Symbol/SymbolFile.h"
3630fdc8d8SChris Lattner #include "lldb/Symbol/SymbolVendor.h"
3730fdc8d8SChris Lattner 
3830fdc8d8SChris Lattner #include "lldb/Target/Process.h"
3930fdc8d8SChris Lattner #include "lldb/Target/Target.h"
4030fdc8d8SChris Lattner 
4130fdc8d8SChris Lattner using namespace lldb;
4230fdc8d8SChris Lattner using namespace lldb_private;
4330fdc8d8SChris Lattner 
4430fdc8d8SChris Lattner 
4530fdc8d8SChris Lattner class CommandObjectLogEnable : public CommandObject
4630fdc8d8SChris Lattner {
4730fdc8d8SChris Lattner public:
4830fdc8d8SChris Lattner     //------------------------------------------------------------------
4930fdc8d8SChris Lattner     // Constructors and Destructors
5030fdc8d8SChris Lattner     //------------------------------------------------------------------
51a7015092SGreg Clayton     CommandObjectLogEnable(CommandInterpreter &interpreter) :
52a7015092SGreg Clayton         CommandObject (interpreter,
53a7015092SGreg Clayton                        "log enable",
5430fdc8d8SChris Lattner                        "Enable logging for a single log channel.",
55eb0103f2SGreg Clayton                         NULL),
56eb0103f2SGreg Clayton         m_options (interpreter)
5730fdc8d8SChris Lattner     {
58ceb6b139SCaroline Tice 
59ceb6b139SCaroline Tice         CommandArgumentEntry arg1;
60ceb6b139SCaroline Tice         CommandArgumentEntry arg2;
61405fe67fSCaroline Tice         CommandArgumentData channel_arg;
62ceb6b139SCaroline Tice         CommandArgumentData category_arg;
63405fe67fSCaroline Tice 
64405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
65405fe67fSCaroline Tice         channel_arg.arg_type = eArgTypeLogChannel;
66405fe67fSCaroline Tice         channel_arg.arg_repetition = eArgRepeatPlain;
67405fe67fSCaroline Tice 
68405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
69ceb6b139SCaroline Tice         arg1.push_back (channel_arg);
70ceb6b139SCaroline Tice 
71ceb6b139SCaroline Tice         category_arg.arg_type = eArgTypeLogCategory;
72ceb6b139SCaroline Tice         category_arg.arg_repetition = eArgRepeatPlus;
73ceb6b139SCaroline Tice 
74ceb6b139SCaroline Tice         arg2.push_back (category_arg);
75405fe67fSCaroline Tice 
76405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
77ceb6b139SCaroline Tice         m_arguments.push_back (arg1);
78ceb6b139SCaroline Tice         m_arguments.push_back (arg2);
7930fdc8d8SChris Lattner     }
8030fdc8d8SChris Lattner 
8130fdc8d8SChris Lattner     virtual
8230fdc8d8SChris Lattner     ~CommandObjectLogEnable()
8330fdc8d8SChris Lattner     {
8430fdc8d8SChris Lattner     }
8530fdc8d8SChris Lattner 
8630fdc8d8SChris Lattner     Options *
8730fdc8d8SChris Lattner     GetOptions ()
8830fdc8d8SChris Lattner     {
8930fdc8d8SChris Lattner         return &m_options;
9030fdc8d8SChris Lattner     }
9130fdc8d8SChris Lattner 
92ab65b34fSGreg Clayton //    int
93ab65b34fSGreg Clayton //    HandleArgumentCompletion (Args &input,
94ab65b34fSGreg Clayton //                              int &cursor_index,
95ab65b34fSGreg Clayton //                              int &cursor_char_position,
96ab65b34fSGreg Clayton //                              OptionElementVector &opt_element_vector,
97ab65b34fSGreg Clayton //                              int match_start_point,
98ab65b34fSGreg Clayton //                              int max_return_elements,
99ab65b34fSGreg Clayton //                              bool &word_complete,
100ab65b34fSGreg Clayton //                              StringList &matches)
101ab65b34fSGreg Clayton //    {
102ab65b34fSGreg Clayton //        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
103ab65b34fSGreg Clayton //        completion_str.erase (cursor_char_position);
104ab65b34fSGreg Clayton //
105ab65b34fSGreg Clayton //        if (cursor_index == 1)
106ab65b34fSGreg Clayton //        {
107ab65b34fSGreg Clayton //            //
108ab65b34fSGreg Clayton //            Log::AutoCompleteChannelName (completion_str.c_str(), matches);
109ab65b34fSGreg Clayton //        }
110ab65b34fSGreg Clayton //        return matches.GetSize();
111ab65b34fSGreg Clayton //    }
112ab65b34fSGreg Clayton //
11330fdc8d8SChris Lattner     virtual bool
114a7015092SGreg Clayton     Execute (Args& args,
11530fdc8d8SChris Lattner              CommandReturnObject &result)
11630fdc8d8SChris Lattner     {
11730fdc8d8SChris Lattner         if (args.GetArgumentCount() < 1)
11830fdc8d8SChris Lattner         {
119e3d26315SCaroline Tice             result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
12030fdc8d8SChris Lattner         }
12130fdc8d8SChris Lattner         else
12230fdc8d8SChris Lattner         {
12330fdc8d8SChris Lattner             Log::Callbacks log_callbacks;
12430fdc8d8SChris Lattner 
12530fdc8d8SChris Lattner             std::string channel(args.GetArgumentAtIndex(0));
12630fdc8d8SChris Lattner             args.Shift ();  // Shift off the channel
12730fdc8d8SChris Lattner             StreamSP log_stream_sp;
12830fdc8d8SChris Lattner             if (m_options.log_file.empty())
12930fdc8d8SChris Lattner             {
13051b1e2d2SGreg Clayton                 log_stream_sp.reset(new StreamFile(m_interpreter.GetDebugger().GetOutputFile().GetDescriptor(), false));
13130fdc8d8SChris Lattner             }
13230fdc8d8SChris Lattner             else
13330fdc8d8SChris Lattner             {
13430fdc8d8SChris Lattner                 LogStreamMap::iterator pos = m_log_streams.find(m_options.log_file);
13530fdc8d8SChris Lattner                 if (pos == m_log_streams.end())
13630fdc8d8SChris Lattner                 {
13751b1e2d2SGreg Clayton                     log_stream_sp.reset (new StreamFile (m_options.log_file.c_str()));
13830fdc8d8SChris Lattner                     m_log_streams[m_options.log_file] = log_stream_sp;
13930fdc8d8SChris Lattner                 }
14030fdc8d8SChris Lattner                 else
14130fdc8d8SChris Lattner                     log_stream_sp = pos->second;
14230fdc8d8SChris Lattner             }
14330fdc8d8SChris Lattner             assert (log_stream_sp.get());
1449f35921bSJim Ingham 
14530fdc8d8SChris Lattner             uint32_t log_options = m_options.log_options;
14630fdc8d8SChris Lattner             if (log_options == 0)
14730fdc8d8SChris Lattner                 log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
14830fdc8d8SChris Lattner             if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
14930fdc8d8SChris Lattner             {
15030fdc8d8SChris Lattner                 log_callbacks.enable (log_stream_sp, log_options, args, &result.GetErrorStream());
15130fdc8d8SChris Lattner                 result.SetStatus(eReturnStatusSuccessFinishNoResult);
15230fdc8d8SChris Lattner             }
15330fdc8d8SChris Lattner             else
15430fdc8d8SChris Lattner             {
155ab65b34fSGreg Clayton                 LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel.c_str()));
15630fdc8d8SChris Lattner                 if (log_channel_sp)
15730fdc8d8SChris Lattner                 {
15830fdc8d8SChris Lattner                     if (log_channel_sp->Enable (log_stream_sp, log_options, &result.GetErrorStream(), args))
15930fdc8d8SChris Lattner                     {
16030fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
16130fdc8d8SChris Lattner                     }
16230fdc8d8SChris Lattner                     else
16330fdc8d8SChris Lattner                     {
16430fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str());
16530fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
16630fdc8d8SChris Lattner                     }
16730fdc8d8SChris Lattner                 }
16830fdc8d8SChris Lattner                 else
16930fdc8d8SChris Lattner                 {
17030fdc8d8SChris Lattner                     result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str());
17130fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
17230fdc8d8SChris Lattner                 }
17330fdc8d8SChris Lattner             }
17430fdc8d8SChris Lattner         }
17530fdc8d8SChris Lattner         return result.Succeeded();
17630fdc8d8SChris Lattner     }
17730fdc8d8SChris Lattner 
17830fdc8d8SChris Lattner 
17930fdc8d8SChris Lattner     class CommandOptions : public Options
18030fdc8d8SChris Lattner     {
18130fdc8d8SChris Lattner     public:
18230fdc8d8SChris Lattner 
183eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
184eb0103f2SGreg Clayton             Options (interpreter),
18530fdc8d8SChris Lattner             log_file (),
18630fdc8d8SChris Lattner             log_options (0)
18730fdc8d8SChris Lattner         {
18830fdc8d8SChris Lattner         }
18930fdc8d8SChris Lattner 
19030fdc8d8SChris Lattner 
19130fdc8d8SChris Lattner         virtual
19230fdc8d8SChris Lattner         ~CommandOptions ()
19330fdc8d8SChris Lattner         {
19430fdc8d8SChris Lattner         }
19530fdc8d8SChris Lattner 
19630fdc8d8SChris Lattner         virtual Error
197f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
19830fdc8d8SChris Lattner         {
19930fdc8d8SChris Lattner             Error error;
20030fdc8d8SChris Lattner             char short_option = (char) m_getopt_table[option_idx].val;
20130fdc8d8SChris Lattner 
20230fdc8d8SChris Lattner             switch (short_option)
20330fdc8d8SChris Lattner             {
20430fdc8d8SChris Lattner             case 'f':  log_file = option_arg;                                 break;
20530fdc8d8SChris Lattner             case 't':  log_options |= LLDB_LOG_OPTION_THREADSAFE;             break;
20630fdc8d8SChris Lattner             case 'v':  log_options |= LLDB_LOG_OPTION_VERBOSE;                break;
20730fdc8d8SChris Lattner             case 'g':  log_options |= LLDB_LOG_OPTION_DEBUG;                  break;
20830fdc8d8SChris Lattner             case 's':  log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE;       break;
20930fdc8d8SChris Lattner             case 'T':  log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP;      break;
21030fdc8d8SChris Lattner             case 'p':  log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;break;
21130fdc8d8SChris Lattner             case 'n':  log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME;    break;
21230fdc8d8SChris Lattner             default:
213*86edbf41SGreg Clayton                 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
21430fdc8d8SChris Lattner                 break;
21530fdc8d8SChris Lattner             }
21630fdc8d8SChris Lattner 
21730fdc8d8SChris Lattner             return error;
21830fdc8d8SChris Lattner         }
21930fdc8d8SChris Lattner 
22030fdc8d8SChris Lattner         void
221f6b8b581SGreg Clayton         OptionParsingStarting ()
22230fdc8d8SChris Lattner         {
22330fdc8d8SChris Lattner             log_file.clear();
22430fdc8d8SChris Lattner             log_options = 0;
22530fdc8d8SChris Lattner         }
22630fdc8d8SChris Lattner 
227e0d378b3SGreg Clayton         const OptionDefinition*
22830fdc8d8SChris Lattner         GetDefinitions ()
22930fdc8d8SChris Lattner         {
23030fdc8d8SChris Lattner             return g_option_table;
23130fdc8d8SChris Lattner         }
23230fdc8d8SChris Lattner 
23330fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
23430fdc8d8SChris Lattner 
235e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
23630fdc8d8SChris Lattner 
23730fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
23830fdc8d8SChris Lattner 
23930fdc8d8SChris Lattner         std::string log_file;
24030fdc8d8SChris Lattner         uint32_t log_options;
24130fdc8d8SChris Lattner     };
24230fdc8d8SChris Lattner 
24330fdc8d8SChris Lattner protected:
24430fdc8d8SChris Lattner     typedef std::map<std::string, StreamSP> LogStreamMap;
24530fdc8d8SChris Lattner     CommandOptions m_options;
24630fdc8d8SChris Lattner     LogStreamMap m_log_streams;
24730fdc8d8SChris Lattner };
24830fdc8d8SChris Lattner 
249e0d378b3SGreg Clayton OptionDefinition
25030fdc8d8SChris Lattner CommandObjectLogEnable::CommandOptions::g_option_table[] =
25130fdc8d8SChris Lattner {
252deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "file",       'f', required_argument, NULL, 0, eArgTypeFilename,   "Set the destination file to log to."},
253deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "threadsafe", 't', no_argument,       NULL, 0, eArgTypeNone,        "Enable thread safe logging to avoid interweaved log lines." },
254deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "verbose",    'v', no_argument,       NULL, 0, eArgTypeNone,       "Enable verbose logging." },
255deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "debug",      'g', no_argument,       NULL, 0, eArgTypeNone,       "Enable debug logging." },
256deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "sequence",   's', no_argument,       NULL, 0, eArgTypeNone,       "Prepend all log lines with an increasing integer sequence id." },
257deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "timestamp",  'T', no_argument,       NULL, 0, eArgTypeNone,       "Prepend all log lines with a timestamp." },
258deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "pid-tid",    'p', no_argument,       NULL, 0, eArgTypeNone,       "Prepend all log lines with the process and thread ID that generates the log line." },
259deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "thread-name",'n', no_argument,       NULL, 0, eArgTypeNone,       "Prepend all log lines with the thread name for the thread that generates the log line." },
260deaab222SCaroline Tice { 0, false, NULL,                       0,  0,                 NULL, 0, eArgTypeNone,       NULL }
26130fdc8d8SChris Lattner };
26230fdc8d8SChris Lattner 
26330fdc8d8SChris Lattner class CommandObjectLogDisable : public CommandObject
26430fdc8d8SChris Lattner {
26530fdc8d8SChris Lattner public:
26630fdc8d8SChris Lattner     //------------------------------------------------------------------
26730fdc8d8SChris Lattner     // Constructors and Destructors
26830fdc8d8SChris Lattner     //------------------------------------------------------------------
269a7015092SGreg Clayton     CommandObjectLogDisable(CommandInterpreter &interpreter) :
270a7015092SGreg Clayton         CommandObject (interpreter,
271a7015092SGreg Clayton                        "log disable",
2727149fab4SCaroline Tice                        "Disable one or more log channel categories.",
273405fe67fSCaroline Tice                        NULL)
27430fdc8d8SChris Lattner     {
2757149fab4SCaroline Tice         CommandArgumentEntry arg1;
2767149fab4SCaroline Tice         CommandArgumentEntry arg2;
277405fe67fSCaroline Tice         CommandArgumentData channel_arg;
2787149fab4SCaroline Tice         CommandArgumentData category_arg;
279405fe67fSCaroline Tice 
280405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
281405fe67fSCaroline Tice         channel_arg.arg_type = eArgTypeLogChannel;
2827149fab4SCaroline Tice         channel_arg.arg_repetition = eArgRepeatPlain;
283405fe67fSCaroline Tice 
284405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
2857149fab4SCaroline Tice         arg1.push_back (channel_arg);
2867149fab4SCaroline Tice 
2877149fab4SCaroline Tice         category_arg.arg_type = eArgTypeLogCategory;
2887149fab4SCaroline Tice         category_arg.arg_repetition = eArgRepeatPlus;
2897149fab4SCaroline Tice 
2907149fab4SCaroline Tice         arg2.push_back (category_arg);
291405fe67fSCaroline Tice 
292405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
2937149fab4SCaroline Tice         m_arguments.push_back (arg1);
2947149fab4SCaroline Tice         m_arguments.push_back (arg2);
29530fdc8d8SChris Lattner     }
29630fdc8d8SChris Lattner 
29730fdc8d8SChris Lattner     virtual
29830fdc8d8SChris Lattner     ~CommandObjectLogDisable()
29930fdc8d8SChris Lattner     {
30030fdc8d8SChris Lattner     }
30130fdc8d8SChris Lattner 
30230fdc8d8SChris Lattner     virtual bool
303a7015092SGreg Clayton     Execute (Args& args,
30430fdc8d8SChris Lattner              CommandReturnObject &result)
30530fdc8d8SChris Lattner     {
30630fdc8d8SChris Lattner         const size_t argc = args.GetArgumentCount();
30730fdc8d8SChris Lattner         if (argc == 0)
30830fdc8d8SChris Lattner         {
309e3d26315SCaroline Tice             result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
31030fdc8d8SChris Lattner         }
31130fdc8d8SChris Lattner         else
31230fdc8d8SChris Lattner         {
31330fdc8d8SChris Lattner             Log::Callbacks log_callbacks;
31430fdc8d8SChris Lattner 
31520ad3c40SCaroline Tice             std::string channel(args.GetArgumentAtIndex(0));
31620ad3c40SCaroline Tice             args.Shift ();  // Shift off the channel
31730fdc8d8SChris Lattner             if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
31830fdc8d8SChris Lattner             {
31920ad3c40SCaroline Tice                 log_callbacks.disable (args, &result.GetErrorStream());
32030fdc8d8SChris Lattner                 result.SetStatus(eReturnStatusSuccessFinishNoResult);
32130fdc8d8SChris Lattner             }
32230fdc8d8SChris Lattner             else if (channel == "all")
32330fdc8d8SChris Lattner             {
32420ad3c40SCaroline Tice                 Log::DisableAllLogChannels(&result.GetErrorStream());
32530fdc8d8SChris Lattner             }
32630fdc8d8SChris Lattner             else
32730fdc8d8SChris Lattner             {
328ab65b34fSGreg Clayton                 LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str()));
32930fdc8d8SChris Lattner                 if (log_channel_sp)
33030fdc8d8SChris Lattner                 {
33120ad3c40SCaroline Tice                     log_channel_sp->Disable(args, &result.GetErrorStream());
33230fdc8d8SChris Lattner                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
33330fdc8d8SChris Lattner                 }
33430fdc8d8SChris Lattner                 else
33530fdc8d8SChris Lattner                     result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0));
33630fdc8d8SChris Lattner             }
33730fdc8d8SChris Lattner         }
33830fdc8d8SChris Lattner         return result.Succeeded();
33930fdc8d8SChris Lattner     }
34030fdc8d8SChris Lattner };
34130fdc8d8SChris Lattner 
34230fdc8d8SChris Lattner class CommandObjectLogList : public CommandObject
34330fdc8d8SChris Lattner {
34430fdc8d8SChris Lattner public:
34530fdc8d8SChris Lattner     //------------------------------------------------------------------
34630fdc8d8SChris Lattner     // Constructors and Destructors
34730fdc8d8SChris Lattner     //------------------------------------------------------------------
348a7015092SGreg Clayton     CommandObjectLogList(CommandInterpreter &interpreter) :
349a7015092SGreg Clayton         CommandObject (interpreter,
350a7015092SGreg Clayton                        "log list",
351405fe67fSCaroline Tice                        "List the log categories for one or more log channels.  If none specified, lists them all.",
352405fe67fSCaroline Tice                        NULL)
35330fdc8d8SChris Lattner     {
354405fe67fSCaroline Tice         CommandArgumentEntry arg;
355405fe67fSCaroline Tice         CommandArgumentData channel_arg;
356405fe67fSCaroline Tice 
357405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
358405fe67fSCaroline Tice         channel_arg.arg_type = eArgTypeLogChannel;
359405fe67fSCaroline Tice         channel_arg.arg_repetition = eArgRepeatStar;
360405fe67fSCaroline Tice 
361405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
362405fe67fSCaroline Tice         arg.push_back (channel_arg);
363405fe67fSCaroline Tice 
364405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
365405fe67fSCaroline Tice         m_arguments.push_back (arg);
36630fdc8d8SChris Lattner     }
36730fdc8d8SChris Lattner 
36830fdc8d8SChris Lattner     virtual
36930fdc8d8SChris Lattner     ~CommandObjectLogList()
37030fdc8d8SChris Lattner     {
37130fdc8d8SChris Lattner     }
37230fdc8d8SChris Lattner 
37330fdc8d8SChris Lattner     virtual bool
374a7015092SGreg Clayton     Execute (Args& args,
37530fdc8d8SChris Lattner              CommandReturnObject &result)
37630fdc8d8SChris Lattner     {
37730fdc8d8SChris Lattner         const size_t argc = args.GetArgumentCount();
37830fdc8d8SChris Lattner         if (argc == 0)
37930fdc8d8SChris Lattner         {
38030fdc8d8SChris Lattner             Log::ListAllLogChannels (&result.GetOutputStream());
38130fdc8d8SChris Lattner             result.SetStatus(eReturnStatusSuccessFinishResult);
38230fdc8d8SChris Lattner         }
38330fdc8d8SChris Lattner         else
38430fdc8d8SChris Lattner         {
38530fdc8d8SChris Lattner             for (size_t i=0; i<argc; ++i)
38630fdc8d8SChris Lattner             {
38730fdc8d8SChris Lattner                 Log::Callbacks log_callbacks;
38830fdc8d8SChris Lattner 
38930fdc8d8SChris Lattner                 std::string channel(args.GetArgumentAtIndex(i));
39030fdc8d8SChris Lattner                 if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
39130fdc8d8SChris Lattner                 {
39230fdc8d8SChris Lattner                     log_callbacks.list_categories (&result.GetOutputStream());
39330fdc8d8SChris Lattner                     result.SetStatus(eReturnStatusSuccessFinishResult);
39430fdc8d8SChris Lattner                 }
39530fdc8d8SChris Lattner                 else if (channel == "all")
39630fdc8d8SChris Lattner                 {
39730fdc8d8SChris Lattner                     Log::ListAllLogChannels (&result.GetOutputStream());
39830fdc8d8SChris Lattner                     result.SetStatus(eReturnStatusSuccessFinishResult);
39930fdc8d8SChris Lattner                 }
40030fdc8d8SChris Lattner                 else
40130fdc8d8SChris Lattner                 {
402ab65b34fSGreg Clayton                     LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str()));
40330fdc8d8SChris Lattner                     if (log_channel_sp)
40430fdc8d8SChris Lattner                     {
40530fdc8d8SChris Lattner                         log_channel_sp->ListCategories(&result.GetOutputStream());
40630fdc8d8SChris Lattner                         result.SetStatus(eReturnStatusSuccessFinishNoResult);
40730fdc8d8SChris Lattner                     }
40830fdc8d8SChris Lattner                     else
40930fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0));
41030fdc8d8SChris Lattner                 }
41130fdc8d8SChris Lattner             }
41230fdc8d8SChris Lattner         }
41330fdc8d8SChris Lattner         return result.Succeeded();
41430fdc8d8SChris Lattner     }
41530fdc8d8SChris Lattner };
41630fdc8d8SChris Lattner 
41730fdc8d8SChris Lattner class CommandObjectLogTimer : public CommandObject
41830fdc8d8SChris Lattner {
41930fdc8d8SChris Lattner public:
42030fdc8d8SChris Lattner     //------------------------------------------------------------------
42130fdc8d8SChris Lattner     // Constructors and Destructors
42230fdc8d8SChris Lattner     //------------------------------------------------------------------
423a7015092SGreg Clayton     CommandObjectLogTimer(CommandInterpreter &interpreter) :
424a7015092SGreg Clayton         CommandObject (interpreter,
425a7015092SGreg Clayton                        "log timers",
42630fdc8d8SChris Lattner                        "Enable, disable, dump, and reset LLDB internal performance timers.",
427f7f4f501SJim Ingham                        "log timers < enable <depth> | disable | dump | increment <bool> | reset >")
42830fdc8d8SChris Lattner     {
42930fdc8d8SChris Lattner     }
43030fdc8d8SChris Lattner 
43130fdc8d8SChris Lattner     virtual
43230fdc8d8SChris Lattner     ~CommandObjectLogTimer()
43330fdc8d8SChris Lattner     {
43430fdc8d8SChris Lattner     }
43530fdc8d8SChris Lattner 
43630fdc8d8SChris Lattner     virtual bool
437a7015092SGreg Clayton     Execute (Args& args,
43830fdc8d8SChris Lattner              CommandReturnObject &result)
43930fdc8d8SChris Lattner     {
44030fdc8d8SChris Lattner         const size_t argc = args.GetArgumentCount();
44130fdc8d8SChris Lattner         result.SetStatus(eReturnStatusFailed);
44230fdc8d8SChris Lattner 
44330fdc8d8SChris Lattner         if (argc == 1)
44430fdc8d8SChris Lattner         {
44530fdc8d8SChris Lattner             const char *sub_command = args.GetArgumentAtIndex(0);
44630fdc8d8SChris Lattner 
44730fdc8d8SChris Lattner             if (strcasecmp(sub_command, "enable") == 0)
44830fdc8d8SChris Lattner             {
44930fdc8d8SChris Lattner                 Timer::SetDisplayDepth (UINT32_MAX);
45030fdc8d8SChris Lattner                 result.SetStatus(eReturnStatusSuccessFinishNoResult);
45130fdc8d8SChris Lattner             }
45230fdc8d8SChris Lattner             else if (strcasecmp(sub_command, "disable") == 0)
45330fdc8d8SChris Lattner             {
45430fdc8d8SChris Lattner                 Timer::DumpCategoryTimes (&result.GetOutputStream());
45530fdc8d8SChris Lattner                 Timer::SetDisplayDepth (0);
45630fdc8d8SChris Lattner                 result.SetStatus(eReturnStatusSuccessFinishResult);
45730fdc8d8SChris Lattner             }
45830fdc8d8SChris Lattner             else if (strcasecmp(sub_command, "dump") == 0)
45930fdc8d8SChris Lattner             {
46030fdc8d8SChris Lattner                 Timer::DumpCategoryTimes (&result.GetOutputStream());
46130fdc8d8SChris Lattner                 result.SetStatus(eReturnStatusSuccessFinishResult);
46230fdc8d8SChris Lattner             }
46330fdc8d8SChris Lattner             else if (strcasecmp(sub_command, "reset") == 0)
46430fdc8d8SChris Lattner             {
46530fdc8d8SChris Lattner                 Timer::ResetCategoryTimes ();
46630fdc8d8SChris Lattner                 result.SetStatus(eReturnStatusSuccessFinishResult);
46730fdc8d8SChris Lattner             }
46830fdc8d8SChris Lattner 
46930fdc8d8SChris Lattner         }
470932725faSJim Ingham         else if (argc == 2)
471932725faSJim Ingham         {
472932725faSJim Ingham             const char *sub_command = args.GetArgumentAtIndex(0);
473932725faSJim Ingham 
474932725faSJim Ingham             if (strcasecmp(sub_command, "enable") == 0)
475932725faSJim Ingham             {
476932725faSJim Ingham                 bool success;
477932725faSJim Ingham                 uint32_t depth = Args::StringToUInt32(args.GetArgumentAtIndex(1), 0, 0, &success);
478932725faSJim Ingham                 if (success)
479932725faSJim Ingham                 {
480932725faSJim Ingham                     Timer::SetDisplayDepth (depth);
481932725faSJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
482932725faSJim Ingham                 }
483932725faSJim Ingham                 else
484932725faSJim Ingham                     result.AppendError("Could not convert enable depth to an unsigned integer.");
485932725faSJim Ingham             }
486f7f4f501SJim Ingham             if (strcasecmp(sub_command, "increment") == 0)
487f7f4f501SJim Ingham             {
488f7f4f501SJim Ingham                 bool success;
489f7f4f501SJim Ingham                 bool increment = Args::StringToBoolean(args.GetArgumentAtIndex(1), false, &success);
490f7f4f501SJim Ingham                 if (success)
491f7f4f501SJim Ingham                 {
492f7f4f501SJim Ingham                     Timer::SetQuiet (!increment);
493f7f4f501SJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
494f7f4f501SJim Ingham                 }
495f7f4f501SJim Ingham                 else
496f7f4f501SJim Ingham                     result.AppendError("Could not convert increment value to boolean.");
497f7f4f501SJim Ingham             }
498932725faSJim Ingham         }
499932725faSJim Ingham 
50030fdc8d8SChris Lattner         if (!result.Succeeded())
50130fdc8d8SChris Lattner         {
50230fdc8d8SChris Lattner             result.AppendError("Missing subcommand");
50330fdc8d8SChris Lattner             result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
50430fdc8d8SChris Lattner         }
50530fdc8d8SChris Lattner         return result.Succeeded();
50630fdc8d8SChris Lattner     }
50730fdc8d8SChris Lattner };
50830fdc8d8SChris Lattner 
50930fdc8d8SChris Lattner //----------------------------------------------------------------------
51030fdc8d8SChris Lattner // CommandObjectLog constructor
51130fdc8d8SChris Lattner //----------------------------------------------------------------------
5126611103cSGreg Clayton CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) :
513a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
514a7015092SGreg Clayton                             "log",
51530fdc8d8SChris Lattner                             "A set of commands for operating on logs.",
51630fdc8d8SChris Lattner                             "log <command> [<command-options>]")
51730fdc8d8SChris Lattner {
518a7015092SGreg Clayton     LoadSubCommand ("enable",  CommandObjectSP (new CommandObjectLogEnable (interpreter)));
519a7015092SGreg Clayton     LoadSubCommand ("disable", CommandObjectSP (new CommandObjectLogDisable (interpreter)));
520a7015092SGreg Clayton     LoadSubCommand ("list",    CommandObjectSP (new CommandObjectLogList (interpreter)));
521a7015092SGreg Clayton     LoadSubCommand ("timers",  CommandObjectSP (new CommandObjectLogTimer (interpreter)));
52230fdc8d8SChris Lattner }
52330fdc8d8SChris Lattner 
52430fdc8d8SChris Lattner //----------------------------------------------------------------------
52530fdc8d8SChris Lattner // Destructor
52630fdc8d8SChris Lattner //----------------------------------------------------------------------
52730fdc8d8SChris Lattner CommandObjectLog::~CommandObjectLog()
52830fdc8d8SChris Lattner {
52930fdc8d8SChris Lattner }
53030fdc8d8SChris Lattner 
53130fdc8d8SChris Lattner 
53230fdc8d8SChris Lattner 
53330fdc8d8SChris Lattner 
534