1ebc09c36SJim Ingham //===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===// 2ebc09c36SJim Ingham // 3ebc09c36SJim Ingham // The LLVM Compiler Infrastructure 4ebc09c36SJim Ingham // 5ebc09c36SJim Ingham // This file is distributed under the University of Illinois Open Source 6ebc09c36SJim Ingham // License. See LICENSE.TXT for details. 7ebc09c36SJim Ingham // 8ebc09c36SJim Ingham //===----------------------------------------------------------------------===// 9ebc09c36SJim Ingham 10ebc09c36SJim Ingham #include "CommandObjectCommands.h" 11ebc09c36SJim Ingham 12ebc09c36SJim Ingham // C Includes 13ebc09c36SJim Ingham // C++ Includes 14ebc09c36SJim Ingham // Other libraries and framework includes 150e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h" 160e5e5a79SGreg Clayton 17ebc09c36SJim Ingham // Project includes 18ebc09c36SJim Ingham #include "lldb/Core/Debugger.h" 1944d93782SGreg Clayton #include "lldb/Core/IOHandler.h" 20be93a35aSEnrico Granata #include "lldb/Core/StringList.h" 21de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h" 227594f14fSEnrico Granata #include "lldb/Interpreter/CommandHistory.h" 23ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h" 24de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h" 25ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h" 26012d4fcaSEnrico Granata #include "lldb/Interpreter/OptionValueBoolean.h" 277594f14fSEnrico Granata #include "lldb/Interpreter/OptionValueUInt64.h" 28ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h" 2999f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h" 30ebc09c36SJim Ingham 31ebc09c36SJim Ingham using namespace lldb; 32ebc09c36SJim Ingham using namespace lldb_private; 33ebc09c36SJim Ingham 34ebc09c36SJim Ingham //------------------------------------------------------------------------- 35ebc09c36SJim Ingham // CommandObjectCommandsSource 36ebc09c36SJim Ingham //------------------------------------------------------------------------- 37ebc09c36SJim Ingham 385a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed 39a5a97ebeSJim Ingham { 405a988416SJim Ingham public: 415a988416SJim Ingham CommandObjectCommandsHistory(CommandInterpreter &interpreter) : 425a988416SJim Ingham CommandObjectParsed (interpreter, 435a988416SJim Ingham "command history", 445a988416SJim Ingham "Dump the history of commands in this session.", 455a988416SJim Ingham NULL), 465a988416SJim Ingham m_options (interpreter) 475a988416SJim Ingham { 485a988416SJim Ingham } 495a988416SJim Ingham 50*13d21e9aSBruce Mitchener ~CommandObjectCommandsHistory () override {} 515a988416SJim Ingham 52*13d21e9aSBruce Mitchener Options * 53*13d21e9aSBruce Mitchener GetOptions () override 545a988416SJim Ingham { 555a988416SJim Ingham return &m_options; 565a988416SJim Ingham } 575a988416SJim Ingham 585a988416SJim Ingham protected: 59a5a97ebeSJim Ingham 60a5a97ebeSJim Ingham class CommandOptions : public Options 61a5a97ebeSJim Ingham { 62a5a97ebeSJim Ingham public: 63a5a97ebeSJim Ingham 64a5a97ebeSJim Ingham CommandOptions (CommandInterpreter &interpreter) : 657594f14fSEnrico Granata Options (interpreter), 667594f14fSEnrico Granata m_start_idx(0), 677594f14fSEnrico Granata m_stop_idx(0), 687594f14fSEnrico Granata m_count(0), 6963123b64SEnrico Granata m_clear(false) 70a5a97ebeSJim Ingham { 71a5a97ebeSJim Ingham } 72a5a97ebeSJim Ingham 73*13d21e9aSBruce Mitchener ~CommandOptions () override {} 74a5a97ebeSJim Ingham 75*13d21e9aSBruce Mitchener Error 76*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 77a5a97ebeSJim Ingham { 78a5a97ebeSJim Ingham Error error; 793bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 80a5a97ebeSJim Ingham 81a5a97ebeSJim Ingham switch (short_option) 82a5a97ebeSJim Ingham { 83a5a97ebeSJim Ingham case 'c': 84c95f7e2aSPavel Labath error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign); 85a5a97ebeSJim Ingham break; 86a5a97ebeSJim Ingham case 's': 877594f14fSEnrico Granata if (option_arg && strcmp("end", option_arg) == 0) 887594f14fSEnrico Granata { 897594f14fSEnrico Granata m_start_idx.SetCurrentValue(UINT64_MAX); 907594f14fSEnrico Granata m_start_idx.SetOptionWasSet(); 917594f14fSEnrico Granata } 927594f14fSEnrico Granata else 93c95f7e2aSPavel Labath error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign); 947594f14fSEnrico Granata break; 957594f14fSEnrico Granata case 'e': 96c95f7e2aSPavel Labath error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign); 977594f14fSEnrico Granata break; 9863123b64SEnrico Granata case 'C': 9963123b64SEnrico Granata m_clear.SetCurrentValue(true); 10063123b64SEnrico Granata m_clear.SetOptionWasSet(); 101a5a97ebeSJim Ingham break; 102a5a97ebeSJim Ingham default: 10386edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 104a5a97ebeSJim Ingham break; 105a5a97ebeSJim Ingham } 106a5a97ebeSJim Ingham 107a5a97ebeSJim Ingham return error; 108a5a97ebeSJim Ingham } 109a5a97ebeSJim Ingham 110a5a97ebeSJim Ingham void 111*13d21e9aSBruce Mitchener OptionParsingStarting () override 112a5a97ebeSJim Ingham { 1137594f14fSEnrico Granata m_start_idx.Clear(); 1147594f14fSEnrico Granata m_stop_idx.Clear(); 1157594f14fSEnrico Granata m_count.Clear(); 11663123b64SEnrico Granata m_clear.Clear(); 117a5a97ebeSJim Ingham } 118a5a97ebeSJim Ingham 119a5a97ebeSJim Ingham const OptionDefinition* 120*13d21e9aSBruce Mitchener GetDefinitions () override 121a5a97ebeSJim Ingham { 122a5a97ebeSJim Ingham return g_option_table; 123a5a97ebeSJim Ingham } 124a5a97ebeSJim Ingham 125a5a97ebeSJim Ingham // Options table: Required for subclasses of Options. 126a5a97ebeSJim Ingham 127a5a97ebeSJim Ingham static OptionDefinition g_option_table[]; 128a5a97ebeSJim Ingham 129a5a97ebeSJim Ingham // Instance variables to hold the values for command options. 130a5a97ebeSJim Ingham 1317594f14fSEnrico Granata OptionValueUInt64 m_start_idx; 1327594f14fSEnrico Granata OptionValueUInt64 m_stop_idx; 1337594f14fSEnrico Granata OptionValueUInt64 m_count; 13463123b64SEnrico Granata OptionValueBoolean m_clear; 135a5a97ebeSJim Ingham }; 136a5a97ebeSJim Ingham 137a5a97ebeSJim Ingham bool 138*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 139a5a97ebeSJim Ingham { 14063123b64SEnrico Granata if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet()) 1417594f14fSEnrico Granata { 1427594f14fSEnrico Granata m_interpreter.GetCommandHistory().Clear(); 1437594f14fSEnrico Granata result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult); 1447594f14fSEnrico Granata } 1457594f14fSEnrico Granata else 1467594f14fSEnrico Granata { 1477594f14fSEnrico Granata if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet()) 1487594f14fSEnrico Granata { 1497594f14fSEnrico Granata result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation"); 1507594f14fSEnrico Granata result.SetStatus(lldb::eReturnStatusFailed); 1517594f14fSEnrico Granata } 1527594f14fSEnrico Granata else 1537594f14fSEnrico Granata { 15484400ec7SVirgile Bello std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue()); 15584400ec7SVirgile Bello std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue()); 15684400ec7SVirgile Bello std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue()); 157a5a97ebeSJim Ingham 1587594f14fSEnrico Granata const CommandHistory& history(m_interpreter.GetCommandHistory()); 1597594f14fSEnrico Granata 1607594f14fSEnrico Granata if (start_idx.first && start_idx.second == UINT64_MAX) 1617594f14fSEnrico Granata { 1627594f14fSEnrico Granata if (count.first) 1637594f14fSEnrico Granata { 1647594f14fSEnrico Granata start_idx.second = history.GetSize() - count.second; 1657594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1667594f14fSEnrico Granata } 1677594f14fSEnrico Granata else if (stop_idx.first) 1687594f14fSEnrico Granata { 1697594f14fSEnrico Granata start_idx.second = stop_idx.second; 1707594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1717594f14fSEnrico Granata } 1727594f14fSEnrico Granata else 1737594f14fSEnrico Granata { 1747594f14fSEnrico Granata start_idx.second = 0; 1757594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1767594f14fSEnrico Granata } 1777594f14fSEnrico Granata } 1787594f14fSEnrico Granata else 1797594f14fSEnrico Granata { 1807594f14fSEnrico Granata if (!start_idx.first && !stop_idx.first && !count.first) 1817594f14fSEnrico Granata { 1827594f14fSEnrico Granata start_idx.second = 0; 1837594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1847594f14fSEnrico Granata } 1857594f14fSEnrico Granata else if (start_idx.first) 1867594f14fSEnrico Granata { 1877594f14fSEnrico Granata if (count.first) 1887594f14fSEnrico Granata { 1897594f14fSEnrico Granata stop_idx.second = start_idx.second + count.second - 1; 1907594f14fSEnrico Granata } 1917594f14fSEnrico Granata else if (!stop_idx.first) 1927594f14fSEnrico Granata { 1937594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1947594f14fSEnrico Granata } 1957594f14fSEnrico Granata } 1967594f14fSEnrico Granata else if (stop_idx.first) 1977594f14fSEnrico Granata { 1987594f14fSEnrico Granata if (count.first) 1997594f14fSEnrico Granata { 2007594f14fSEnrico Granata if (stop_idx.second >= count.second) 2017594f14fSEnrico Granata start_idx.second = stop_idx.second - count.second + 1; 2027594f14fSEnrico Granata else 2037594f14fSEnrico Granata start_idx.second = 0; 2047594f14fSEnrico Granata } 2057594f14fSEnrico Granata } 2067594f14fSEnrico Granata else /* if (count.first) */ 2077594f14fSEnrico Granata { 2087594f14fSEnrico Granata start_idx.second = 0; 2097594f14fSEnrico Granata stop_idx.second = count.second - 1; 2107594f14fSEnrico Granata } 2117594f14fSEnrico Granata } 2127594f14fSEnrico Granata history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second); 2137594f14fSEnrico Granata } 2147594f14fSEnrico Granata } 215a5a97ebeSJim Ingham return result.Succeeded(); 216a5a97ebeSJim Ingham 217a5a97ebeSJim Ingham } 2185a988416SJim Ingham 2195a988416SJim Ingham CommandOptions m_options; 220a5a97ebeSJim Ingham }; 221a5a97ebeSJim Ingham 222a5a97ebeSJim Ingham OptionDefinition 223a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] = 224a5a97ebeSJim Ingham { 225d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."}, 226d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."}, 227d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."}, 228d37221dcSZachary Turner { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeBoolean, "Clears the current command history."}, 229d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 230a5a97ebeSJim Ingham }; 231a5a97ebeSJim Ingham 232a5a97ebeSJim Ingham 233a5a97ebeSJim Ingham //------------------------------------------------------------------------- 234a5a97ebeSJim Ingham // CommandObjectCommandsSource 235a5a97ebeSJim Ingham //------------------------------------------------------------------------- 236a5a97ebeSJim Ingham 2375a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed 238ebc09c36SJim Ingham { 2395a988416SJim Ingham public: 2405a988416SJim Ingham CommandObjectCommandsSource(CommandInterpreter &interpreter) : 2415a988416SJim Ingham CommandObjectParsed (interpreter, 2425a988416SJim Ingham "command source", 2435a988416SJim Ingham "Read in debugger commands from the file <filename> and execute them.", 2445a988416SJim Ingham NULL), 2455a988416SJim Ingham m_options (interpreter) 2465a988416SJim Ingham { 2475a988416SJim Ingham CommandArgumentEntry arg; 2485a988416SJim Ingham CommandArgumentData file_arg; 2495a988416SJim Ingham 2505a988416SJim Ingham // Define the first (and only) variant of this arg. 2515a988416SJim Ingham file_arg.arg_type = eArgTypeFilename; 2525a988416SJim Ingham file_arg.arg_repetition = eArgRepeatPlain; 2535a988416SJim Ingham 2545a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 2555a988416SJim Ingham arg.push_back (file_arg); 2565a988416SJim Ingham 2575a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 2585a988416SJim Ingham m_arguments.push_back (arg); 2595a988416SJim Ingham } 2605a988416SJim Ingham 261*13d21e9aSBruce Mitchener ~CommandObjectCommandsSource () override {} 2625a988416SJim Ingham 263*13d21e9aSBruce Mitchener const char* 264*13d21e9aSBruce Mitchener GetRepeatCommand (Args ¤t_command_args, uint32_t index) override 2655a988416SJim Ingham { 2665a988416SJim Ingham return ""; 2675a988416SJim Ingham } 2685a988416SJim Ingham 269*13d21e9aSBruce Mitchener int 2705a988416SJim Ingham HandleArgumentCompletion (Args &input, 2715a988416SJim Ingham int &cursor_index, 2725a988416SJim Ingham int &cursor_char_position, 2735a988416SJim Ingham OptionElementVector &opt_element_vector, 2745a988416SJim Ingham int match_start_point, 2755a988416SJim Ingham int max_return_elements, 2765a988416SJim Ingham bool &word_complete, 277*13d21e9aSBruce Mitchener StringList &matches) override 2785a988416SJim Ingham { 2795a988416SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2805a988416SJim Ingham completion_str.erase (cursor_char_position); 2815a988416SJim Ingham 2825a988416SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2835a988416SJim Ingham CommandCompletions::eDiskFileCompletion, 2845a988416SJim Ingham completion_str.c_str(), 2855a988416SJim Ingham match_start_point, 2865a988416SJim Ingham max_return_elements, 2875a988416SJim Ingham NULL, 2885a988416SJim Ingham word_complete, 2895a988416SJim Ingham matches); 2905a988416SJim Ingham return matches.GetSize(); 2915a988416SJim Ingham } 2925a988416SJim Ingham 293*13d21e9aSBruce Mitchener Options * 294*13d21e9aSBruce Mitchener GetOptions () override 2955a988416SJim Ingham { 2965a988416SJim Ingham return &m_options; 2975a988416SJim Ingham } 2985a988416SJim Ingham 2995a988416SJim Ingham protected: 300e16c50a1SJim Ingham 301e16c50a1SJim Ingham class CommandOptions : public Options 302e16c50a1SJim Ingham { 303e16c50a1SJim Ingham public: 304e16c50a1SJim Ingham 305eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 306012d4fcaSEnrico Granata Options (interpreter), 307340b0309SGreg Clayton m_stop_on_error (true), 308340b0309SGreg Clayton m_silent_run (false), 309340b0309SGreg Clayton m_stop_on_continue (true) 310eb0103f2SGreg Clayton { 311eb0103f2SGreg Clayton } 312e16c50a1SJim Ingham 313*13d21e9aSBruce Mitchener ~CommandOptions () override {} 314e16c50a1SJim Ingham 315*13d21e9aSBruce Mitchener Error 316*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 317e16c50a1SJim Ingham { 318e16c50a1SJim Ingham Error error; 3193bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 320e16c50a1SJim Ingham 321e16c50a1SJim Ingham switch (short_option) 322e16c50a1SJim Ingham { 323e16c50a1SJim Ingham case 'e': 324c95f7e2aSPavel Labath error = m_stop_on_error.SetValueFromString(option_arg); 325e16c50a1SJim Ingham break; 326340b0309SGreg Clayton 327e16c50a1SJim Ingham case 'c': 328c95f7e2aSPavel Labath error = m_stop_on_continue.SetValueFromString(option_arg); 329e16c50a1SJim Ingham break; 330340b0309SGreg Clayton 33160986174SMichael Sartain case 's': 332c95f7e2aSPavel Labath error = m_silent_run.SetValueFromString(option_arg); 33360986174SMichael Sartain break; 334340b0309SGreg Clayton 335e16c50a1SJim Ingham default: 33686edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 337e16c50a1SJim Ingham break; 338e16c50a1SJim Ingham } 339e16c50a1SJim Ingham 340e16c50a1SJim Ingham return error; 341e16c50a1SJim Ingham } 342e16c50a1SJim Ingham 343e16c50a1SJim Ingham void 344*13d21e9aSBruce Mitchener OptionParsingStarting () override 345e16c50a1SJim Ingham { 346012d4fcaSEnrico Granata m_stop_on_error.Clear(); 347340b0309SGreg Clayton m_silent_run.Clear(); 348340b0309SGreg Clayton m_stop_on_continue.Clear(); 349e16c50a1SJim Ingham } 350e16c50a1SJim Ingham 351e0d378b3SGreg Clayton const OptionDefinition* 352*13d21e9aSBruce Mitchener GetDefinitions () override 353e16c50a1SJim Ingham { 354e16c50a1SJim Ingham return g_option_table; 355e16c50a1SJim Ingham } 356e16c50a1SJim Ingham 357e16c50a1SJim Ingham // Options table: Required for subclasses of Options. 358e16c50a1SJim Ingham 359e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 360e16c50a1SJim Ingham 361e16c50a1SJim Ingham // Instance variables to hold the values for command options. 362e16c50a1SJim Ingham 363012d4fcaSEnrico Granata OptionValueBoolean m_stop_on_error; 364340b0309SGreg Clayton OptionValueBoolean m_silent_run; 365340b0309SGreg Clayton OptionValueBoolean m_stop_on_continue; 366e16c50a1SJim Ingham }; 367e16c50a1SJim Ingham 368ebc09c36SJim Ingham bool 369*13d21e9aSBruce Mitchener DoExecute(Args& command, CommandReturnObject &result) override 370ebc09c36SJim Ingham { 371c7bece56SGreg Clayton const size_t argc = command.GetArgumentCount(); 372ebc09c36SJim Ingham if (argc == 1) 373ebc09c36SJim Ingham { 3745a988416SJim Ingham const char *filename = command.GetArgumentAtIndex(0); 375ebc09c36SJim Ingham 3761ee3853fSJohnny Chen FileSpec cmd_file (filename, true); 377e16c50a1SJim Ingham ExecutionContext *exe_ctx = NULL; // Just use the default context. 378ebc09c36SJim Ingham 379340b0309SGreg Clayton // If any options were set, then use them 380340b0309SGreg Clayton if (m_options.m_stop_on_error.OptionWasSet() || 381340b0309SGreg Clayton m_options.m_silent_run.OptionWasSet() || 382340b0309SGreg Clayton m_options.m_stop_on_continue.OptionWasSet()) 383340b0309SGreg Clayton { 384340b0309SGreg Clayton // Use user set settings 38526c7bf93SJim Ingham CommandInterpreterRunOptions options; 38626c7bf93SJim Ingham options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue()); 38726c7bf93SJim Ingham options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue()); 3887d8555c4SJim Ingham options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue()); 3897d8555c4SJim Ingham options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue()); 39026c7bf93SJim Ingham 391e16c50a1SJim Ingham m_interpreter.HandleCommandsFromFile (cmd_file, 392e16c50a1SJim Ingham exe_ctx, 39326c7bf93SJim Ingham options, 394e16c50a1SJim Ingham result); 395340b0309SGreg Clayton 396340b0309SGreg Clayton } 397340b0309SGreg Clayton else 398340b0309SGreg Clayton { 399340b0309SGreg Clayton // No options were set, inherit any settings from nested "command source" commands, 400340b0309SGreg Clayton // or set to sane default settings... 40126c7bf93SJim Ingham CommandInterpreterRunOptions options; 402340b0309SGreg Clayton m_interpreter.HandleCommandsFromFile (cmd_file, 403340b0309SGreg Clayton exe_ctx, 40426c7bf93SJim Ingham options, 405340b0309SGreg Clayton result); 406340b0309SGreg Clayton 407340b0309SGreg Clayton } 408ebc09c36SJim Ingham } 409ebc09c36SJim Ingham else 410ebc09c36SJim Ingham { 411ebc09c36SJim Ingham result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName()); 412ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 413ebc09c36SJim Ingham } 414ebc09c36SJim Ingham return result.Succeeded(); 415ebc09c36SJim Ingham 416ebc09c36SJim Ingham } 4175a988416SJim Ingham CommandOptions m_options; 418ebc09c36SJim Ingham }; 419ebc09c36SJim Ingham 420e0d378b3SGreg Clayton OptionDefinition 421e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] = 422e16c50a1SJim Ingham { 423d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."}, 424d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."}, 425d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."}, 426d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 427e16c50a1SJim Ingham }; 428e16c50a1SJim Ingham 429ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias 430ebc09c36SJim Ingham //------------------------------------------------------------------------- 431ebc09c36SJim Ingham // CommandObjectCommandsAlias 432ebc09c36SJim Ingham //------------------------------------------------------------------------- 433ebc09c36SJim Ingham 434be93a35aSEnrico Granata static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" 435be93a35aSEnrico Granata "You must define a Python function with this signature:\n" 43644d93782SGreg Clayton "def my_command_impl(debugger, args, result, internal_dict):\n"; 437be93a35aSEnrico Granata 438be93a35aSEnrico Granata 4395a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw 440ebc09c36SJim Ingham { 441be93a35aSEnrico Granata 442be93a35aSEnrico Granata 443ebc09c36SJim Ingham public: 444a7015092SGreg Clayton CommandObjectCommandsAlias (CommandInterpreter &interpreter) : 4455a988416SJim Ingham CommandObjectRaw (interpreter, 4460e5e5a79SGreg Clayton "command alias", 447e3d26315SCaroline Tice "Allow users to define their own debugger command abbreviations.", 448405fe67fSCaroline Tice NULL) 449ebc09c36SJim Ingham { 450ebc09c36SJim Ingham SetHelpLong( 451ea671fbdSKate Stone "'alias' allows the user to create a short-cut or abbreviation for long \ 452ea671fbdSKate Stone commands, multi-word commands, and commands that take particular options. \ 453ea671fbdSKate Stone Below are some simple examples of how one might use the 'alias' command:" R"( 454ea671fbdSKate Stone 455ea671fbdSKate Stone (lldb) command alias sc script 456ea671fbdSKate Stone 457ea671fbdSKate Stone Creates the abbreviation 'sc' for the 'script' command. 458ea671fbdSKate Stone 459ea671fbdSKate Stone (lldb) command alias bp breakpoint 460ea671fbdSKate Stone 461ea671fbdSKate Stone )" " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \ 462ea671fbdSKate Stone breakpoint commands are two-word commands, the user would still need to \ 463ea671fbdSKate Stone enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"( 464ea671fbdSKate Stone 465ea671fbdSKate Stone (lldb) command alias bpl breakpoint list 466ea671fbdSKate Stone 467ea671fbdSKate Stone Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'. 468ea671fbdSKate Stone 469ea671fbdSKate Stone )" "An alias can include some options for the command, with the values either \ 470ea671fbdSKate Stone filled in at the time the alias is created, or specified as positional \ 471ea671fbdSKate Stone arguments, to be filled in when the alias is invoked. The following example \ 472ea671fbdSKate Stone shows how to create aliases with options:" R"( 473ea671fbdSKate Stone 474ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2 475ea671fbdSKate Stone 476ea671fbdSKate Stone )" " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \ 477ea671fbdSKate Stone options already part of the alias. So if the user wants to set a breakpoint \ 478ea671fbdSKate Stone by file and line without explicitly having to use the -f and -l options, the \ 479ea671fbdSKate Stone user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \ 480ea671fbdSKate Stone for the actual arguments that will be passed when the alias command is used. \ 481ea671fbdSKate Stone The number in the placeholder refers to the position/order the actual value \ 482ea671fbdSKate Stone occupies when the alias is used. All the occurrences of '%1' in the alias \ 483ea671fbdSKate Stone will be replaced with the first argument, all the occurrences of '%2' in the \ 484ea671fbdSKate Stone alias will be replaced with the second argument, and so on. This also allows \ 485ea671fbdSKate Stone actual arguments to be used multiple times within an alias (see 'process \ 486ea671fbdSKate Stone launch' example below)." R"( 487ea671fbdSKate Stone 488ea671fbdSKate Stone )" "Note: the positional arguments must substitute as whole words in the resultant \ 489ea671fbdSKate Stone command, so you can't at present do something like this to append the file extension \ 490ea671fbdSKate Stone \".cpp\":" R"( 491ea671fbdSKate Stone 492ea671fbdSKate Stone (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2 493ea671fbdSKate Stone 494ea671fbdSKate Stone )" "For more complex aliasing, use the \"command regex\" command instead. In the \ 495ea671fbdSKate Stone 'bfl' case above, the actual file value will be filled in with the first argument \ 496ea671fbdSKate Stone following 'bfl' and the actual line number value will be filled in with the second \ 497ea671fbdSKate Stone argument. The user would use this alias as follows:" R"( 498ea671fbdSKate Stone 499ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2 500ea671fbdSKate Stone (lldb) bfl my-file.c 137 501ea671fbdSKate Stone 502ea671fbdSKate Stone This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'. 503ea671fbdSKate Stone 504ea671fbdSKate Stone Another example: 505ea671fbdSKate Stone 506ea671fbdSKate Stone (lldb) command alias pltty process launch -s -o %1 -e %1 507ea671fbdSKate Stone (lldb) pltty /dev/tty0 508ea671fbdSKate Stone 509ea671fbdSKate Stone Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0' 510ea671fbdSKate Stone 511ea671fbdSKate Stone )" "If the user always wanted to pass the same value to a particular option, the \ 512ea671fbdSKate Stone alias could be defined with that value directly in the alias as a constant, \ 513ea671fbdSKate Stone rather than using a positional placeholder:" R"( 514ea671fbdSKate Stone 515ea671fbdSKate Stone (lldb) command alias bl3 breakpoint set -f %1 -l 3 516ea671fbdSKate Stone 517ea671fbdSKate Stone Always sets a breakpoint on line 3 of whatever file is indicated.)" 518ea671fbdSKate Stone ); 519ebc09c36SJim Ingham 520405fe67fSCaroline Tice CommandArgumentEntry arg1; 521405fe67fSCaroline Tice CommandArgumentEntry arg2; 522405fe67fSCaroline Tice CommandArgumentEntry arg3; 523405fe67fSCaroline Tice CommandArgumentData alias_arg; 524405fe67fSCaroline Tice CommandArgumentData cmd_arg; 525405fe67fSCaroline Tice CommandArgumentData options_arg; 526405fe67fSCaroline Tice 527405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 528405fe67fSCaroline Tice alias_arg.arg_type = eArgTypeAliasName; 529405fe67fSCaroline Tice alias_arg.arg_repetition = eArgRepeatPlain; 530405fe67fSCaroline Tice 531405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 532405fe67fSCaroline Tice arg1.push_back (alias_arg); 533405fe67fSCaroline Tice 534405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 535405fe67fSCaroline Tice cmd_arg.arg_type = eArgTypeCommandName; 536405fe67fSCaroline Tice cmd_arg.arg_repetition = eArgRepeatPlain; 537405fe67fSCaroline Tice 538405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 539405fe67fSCaroline Tice arg2.push_back (cmd_arg); 540405fe67fSCaroline Tice 541405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 542405fe67fSCaroline Tice options_arg.arg_type = eArgTypeAliasOptions; 543405fe67fSCaroline Tice options_arg.arg_repetition = eArgRepeatOptional; 544405fe67fSCaroline Tice 545405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 546405fe67fSCaroline Tice arg3.push_back (options_arg); 547405fe67fSCaroline Tice 548405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 549405fe67fSCaroline Tice m_arguments.push_back (arg1); 550405fe67fSCaroline Tice m_arguments.push_back (arg2); 551405fe67fSCaroline Tice m_arguments.push_back (arg3); 552ebc09c36SJim Ingham } 553ebc09c36SJim Ingham 554*13d21e9aSBruce Mitchener ~CommandObjectCommandsAlias () override 555ebc09c36SJim Ingham { 556ebc09c36SJim Ingham } 557ebc09c36SJim Ingham 5585a988416SJim Ingham protected: 559*13d21e9aSBruce Mitchener bool 560*13d21e9aSBruce Mitchener DoExecute (const char *raw_command_line, CommandReturnObject &result) override 561844d2303SCaroline Tice { 562844d2303SCaroline Tice Args args (raw_command_line); 563844d2303SCaroline Tice std::string raw_command_string (raw_command_line); 564844d2303SCaroline Tice 565844d2303SCaroline Tice size_t argc = args.GetArgumentCount(); 566844d2303SCaroline Tice 567844d2303SCaroline Tice if (argc < 2) 568844d2303SCaroline Tice { 569844d2303SCaroline Tice result.AppendError ("'alias' requires at least two arguments"); 570844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 571844d2303SCaroline Tice return false; 572844d2303SCaroline Tice } 573844d2303SCaroline Tice 574844d2303SCaroline Tice // Get the alias command. 575844d2303SCaroline Tice 576844d2303SCaroline Tice const std::string alias_command = args.GetArgumentAtIndex (0); 577844d2303SCaroline Tice 578844d2303SCaroline Tice // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which 579844d2303SCaroline Tice // does the stripping itself. 580844d2303SCaroline Tice size_t pos = raw_command_string.find (alias_command); 581844d2303SCaroline Tice if (pos == 0) 582844d2303SCaroline Tice { 583844d2303SCaroline Tice raw_command_string = raw_command_string.substr (alias_command.size()); 584844d2303SCaroline Tice pos = raw_command_string.find_first_not_of (' '); 585844d2303SCaroline Tice if ((pos != std::string::npos) && (pos > 0)) 586844d2303SCaroline Tice raw_command_string = raw_command_string.substr (pos); 587844d2303SCaroline Tice } 588844d2303SCaroline Tice else 589844d2303SCaroline Tice { 590844d2303SCaroline Tice result.AppendError ("Error parsing command string. No alias created."); 591844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 592844d2303SCaroline Tice return false; 593844d2303SCaroline Tice } 594844d2303SCaroline Tice 595844d2303SCaroline Tice 596844d2303SCaroline Tice // Verify that the command is alias-able. 597844d2303SCaroline Tice if (m_interpreter.CommandExists (alias_command.c_str())) 598844d2303SCaroline Tice { 599844d2303SCaroline Tice result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 600844d2303SCaroline Tice alias_command.c_str()); 601844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 602844d2303SCaroline Tice return false; 603844d2303SCaroline Tice } 604844d2303SCaroline Tice 605844d2303SCaroline Tice // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string. 606844d2303SCaroline Tice // raw_command_string is returned with the name of the command object stripped off the front. 607844d2303SCaroline Tice CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string); 608844d2303SCaroline Tice 609844d2303SCaroline Tice if (!cmd_obj) 610844d2303SCaroline Tice { 61186edbf41SGreg Clayton result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command." 612844d2303SCaroline Tice " No alias created.", raw_command_string.c_str()); 613844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 614844d2303SCaroline Tice return false; 615844d2303SCaroline Tice } 616844d2303SCaroline Tice else if (!cmd_obj->WantsRawCommandString ()) 617844d2303SCaroline Tice { 618844d2303SCaroline Tice // Note that args was initialized with the original command, and has not been updated to this point. 619844d2303SCaroline Tice // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias. 6205a988416SJim Ingham return HandleAliasingNormalCommand (args, result); 621844d2303SCaroline Tice } 622844d2303SCaroline Tice else 623844d2303SCaroline Tice { 6245a988416SJim Ingham return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result); 6255a988416SJim Ingham } 6265a988416SJim Ingham return result.Succeeded(); 6275a988416SJim Ingham } 6285a988416SJim Ingham 6295a988416SJim Ingham bool 6305a988416SJim Ingham HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result) 6315a988416SJim Ingham { 632844d2303SCaroline Tice // Verify & handle any options/arguments passed to the alias command 633844d2303SCaroline Tice 634844d2303SCaroline Tice OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 635844d2303SCaroline Tice OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 636844d2303SCaroline Tice 6375a988416SJim Ingham CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false); 638844d2303SCaroline Tice 639ca90c47eSCaroline Tice if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp)) 640844d2303SCaroline Tice { 641844d2303SCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 642ca90c47eSCaroline Tice result.SetStatus (eReturnStatusFailed); 643844d2303SCaroline Tice return false; 644844d2303SCaroline Tice } 645844d2303SCaroline Tice 646844d2303SCaroline Tice // Create the alias 647844d2303SCaroline Tice if (m_interpreter.AliasExists (alias_command.c_str()) 648844d2303SCaroline Tice || m_interpreter.UserCommandExists (alias_command.c_str())) 649844d2303SCaroline Tice { 650844d2303SCaroline Tice OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 651844d2303SCaroline Tice if (temp_option_arg_sp.get()) 652844d2303SCaroline Tice { 653844d2303SCaroline Tice if (option_arg_vector->size() == 0) 654844d2303SCaroline Tice m_interpreter.RemoveAliasOptions (alias_command.c_str()); 655844d2303SCaroline Tice } 656844d2303SCaroline Tice result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 657844d2303SCaroline Tice alias_command.c_str()); 658844d2303SCaroline Tice } 659844d2303SCaroline Tice 660472362e6SCaroline Tice if (cmd_obj_sp) 661472362e6SCaroline Tice { 662844d2303SCaroline Tice m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp); 663844d2303SCaroline Tice if (option_arg_vector->size() > 0) 664844d2303SCaroline Tice m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 665844d2303SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 666844d2303SCaroline Tice } 667472362e6SCaroline Tice else 668472362e6SCaroline Tice { 669472362e6SCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 670472362e6SCaroline Tice result.SetStatus (eReturnStatusFailed); 671472362e6SCaroline Tice } 672844d2303SCaroline Tice return result.Succeeded (); 673844d2303SCaroline Tice } 674ebc09c36SJim Ingham 675ebc09c36SJim Ingham bool 6765a988416SJim Ingham HandleAliasingNormalCommand (Args& args, CommandReturnObject &result) 677ebc09c36SJim Ingham { 678867b185dSCaroline Tice size_t argc = args.GetArgumentCount(); 679ebc09c36SJim Ingham 680ebc09c36SJim Ingham if (argc < 2) 681ebc09c36SJim Ingham { 682ebc09c36SJim Ingham result.AppendError ("'alias' requires at least two arguments"); 683ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 684ebc09c36SJim Ingham return false; 685ebc09c36SJim Ingham } 686ebc09c36SJim Ingham 687ebc09c36SJim Ingham const std::string alias_command = args.GetArgumentAtIndex(0); 688ebc09c36SJim Ingham const std::string actual_command = args.GetArgumentAtIndex(1); 689ebc09c36SJim Ingham 690ebc09c36SJim Ingham args.Shift(); // Shift the alias command word off the argument vector. 691ebc09c36SJim Ingham args.Shift(); // Shift the old command word off the argument vector. 692ebc09c36SJim Ingham 693ebc09c36SJim Ingham // Verify that the command is alias'able, and get the appropriate command object. 694ebc09c36SJim Ingham 695a7015092SGreg Clayton if (m_interpreter.CommandExists (alias_command.c_str())) 696ebc09c36SJim Ingham { 697ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 698ebc09c36SJim Ingham alias_command.c_str()); 699ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 700ebc09c36SJim Ingham } 701ebc09c36SJim Ingham else 702ebc09c36SJim Ingham { 703a7015092SGreg Clayton CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true)); 704ebc09c36SJim Ingham CommandObjectSP subcommand_obj_sp; 705ebc09c36SJim Ingham bool use_subcommand = false; 706ebc09c36SJim Ingham if (command_obj_sp.get()) 707ebc09c36SJim Ingham { 708ebc09c36SJim Ingham CommandObject *cmd_obj = command_obj_sp.get(); 709c982c768SGreg Clayton CommandObject *sub_cmd_obj = NULL; 710ebc09c36SJim Ingham OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 711ebc09c36SJim Ingham OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 712ebc09c36SJim Ingham 713844d2303SCaroline Tice while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0) 714ebc09c36SJim Ingham { 715ebc09c36SJim Ingham if (argc >= 3) 716ebc09c36SJim Ingham { 717ebc09c36SJim Ingham const std::string sub_command = args.GetArgumentAtIndex(0); 718ebc09c36SJim Ingham assert (sub_command.length() != 0); 719998255bfSGreg Clayton subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str()); 720ebc09c36SJim Ingham if (subcommand_obj_sp.get()) 721ebc09c36SJim Ingham { 722ebc09c36SJim Ingham sub_cmd_obj = subcommand_obj_sp.get(); 723ebc09c36SJim Ingham use_subcommand = true; 724ebc09c36SJim Ingham args.Shift(); // Shift the sub_command word off the argument vector. 725844d2303SCaroline Tice cmd_obj = sub_cmd_obj; 726ebc09c36SJim Ingham } 727ebc09c36SJim Ingham else 728ebc09c36SJim Ingham { 729f415eeb4SCaroline Tice result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. " 730f415eeb4SCaroline Tice "Unable to create alias.\n", 731f415eeb4SCaroline Tice sub_command.c_str(), actual_command.c_str()); 732ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 733ebc09c36SJim Ingham return false; 734ebc09c36SJim Ingham } 735ebc09c36SJim Ingham } 736ebc09c36SJim Ingham } 737ebc09c36SJim Ingham 738ebc09c36SJim Ingham // Verify & handle any options/arguments passed to the alias command 739ebc09c36SJim Ingham 740ebc09c36SJim Ingham if (args.GetArgumentCount () > 0) 741ebc09c36SJim Ingham { 742ca90c47eSCaroline Tice CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); 743ebc09c36SJim Ingham if (use_subcommand) 744ca90c47eSCaroline Tice tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false); 745ca90c47eSCaroline Tice 746ca90c47eSCaroline Tice std::string args_string; 747ca90c47eSCaroline Tice args.GetCommandString (args_string); 748ca90c47eSCaroline Tice 749ca90c47eSCaroline Tice if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp)) 750ebc09c36SJim Ingham { 751ca90c47eSCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 752ca90c47eSCaroline Tice result.SetStatus (eReturnStatusFailed); 753e7941795SCaroline Tice return false; 754867b185dSCaroline Tice } 755867b185dSCaroline Tice } 756867b185dSCaroline Tice 757ebc09c36SJim Ingham // Create the alias. 758ebc09c36SJim Ingham 759a7015092SGreg Clayton if (m_interpreter.AliasExists (alias_command.c_str()) 760a7015092SGreg Clayton || m_interpreter.UserCommandExists (alias_command.c_str())) 761ebc09c36SJim Ingham { 762a7015092SGreg Clayton OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 763ebc09c36SJim Ingham if (tmp_option_arg_sp.get()) 764ebc09c36SJim Ingham { 765ebc09c36SJim Ingham if (option_arg_vector->size() == 0) 766a7015092SGreg Clayton m_interpreter.RemoveAliasOptions (alias_command.c_str()); 767ebc09c36SJim Ingham } 768ebc09c36SJim Ingham result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 769ebc09c36SJim Ingham alias_command.c_str()); 770ebc09c36SJim Ingham } 771ebc09c36SJim Ingham 772ebc09c36SJim Ingham if (use_subcommand) 773a7015092SGreg Clayton m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp); 774ebc09c36SJim Ingham else 775a7015092SGreg Clayton m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp); 776ebc09c36SJim Ingham if (option_arg_vector->size() > 0) 777a7015092SGreg Clayton m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 778ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 779ebc09c36SJim Ingham } 780ebc09c36SJim Ingham else 781ebc09c36SJim Ingham { 782ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str()); 783ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 784e7941795SCaroline Tice return false; 785ebc09c36SJim Ingham } 786ebc09c36SJim Ingham } 787ebc09c36SJim Ingham 788ebc09c36SJim Ingham return result.Succeeded(); 789ebc09c36SJim Ingham } 7905a988416SJim Ingham 791ebc09c36SJim Ingham }; 792ebc09c36SJim Ingham 793ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias 794ebc09c36SJim Ingham //------------------------------------------------------------------------- 795ebc09c36SJim Ingham // CommandObjectCommandsUnalias 796ebc09c36SJim Ingham //------------------------------------------------------------------------- 797ebc09c36SJim Ingham 7985a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed 799ebc09c36SJim Ingham { 800ebc09c36SJim Ingham public: 801a7015092SGreg Clayton CommandObjectCommandsUnalias (CommandInterpreter &interpreter) : 8025a988416SJim Ingham CommandObjectParsed (interpreter, 8030e5e5a79SGreg Clayton "command unalias", 80486ddae50SCaroline Tice "Allow the user to remove/delete a user-defined command abbreviation.", 805405fe67fSCaroline Tice NULL) 806ebc09c36SJim Ingham { 807405fe67fSCaroline Tice CommandArgumentEntry arg; 808405fe67fSCaroline Tice CommandArgumentData alias_arg; 809405fe67fSCaroline Tice 810405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 811405fe67fSCaroline Tice alias_arg.arg_type = eArgTypeAliasName; 812405fe67fSCaroline Tice alias_arg.arg_repetition = eArgRepeatPlain; 813405fe67fSCaroline Tice 814405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 815405fe67fSCaroline Tice arg.push_back (alias_arg); 816405fe67fSCaroline Tice 817405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 818405fe67fSCaroline Tice m_arguments.push_back (arg); 819ebc09c36SJim Ingham } 820ebc09c36SJim Ingham 821*13d21e9aSBruce Mitchener ~CommandObjectCommandsUnalias() override 822ebc09c36SJim Ingham { 823ebc09c36SJim Ingham } 824ebc09c36SJim Ingham 8255a988416SJim Ingham protected: 826ebc09c36SJim Ingham bool 827*13d21e9aSBruce Mitchener DoExecute (Args& args, CommandReturnObject &result) override 828ebc09c36SJim Ingham { 829ebc09c36SJim Ingham CommandObject::CommandMap::iterator pos; 830ebc09c36SJim Ingham CommandObject *cmd_obj; 831ebc09c36SJim Ingham 832ebc09c36SJim Ingham if (args.GetArgumentCount() != 0) 833ebc09c36SJim Ingham { 834ebc09c36SJim Ingham const char *command_name = args.GetArgumentAtIndex(0); 835a7015092SGreg Clayton cmd_obj = m_interpreter.GetCommandObject(command_name); 836ebc09c36SJim Ingham if (cmd_obj) 837ebc09c36SJim Ingham { 838a7015092SGreg Clayton if (m_interpreter.CommandExists (command_name)) 839ebc09c36SJim Ingham { 840b547278cSGreg Clayton if (cmd_obj->IsRemovable()) 841b547278cSGreg Clayton { 842b547278cSGreg Clayton result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n", 843b547278cSGreg Clayton command_name); 844b547278cSGreg Clayton } 845b547278cSGreg Clayton else 846b547278cSGreg Clayton { 847ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 848ebc09c36SJim Ingham command_name); 849b547278cSGreg Clayton } 850ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 851ebc09c36SJim Ingham } 852ebc09c36SJim Ingham else 853ebc09c36SJim Ingham { 854ebc09c36SJim Ingham 855a7015092SGreg Clayton if (m_interpreter.RemoveAlias (command_name) == false) 856ebc09c36SJim Ingham { 857a7015092SGreg Clayton if (m_interpreter.AliasExists (command_name)) 858ebc09c36SJim Ingham result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n", 859ebc09c36SJim Ingham command_name); 860ebc09c36SJim Ingham else 861ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name); 862ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 863ebc09c36SJim Ingham } 864ebc09c36SJim Ingham else 865ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 866ebc09c36SJim Ingham } 867ebc09c36SJim Ingham } 868ebc09c36SJim Ingham else 869ebc09c36SJim Ingham { 870ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a " 871ebc09c36SJim Ingham "current list of commands.\n", 872ebc09c36SJim Ingham command_name); 873ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 874ebc09c36SJim Ingham } 875ebc09c36SJim Ingham } 876ebc09c36SJim Ingham else 877ebc09c36SJim Ingham { 878ebc09c36SJim Ingham result.AppendError ("must call 'unalias' with a valid alias"); 879ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 880ebc09c36SJim Ingham } 881ebc09c36SJim Ingham 882ebc09c36SJim Ingham return result.Succeeded(); 883ebc09c36SJim Ingham } 884ebc09c36SJim Ingham }; 885ebc09c36SJim Ingham 886b547278cSGreg Clayton #pragma mark CommandObjectCommandsDelete 887b547278cSGreg Clayton //------------------------------------------------------------------------- 888b547278cSGreg Clayton // CommandObjectCommandsDelete 889b547278cSGreg Clayton //------------------------------------------------------------------------- 890b547278cSGreg Clayton 891b547278cSGreg Clayton class CommandObjectCommandsDelete : public CommandObjectParsed 892b547278cSGreg Clayton { 893b547278cSGreg Clayton public: 894b547278cSGreg Clayton CommandObjectCommandsDelete (CommandInterpreter &interpreter) : 895b547278cSGreg Clayton CommandObjectParsed (interpreter, 896b547278cSGreg Clayton "command delete", 897b547278cSGreg Clayton "Allow the user to delete user-defined regular expression, python or multi-word commands.", 898b547278cSGreg Clayton NULL) 899b547278cSGreg Clayton { 900b547278cSGreg Clayton CommandArgumentEntry arg; 901b547278cSGreg Clayton CommandArgumentData alias_arg; 902b547278cSGreg Clayton 903b547278cSGreg Clayton // Define the first (and only) variant of this arg. 904b547278cSGreg Clayton alias_arg.arg_type = eArgTypeCommandName; 905b547278cSGreg Clayton alias_arg.arg_repetition = eArgRepeatPlain; 906b547278cSGreg Clayton 907b547278cSGreg Clayton // There is only one variant this argument could be; put it into the argument entry. 908b547278cSGreg Clayton arg.push_back (alias_arg); 909b547278cSGreg Clayton 910b547278cSGreg Clayton // Push the data for the first argument into the m_arguments vector. 911b547278cSGreg Clayton m_arguments.push_back (arg); 912b547278cSGreg Clayton } 913b547278cSGreg Clayton 914*13d21e9aSBruce Mitchener ~CommandObjectCommandsDelete() override 915b547278cSGreg Clayton { 916b547278cSGreg Clayton } 917b547278cSGreg Clayton 918b547278cSGreg Clayton protected: 919b547278cSGreg Clayton bool 920*13d21e9aSBruce Mitchener DoExecute (Args& args, CommandReturnObject &result) override 921b547278cSGreg Clayton { 922b547278cSGreg Clayton CommandObject::CommandMap::iterator pos; 923b547278cSGreg Clayton 924b547278cSGreg Clayton if (args.GetArgumentCount() != 0) 925b547278cSGreg Clayton { 926b547278cSGreg Clayton const char *command_name = args.GetArgumentAtIndex(0); 927b547278cSGreg Clayton if (m_interpreter.CommandExists (command_name)) 928b547278cSGreg Clayton { 929b547278cSGreg Clayton if (m_interpreter.RemoveCommand (command_name)) 930b547278cSGreg Clayton { 931b547278cSGreg Clayton result.SetStatus (eReturnStatusSuccessFinishNoResult); 932b547278cSGreg Clayton } 933b547278cSGreg Clayton else 934b547278cSGreg Clayton { 935b547278cSGreg Clayton result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 936b547278cSGreg Clayton command_name); 937b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 938b547278cSGreg Clayton } 939b547278cSGreg Clayton } 940b547278cSGreg Clayton else 941b547278cSGreg Clayton { 942b547278cSGreg Clayton result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n", 943b547278cSGreg Clayton command_name); 944b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 945b547278cSGreg Clayton } 946b547278cSGreg Clayton } 947b547278cSGreg Clayton else 948b547278cSGreg Clayton { 949b547278cSGreg Clayton result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ()); 950b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 951b547278cSGreg Clayton } 952b547278cSGreg Clayton 953b547278cSGreg Clayton return result.Succeeded(); 954b547278cSGreg Clayton } 955b547278cSGreg Clayton }; 956b547278cSGreg Clayton 957de164aaaSGreg Clayton //------------------------------------------------------------------------- 958de164aaaSGreg Clayton // CommandObjectCommandsAddRegex 959de164aaaSGreg Clayton //------------------------------------------------------------------------- 9605a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex 961de164aaaSGreg Clayton 96244d93782SGreg Clayton class CommandObjectCommandsAddRegex : 96344d93782SGreg Clayton public CommandObjectParsed, 964ea508635SGreg Clayton public IOHandlerDelegateMultiline 965de164aaaSGreg Clayton { 966de164aaaSGreg Clayton public: 967de164aaaSGreg Clayton CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) : 9685a988416SJim Ingham CommandObjectParsed (interpreter, 9690e5e5a79SGreg Clayton "command regex", 970de164aaaSGreg Clayton "Allow the user to create a regular expression command.", 9710e5e5a79SGreg Clayton "command regex <cmd-name> [s/<regex>/<subst>/ ...]"), 972ea508635SGreg Clayton IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand), 973de164aaaSGreg Clayton m_options (interpreter) 974de164aaaSGreg Clayton { 975ea671fbdSKate Stone SetHelpLong(R"( 976ea671fbdSKate Stone )" "This command allows the user to create powerful regular expression commands \ 977ea671fbdSKate Stone with substitutions. The regular expressions and substitutions are specified \ 978ea671fbdSKate Stone using the regular expression substitution format of:" R"( 979ea671fbdSKate Stone 980ea671fbdSKate Stone s/<regex>/<subst>/ 981ea671fbdSKate Stone 982ea671fbdSKate Stone )" "<regex> is a regular expression that can use parenthesis to capture regular \ 983ea671fbdSKate Stone expression input and substitute the captured matches in the output using %1 \ 984ea671fbdSKate Stone for the first match, %2 for the second, and so on." R"( 985ea671fbdSKate Stone 986ea671fbdSKate Stone )" "The regular expressions can all be specified on the command line if more than \ 987ea671fbdSKate Stone one argument is provided. If just the command name is provided on the command \ 988ea671fbdSKate Stone line, then the regular expressions and substitutions can be entered on separate \ 989ea671fbdSKate Stone lines, followed by an empty line to terminate the command definition." R"( 990ea671fbdSKate Stone 991ea671fbdSKate Stone EXAMPLES 992ea671fbdSKate Stone 993ea671fbdSKate Stone )" "The following example will define a regular expression command named 'f' that \ 994ea671fbdSKate Stone will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \ 995ea671fbdSKate Stone a number follows 'f':" R"( 996ea671fbdSKate Stone 997ea671fbdSKate Stone (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')" 9980e5e5a79SGreg Clayton ); 999de164aaaSGreg Clayton } 1000de164aaaSGreg Clayton 1001*13d21e9aSBruce Mitchener ~CommandObjectCommandsAddRegex() override 1002de164aaaSGreg Clayton { 1003de164aaaSGreg Clayton } 1004de164aaaSGreg Clayton 1005de164aaaSGreg Clayton 10065a988416SJim Ingham protected: 100744d93782SGreg Clayton 1008ea508635SGreg Clayton void 1009ea508635SGreg Clayton IOHandlerActivated (IOHandler &io_handler) override 101044d93782SGreg Clayton { 101144d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 101244d93782SGreg Clayton if (output_sp) 101344d93782SGreg Clayton { 101444d93782SGreg Clayton output_sp->PutCString("Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\nTerminate the substitution list with an empty line.\n"); 101544d93782SGreg Clayton output_sp->Flush(); 101644d93782SGreg Clayton } 101744d93782SGreg Clayton } 101844d93782SGreg Clayton 1019ea508635SGreg Clayton void 1020ea508635SGreg Clayton IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override 102144d93782SGreg Clayton { 102244d93782SGreg Clayton io_handler.SetIsDone(true); 102344d93782SGreg Clayton if (m_regex_cmd_ap.get()) 102444d93782SGreg Clayton { 102544d93782SGreg Clayton StringList lines; 102644d93782SGreg Clayton if (lines.SplitIntoLines (data)) 102744d93782SGreg Clayton { 102844d93782SGreg Clayton const size_t num_lines = lines.GetSize(); 102944d93782SGreg Clayton bool check_only = false; 103044d93782SGreg Clayton for (size_t i=0; i<num_lines; ++i) 103144d93782SGreg Clayton { 103244d93782SGreg Clayton llvm::StringRef bytes_strref (lines[i]); 103344d93782SGreg Clayton Error error = AppendRegexSubstitution (bytes_strref, check_only); 103444d93782SGreg Clayton if (error.Fail()) 103544d93782SGreg Clayton { 103644d93782SGreg Clayton if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) 103744d93782SGreg Clayton { 103844d93782SGreg Clayton StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream(); 103944d93782SGreg Clayton out_stream->Printf("error: %s\n", error.AsCString()); 104044d93782SGreg Clayton } 104144d93782SGreg Clayton } 104244d93782SGreg Clayton } 104344d93782SGreg Clayton } 104444d93782SGreg Clayton if (m_regex_cmd_ap->HasRegexEntries()) 104544d93782SGreg Clayton { 104644d93782SGreg Clayton CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 104744d93782SGreg Clayton m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 104844d93782SGreg Clayton } 104944d93782SGreg Clayton } 105044d93782SGreg Clayton } 105144d93782SGreg Clayton 1052de164aaaSGreg Clayton bool 1053b0a1814fSEric Christopher DoExecute (Args& command, CommandReturnObject &result) override 1054de164aaaSGreg Clayton { 10555a988416SJim Ingham const size_t argc = command.GetArgumentCount(); 10560e5e5a79SGreg Clayton if (argc == 0) 1057de164aaaSGreg Clayton { 105869c12ccbSJason Molenda result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n"); 10590e5e5a79SGreg Clayton result.SetStatus (eReturnStatusFailed); 10600e5e5a79SGreg Clayton } 10610e5e5a79SGreg Clayton else 10620e5e5a79SGreg Clayton { 10630e5e5a79SGreg Clayton Error error; 10645a988416SJim Ingham const char *name = command.GetArgumentAtIndex(0); 1065de164aaaSGreg Clayton m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter, 1066de164aaaSGreg Clayton name, 1067de164aaaSGreg Clayton m_options.GetHelp (), 1068de164aaaSGreg Clayton m_options.GetSyntax (), 1069b547278cSGreg Clayton 10, 1070b547278cSGreg Clayton 0, 1071b547278cSGreg Clayton true)); 10720e5e5a79SGreg Clayton 10730e5e5a79SGreg Clayton if (argc == 1) 10740e5e5a79SGreg Clayton { 107544d93782SGreg Clayton Debugger &debugger = m_interpreter.GetDebugger(); 1076e30f11d9SKate Stone bool color_prompt = debugger.GetUseColor(); 107744d93782SGreg Clayton const bool multiple_lines = true; // Get multiple lines 107844d93782SGreg Clayton IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, 1079e30f11d9SKate Stone IOHandler::Type::Other, 108073d80faaSGreg Clayton "lldb-regex", // Name of input reader for history 1081ea508635SGreg Clayton "> ", // Prompt 1082e30f11d9SKate Stone NULL, // Continuation prompt 108344d93782SGreg Clayton multiple_lines, 1084e30f11d9SKate Stone color_prompt, 1085f6913cd7SGreg Clayton 0, // Don't show line numbers 108644d93782SGreg Clayton *this)); 108744d93782SGreg Clayton 108844d93782SGreg Clayton if (io_handler_sp) 1089de164aaaSGreg Clayton { 109044d93782SGreg Clayton debugger.PushIOHandler(io_handler_sp); 1091de164aaaSGreg Clayton result.SetStatus (eReturnStatusSuccessFinishNoResult); 1092de164aaaSGreg Clayton } 1093de164aaaSGreg Clayton } 1094de164aaaSGreg Clayton else 1095de164aaaSGreg Clayton { 10960e5e5a79SGreg Clayton for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) 10970e5e5a79SGreg Clayton { 10985a988416SJim Ingham llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx)); 109944d93782SGreg Clayton bool check_only = false; 110044d93782SGreg Clayton error = AppendRegexSubstitution (arg_strref, check_only); 11010e5e5a79SGreg Clayton if (error.Fail()) 11020e5e5a79SGreg Clayton break; 11030e5e5a79SGreg Clayton } 11040e5e5a79SGreg Clayton 11050e5e5a79SGreg Clayton if (error.Success()) 11060e5e5a79SGreg Clayton { 11070e5e5a79SGreg Clayton AddRegexCommandToInterpreter(); 11080e5e5a79SGreg Clayton } 11090e5e5a79SGreg Clayton } 11100e5e5a79SGreg Clayton if (error.Fail()) 11110e5e5a79SGreg Clayton { 11120e5e5a79SGreg Clayton result.AppendError (error.AsCString()); 1113de164aaaSGreg Clayton result.SetStatus (eReturnStatusFailed); 1114de164aaaSGreg Clayton } 11150e5e5a79SGreg Clayton } 11160e5e5a79SGreg Clayton 1117de164aaaSGreg Clayton return result.Succeeded(); 1118de164aaaSGreg Clayton } 1119de164aaaSGreg Clayton 11200e5e5a79SGreg Clayton Error 112144d93782SGreg Clayton AppendRegexSubstitution (const llvm::StringRef ®ex_sed, bool check_only) 1122de164aaaSGreg Clayton { 11230e5e5a79SGreg Clayton Error error; 11240e5e5a79SGreg Clayton 11250e5e5a79SGreg Clayton if (m_regex_cmd_ap.get() == NULL) 1126de164aaaSGreg Clayton { 11270e5e5a79SGreg Clayton error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'", 11280e5e5a79SGreg Clayton (int)regex_sed.size(), 11290e5e5a79SGreg Clayton regex_sed.data()); 11300e5e5a79SGreg Clayton return error; 1131de164aaaSGreg Clayton } 11320e5e5a79SGreg Clayton 11330e5e5a79SGreg Clayton size_t regex_sed_size = regex_sed.size(); 11340e5e5a79SGreg Clayton 11350e5e5a79SGreg Clayton if (regex_sed_size <= 1) 11360e5e5a79SGreg Clayton { 11370e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'", 11380e5e5a79SGreg Clayton (int)regex_sed.size(), 11390e5e5a79SGreg Clayton regex_sed.data()); 11400e5e5a79SGreg Clayton return error; 11410e5e5a79SGreg Clayton } 11420e5e5a79SGreg Clayton 11430e5e5a79SGreg Clayton if (regex_sed[0] != 's') 11440e5e5a79SGreg Clayton { 11450e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'", 11460e5e5a79SGreg Clayton (int)regex_sed.size(), 11470e5e5a79SGreg Clayton regex_sed.data()); 11480e5e5a79SGreg Clayton return error; 11490e5e5a79SGreg Clayton } 11500e5e5a79SGreg Clayton const size_t first_separator_char_pos = 1; 11510e5e5a79SGreg Clayton // use the char that follows 's' as the regex separator character 11520e5e5a79SGreg Clayton // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" 11530e5e5a79SGreg Clayton const char separator_char = regex_sed[first_separator_char_pos]; 11540e5e5a79SGreg Clayton const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1); 11550e5e5a79SGreg Clayton 11560e5e5a79SGreg Clayton if (second_separator_char_pos == std::string::npos) 11570e5e5a79SGreg Clayton { 1158ea508635SGreg Clayton error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'", 11590e5e5a79SGreg Clayton separator_char, 11600e5e5a79SGreg Clayton (int)(regex_sed.size() - first_separator_char_pos - 1), 1161ea508635SGreg Clayton regex_sed.data() + (first_separator_char_pos + 1), 1162ea508635SGreg Clayton (int)regex_sed.size(), 1163ea508635SGreg Clayton regex_sed.data()); 11640e5e5a79SGreg Clayton return error; 11650e5e5a79SGreg Clayton } 11660e5e5a79SGreg Clayton 11670e5e5a79SGreg Clayton const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1); 11680e5e5a79SGreg Clayton 11690e5e5a79SGreg Clayton if (third_separator_char_pos == std::string::npos) 11700e5e5a79SGreg Clayton { 1171ea508635SGreg Clayton error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'", 11720e5e5a79SGreg Clayton separator_char, 11730e5e5a79SGreg Clayton (int)(regex_sed.size() - second_separator_char_pos - 1), 1174ea508635SGreg Clayton regex_sed.data() + (second_separator_char_pos + 1), 1175ea508635SGreg Clayton (int)regex_sed.size(), 1176ea508635SGreg Clayton regex_sed.data()); 11770e5e5a79SGreg Clayton return error; 11780e5e5a79SGreg Clayton } 11790e5e5a79SGreg Clayton 11800e5e5a79SGreg Clayton if (third_separator_char_pos != regex_sed_size - 1) 11810e5e5a79SGreg Clayton { 11820e5e5a79SGreg Clayton // Make sure that everything that follows the last regex 11830e5e5a79SGreg Clayton // separator char 11840e5e5a79SGreg Clayton if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) 11850e5e5a79SGreg Clayton { 11860e5e5a79SGreg Clayton error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'", 11870e5e5a79SGreg Clayton (int)third_separator_char_pos + 1, 11880e5e5a79SGreg Clayton regex_sed.data(), 11890e5e5a79SGreg Clayton (int)(regex_sed.size() - third_separator_char_pos - 1), 11900e5e5a79SGreg Clayton regex_sed.data() + (third_separator_char_pos + 1)); 11910e5e5a79SGreg Clayton return error; 11920e5e5a79SGreg Clayton } 11930e5e5a79SGreg Clayton 11940e5e5a79SGreg Clayton } 11950e5e5a79SGreg Clayton else if (first_separator_char_pos + 1 == second_separator_char_pos) 11960e5e5a79SGreg Clayton { 11970e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 11980e5e5a79SGreg Clayton separator_char, 11990e5e5a79SGreg Clayton separator_char, 12000e5e5a79SGreg Clayton separator_char, 12010e5e5a79SGreg Clayton (int)regex_sed.size(), 12020e5e5a79SGreg Clayton regex_sed.data()); 12030e5e5a79SGreg Clayton return error; 12040e5e5a79SGreg Clayton } 12050e5e5a79SGreg Clayton else if (second_separator_char_pos + 1 == third_separator_char_pos) 12060e5e5a79SGreg Clayton { 12070e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 12080e5e5a79SGreg Clayton separator_char, 12090e5e5a79SGreg Clayton separator_char, 12100e5e5a79SGreg Clayton separator_char, 12110e5e5a79SGreg Clayton (int)regex_sed.size(), 12120e5e5a79SGreg Clayton regex_sed.data()); 12130e5e5a79SGreg Clayton return error; 12140e5e5a79SGreg Clayton } 121544d93782SGreg Clayton 121644d93782SGreg Clayton if (check_only == false) 121744d93782SGreg Clayton { 12180e5e5a79SGreg Clayton std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1)); 12190e5e5a79SGreg Clayton std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1)); 12200e5e5a79SGreg Clayton m_regex_cmd_ap->AddRegexCommand (regex.c_str(), 12210e5e5a79SGreg Clayton subst.c_str()); 122244d93782SGreg Clayton } 12230e5e5a79SGreg Clayton return error; 1224de164aaaSGreg Clayton } 1225de164aaaSGreg Clayton 1226de164aaaSGreg Clayton void 12270e5e5a79SGreg Clayton AddRegexCommandToInterpreter() 1228de164aaaSGreg Clayton { 1229de164aaaSGreg Clayton if (m_regex_cmd_ap.get()) 1230de164aaaSGreg Clayton { 1231de164aaaSGreg Clayton if (m_regex_cmd_ap->HasRegexEntries()) 1232de164aaaSGreg Clayton { 1233de164aaaSGreg Clayton CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 1234de164aaaSGreg Clayton m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 1235de164aaaSGreg Clayton } 1236de164aaaSGreg Clayton } 1237de164aaaSGreg Clayton } 1238de164aaaSGreg Clayton 1239de164aaaSGreg Clayton private: 12407b0992d9SGreg Clayton std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap; 1241de164aaaSGreg Clayton 1242de164aaaSGreg Clayton class CommandOptions : public Options 1243de164aaaSGreg Clayton { 1244de164aaaSGreg Clayton public: 1245de164aaaSGreg Clayton 1246de164aaaSGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 1247de164aaaSGreg Clayton Options (interpreter) 1248de164aaaSGreg Clayton { 1249de164aaaSGreg Clayton } 1250de164aaaSGreg Clayton 1251*13d21e9aSBruce Mitchener ~CommandOptions () override {} 1252de164aaaSGreg Clayton 1253*13d21e9aSBruce Mitchener Error 1254*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 1255de164aaaSGreg Clayton { 1256de164aaaSGreg Clayton Error error; 12573bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 1258de164aaaSGreg Clayton 1259de164aaaSGreg Clayton switch (short_option) 1260de164aaaSGreg Clayton { 1261de164aaaSGreg Clayton case 'h': 1262de164aaaSGreg Clayton m_help.assign (option_arg); 1263de164aaaSGreg Clayton break; 1264de164aaaSGreg Clayton case 's': 1265de164aaaSGreg Clayton m_syntax.assign (option_arg); 1266de164aaaSGreg Clayton break; 1267de164aaaSGreg Clayton 1268de164aaaSGreg Clayton default: 126986edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1270de164aaaSGreg Clayton break; 1271de164aaaSGreg Clayton } 1272de164aaaSGreg Clayton 1273de164aaaSGreg Clayton return error; 1274de164aaaSGreg Clayton } 1275de164aaaSGreg Clayton 1276de164aaaSGreg Clayton void 1277*13d21e9aSBruce Mitchener OptionParsingStarting () override 1278de164aaaSGreg Clayton { 1279de164aaaSGreg Clayton m_help.clear(); 1280de164aaaSGreg Clayton m_syntax.clear(); 1281de164aaaSGreg Clayton } 1282de164aaaSGreg Clayton 1283de164aaaSGreg Clayton const OptionDefinition* 1284*13d21e9aSBruce Mitchener GetDefinitions () override 1285de164aaaSGreg Clayton { 1286de164aaaSGreg Clayton return g_option_table; 1287de164aaaSGreg Clayton } 1288de164aaaSGreg Clayton 1289de164aaaSGreg Clayton // Options table: Required for subclasses of Options. 1290de164aaaSGreg Clayton 1291de164aaaSGreg Clayton static OptionDefinition g_option_table[]; 1292de164aaaSGreg Clayton 1293de164aaaSGreg Clayton const char * 1294de164aaaSGreg Clayton GetHelp () 1295de164aaaSGreg Clayton { 1296de164aaaSGreg Clayton if (m_help.empty()) 1297de164aaaSGreg Clayton return NULL; 1298de164aaaSGreg Clayton return m_help.c_str(); 1299de164aaaSGreg Clayton } 1300de164aaaSGreg Clayton const char * 1301de164aaaSGreg Clayton GetSyntax () 1302de164aaaSGreg Clayton { 1303de164aaaSGreg Clayton if (m_syntax.empty()) 1304de164aaaSGreg Clayton return NULL; 1305de164aaaSGreg Clayton return m_syntax.c_str(); 1306de164aaaSGreg Clayton } 1307de164aaaSGreg Clayton // Instance variables to hold the values for command options. 1308de164aaaSGreg Clayton protected: 1309de164aaaSGreg Clayton std::string m_help; 1310de164aaaSGreg Clayton std::string m_syntax; 1311de164aaaSGreg Clayton }; 1312de164aaaSGreg Clayton 1313b0a1814fSEric Christopher Options * 1314b0a1814fSEric Christopher GetOptions () override 1315de164aaaSGreg Clayton { 1316de164aaaSGreg Clayton return &m_options; 1317de164aaaSGreg Clayton } 1318de164aaaSGreg Clayton 13195a988416SJim Ingham CommandOptions m_options; 1320de164aaaSGreg Clayton }; 1321de164aaaSGreg Clayton 1322de164aaaSGreg Clayton OptionDefinition 1323de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = 1324de164aaaSGreg Clayton { 1325d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."}, 1326d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, 1327d37221dcSZachary Turner { 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone, NULL } 1328de164aaaSGreg Clayton }; 1329de164aaaSGreg Clayton 1330de164aaaSGreg Clayton 13315a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw 1332223383edSEnrico Granata { 1333223383edSEnrico Granata private: 1334223383edSEnrico Granata std::string m_function_name; 13350a305db7SEnrico Granata ScriptedCommandSynchronicity m_synchro; 1336fac939e9SEnrico Granata bool m_fetched_help_long; 1337223383edSEnrico Granata 1338223383edSEnrico Granata public: 1339223383edSEnrico Granata 1340223383edSEnrico Granata CommandObjectPythonFunction (CommandInterpreter &interpreter, 1341223383edSEnrico Granata std::string name, 13420a305db7SEnrico Granata std::string funct, 1343735152e3SEnrico Granata std::string help, 13440a305db7SEnrico Granata ScriptedCommandSynchronicity synch) : 13455a988416SJim Ingham CommandObjectRaw (interpreter, 1346223383edSEnrico Granata name.c_str(), 1347735152e3SEnrico Granata NULL, 1348223383edSEnrico Granata NULL), 13490a305db7SEnrico Granata m_function_name(funct), 1350fac939e9SEnrico Granata m_synchro(synch), 1351fac939e9SEnrico Granata m_fetched_help_long(false) 1352223383edSEnrico Granata { 1353735152e3SEnrico Granata if (!help.empty()) 1354735152e3SEnrico Granata SetHelp(help.c_str()); 1355735152e3SEnrico Granata else 1356735152e3SEnrico Granata { 1357735152e3SEnrico Granata StreamString stream; 1358735152e3SEnrico Granata stream.Printf("For more information run 'help %s'",name.c_str()); 1359735152e3SEnrico Granata SetHelp(stream.GetData()); 1360735152e3SEnrico Granata } 1361223383edSEnrico Granata } 1362223383edSEnrico Granata 1363*13d21e9aSBruce Mitchener ~CommandObjectPythonFunction () override 1364223383edSEnrico Granata { 1365223383edSEnrico Granata } 1366223383edSEnrico Granata 1367*13d21e9aSBruce Mitchener bool 1368*13d21e9aSBruce Mitchener IsRemovable () const override 13695a988416SJim Ingham { 13705a988416SJim Ingham return true; 13715a988416SJim Ingham } 13725a988416SJim Ingham 13735a988416SJim Ingham const std::string& 13745a988416SJim Ingham GetFunctionName () 13755a988416SJim Ingham { 13765a988416SJim Ingham return m_function_name; 13775a988416SJim Ingham } 13785a988416SJim Ingham 13795a988416SJim Ingham ScriptedCommandSynchronicity 13805a988416SJim Ingham GetSynchronicity () 13815a988416SJim Ingham { 13825a988416SJim Ingham return m_synchro; 13835a988416SJim Ingham } 13845a988416SJim Ingham 1385*13d21e9aSBruce Mitchener const char * 1386*13d21e9aSBruce Mitchener GetHelpLong () override 1387fac939e9SEnrico Granata { 1388fac939e9SEnrico Granata if (!m_fetched_help_long) 1389fac939e9SEnrico Granata { 1390fac939e9SEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1391fac939e9SEnrico Granata if (scripter) 1392fac939e9SEnrico Granata { 1393fac939e9SEnrico Granata std::string docstring; 1394fac939e9SEnrico Granata m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring); 1395fac939e9SEnrico Granata if (!docstring.empty()) 1396fac939e9SEnrico Granata SetHelpLong(docstring); 1397fac939e9SEnrico Granata } 1398fac939e9SEnrico Granata } 1399fac939e9SEnrico Granata return CommandObjectRaw::GetHelpLong(); 1400fac939e9SEnrico Granata } 1401fac939e9SEnrico Granata 14025a988416SJim Ingham protected: 1403*13d21e9aSBruce Mitchener bool 1404*13d21e9aSBruce Mitchener DoExecute (const char *raw_command_line, CommandReturnObject &result) override 1405223383edSEnrico Granata { 1406223383edSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1407223383edSEnrico Granata 1408223383edSEnrico Granata Error error; 1409223383edSEnrico Granata 141070f11f88SJim Ingham result.SetStatus(eReturnStatusInvalid); 141170f11f88SJim Ingham 1412223383edSEnrico Granata if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(), 1413223383edSEnrico Granata raw_command_line, 14140a305db7SEnrico Granata m_synchro, 1415223383edSEnrico Granata result, 141606be059aSEnrico Granata error, 141706be059aSEnrico Granata m_exe_ctx) == false) 1418223383edSEnrico Granata { 1419223383edSEnrico Granata result.AppendError(error.AsCString()); 1420223383edSEnrico Granata result.SetStatus(eReturnStatusFailed); 1421223383edSEnrico Granata } 1422223383edSEnrico Granata else 142370f11f88SJim Ingham { 142470f11f88SJim Ingham // Don't change the status if the command already set it... 142570f11f88SJim Ingham if (result.GetStatus() == eReturnStatusInvalid) 142670f11f88SJim Ingham { 14279a71a7d8SDaniel Malea if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') 1428223383edSEnrico Granata result.SetStatus(eReturnStatusSuccessFinishNoResult); 142970f11f88SJim Ingham else 143070f11f88SJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult); 143170f11f88SJim Ingham } 143270f11f88SJim Ingham } 1433223383edSEnrico Granata 1434223383edSEnrico Granata return result.Succeeded(); 1435223383edSEnrico Granata } 1436223383edSEnrico Granata 1437223383edSEnrico Granata }; 1438223383edSEnrico Granata 14399fe00e52SEnrico Granata class CommandObjectScriptingObject : public CommandObjectRaw 14409fe00e52SEnrico Granata { 14419fe00e52SEnrico Granata private: 14420641ca1aSZachary Turner StructuredData::GenericSP m_cmd_obj_sp; 14439fe00e52SEnrico Granata ScriptedCommandSynchronicity m_synchro; 14446f79bb2dSEnrico Granata bool m_fetched_help_short:1; 14456f79bb2dSEnrico Granata bool m_fetched_help_long:1; 14469fe00e52SEnrico Granata 14479fe00e52SEnrico Granata public: 14489fe00e52SEnrico Granata 14499fe00e52SEnrico Granata CommandObjectScriptingObject (CommandInterpreter &interpreter, 14509fe00e52SEnrico Granata std::string name, 14510641ca1aSZachary Turner StructuredData::GenericSP cmd_obj_sp, 14529fe00e52SEnrico Granata ScriptedCommandSynchronicity synch) : 14539fe00e52SEnrico Granata CommandObjectRaw (interpreter, 14549fe00e52SEnrico Granata name.c_str(), 14559fe00e52SEnrico Granata NULL, 14569fe00e52SEnrico Granata NULL), 14579fe00e52SEnrico Granata m_cmd_obj_sp(cmd_obj_sp), 14586f79bb2dSEnrico Granata m_synchro(synch), 14596f79bb2dSEnrico Granata m_fetched_help_short(false), 14606f79bb2dSEnrico Granata m_fetched_help_long(false) 14619fe00e52SEnrico Granata { 14629fe00e52SEnrico Granata StreamString stream; 14639fe00e52SEnrico Granata stream.Printf("For more information run 'help %s'",name.c_str()); 14649fe00e52SEnrico Granata SetHelp(stream.GetData()); 1465e87764f2SEnrico Granata if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter()) 1466e87764f2SEnrico Granata GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp)); 14679fe00e52SEnrico Granata } 14689fe00e52SEnrico Granata 1469*13d21e9aSBruce Mitchener ~CommandObjectScriptingObject () override 14709fe00e52SEnrico Granata { 14719fe00e52SEnrico Granata } 14729fe00e52SEnrico Granata 1473*13d21e9aSBruce Mitchener bool 1474*13d21e9aSBruce Mitchener IsRemovable () const override 14759fe00e52SEnrico Granata { 14769fe00e52SEnrico Granata return true; 14779fe00e52SEnrico Granata } 14789fe00e52SEnrico Granata 14790641ca1aSZachary Turner StructuredData::GenericSP 14809fe00e52SEnrico Granata GetImplementingObject () 14819fe00e52SEnrico Granata { 14829fe00e52SEnrico Granata return m_cmd_obj_sp; 14839fe00e52SEnrico Granata } 14849fe00e52SEnrico Granata 14859fe00e52SEnrico Granata ScriptedCommandSynchronicity 14869fe00e52SEnrico Granata GetSynchronicity () 14879fe00e52SEnrico Granata { 14889fe00e52SEnrico Granata return m_synchro; 14899fe00e52SEnrico Granata } 14909fe00e52SEnrico Granata 1491*13d21e9aSBruce Mitchener const char * 1492*13d21e9aSBruce Mitchener GetHelp () override 14936f79bb2dSEnrico Granata { 14946f79bb2dSEnrico Granata if (!m_fetched_help_short) 14956f79bb2dSEnrico Granata { 14966f79bb2dSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 14976f79bb2dSEnrico Granata if (scripter) 14986f79bb2dSEnrico Granata { 14996f79bb2dSEnrico Granata std::string docstring; 15006f79bb2dSEnrico Granata m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring); 15016f79bb2dSEnrico Granata if (!docstring.empty()) 15026f79bb2dSEnrico Granata SetHelp(docstring); 15036f79bb2dSEnrico Granata } 15046f79bb2dSEnrico Granata } 15056f79bb2dSEnrico Granata return CommandObjectRaw::GetHelp(); 15066f79bb2dSEnrico Granata } 15076f79bb2dSEnrico Granata 1508*13d21e9aSBruce Mitchener const char * 1509*13d21e9aSBruce Mitchener GetHelpLong () override 15109fe00e52SEnrico Granata { 15116f79bb2dSEnrico Granata if (!m_fetched_help_long) 15126f79bb2dSEnrico Granata { 15136f79bb2dSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 15146f79bb2dSEnrico Granata if (scripter) 15156f79bb2dSEnrico Granata { 15166f79bb2dSEnrico Granata std::string docstring; 15176f79bb2dSEnrico Granata m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring); 15186f79bb2dSEnrico Granata if (!docstring.empty()) 15196f79bb2dSEnrico Granata SetHelpLong(docstring); 15206f79bb2dSEnrico Granata } 15216f79bb2dSEnrico Granata } 15229fe00e52SEnrico Granata return CommandObjectRaw::GetHelpLong(); 15239fe00e52SEnrico Granata } 15249fe00e52SEnrico Granata 15259fe00e52SEnrico Granata protected: 1526*13d21e9aSBruce Mitchener bool 1527*13d21e9aSBruce Mitchener DoExecute (const char *raw_command_line, CommandReturnObject &result) override 15289fe00e52SEnrico Granata { 15299fe00e52SEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 15309fe00e52SEnrico Granata 15319fe00e52SEnrico Granata Error error; 15329fe00e52SEnrico Granata 15339fe00e52SEnrico Granata result.SetStatus(eReturnStatusInvalid); 15349fe00e52SEnrico Granata 15359fe00e52SEnrico Granata if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp, 15369fe00e52SEnrico Granata raw_command_line, 15379fe00e52SEnrico Granata m_synchro, 15389fe00e52SEnrico Granata result, 15399fe00e52SEnrico Granata error, 15409fe00e52SEnrico Granata m_exe_ctx) == false) 15419fe00e52SEnrico Granata { 15429fe00e52SEnrico Granata result.AppendError(error.AsCString()); 15439fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 15449fe00e52SEnrico Granata } 15459fe00e52SEnrico Granata else 15469fe00e52SEnrico Granata { 15479fe00e52SEnrico Granata // Don't change the status if the command already set it... 15489fe00e52SEnrico Granata if (result.GetStatus() == eReturnStatusInvalid) 15499fe00e52SEnrico Granata { 15509fe00e52SEnrico Granata if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') 15519fe00e52SEnrico Granata result.SetStatus(eReturnStatusSuccessFinishNoResult); 15529fe00e52SEnrico Granata else 15539fe00e52SEnrico Granata result.SetStatus(eReturnStatusSuccessFinishResult); 15549fe00e52SEnrico Granata } 15559fe00e52SEnrico Granata } 15569fe00e52SEnrico Granata 15579fe00e52SEnrico Granata return result.Succeeded(); 15589fe00e52SEnrico Granata } 15599fe00e52SEnrico Granata 15609fe00e52SEnrico Granata }; 15619fe00e52SEnrico Granata 1562a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1563a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport 1564a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1565a9dbf432SEnrico Granata 15665a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed 1567a9dbf432SEnrico Granata { 15685a988416SJim Ingham public: 15695a988416SJim Ingham CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 15705a988416SJim Ingham CommandObjectParsed (interpreter, 15715a988416SJim Ingham "command script import", 15725a988416SJim Ingham "Import a scripting module in LLDB.", 15735a988416SJim Ingham NULL), 15745a988416SJim Ingham m_options(interpreter) 15755a988416SJim Ingham { 15765a988416SJim Ingham CommandArgumentEntry arg1; 15775a988416SJim Ingham CommandArgumentData cmd_arg; 15785a988416SJim Ingham 15795a988416SJim Ingham // Define the first (and only) variant of this arg. 15805a988416SJim Ingham cmd_arg.arg_type = eArgTypeFilename; 15813b00e35bSEnrico Granata cmd_arg.arg_repetition = eArgRepeatPlus; 15825a988416SJim Ingham 15835a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 15845a988416SJim Ingham arg1.push_back (cmd_arg); 15855a988416SJim Ingham 15865a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 15875a988416SJim Ingham m_arguments.push_back (arg1); 15885a988416SJim Ingham } 15895a988416SJim Ingham 1590*13d21e9aSBruce Mitchener ~CommandObjectCommandsScriptImport () override 15915a988416SJim Ingham { 15925a988416SJim Ingham } 15935a988416SJim Ingham 1594*13d21e9aSBruce Mitchener int 15955a988416SJim Ingham HandleArgumentCompletion (Args &input, 15965a988416SJim Ingham int &cursor_index, 15975a988416SJim Ingham int &cursor_char_position, 15985a988416SJim Ingham OptionElementVector &opt_element_vector, 15995a988416SJim Ingham int match_start_point, 16005a988416SJim Ingham int max_return_elements, 16015a988416SJim Ingham bool &word_complete, 1602*13d21e9aSBruce Mitchener StringList &matches) override 16035a988416SJim Ingham { 16045a988416SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 16055a988416SJim Ingham completion_str.erase (cursor_char_position); 16065a988416SJim Ingham 16075a988416SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 16085a988416SJim Ingham CommandCompletions::eDiskFileCompletion, 16095a988416SJim Ingham completion_str.c_str(), 16105a988416SJim Ingham match_start_point, 16115a988416SJim Ingham max_return_elements, 16125a988416SJim Ingham NULL, 16135a988416SJim Ingham word_complete, 16145a988416SJim Ingham matches); 16155a988416SJim Ingham return matches.GetSize(); 16165a988416SJim Ingham } 16175a988416SJim Ingham 1618*13d21e9aSBruce Mitchener Options * 1619*13d21e9aSBruce Mitchener GetOptions () override 16205a988416SJim Ingham { 16215a988416SJim Ingham return &m_options; 16225a988416SJim Ingham } 16235a988416SJim Ingham 16245a988416SJim Ingham protected: 16250a305db7SEnrico Granata 16260a305db7SEnrico Granata class CommandOptions : public Options 16270a305db7SEnrico Granata { 16280a305db7SEnrico Granata public: 16290a305db7SEnrico Granata 16300a305db7SEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 16310a305db7SEnrico Granata Options (interpreter) 16320a305db7SEnrico Granata { 16330a305db7SEnrico Granata } 16340a305db7SEnrico Granata 1635*13d21e9aSBruce Mitchener ~CommandOptions () override {} 16360a305db7SEnrico Granata 1637*13d21e9aSBruce Mitchener Error 1638*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 16390a305db7SEnrico Granata { 16400a305db7SEnrico Granata Error error; 16413bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 16420a305db7SEnrico Granata 16430a305db7SEnrico Granata switch (short_option) 16440a305db7SEnrico Granata { 16450a305db7SEnrico Granata case 'r': 16460a305db7SEnrico Granata m_allow_reload = true; 16470a305db7SEnrico Granata break; 16480a305db7SEnrico Granata default: 16490a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 16500a305db7SEnrico Granata break; 16510a305db7SEnrico Granata } 16520a305db7SEnrico Granata 16530a305db7SEnrico Granata return error; 16540a305db7SEnrico Granata } 16550a305db7SEnrico Granata 16560a305db7SEnrico Granata void 1657*13d21e9aSBruce Mitchener OptionParsingStarting () override 16580a305db7SEnrico Granata { 1659e0c70f1bSEnrico Granata m_allow_reload = true; 16600a305db7SEnrico Granata } 16610a305db7SEnrico Granata 16620a305db7SEnrico Granata const OptionDefinition* 1663*13d21e9aSBruce Mitchener GetDefinitions () override 16640a305db7SEnrico Granata { 16650a305db7SEnrico Granata return g_option_table; 16660a305db7SEnrico Granata } 16670a305db7SEnrico Granata 16680a305db7SEnrico Granata // Options table: Required for subclasses of Options. 16690a305db7SEnrico Granata 16700a305db7SEnrico Granata static OptionDefinition g_option_table[]; 16710a305db7SEnrico Granata 16720a305db7SEnrico Granata // Instance variables to hold the values for command options. 16730a305db7SEnrico Granata 16740a305db7SEnrico Granata bool m_allow_reload; 16750a305db7SEnrico Granata }; 16760a305db7SEnrico Granata 1677a9dbf432SEnrico Granata bool 1678*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 1679a9dbf432SEnrico Granata { 1680a9dbf432SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1681a9dbf432SEnrico Granata { 1682a9dbf432SEnrico Granata result.AppendError ("only scripting language supported for module importing is currently Python"); 1683a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1684a9dbf432SEnrico Granata return false; 1685a9dbf432SEnrico Granata } 1686a9dbf432SEnrico Granata 16875a988416SJim Ingham size_t argc = command.GetArgumentCount(); 16883b00e35bSEnrico Granata if (0 == argc) 1689a9dbf432SEnrico Granata { 16903b00e35bSEnrico Granata result.AppendError("command script import needs one or more arguments"); 1691a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1692a9dbf432SEnrico Granata return false; 1693a9dbf432SEnrico Granata } 1694a9dbf432SEnrico Granata 16950e978481SEd Maste for (size_t i = 0; 16963b00e35bSEnrico Granata i < argc; 16973b00e35bSEnrico Granata i++) 16983b00e35bSEnrico Granata { 16993b00e35bSEnrico Granata std::string path = command.GetArgumentAtIndex(i); 1700a9dbf432SEnrico Granata Error error; 1701a9dbf432SEnrico Granata 1702c9d645d3SGreg Clayton const bool init_session = true; 1703078551c7SEnrico Granata // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that 1704078551c7SEnrico Granata // commands won't ever be recursively invoked, but it's actually possible to craft 1705078551c7SEnrico Granata // a Python script that does other "command script imports" in __lldb_init_module 1706078551c7SEnrico Granata // the real fix is to have recursive commands possible with a CommandInvocation object 1707078551c7SEnrico Granata // separate from the CommandObject itself, so that recursive command invocations 1708078551c7SEnrico Granata // won't stomp on each other (wrt to execution contents, options, and more) 1709078551c7SEnrico Granata m_exe_ctx.Clear(); 1710a9dbf432SEnrico Granata if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 17110a305db7SEnrico Granata m_options.m_allow_reload, 1712c9d645d3SGreg Clayton init_session, 1713a9dbf432SEnrico Granata error)) 1714a9dbf432SEnrico Granata { 1715a9dbf432SEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1716a9dbf432SEnrico Granata } 1717a9dbf432SEnrico Granata else 1718a9dbf432SEnrico Granata { 1719a9dbf432SEnrico Granata result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1720a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1721a9dbf432SEnrico Granata } 17223b00e35bSEnrico Granata } 1723a9dbf432SEnrico Granata 1724a9dbf432SEnrico Granata return result.Succeeded(); 1725a9dbf432SEnrico Granata } 17260a305db7SEnrico Granata 17275a988416SJim Ingham CommandOptions m_options; 1728a9dbf432SEnrico Granata }; 1729223383edSEnrico Granata 17300a305db7SEnrico Granata OptionDefinition 17310a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 17320a305db7SEnrico Granata { 1733d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."}, 1734d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 17350a305db7SEnrico Granata }; 17360a305db7SEnrico Granata 17370a305db7SEnrico Granata 1738223383edSEnrico Granata //------------------------------------------------------------------------- 1739223383edSEnrico Granata // CommandObjectCommandsScriptAdd 1740223383edSEnrico Granata //------------------------------------------------------------------------- 1741223383edSEnrico Granata 174244d93782SGreg Clayton class CommandObjectCommandsScriptAdd : 174344d93782SGreg Clayton public CommandObjectParsed, 174444d93782SGreg Clayton public IOHandlerDelegateMultiline 1745223383edSEnrico Granata { 17465a988416SJim Ingham public: 17475a988416SJim Ingham CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 17485a988416SJim Ingham CommandObjectParsed (interpreter, 17495a988416SJim Ingham "command script add", 17505a988416SJim Ingham "Add a scripted function as an LLDB command.", 17515a988416SJim Ingham NULL), 1752c3d874a5SGreg Clayton IOHandlerDelegateMultiline ("DONE"), 17535a988416SJim Ingham m_options (interpreter) 17545a988416SJim Ingham { 17555a988416SJim Ingham CommandArgumentEntry arg1; 17565a988416SJim Ingham CommandArgumentData cmd_arg; 17575a988416SJim Ingham 17585a988416SJim Ingham // Define the first (and only) variant of this arg. 17595a988416SJim Ingham cmd_arg.arg_type = eArgTypeCommandName; 17605a988416SJim Ingham cmd_arg.arg_repetition = eArgRepeatPlain; 17615a988416SJim Ingham 17625a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 17635a988416SJim Ingham arg1.push_back (cmd_arg); 17645a988416SJim Ingham 17655a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 17665a988416SJim Ingham m_arguments.push_back (arg1); 17675a988416SJim Ingham } 17685a988416SJim Ingham 1769*13d21e9aSBruce Mitchener ~CommandObjectCommandsScriptAdd () override 17705a988416SJim Ingham { 17715a988416SJim Ingham } 17725a988416SJim Ingham 1773*13d21e9aSBruce Mitchener Options * 1774*13d21e9aSBruce Mitchener GetOptions () override 17755a988416SJim Ingham { 17765a988416SJim Ingham return &m_options; 17775a988416SJim Ingham } 17785a988416SJim Ingham 17795a988416SJim Ingham protected: 1780223383edSEnrico Granata 1781223383edSEnrico Granata class CommandOptions : public Options 1782223383edSEnrico Granata { 1783223383edSEnrico Granata public: 1784223383edSEnrico Granata 1785223383edSEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 17869fe00e52SEnrico Granata Options (interpreter), 17879fe00e52SEnrico Granata m_class_name(), 17889fe00e52SEnrico Granata m_funct_name(), 17899fe00e52SEnrico Granata m_short_help(), 17909fe00e52SEnrico Granata m_synchronicity(eScriptedCommandSynchronicitySynchronous) 1791223383edSEnrico Granata { 1792223383edSEnrico Granata } 1793223383edSEnrico Granata 1794*13d21e9aSBruce Mitchener ~CommandOptions () override {} 1795223383edSEnrico Granata 1796*13d21e9aSBruce Mitchener Error 1797*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 1798223383edSEnrico Granata { 1799223383edSEnrico Granata Error error; 18003bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 1801223383edSEnrico Granata 1802223383edSEnrico Granata switch (short_option) 1803223383edSEnrico Granata { 1804223383edSEnrico Granata case 'f': 1805735152e3SEnrico Granata if (option_arg) 1806735152e3SEnrico Granata m_funct_name.assign(option_arg); 1807735152e3SEnrico Granata break; 18089fe00e52SEnrico Granata case 'c': 18099fe00e52SEnrico Granata if (option_arg) 18109fe00e52SEnrico Granata m_class_name.assign(option_arg); 18119fe00e52SEnrico Granata break; 1812735152e3SEnrico Granata case 'h': 1813735152e3SEnrico Granata if (option_arg) 1814735152e3SEnrico Granata m_short_help.assign(option_arg); 1815223383edSEnrico Granata break; 18160a305db7SEnrico Granata case 's': 181744d93782SGreg Clayton m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 18180a305db7SEnrico Granata if (!error.Success()) 18190a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 18200a305db7SEnrico Granata break; 1821223383edSEnrico Granata default: 182286edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1823223383edSEnrico Granata break; 1824223383edSEnrico Granata } 1825223383edSEnrico Granata 1826223383edSEnrico Granata return error; 1827223383edSEnrico Granata } 1828223383edSEnrico Granata 1829223383edSEnrico Granata void 1830*13d21e9aSBruce Mitchener OptionParsingStarting () override 1831223383edSEnrico Granata { 18329fe00e52SEnrico Granata m_class_name.clear(); 1833735152e3SEnrico Granata m_funct_name.clear(); 1834735152e3SEnrico Granata m_short_help.clear(); 183544d93782SGreg Clayton m_synchronicity = eScriptedCommandSynchronicitySynchronous; 1836223383edSEnrico Granata } 1837223383edSEnrico Granata 1838223383edSEnrico Granata const OptionDefinition* 1839*13d21e9aSBruce Mitchener GetDefinitions () override 1840223383edSEnrico Granata { 1841223383edSEnrico Granata return g_option_table; 1842223383edSEnrico Granata } 1843223383edSEnrico Granata 1844223383edSEnrico Granata // Options table: Required for subclasses of Options. 1845223383edSEnrico Granata 1846223383edSEnrico Granata static OptionDefinition g_option_table[]; 1847223383edSEnrico Granata 1848223383edSEnrico Granata // Instance variables to hold the values for command options. 1849223383edSEnrico Granata 18509fe00e52SEnrico Granata std::string m_class_name; 1851223383edSEnrico Granata std::string m_funct_name; 1852735152e3SEnrico Granata std::string m_short_help; 185344d93782SGreg Clayton ScriptedCommandSynchronicity m_synchronicity; 1854223383edSEnrico Granata }; 1855223383edSEnrico Granata 1856*13d21e9aSBruce Mitchener void 1857*13d21e9aSBruce Mitchener IOHandlerActivated (IOHandler &io_handler) override 1858223383edSEnrico Granata { 185944d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 186044d93782SGreg Clayton if (output_sp) 1861223383edSEnrico Granata { 186244d93782SGreg Clayton output_sp->PutCString(g_python_command_instructions); 186344d93782SGreg Clayton output_sp->Flush(); 1864223383edSEnrico Granata } 1865223383edSEnrico Granata } 1866223383edSEnrico Granata 1867223383edSEnrico Granata 1868*13d21e9aSBruce Mitchener void 1869*13d21e9aSBruce Mitchener IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override 1870223383edSEnrico Granata { 187144d93782SGreg Clayton StreamFileSP error_sp = io_handler.GetErrorStreamFile(); 187244d93782SGreg Clayton 187344d93782SGreg Clayton ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 187444d93782SGreg Clayton if (interpreter) 187544d93782SGreg Clayton { 187644d93782SGreg Clayton 187744d93782SGreg Clayton StringList lines; 187844d93782SGreg Clayton lines.SplitIntoLines(data); 187944d93782SGreg Clayton if (lines.GetSize() > 0) 188044d93782SGreg Clayton { 1881a73b7df7SEnrico Granata std::string funct_name_str; 188244d93782SGreg Clayton if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str)) 1883223383edSEnrico Granata { 1884a73b7df7SEnrico Granata if (funct_name_str.empty()) 1885223383edSEnrico Granata { 188644d93782SGreg Clayton error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n"); 188744d93782SGreg Clayton error_sp->Flush(); 1888223383edSEnrico Granata } 188944d93782SGreg Clayton else 189044d93782SGreg Clayton { 1891223383edSEnrico Granata // everything should be fine now, let's add this alias 1892223383edSEnrico Granata 1893223383edSEnrico Granata CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter, 1894223383edSEnrico Granata m_cmd_name, 1895a73b7df7SEnrico Granata funct_name_str.c_str(), 1896735152e3SEnrico Granata m_short_help, 189744d93782SGreg Clayton m_synchronicity)); 1898223383edSEnrico Granata 18990a305db7SEnrico Granata if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 1900223383edSEnrico Granata { 190144d93782SGreg Clayton error_sp->Printf ("error: unable to add selected command, didn't add python command.\n"); 190244d93782SGreg Clayton error_sp->Flush(); 1903223383edSEnrico Granata } 1904223383edSEnrico Granata } 190544d93782SGreg Clayton } 190644d93782SGreg Clayton else 190744d93782SGreg Clayton { 190844d93782SGreg Clayton error_sp->Printf ("error: unable to create function, didn't add python command.\n"); 190944d93782SGreg Clayton error_sp->Flush(); 191044d93782SGreg Clayton } 191144d93782SGreg Clayton } 191244d93782SGreg Clayton else 191344d93782SGreg Clayton { 191444d93782SGreg Clayton error_sp->Printf ("error: empty function, didn't add python command.\n"); 191544d93782SGreg Clayton error_sp->Flush(); 191644d93782SGreg Clayton } 191744d93782SGreg Clayton } 191844d93782SGreg Clayton else 191944d93782SGreg Clayton { 192044d93782SGreg Clayton error_sp->Printf ("error: script interpreter missing, didn't add python command.\n"); 192144d93782SGreg Clayton error_sp->Flush(); 192244d93782SGreg Clayton } 192344d93782SGreg Clayton 192444d93782SGreg Clayton io_handler.SetIsDone(true); 192544d93782SGreg Clayton 192644d93782SGreg Clayton 192744d93782SGreg Clayton } 1928223383edSEnrico Granata 19295a988416SJim Ingham protected: 1930223383edSEnrico Granata bool 1931*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 1932223383edSEnrico Granata { 193399f0b8f9SEnrico Granata 193499f0b8f9SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 193599f0b8f9SEnrico Granata { 193699f0b8f9SEnrico Granata result.AppendError ("only scripting language supported for scripted commands is currently Python"); 193799f0b8f9SEnrico Granata result.SetStatus (eReturnStatusFailed); 193899f0b8f9SEnrico Granata return false; 193999f0b8f9SEnrico Granata } 194099f0b8f9SEnrico Granata 19415a988416SJim Ingham size_t argc = command.GetArgumentCount(); 1942223383edSEnrico Granata 1943223383edSEnrico Granata if (argc != 1) 1944223383edSEnrico Granata { 1945223383edSEnrico Granata result.AppendError ("'command script add' requires one argument"); 1946223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1947223383edSEnrico Granata return false; 1948223383edSEnrico Granata } 1949223383edSEnrico Granata 1950735152e3SEnrico Granata // Store the options in case we get multi-line input 195144d93782SGreg Clayton m_cmd_name = command.GetArgumentAtIndex(0); 1952735152e3SEnrico Granata m_short_help.assign(m_options.m_short_help); 195344d93782SGreg Clayton m_synchronicity = m_options.m_synchronicity; 1954223383edSEnrico Granata 19559fe00e52SEnrico Granata if (m_options.m_class_name.empty()) 19569fe00e52SEnrico Granata { 1957223383edSEnrico Granata if (m_options.m_funct_name.empty()) 1958223383edSEnrico Granata { 195944d93782SGreg Clayton m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt 196044d93782SGreg Clayton *this, // IOHandlerDelegate 196144d93782SGreg Clayton true, // Run IOHandler in async mode 196244d93782SGreg Clayton NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 1963223383edSEnrico Granata } 1964223383edSEnrico Granata else 1965223383edSEnrico Granata { 19660a305db7SEnrico Granata CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 196744d93782SGreg Clayton m_cmd_name, 19680a305db7SEnrico Granata m_options.m_funct_name, 1969735152e3SEnrico Granata m_options.m_short_help, 197044d93782SGreg Clayton m_synchronicity)); 197144d93782SGreg Clayton if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 1972223383edSEnrico Granata { 1973223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1974223383edSEnrico Granata } 1975223383edSEnrico Granata else 1976223383edSEnrico Granata { 1977223383edSEnrico Granata result.AppendError("cannot add command"); 1978223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1979223383edSEnrico Granata } 1980223383edSEnrico Granata } 19819fe00e52SEnrico Granata } 19829fe00e52SEnrico Granata else 19839fe00e52SEnrico Granata { 19849fe00e52SEnrico Granata ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter(); 19859fe00e52SEnrico Granata if (!interpreter) 19869fe00e52SEnrico Granata { 19879fe00e52SEnrico Granata result.AppendError("cannot find ScriptInterpreter"); 19889fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 19899fe00e52SEnrico Granata return false; 19909fe00e52SEnrico Granata } 19919fe00e52SEnrico Granata 19929fe00e52SEnrico Granata auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str()); 19939fe00e52SEnrico Granata if (!cmd_obj_sp) 19949fe00e52SEnrico Granata { 19959fe00e52SEnrico Granata result.AppendError("cannot create helper object"); 19969fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 19979fe00e52SEnrico Granata return false; 19989fe00e52SEnrico Granata } 19999fe00e52SEnrico Granata 20009fe00e52SEnrico Granata CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter, 20019fe00e52SEnrico Granata m_cmd_name, 20029fe00e52SEnrico Granata cmd_obj_sp, 20039fe00e52SEnrico Granata m_synchronicity)); 20049fe00e52SEnrico Granata if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 20059fe00e52SEnrico Granata { 20069fe00e52SEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 20079fe00e52SEnrico Granata } 20089fe00e52SEnrico Granata else 20099fe00e52SEnrico Granata { 20109fe00e52SEnrico Granata result.AppendError("cannot add command"); 20119fe00e52SEnrico Granata result.SetStatus (eReturnStatusFailed); 20129fe00e52SEnrico Granata } 20139fe00e52SEnrico Granata } 2014223383edSEnrico Granata 2015223383edSEnrico Granata return result.Succeeded(); 2016223383edSEnrico Granata 2017223383edSEnrico Granata } 20185a988416SJim Ingham 20195a988416SJim Ingham CommandOptions m_options; 202044d93782SGreg Clayton std::string m_cmd_name; 2021735152e3SEnrico Granata std::string m_short_help; 202244d93782SGreg Clayton ScriptedCommandSynchronicity m_synchronicity; 2023223383edSEnrico Granata }; 2024223383edSEnrico Granata 20250a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] = 20260a305db7SEnrico Granata { 20270a305db7SEnrico Granata { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 20280a305db7SEnrico Granata { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 20290a305db7SEnrico Granata { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 20300a305db7SEnrico Granata { 0, NULL, NULL } 20310a305db7SEnrico Granata }; 20320a305db7SEnrico Granata 2033223383edSEnrico Granata OptionDefinition 2034223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 2035223383edSEnrico Granata { 2036d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 20379fe00e52SEnrico Granata { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."}, 20389370d278SEnrico Granata { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."}, 20399fe00e52SEnrico Granata { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."}, 2040d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2041223383edSEnrico Granata }; 2042223383edSEnrico Granata 2043223383edSEnrico Granata //------------------------------------------------------------------------- 2044223383edSEnrico Granata // CommandObjectCommandsScriptList 2045223383edSEnrico Granata //------------------------------------------------------------------------- 2046223383edSEnrico Granata 20475a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed 2048223383edSEnrico Granata { 2049223383edSEnrico Granata private: 2050223383edSEnrico Granata 2051223383edSEnrico Granata public: 2052223383edSEnrico Granata CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 20535a988416SJim Ingham CommandObjectParsed (interpreter, 2054223383edSEnrico Granata "command script list", 2055223383edSEnrico Granata "List defined scripted commands.", 2056223383edSEnrico Granata NULL) 2057223383edSEnrico Granata { 2058223383edSEnrico Granata } 2059223383edSEnrico Granata 2060*13d21e9aSBruce Mitchener ~CommandObjectCommandsScriptList () override 2061223383edSEnrico Granata { 2062223383edSEnrico Granata } 2063223383edSEnrico Granata 2064223383edSEnrico Granata bool 2065*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 2066223383edSEnrico Granata { 2067223383edSEnrico Granata 2068223383edSEnrico Granata m_interpreter.GetHelp(result, 2069223383edSEnrico Granata CommandInterpreter::eCommandTypesUserDef); 2070223383edSEnrico Granata 2071223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2072223383edSEnrico Granata 2073223383edSEnrico Granata return true; 2074223383edSEnrico Granata 2075223383edSEnrico Granata 2076223383edSEnrico Granata } 2077223383edSEnrico Granata }; 2078223383edSEnrico Granata 2079223383edSEnrico Granata //------------------------------------------------------------------------- 2080223383edSEnrico Granata // CommandObjectCommandsScriptClear 2081223383edSEnrico Granata //------------------------------------------------------------------------- 2082223383edSEnrico Granata 20835a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed 2084223383edSEnrico Granata { 2085223383edSEnrico Granata private: 2086223383edSEnrico Granata 2087223383edSEnrico Granata public: 2088223383edSEnrico Granata CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 20895a988416SJim Ingham CommandObjectParsed (interpreter, 2090223383edSEnrico Granata "command script clear", 2091223383edSEnrico Granata "Delete all scripted commands.", 2092223383edSEnrico Granata NULL) 2093223383edSEnrico Granata { 2094223383edSEnrico Granata } 2095223383edSEnrico Granata 2096*13d21e9aSBruce Mitchener ~CommandObjectCommandsScriptClear () override 2097223383edSEnrico Granata { 2098223383edSEnrico Granata } 2099223383edSEnrico Granata 21005a988416SJim Ingham protected: 2101223383edSEnrico Granata bool 2102*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 2103223383edSEnrico Granata { 2104223383edSEnrico Granata 2105223383edSEnrico Granata m_interpreter.RemoveAllUser(); 2106223383edSEnrico Granata 2107223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2108223383edSEnrico Granata 2109223383edSEnrico Granata return true; 2110223383edSEnrico Granata } 2111223383edSEnrico Granata }; 2112223383edSEnrico Granata 2113223383edSEnrico Granata //------------------------------------------------------------------------- 2114223383edSEnrico Granata // CommandObjectCommandsScriptDelete 2115223383edSEnrico Granata //------------------------------------------------------------------------- 2116223383edSEnrico Granata 21175a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed 2118223383edSEnrico Granata { 2119223383edSEnrico Granata public: 2120223383edSEnrico Granata CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 21215a988416SJim Ingham CommandObjectParsed (interpreter, 2122223383edSEnrico Granata "command script delete", 2123223383edSEnrico Granata "Delete a scripted command.", 2124223383edSEnrico Granata NULL) 2125223383edSEnrico Granata { 2126223383edSEnrico Granata CommandArgumentEntry arg1; 2127223383edSEnrico Granata CommandArgumentData cmd_arg; 2128223383edSEnrico Granata 2129223383edSEnrico Granata // Define the first (and only) variant of this arg. 2130223383edSEnrico Granata cmd_arg.arg_type = eArgTypeCommandName; 2131223383edSEnrico Granata cmd_arg.arg_repetition = eArgRepeatPlain; 2132223383edSEnrico Granata 2133223383edSEnrico Granata // There is only one variant this argument could be; put it into the argument entry. 2134223383edSEnrico Granata arg1.push_back (cmd_arg); 2135223383edSEnrico Granata 2136223383edSEnrico Granata // Push the data for the first argument into the m_arguments vector. 2137223383edSEnrico Granata m_arguments.push_back (arg1); 2138223383edSEnrico Granata } 2139223383edSEnrico Granata 2140*13d21e9aSBruce Mitchener ~CommandObjectCommandsScriptDelete () override 2141223383edSEnrico Granata { 2142223383edSEnrico Granata } 2143223383edSEnrico Granata 21445a988416SJim Ingham protected: 2145223383edSEnrico Granata bool 2146*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 2147223383edSEnrico Granata { 2148223383edSEnrico Granata 21495a988416SJim Ingham size_t argc = command.GetArgumentCount(); 2150223383edSEnrico Granata 2151223383edSEnrico Granata if (argc != 1) 2152223383edSEnrico Granata { 2153223383edSEnrico Granata result.AppendError ("'command script delete' requires one argument"); 2154223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2155223383edSEnrico Granata return false; 2156223383edSEnrico Granata } 2157223383edSEnrico Granata 21585a988416SJim Ingham const char* cmd_name = command.GetArgumentAtIndex(0); 2159223383edSEnrico Granata 2160223383edSEnrico Granata if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 2161223383edSEnrico Granata { 2162223383edSEnrico Granata m_interpreter.RemoveUser(cmd_name); 2163223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2164223383edSEnrico Granata } 2165223383edSEnrico Granata else 2166223383edSEnrico Granata { 2167223383edSEnrico Granata result.AppendErrorWithFormat ("command %s not found", cmd_name); 2168223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2169223383edSEnrico Granata } 2170223383edSEnrico Granata 2171223383edSEnrico Granata return result.Succeeded(); 2172223383edSEnrico Granata 2173223383edSEnrico Granata } 2174223383edSEnrico Granata }; 2175223383edSEnrico Granata 2176223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript 2177223383edSEnrico Granata 2178223383edSEnrico Granata //------------------------------------------------------------------------- 2179223383edSEnrico Granata // CommandObjectMultiwordCommandsScript 2180223383edSEnrico Granata //------------------------------------------------------------------------- 2181223383edSEnrico Granata 2182223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 2183223383edSEnrico Granata { 2184223383edSEnrico Granata public: 2185223383edSEnrico Granata CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 2186223383edSEnrico Granata CommandObjectMultiword (interpreter, 2187223383edSEnrico Granata "command script", 2188223383edSEnrico Granata "A set of commands for managing or customizing script commands.", 2189223383edSEnrico Granata "command script <subcommand> [<subcommand-options>]") 2190223383edSEnrico Granata { 2191223383edSEnrico Granata LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 2192223383edSEnrico Granata LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 2193223383edSEnrico Granata LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 2194223383edSEnrico Granata LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 2195a9dbf432SEnrico Granata LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 2196223383edSEnrico Granata } 2197223383edSEnrico Granata 2198*13d21e9aSBruce Mitchener ~CommandObjectMultiwordCommandsScript () override 2199223383edSEnrico Granata { 2200223383edSEnrico Granata } 2201223383edSEnrico Granata 2202223383edSEnrico Granata }; 2203223383edSEnrico Granata 2204223383edSEnrico Granata 2205ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands 2206ebc09c36SJim Ingham 2207ebc09c36SJim Ingham //------------------------------------------------------------------------- 2208ebc09c36SJim Ingham // CommandObjectMultiwordCommands 2209ebc09c36SJim Ingham //------------------------------------------------------------------------- 2210ebc09c36SJim Ingham 2211ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 2212a7015092SGreg Clayton CommandObjectMultiword (interpreter, 22130e5e5a79SGreg Clayton "command", 22143f4c09c1SCaroline Tice "A set of commands for managing or customizing the debugger commands.", 22150e5e5a79SGreg Clayton "command <subcommand> [<subcommand-options>]") 2216ebc09c36SJim Ingham { 2217a7015092SGreg Clayton LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 2218a7015092SGreg Clayton LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 2219a7015092SGreg Clayton LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 2220b547278cSGreg Clayton LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter))); 2221de164aaaSGreg Clayton LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 2222a5a97ebeSJim Ingham LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 2223223383edSEnrico Granata LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 2224ebc09c36SJim Ingham } 2225ebc09c36SJim Ingham 2226ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () 2227ebc09c36SJim Ingham { 2228ebc09c36SJim Ingham } 2229ebc09c36SJim Ingham 2230