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 // C Includes 11ebc09c36SJim Ingham // C++ Includes 12ebc09c36SJim Ingham // Other libraries and framework includes 130e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h" 140e5e5a79SGreg Clayton 15ebc09c36SJim Ingham // Project includes 166e3d8e7fSEugene Zelenko #include "CommandObjectCommands.h" 1746d4aa21SEnrico Granata #include "CommandObjectHelp.h" 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" 27*45d0e238SEnrico Granata #include "lldb/Interpreter/OptionValueString.h" 287594f14fSEnrico Granata #include "lldb/Interpreter/OptionValueUInt64.h" 29ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h" 3099f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h" 31ebc09c36SJim Ingham 32ebc09c36SJim Ingham using namespace lldb; 33ebc09c36SJim Ingham using namespace lldb_private; 34ebc09c36SJim Ingham 35ebc09c36SJim Ingham //------------------------------------------------------------------------- 36ebc09c36SJim Ingham // CommandObjectCommandsSource 37ebc09c36SJim Ingham //------------------------------------------------------------------------- 38ebc09c36SJim Ingham 395a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed 40a5a97ebeSJim Ingham { 415a988416SJim Ingham public: 425a988416SJim Ingham CommandObjectCommandsHistory(CommandInterpreter &interpreter) : 435a988416SJim Ingham CommandObjectParsed(interpreter, 445a988416SJim Ingham "command history", 455a988416SJim Ingham "Dump the history of commands in this session.", 466e3d8e7fSEugene Zelenko nullptr), 475a988416SJim Ingham m_options (interpreter) 485a988416SJim Ingham { 495a988416SJim Ingham } 505a988416SJim Ingham 516e3d8e7fSEugene Zelenko ~CommandObjectCommandsHistory() override = default; 525a988416SJim Ingham 5313d21e9aSBruce Mitchener Options * 5413d21e9aSBruce Mitchener GetOptions () override 555a988416SJim Ingham { 565a988416SJim Ingham return &m_options; 575a988416SJim Ingham } 585a988416SJim Ingham 595a988416SJim Ingham protected: 60a5a97ebeSJim Ingham class CommandOptions : public Options 61a5a97ebeSJim Ingham { 62a5a97ebeSJim Ingham public: 63a5a97ebeSJim Ingham CommandOptions (CommandInterpreter &interpreter) : 647594f14fSEnrico Granata Options (interpreter), 657594f14fSEnrico Granata m_start_idx(0), 667594f14fSEnrico Granata m_stop_idx(0), 677594f14fSEnrico Granata m_count(0), 6863123b64SEnrico Granata m_clear(false) 69a5a97ebeSJim Ingham { 70a5a97ebeSJim Ingham } 71a5a97ebeSJim Ingham 726e3d8e7fSEugene Zelenko ~CommandOptions() override = default; 73a5a97ebeSJim Ingham 7413d21e9aSBruce Mitchener Error 7513d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 76a5a97ebeSJim Ingham { 77a5a97ebeSJim Ingham Error error; 783bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 79a5a97ebeSJim Ingham 80a5a97ebeSJim Ingham switch (short_option) 81a5a97ebeSJim Ingham { 82a5a97ebeSJim Ingham case 'c': 83c95f7e2aSPavel Labath error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign); 84a5a97ebeSJim Ingham break; 85a5a97ebeSJim Ingham case 's': 867594f14fSEnrico Granata if (option_arg && strcmp("end", option_arg) == 0) 877594f14fSEnrico Granata { 887594f14fSEnrico Granata m_start_idx.SetCurrentValue(UINT64_MAX); 897594f14fSEnrico Granata m_start_idx.SetOptionWasSet(); 907594f14fSEnrico Granata } 917594f14fSEnrico Granata else 92c95f7e2aSPavel Labath error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign); 937594f14fSEnrico Granata break; 947594f14fSEnrico Granata case 'e': 95c95f7e2aSPavel Labath error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign); 967594f14fSEnrico Granata break; 9763123b64SEnrico Granata case 'C': 9863123b64SEnrico Granata m_clear.SetCurrentValue(true); 9963123b64SEnrico Granata m_clear.SetOptionWasSet(); 100a5a97ebeSJim Ingham break; 101a5a97ebeSJim Ingham default: 10286edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 103a5a97ebeSJim Ingham break; 104a5a97ebeSJim Ingham } 105a5a97ebeSJim Ingham 106a5a97ebeSJim Ingham return error; 107a5a97ebeSJim Ingham } 108a5a97ebeSJim Ingham 109a5a97ebeSJim Ingham void 11013d21e9aSBruce Mitchener OptionParsingStarting () override 111a5a97ebeSJim Ingham { 1127594f14fSEnrico Granata m_start_idx.Clear(); 1137594f14fSEnrico Granata m_stop_idx.Clear(); 1147594f14fSEnrico Granata m_count.Clear(); 11563123b64SEnrico Granata m_clear.Clear(); 116a5a97ebeSJim Ingham } 117a5a97ebeSJim Ingham 118a5a97ebeSJim Ingham const OptionDefinition* 11913d21e9aSBruce Mitchener GetDefinitions () override 120a5a97ebeSJim Ingham { 121a5a97ebeSJim Ingham return g_option_table; 122a5a97ebeSJim Ingham } 123a5a97ebeSJim Ingham 124a5a97ebeSJim Ingham // Options table: Required for subclasses of Options. 125a5a97ebeSJim Ingham 126a5a97ebeSJim Ingham static OptionDefinition g_option_table[]; 127a5a97ebeSJim Ingham 128a5a97ebeSJim Ingham // Instance variables to hold the values for command options. 129a5a97ebeSJim Ingham 1307594f14fSEnrico Granata OptionValueUInt64 m_start_idx; 1317594f14fSEnrico Granata OptionValueUInt64 m_stop_idx; 1327594f14fSEnrico Granata OptionValueUInt64 m_count; 13363123b64SEnrico Granata OptionValueBoolean m_clear; 134a5a97ebeSJim Ingham }; 135a5a97ebeSJim Ingham 136a5a97ebeSJim Ingham bool 13713d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 138a5a97ebeSJim Ingham { 13963123b64SEnrico Granata if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet()) 1407594f14fSEnrico Granata { 1417594f14fSEnrico Granata m_interpreter.GetCommandHistory().Clear(); 1427594f14fSEnrico Granata result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult); 1437594f14fSEnrico Granata } 1447594f14fSEnrico Granata else 1457594f14fSEnrico Granata { 1467594f14fSEnrico Granata if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet()) 1477594f14fSEnrico Granata { 1487594f14fSEnrico Granata result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation"); 1497594f14fSEnrico Granata result.SetStatus(lldb::eReturnStatusFailed); 1507594f14fSEnrico Granata } 1517594f14fSEnrico Granata else 1527594f14fSEnrico Granata { 15384400ec7SVirgile Bello std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue()); 15484400ec7SVirgile Bello std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue()); 15584400ec7SVirgile Bello std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue()); 156a5a97ebeSJim Ingham 1577594f14fSEnrico Granata const CommandHistory& history(m_interpreter.GetCommandHistory()); 1587594f14fSEnrico Granata 1597594f14fSEnrico Granata if (start_idx.first && start_idx.second == UINT64_MAX) 1607594f14fSEnrico Granata { 1617594f14fSEnrico Granata if (count.first) 1627594f14fSEnrico Granata { 1637594f14fSEnrico Granata start_idx.second = history.GetSize() - count.second; 1647594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1657594f14fSEnrico Granata } 1667594f14fSEnrico Granata else if (stop_idx.first) 1677594f14fSEnrico Granata { 1687594f14fSEnrico Granata start_idx.second = stop_idx.second; 1697594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1707594f14fSEnrico Granata } 1717594f14fSEnrico Granata else 1727594f14fSEnrico Granata { 1737594f14fSEnrico Granata start_idx.second = 0; 1747594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1757594f14fSEnrico Granata } 1767594f14fSEnrico Granata } 1777594f14fSEnrico Granata else 1787594f14fSEnrico Granata { 1797594f14fSEnrico Granata if (!start_idx.first && !stop_idx.first && !count.first) 1807594f14fSEnrico Granata { 1817594f14fSEnrico Granata start_idx.second = 0; 1827594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1837594f14fSEnrico Granata } 1847594f14fSEnrico Granata else if (start_idx.first) 1857594f14fSEnrico Granata { 1867594f14fSEnrico Granata if (count.first) 1877594f14fSEnrico Granata { 1887594f14fSEnrico Granata stop_idx.second = start_idx.second + count.second - 1; 1897594f14fSEnrico Granata } 1907594f14fSEnrico Granata else if (!stop_idx.first) 1917594f14fSEnrico Granata { 1927594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1937594f14fSEnrico Granata } 1947594f14fSEnrico Granata } 1957594f14fSEnrico Granata else if (stop_idx.first) 1967594f14fSEnrico Granata { 1977594f14fSEnrico Granata if (count.first) 1987594f14fSEnrico Granata { 1997594f14fSEnrico Granata if (stop_idx.second >= count.second) 2007594f14fSEnrico Granata start_idx.second = stop_idx.second - count.second + 1; 2017594f14fSEnrico Granata else 2027594f14fSEnrico Granata start_idx.second = 0; 2037594f14fSEnrico Granata } 2047594f14fSEnrico Granata } 2057594f14fSEnrico Granata else /* if (count.first) */ 2067594f14fSEnrico Granata { 2077594f14fSEnrico Granata start_idx.second = 0; 2087594f14fSEnrico Granata stop_idx.second = count.second - 1; 2097594f14fSEnrico Granata } 2107594f14fSEnrico Granata } 2117594f14fSEnrico Granata history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second); 2127594f14fSEnrico Granata } 2137594f14fSEnrico Granata } 214a5a97ebeSJim Ingham return result.Succeeded(); 215a5a97ebeSJim Ingham 216a5a97ebeSJim Ingham } 2175a988416SJim Ingham 2185a988416SJim Ingham CommandOptions m_options; 219a5a97ebeSJim Ingham }; 220a5a97ebeSJim Ingham 221a5a97ebeSJim Ingham OptionDefinition 222a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] = 223a5a97ebeSJim Ingham { 2246e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "How many history commands to print."}, 2256e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."}, 2266e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."}, 2276e3d8e7fSEugene Zelenko { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clears the current command history."}, 2286e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 229a5a97ebeSJim Ingham }; 230a5a97ebeSJim Ingham 231a5a97ebeSJim Ingham //------------------------------------------------------------------------- 232a5a97ebeSJim Ingham // CommandObjectCommandsSource 233a5a97ebeSJim Ingham //------------------------------------------------------------------------- 234a5a97ebeSJim Ingham 2355a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed 236ebc09c36SJim Ingham { 2375a988416SJim Ingham public: 2385a988416SJim Ingham CommandObjectCommandsSource(CommandInterpreter &interpreter) : 2395a988416SJim Ingham CommandObjectParsed(interpreter, 2405a988416SJim Ingham "command source", 2415a988416SJim Ingham "Read in debugger commands from the file <filename> and execute them.", 2426e3d8e7fSEugene Zelenko nullptr), 2435a988416SJim Ingham m_options (interpreter) 2445a988416SJim Ingham { 2455a988416SJim Ingham CommandArgumentEntry arg; 2465a988416SJim Ingham CommandArgumentData file_arg; 2475a988416SJim Ingham 2485a988416SJim Ingham // Define the first (and only) variant of this arg. 2495a988416SJim Ingham file_arg.arg_type = eArgTypeFilename; 2505a988416SJim Ingham file_arg.arg_repetition = eArgRepeatPlain; 2515a988416SJim Ingham 2525a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 2535a988416SJim Ingham arg.push_back (file_arg); 2545a988416SJim Ingham 2555a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 2565a988416SJim Ingham m_arguments.push_back (arg); 2575a988416SJim Ingham } 2585a988416SJim Ingham 2596e3d8e7fSEugene Zelenko ~CommandObjectCommandsSource() override = default; 2605a988416SJim Ingham 26113d21e9aSBruce Mitchener const char* 26213d21e9aSBruce Mitchener GetRepeatCommand (Args ¤t_command_args, uint32_t index) override 2635a988416SJim Ingham { 2645a988416SJim Ingham return ""; 2655a988416SJim Ingham } 2665a988416SJim Ingham 26713d21e9aSBruce Mitchener int 2685a988416SJim Ingham HandleArgumentCompletion (Args &input, 2695a988416SJim Ingham int &cursor_index, 2705a988416SJim Ingham int &cursor_char_position, 2715a988416SJim Ingham OptionElementVector &opt_element_vector, 2725a988416SJim Ingham int match_start_point, 2735a988416SJim Ingham int max_return_elements, 2745a988416SJim Ingham bool &word_complete, 27513d21e9aSBruce Mitchener StringList &matches) override 2765a988416SJim Ingham { 2775a988416SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2785a988416SJim Ingham completion_str.erase (cursor_char_position); 2795a988416SJim Ingham 2805a988416SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter, 2815a988416SJim Ingham CommandCompletions::eDiskFileCompletion, 2825a988416SJim Ingham completion_str.c_str(), 2835a988416SJim Ingham match_start_point, 2845a988416SJim Ingham max_return_elements, 2856e3d8e7fSEugene Zelenko nullptr, 2865a988416SJim Ingham word_complete, 2875a988416SJim Ingham matches); 2885a988416SJim Ingham return matches.GetSize(); 2895a988416SJim Ingham } 2905a988416SJim Ingham 29113d21e9aSBruce Mitchener Options * 29213d21e9aSBruce Mitchener GetOptions () override 2935a988416SJim Ingham { 2945a988416SJim Ingham return &m_options; 2955a988416SJim Ingham } 2965a988416SJim Ingham 2975a988416SJim Ingham protected: 298e16c50a1SJim Ingham class CommandOptions : public Options 299e16c50a1SJim Ingham { 300e16c50a1SJim Ingham public: 301eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 302012d4fcaSEnrico Granata Options (interpreter), 303340b0309SGreg Clayton m_stop_on_error (true), 304340b0309SGreg Clayton m_silent_run (false), 305340b0309SGreg Clayton m_stop_on_continue (true) 306eb0103f2SGreg Clayton { 307eb0103f2SGreg Clayton } 308e16c50a1SJim Ingham 3096e3d8e7fSEugene Zelenko ~CommandOptions() override = default; 310e16c50a1SJim Ingham 31113d21e9aSBruce Mitchener Error 31213d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 313e16c50a1SJim Ingham { 314e16c50a1SJim Ingham Error error; 3153bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 316e16c50a1SJim Ingham 317e16c50a1SJim Ingham switch (short_option) 318e16c50a1SJim Ingham { 319e16c50a1SJim Ingham case 'e': 320c95f7e2aSPavel Labath error = m_stop_on_error.SetValueFromString(option_arg); 321e16c50a1SJim Ingham break; 322340b0309SGreg Clayton 323e16c50a1SJim Ingham case 'c': 324c95f7e2aSPavel Labath error = m_stop_on_continue.SetValueFromString(option_arg); 325e16c50a1SJim Ingham break; 326340b0309SGreg Clayton 32760986174SMichael Sartain case 's': 328c95f7e2aSPavel Labath error = m_silent_run.SetValueFromString(option_arg); 32960986174SMichael Sartain break; 330340b0309SGreg Clayton 331e16c50a1SJim Ingham default: 33286edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 333e16c50a1SJim Ingham break; 334e16c50a1SJim Ingham } 335e16c50a1SJim Ingham 336e16c50a1SJim Ingham return error; 337e16c50a1SJim Ingham } 338e16c50a1SJim Ingham 339e16c50a1SJim Ingham void 34013d21e9aSBruce Mitchener OptionParsingStarting () override 341e16c50a1SJim Ingham { 342012d4fcaSEnrico Granata m_stop_on_error.Clear(); 343340b0309SGreg Clayton m_silent_run.Clear(); 344340b0309SGreg Clayton m_stop_on_continue.Clear(); 345e16c50a1SJim Ingham } 346e16c50a1SJim Ingham 347e0d378b3SGreg Clayton const OptionDefinition* 34813d21e9aSBruce Mitchener GetDefinitions () override 349e16c50a1SJim Ingham { 350e16c50a1SJim Ingham return g_option_table; 351e16c50a1SJim Ingham } 352e16c50a1SJim Ingham 353e16c50a1SJim Ingham // Options table: Required for subclasses of Options. 354e16c50a1SJim Ingham 355e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 356e16c50a1SJim Ingham 357e16c50a1SJim Ingham // Instance variables to hold the values for command options. 358e16c50a1SJim Ingham 359012d4fcaSEnrico Granata OptionValueBoolean m_stop_on_error; 360340b0309SGreg Clayton OptionValueBoolean m_silent_run; 361340b0309SGreg Clayton OptionValueBoolean m_stop_on_continue; 362e16c50a1SJim Ingham }; 363e16c50a1SJim Ingham 364ebc09c36SJim Ingham bool 36513d21e9aSBruce Mitchener DoExecute(Args& command, CommandReturnObject &result) override 366ebc09c36SJim Ingham { 367c7bece56SGreg Clayton const size_t argc = command.GetArgumentCount(); 368ebc09c36SJim Ingham if (argc == 1) 369ebc09c36SJim Ingham { 3705a988416SJim Ingham const char *filename = command.GetArgumentAtIndex(0); 371ebc09c36SJim Ingham 3721ee3853fSJohnny Chen FileSpec cmd_file (filename, true); 3736e3d8e7fSEugene Zelenko ExecutionContext *exe_ctx = nullptr; // Just use the default context. 374ebc09c36SJim Ingham 375340b0309SGreg Clayton // If any options were set, then use them 376340b0309SGreg Clayton if (m_options.m_stop_on_error.OptionWasSet() || 377340b0309SGreg Clayton m_options.m_silent_run.OptionWasSet() || 378340b0309SGreg Clayton m_options.m_stop_on_continue.OptionWasSet()) 379340b0309SGreg Clayton { 380340b0309SGreg Clayton // Use user set settings 38126c7bf93SJim Ingham CommandInterpreterRunOptions options; 38226c7bf93SJim Ingham options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue()); 38326c7bf93SJim Ingham options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue()); 3847d8555c4SJim Ingham options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue()); 3857d8555c4SJim Ingham options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue()); 38626c7bf93SJim Ingham 387e16c50a1SJim Ingham m_interpreter.HandleCommandsFromFile (cmd_file, 388e16c50a1SJim Ingham exe_ctx, 38926c7bf93SJim Ingham options, 390e16c50a1SJim Ingham result); 391340b0309SGreg Clayton } 392340b0309SGreg Clayton else 393340b0309SGreg Clayton { 394340b0309SGreg Clayton // No options were set, inherit any settings from nested "command source" commands, 395340b0309SGreg Clayton // or set to sane default settings... 39626c7bf93SJim Ingham CommandInterpreterRunOptions options; 397340b0309SGreg Clayton m_interpreter.HandleCommandsFromFile (cmd_file, 398340b0309SGreg Clayton exe_ctx, 39926c7bf93SJim Ingham options, 400340b0309SGreg Clayton result); 401340b0309SGreg Clayton } 402ebc09c36SJim Ingham } 403ebc09c36SJim Ingham else 404ebc09c36SJim Ingham { 405ebc09c36SJim Ingham result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName()); 406ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 407ebc09c36SJim Ingham } 408ebc09c36SJim Ingham return result.Succeeded(); 409ebc09c36SJim Ingham } 4106e3d8e7fSEugene Zelenko 4115a988416SJim Ingham CommandOptions m_options; 412ebc09c36SJim Ingham }; 413ebc09c36SJim Ingham 414e0d378b3SGreg Clayton OptionDefinition 415e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] = 416e16c50a1SJim Ingham { 4176e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on error."}, 4186e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on continue."}, 4196e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true don't echo commands while executing."}, 4206e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 421e16c50a1SJim Ingham }; 422e16c50a1SJim Ingham 423ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias 424ebc09c36SJim Ingham //------------------------------------------------------------------------- 425ebc09c36SJim Ingham // CommandObjectCommandsAlias 426ebc09c36SJim Ingham //------------------------------------------------------------------------- 427ebc09c36SJim Ingham 428be93a35aSEnrico Granata static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" 429be93a35aSEnrico Granata "You must define a Python function with this signature:\n" 43044d93782SGreg Clayton "def my_command_impl(debugger, args, result, internal_dict):\n"; 431be93a35aSEnrico Granata 4325a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw 433ebc09c36SJim Ingham { 434*45d0e238SEnrico Granata protected: 435*45d0e238SEnrico Granata class CommandOptions : public OptionGroup 436*45d0e238SEnrico Granata { 437ebc09c36SJim Ingham public: 438*45d0e238SEnrico Granata CommandOptions () : 439*45d0e238SEnrico Granata OptionGroup(), 440*45d0e238SEnrico Granata m_help(), 441*45d0e238SEnrico Granata m_long_help() 442*45d0e238SEnrico Granata {} 443*45d0e238SEnrico Granata 444*45d0e238SEnrico Granata ~CommandOptions() override = default; 445*45d0e238SEnrico Granata 446*45d0e238SEnrico Granata uint32_t 447*45d0e238SEnrico Granata GetNumDefinitions () override 448*45d0e238SEnrico Granata { 449*45d0e238SEnrico Granata return 3; 450*45d0e238SEnrico Granata } 451*45d0e238SEnrico Granata 452*45d0e238SEnrico Granata const OptionDefinition* 453*45d0e238SEnrico Granata GetDefinitions () override 454*45d0e238SEnrico Granata { 455*45d0e238SEnrico Granata return g_option_table; 456*45d0e238SEnrico Granata } 457*45d0e238SEnrico Granata 458*45d0e238SEnrico Granata Error 459*45d0e238SEnrico Granata SetOptionValue (CommandInterpreter &interpreter, 460*45d0e238SEnrico Granata uint32_t option_idx, 461*45d0e238SEnrico Granata const char *option_value) override 462*45d0e238SEnrico Granata { 463*45d0e238SEnrico Granata Error error; 464*45d0e238SEnrico Granata 465*45d0e238SEnrico Granata const int short_option = g_option_table[option_idx].short_option; 466*45d0e238SEnrico Granata 467*45d0e238SEnrico Granata switch (short_option) 468*45d0e238SEnrico Granata { 469*45d0e238SEnrico Granata case 'h': 470*45d0e238SEnrico Granata m_help.SetCurrentValue(option_value); 471*45d0e238SEnrico Granata m_help.SetOptionWasSet(); 472*45d0e238SEnrico Granata break; 473*45d0e238SEnrico Granata 474*45d0e238SEnrico Granata case 'H': 475*45d0e238SEnrico Granata m_long_help.SetCurrentValue(option_value); 476*45d0e238SEnrico Granata m_long_help.SetOptionWasSet(); 477*45d0e238SEnrico Granata break; 478*45d0e238SEnrico Granata 479*45d0e238SEnrico Granata default: 480*45d0e238SEnrico Granata error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 481*45d0e238SEnrico Granata break; 482*45d0e238SEnrico Granata } 483*45d0e238SEnrico Granata 484*45d0e238SEnrico Granata return error; 485*45d0e238SEnrico Granata } 486*45d0e238SEnrico Granata 487*45d0e238SEnrico Granata void 488*45d0e238SEnrico Granata OptionParsingStarting (CommandInterpreter &interpreter) override 489*45d0e238SEnrico Granata { 490*45d0e238SEnrico Granata m_help.Clear(); 491*45d0e238SEnrico Granata m_long_help.Clear(); 492*45d0e238SEnrico Granata } 493*45d0e238SEnrico Granata 494*45d0e238SEnrico Granata // Options table: Required for subclasses of Options. 495*45d0e238SEnrico Granata 496*45d0e238SEnrico Granata static OptionDefinition g_option_table[]; 497*45d0e238SEnrico Granata OptionValueString m_help; 498*45d0e238SEnrico Granata OptionValueString m_long_help; 499*45d0e238SEnrico Granata }; 500*45d0e238SEnrico Granata 501*45d0e238SEnrico Granata OptionGroupOptions m_option_group; 502*45d0e238SEnrico Granata CommandOptions m_command_options; 503*45d0e238SEnrico Granata 504*45d0e238SEnrico Granata public: 505*45d0e238SEnrico Granata Options * 506*45d0e238SEnrico Granata GetOptions () override 507*45d0e238SEnrico Granata { 508*45d0e238SEnrico Granata return &m_option_group; 509*45d0e238SEnrico Granata } 510*45d0e238SEnrico Granata 511a7015092SGreg Clayton CommandObjectCommandsAlias (CommandInterpreter &interpreter) : 5125a988416SJim Ingham CommandObjectRaw(interpreter, 5130e5e5a79SGreg Clayton "command alias", 514e3d26315SCaroline Tice "Allow users to define their own debugger command abbreviations.", 515*45d0e238SEnrico Granata nullptr), 516*45d0e238SEnrico Granata m_option_group(interpreter), 517*45d0e238SEnrico Granata m_command_options() 518ebc09c36SJim Ingham { 519*45d0e238SEnrico Granata m_option_group.Append(&m_command_options); 520*45d0e238SEnrico Granata m_option_group.Finalize(); 521*45d0e238SEnrico Granata 522ebc09c36SJim Ingham SetHelpLong( 523ea671fbdSKate Stone "'alias' allows the user to create a short-cut or abbreviation for long \ 524ea671fbdSKate Stone commands, multi-word commands, and commands that take particular options. \ 525ea671fbdSKate Stone Below are some simple examples of how one might use the 'alias' command:" R"( 526ea671fbdSKate Stone 527ea671fbdSKate Stone (lldb) command alias sc script 528ea671fbdSKate Stone 529ea671fbdSKate Stone Creates the abbreviation 'sc' for the 'script' command. 530ea671fbdSKate Stone 531ea671fbdSKate Stone (lldb) command alias bp breakpoint 532ea671fbdSKate Stone 533ea671fbdSKate Stone )" " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \ 534ea671fbdSKate Stone breakpoint commands are two-word commands, the user would still need to \ 535ea671fbdSKate Stone enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"( 536ea671fbdSKate Stone 537ea671fbdSKate Stone (lldb) command alias bpl breakpoint list 538ea671fbdSKate Stone 539ea671fbdSKate Stone Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'. 540ea671fbdSKate Stone 541ea671fbdSKate Stone )" "An alias can include some options for the command, with the values either \ 542ea671fbdSKate Stone filled in at the time the alias is created, or specified as positional \ 543ea671fbdSKate Stone arguments, to be filled in when the alias is invoked. The following example \ 544ea671fbdSKate Stone shows how to create aliases with options:" R"( 545ea671fbdSKate Stone 546ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2 547ea671fbdSKate Stone 548ea671fbdSKate Stone )" " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \ 549ea671fbdSKate Stone options already part of the alias. So if the user wants to set a breakpoint \ 550ea671fbdSKate Stone by file and line without explicitly having to use the -f and -l options, the \ 551ea671fbdSKate Stone user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \ 552ea671fbdSKate Stone for the actual arguments that will be passed when the alias command is used. \ 553ea671fbdSKate Stone The number in the placeholder refers to the position/order the actual value \ 554ea671fbdSKate Stone occupies when the alias is used. All the occurrences of '%1' in the alias \ 555ea671fbdSKate Stone will be replaced with the first argument, all the occurrences of '%2' in the \ 556ea671fbdSKate Stone alias will be replaced with the second argument, and so on. This also allows \ 557ea671fbdSKate Stone actual arguments to be used multiple times within an alias (see 'process \ 558ea671fbdSKate Stone launch' example below)." R"( 559ea671fbdSKate Stone 560ea671fbdSKate Stone )" "Note: the positional arguments must substitute as whole words in the resultant \ 561ea671fbdSKate Stone command, so you can't at present do something like this to append the file extension \ 562ea671fbdSKate Stone \".cpp\":" R"( 563ea671fbdSKate Stone 564ea671fbdSKate Stone (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2 565ea671fbdSKate Stone 566ea671fbdSKate Stone )" "For more complex aliasing, use the \"command regex\" command instead. In the \ 567ea671fbdSKate Stone 'bfl' case above, the actual file value will be filled in with the first argument \ 568ea671fbdSKate Stone following 'bfl' and the actual line number value will be filled in with the second \ 569ea671fbdSKate Stone argument. The user would use this alias as follows:" R"( 570ea671fbdSKate Stone 571ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2 572ea671fbdSKate Stone (lldb) bfl my-file.c 137 573ea671fbdSKate Stone 574ea671fbdSKate Stone This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'. 575ea671fbdSKate Stone 576ea671fbdSKate Stone Another example: 577ea671fbdSKate Stone 578ea671fbdSKate Stone (lldb) command alias pltty process launch -s -o %1 -e %1 579ea671fbdSKate Stone (lldb) pltty /dev/tty0 580ea671fbdSKate Stone 581ea671fbdSKate Stone Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0' 582ea671fbdSKate Stone 583ea671fbdSKate Stone )" "If the user always wanted to pass the same value to a particular option, the \ 584ea671fbdSKate Stone alias could be defined with that value directly in the alias as a constant, \ 585ea671fbdSKate Stone rather than using a positional placeholder:" R"( 586ea671fbdSKate Stone 587ea671fbdSKate Stone (lldb) command alias bl3 breakpoint set -f %1 -l 3 588ea671fbdSKate Stone 589ea671fbdSKate Stone Always sets a breakpoint on line 3 of whatever file is indicated.)" 590ea671fbdSKate Stone ); 591ebc09c36SJim Ingham 592405fe67fSCaroline Tice CommandArgumentEntry arg1; 593405fe67fSCaroline Tice CommandArgumentEntry arg2; 594405fe67fSCaroline Tice CommandArgumentEntry arg3; 595405fe67fSCaroline Tice CommandArgumentData alias_arg; 596405fe67fSCaroline Tice CommandArgumentData cmd_arg; 597405fe67fSCaroline Tice CommandArgumentData options_arg; 598405fe67fSCaroline Tice 599405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 600405fe67fSCaroline Tice alias_arg.arg_type = eArgTypeAliasName; 601405fe67fSCaroline Tice alias_arg.arg_repetition = eArgRepeatPlain; 602405fe67fSCaroline Tice 603405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 604405fe67fSCaroline Tice arg1.push_back (alias_arg); 605405fe67fSCaroline Tice 606405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 607405fe67fSCaroline Tice cmd_arg.arg_type = eArgTypeCommandName; 608405fe67fSCaroline Tice cmd_arg.arg_repetition = eArgRepeatPlain; 609405fe67fSCaroline Tice 610405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 611405fe67fSCaroline Tice arg2.push_back (cmd_arg); 612405fe67fSCaroline Tice 613405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 614405fe67fSCaroline Tice options_arg.arg_type = eArgTypeAliasOptions; 615405fe67fSCaroline Tice options_arg.arg_repetition = eArgRepeatOptional; 616405fe67fSCaroline Tice 617405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 618405fe67fSCaroline Tice arg3.push_back (options_arg); 619405fe67fSCaroline Tice 620405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 621405fe67fSCaroline Tice m_arguments.push_back (arg1); 622405fe67fSCaroline Tice m_arguments.push_back (arg2); 623405fe67fSCaroline Tice m_arguments.push_back (arg3); 624ebc09c36SJim Ingham } 625ebc09c36SJim Ingham 6266e3d8e7fSEugene Zelenko ~CommandObjectCommandsAlias() override = default; 627ebc09c36SJim Ingham 6285a988416SJim Ingham protected: 62913d21e9aSBruce Mitchener bool 63013d21e9aSBruce Mitchener DoExecute (const char *raw_command_line, CommandReturnObject &result) override 631844d2303SCaroline Tice { 632*45d0e238SEnrico Granata if (!raw_command_line || !raw_command_line[0]) 633*45d0e238SEnrico Granata { 634*45d0e238SEnrico Granata result.AppendError ("'alias' requires at least two arguments"); 635*45d0e238SEnrico Granata return false; 636*45d0e238SEnrico Granata } 637*45d0e238SEnrico Granata 638*45d0e238SEnrico Granata m_option_group.NotifyOptionParsingStarting(); 639*45d0e238SEnrico Granata 640*45d0e238SEnrico Granata const char * remainder = nullptr; 641*45d0e238SEnrico Granata 642*45d0e238SEnrico Granata if (raw_command_line[0] == '-') 643*45d0e238SEnrico Granata { 644*45d0e238SEnrico Granata // We have some options and these options MUST end with --. 645*45d0e238SEnrico Granata const char *end_options = nullptr; 646*45d0e238SEnrico Granata const char *s = raw_command_line; 647*45d0e238SEnrico Granata while (s && s[0]) 648*45d0e238SEnrico Granata { 649*45d0e238SEnrico Granata end_options = ::strstr (s, "--"); 650*45d0e238SEnrico Granata if (end_options) 651*45d0e238SEnrico Granata { 652*45d0e238SEnrico Granata end_options += 2; // Get past the "--" 653*45d0e238SEnrico Granata if (::isspace (end_options[0])) 654*45d0e238SEnrico Granata { 655*45d0e238SEnrico Granata remainder = end_options; 656*45d0e238SEnrico Granata while (::isspace (*remainder)) 657*45d0e238SEnrico Granata ++remainder; 658*45d0e238SEnrico Granata break; 659*45d0e238SEnrico Granata } 660*45d0e238SEnrico Granata } 661*45d0e238SEnrico Granata s = end_options; 662*45d0e238SEnrico Granata } 663*45d0e238SEnrico Granata 664*45d0e238SEnrico Granata if (end_options) 665*45d0e238SEnrico Granata { 666*45d0e238SEnrico Granata Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line)); 667*45d0e238SEnrico Granata if (!ParseOptions (args, result)) 668*45d0e238SEnrico Granata return false; 669*45d0e238SEnrico Granata 670*45d0e238SEnrico Granata Error error (m_option_group.NotifyOptionParsingFinished()); 671*45d0e238SEnrico Granata if (error.Fail()) 672*45d0e238SEnrico Granata { 673*45d0e238SEnrico Granata result.AppendError (error.AsCString()); 674*45d0e238SEnrico Granata result.SetStatus (eReturnStatusFailed); 675*45d0e238SEnrico Granata return false; 676*45d0e238SEnrico Granata } 677*45d0e238SEnrico Granata } 678*45d0e238SEnrico Granata } 679*45d0e238SEnrico Granata if (nullptr == remainder) 680*45d0e238SEnrico Granata remainder = raw_command_line; 681*45d0e238SEnrico Granata 682*45d0e238SEnrico Granata std::string raw_command_string (remainder); 683*45d0e238SEnrico Granata Args args (raw_command_string.c_str()); 684844d2303SCaroline Tice 685844d2303SCaroline Tice size_t argc = args.GetArgumentCount(); 686844d2303SCaroline Tice 687844d2303SCaroline Tice if (argc < 2) 688844d2303SCaroline Tice { 689844d2303SCaroline Tice result.AppendError ("'alias' requires at least two arguments"); 690844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 691844d2303SCaroline Tice return false; 692844d2303SCaroline Tice } 693844d2303SCaroline Tice 694844d2303SCaroline Tice // Get the alias command. 695844d2303SCaroline Tice 696844d2303SCaroline Tice const std::string alias_command = args.GetArgumentAtIndex (0); 697844d2303SCaroline Tice 698844d2303SCaroline Tice // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which 699844d2303SCaroline Tice // does the stripping itself. 700844d2303SCaroline Tice size_t pos = raw_command_string.find (alias_command); 701844d2303SCaroline Tice if (pos == 0) 702844d2303SCaroline Tice { 703844d2303SCaroline Tice raw_command_string = raw_command_string.substr (alias_command.size()); 704844d2303SCaroline Tice pos = raw_command_string.find_first_not_of (' '); 705844d2303SCaroline Tice if ((pos != std::string::npos) && (pos > 0)) 706844d2303SCaroline Tice raw_command_string = raw_command_string.substr (pos); 707844d2303SCaroline Tice } 708844d2303SCaroline Tice else 709844d2303SCaroline Tice { 710844d2303SCaroline Tice result.AppendError ("Error parsing command string. No alias created."); 711844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 712844d2303SCaroline Tice return false; 713844d2303SCaroline Tice } 714844d2303SCaroline Tice 715844d2303SCaroline Tice 716844d2303SCaroline Tice // Verify that the command is alias-able. 717844d2303SCaroline Tice if (m_interpreter.CommandExists (alias_command.c_str())) 718844d2303SCaroline Tice { 719844d2303SCaroline Tice result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 720844d2303SCaroline Tice alias_command.c_str()); 721844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 722844d2303SCaroline Tice return false; 723844d2303SCaroline Tice } 724844d2303SCaroline Tice 725844d2303SCaroline Tice // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string. 726844d2303SCaroline Tice // raw_command_string is returned with the name of the command object stripped off the front. 727844d2303SCaroline Tice CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string); 728844d2303SCaroline Tice 729844d2303SCaroline Tice if (!cmd_obj) 730844d2303SCaroline Tice { 73186edbf41SGreg Clayton result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command." 732844d2303SCaroline Tice " No alias created.", raw_command_string.c_str()); 733844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 734844d2303SCaroline Tice return false; 735844d2303SCaroline Tice } 736844d2303SCaroline Tice else if (!cmd_obj->WantsRawCommandString ()) 737844d2303SCaroline Tice { 738844d2303SCaroline Tice // Note that args was initialized with the original command, and has not been updated to this point. 739844d2303SCaroline Tice // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias. 7405a988416SJim Ingham return HandleAliasingNormalCommand (args, result); 741844d2303SCaroline Tice } 742844d2303SCaroline Tice else 743844d2303SCaroline Tice { 7445a988416SJim Ingham return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result); 7455a988416SJim Ingham } 7465a988416SJim Ingham return result.Succeeded(); 7475a988416SJim Ingham } 7485a988416SJim Ingham 7495a988416SJim Ingham bool 7505a988416SJim Ingham HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result) 7515a988416SJim Ingham { 752844d2303SCaroline Tice // Verify & handle any options/arguments passed to the alias command 753844d2303SCaroline Tice 754844d2303SCaroline Tice OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 755844d2303SCaroline Tice 756212130acSEnrico Granata if (CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false)) 757844d2303SCaroline Tice { 758844d2303SCaroline Tice if (m_interpreter.AliasExists (alias_command.c_str()) 759844d2303SCaroline Tice || m_interpreter.UserCommandExists (alias_command.c_str())) 760844d2303SCaroline Tice { 761844d2303SCaroline Tice result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 762844d2303SCaroline Tice alias_command.c_str()); 763844d2303SCaroline Tice } 764*45d0e238SEnrico Granata if (CommandAlias *alias = m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp, raw_command_string.c_str())) 765472362e6SCaroline Tice { 766*45d0e238SEnrico Granata if (m_command_options.m_help.OptionWasSet()) 767*45d0e238SEnrico Granata alias->SetHelp(m_command_options.m_help.GetCurrentValue()); 768*45d0e238SEnrico Granata if (m_command_options.m_long_help.OptionWasSet()) 769*45d0e238SEnrico Granata alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue()); 770844d2303SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 771844d2303SCaroline Tice } 772472362e6SCaroline Tice else 773472362e6SCaroline Tice { 774472362e6SCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 775472362e6SCaroline Tice result.SetStatus (eReturnStatusFailed); 776472362e6SCaroline Tice } 777212130acSEnrico Granata 778212130acSEnrico Granata } 779212130acSEnrico Granata else 780212130acSEnrico Granata { 781212130acSEnrico Granata result.AppendError ("Unable to create requested alias.\n"); 782212130acSEnrico Granata result.SetStatus (eReturnStatusFailed); 783212130acSEnrico Granata } 784212130acSEnrico Granata 785844d2303SCaroline Tice return result.Succeeded (); 786844d2303SCaroline Tice } 787ebc09c36SJim Ingham 788ebc09c36SJim Ingham bool 7895a988416SJim Ingham HandleAliasingNormalCommand (Args& args, CommandReturnObject &result) 790ebc09c36SJim Ingham { 791867b185dSCaroline Tice size_t argc = args.GetArgumentCount(); 792ebc09c36SJim Ingham 793ebc09c36SJim Ingham if (argc < 2) 794ebc09c36SJim Ingham { 795ebc09c36SJim Ingham result.AppendError ("'alias' requires at least two arguments"); 796ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 797ebc09c36SJim Ingham return false; 798ebc09c36SJim Ingham } 799ebc09c36SJim Ingham 800ebc09c36SJim Ingham const std::string alias_command = args.GetArgumentAtIndex(0); 801ebc09c36SJim Ingham const std::string actual_command = args.GetArgumentAtIndex(1); 802ebc09c36SJim Ingham 803ebc09c36SJim Ingham args.Shift(); // Shift the alias command word off the argument vector. 804ebc09c36SJim Ingham args.Shift(); // Shift the old command word off the argument vector. 805ebc09c36SJim Ingham 806ebc09c36SJim Ingham // Verify that the command is alias'able, and get the appropriate command object. 807ebc09c36SJim Ingham 808a7015092SGreg Clayton if (m_interpreter.CommandExists (alias_command.c_str())) 809ebc09c36SJim Ingham { 810ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 811ebc09c36SJim Ingham alias_command.c_str()); 812ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 813ebc09c36SJim Ingham } 814ebc09c36SJim Ingham else 815ebc09c36SJim Ingham { 816a7015092SGreg Clayton CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true)); 817ebc09c36SJim Ingham CommandObjectSP subcommand_obj_sp; 818ebc09c36SJim Ingham bool use_subcommand = false; 8196e3d8e7fSEugene Zelenko if (command_obj_sp) 820ebc09c36SJim Ingham { 821ebc09c36SJim Ingham CommandObject *cmd_obj = command_obj_sp.get(); 8226e3d8e7fSEugene Zelenko CommandObject *sub_cmd_obj = nullptr; 823ebc09c36SJim Ingham OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 824ebc09c36SJim Ingham 825844d2303SCaroline Tice while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0) 826ebc09c36SJim Ingham { 827ebc09c36SJim Ingham if (argc >= 3) 828ebc09c36SJim Ingham { 829ebc09c36SJim Ingham const std::string sub_command = args.GetArgumentAtIndex(0); 830ebc09c36SJim Ingham assert (sub_command.length() != 0); 831998255bfSGreg Clayton subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str()); 8326e3d8e7fSEugene Zelenko if (subcommand_obj_sp) 833ebc09c36SJim Ingham { 834ebc09c36SJim Ingham sub_cmd_obj = subcommand_obj_sp.get(); 835ebc09c36SJim Ingham use_subcommand = true; 836ebc09c36SJim Ingham args.Shift(); // Shift the sub_command word off the argument vector. 837844d2303SCaroline Tice cmd_obj = sub_cmd_obj; 838ebc09c36SJim Ingham } 839ebc09c36SJim Ingham else 840ebc09c36SJim Ingham { 841f415eeb4SCaroline Tice result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. " 842f415eeb4SCaroline Tice "Unable to create alias.\n", 843f415eeb4SCaroline Tice sub_command.c_str(), actual_command.c_str()); 844ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 845ebc09c36SJim Ingham return false; 846ebc09c36SJim Ingham } 847ebc09c36SJim Ingham } 848ebc09c36SJim Ingham } 849ebc09c36SJim Ingham 850ebc09c36SJim Ingham // Verify & handle any options/arguments passed to the alias command 851ebc09c36SJim Ingham 852212130acSEnrico Granata std::string args_string; 853212130acSEnrico Granata 854ebc09c36SJim Ingham if (args.GetArgumentCount () > 0) 855ebc09c36SJim Ingham { 856ca90c47eSCaroline Tice CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); 857ebc09c36SJim Ingham if (use_subcommand) 858ca90c47eSCaroline Tice tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false); 859ca90c47eSCaroline Tice 860ca90c47eSCaroline Tice args.GetCommandString (args_string); 861867b185dSCaroline Tice } 862ebc09c36SJim Ingham 863a7015092SGreg Clayton if (m_interpreter.AliasExists (alias_command.c_str()) 864a7015092SGreg Clayton || m_interpreter.UserCommandExists (alias_command.c_str())) 865ebc09c36SJim Ingham { 866ebc09c36SJim Ingham result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 867ebc09c36SJim Ingham alias_command.c_str()); 868ebc09c36SJim Ingham } 869ebc09c36SJim Ingham 870*45d0e238SEnrico Granata if (CommandAlias *alias = m_interpreter.AddAlias(alias_command.c_str(), 871212130acSEnrico Granata use_subcommand ? subcommand_obj_sp : command_obj_sp, 872212130acSEnrico Granata args_string.c_str())) 873212130acSEnrico Granata { 874*45d0e238SEnrico Granata if (m_command_options.m_help.OptionWasSet()) 875*45d0e238SEnrico Granata alias->SetHelp(m_command_options.m_help.GetCurrentValue()); 876*45d0e238SEnrico Granata if (m_command_options.m_long_help.OptionWasSet()) 877*45d0e238SEnrico Granata alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue()); 878ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 879ebc09c36SJim Ingham } 880ebc09c36SJim Ingham else 881ebc09c36SJim Ingham { 882212130acSEnrico Granata result.AppendError ("Unable to create requested alias.\n"); 883212130acSEnrico Granata result.SetStatus (eReturnStatusFailed); 884212130acSEnrico Granata return false; 885212130acSEnrico Granata } 886212130acSEnrico Granata } 887212130acSEnrico Granata else 888212130acSEnrico Granata { 889ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str()); 890ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 891e7941795SCaroline Tice return false; 892ebc09c36SJim Ingham } 893ebc09c36SJim Ingham } 894ebc09c36SJim Ingham 895ebc09c36SJim Ingham return result.Succeeded(); 896ebc09c36SJim Ingham } 897ebc09c36SJim Ingham }; 898ebc09c36SJim Ingham 899*45d0e238SEnrico Granata OptionDefinition 900*45d0e238SEnrico Granata CommandObjectCommandsAlias::CommandOptions::g_option_table[] = 901*45d0e238SEnrico Granata { 902*45d0e238SEnrico Granata { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Help text for this command"}, 903*45d0e238SEnrico Granata { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Long help text for this command"}, 904*45d0e238SEnrico Granata { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 905*45d0e238SEnrico Granata }; 906*45d0e238SEnrico Granata 907ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias 908ebc09c36SJim Ingham //------------------------------------------------------------------------- 909ebc09c36SJim Ingham // CommandObjectCommandsUnalias 910ebc09c36SJim Ingham //------------------------------------------------------------------------- 911ebc09c36SJim Ingham 9125a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed 913ebc09c36SJim Ingham { 914ebc09c36SJim Ingham public: 915a7015092SGreg Clayton CommandObjectCommandsUnalias (CommandInterpreter &interpreter) : 9165a988416SJim Ingham CommandObjectParsed(interpreter, 9170e5e5a79SGreg Clayton "command unalias", 91886ddae50SCaroline Tice "Allow the user to remove/delete a user-defined command abbreviation.", 9196e3d8e7fSEugene Zelenko nullptr) 920ebc09c36SJim Ingham { 921405fe67fSCaroline Tice CommandArgumentEntry arg; 922405fe67fSCaroline Tice CommandArgumentData alias_arg; 923405fe67fSCaroline Tice 924405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 925405fe67fSCaroline Tice alias_arg.arg_type = eArgTypeAliasName; 926405fe67fSCaroline Tice alias_arg.arg_repetition = eArgRepeatPlain; 927405fe67fSCaroline Tice 928405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 929405fe67fSCaroline Tice arg.push_back (alias_arg); 930405fe67fSCaroline Tice 931405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 932405fe67fSCaroline Tice m_arguments.push_back (arg); 933ebc09c36SJim Ingham } 934ebc09c36SJim Ingham 9356e3d8e7fSEugene Zelenko ~CommandObjectCommandsUnalias() override = default; 936ebc09c36SJim Ingham 9375a988416SJim Ingham protected: 938ebc09c36SJim Ingham bool 93913d21e9aSBruce Mitchener DoExecute (Args& args, CommandReturnObject &result) override 940ebc09c36SJim Ingham { 941ebc09c36SJim Ingham CommandObject::CommandMap::iterator pos; 942ebc09c36SJim Ingham CommandObject *cmd_obj; 943ebc09c36SJim Ingham 944ebc09c36SJim Ingham if (args.GetArgumentCount() != 0) 945ebc09c36SJim Ingham { 946ebc09c36SJim Ingham const char *command_name = args.GetArgumentAtIndex(0); 947a7015092SGreg Clayton cmd_obj = m_interpreter.GetCommandObject(command_name); 948ebc09c36SJim Ingham if (cmd_obj) 949ebc09c36SJim Ingham { 950a7015092SGreg Clayton if (m_interpreter.CommandExists (command_name)) 951ebc09c36SJim Ingham { 952b547278cSGreg Clayton if (cmd_obj->IsRemovable()) 953b547278cSGreg Clayton { 954b547278cSGreg Clayton result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n", 955b547278cSGreg Clayton command_name); 956b547278cSGreg Clayton } 957b547278cSGreg Clayton else 958b547278cSGreg Clayton { 959ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 960ebc09c36SJim Ingham command_name); 961b547278cSGreg Clayton } 962ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 963ebc09c36SJim Ingham } 964ebc09c36SJim Ingham else 965ebc09c36SJim Ingham { 9666e3d8e7fSEugene Zelenko if (!m_interpreter.RemoveAlias(command_name)) 967ebc09c36SJim Ingham { 968a7015092SGreg Clayton if (m_interpreter.AliasExists (command_name)) 969ebc09c36SJim Ingham result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n", 970ebc09c36SJim Ingham command_name); 971ebc09c36SJim Ingham else 972ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name); 973ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 974ebc09c36SJim Ingham } 975ebc09c36SJim Ingham else 976ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 977ebc09c36SJim Ingham } 978ebc09c36SJim Ingham } 979ebc09c36SJim Ingham else 980ebc09c36SJim Ingham { 981ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a " 982ebc09c36SJim Ingham "current list of commands.\n", 983ebc09c36SJim Ingham command_name); 984ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 985ebc09c36SJim Ingham } 986ebc09c36SJim Ingham } 987ebc09c36SJim Ingham else 988ebc09c36SJim Ingham { 989ebc09c36SJim Ingham result.AppendError ("must call 'unalias' with a valid alias"); 990ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 991ebc09c36SJim Ingham } 992ebc09c36SJim Ingham 993ebc09c36SJim Ingham return result.Succeeded(); 994ebc09c36SJim Ingham } 995ebc09c36SJim Ingham }; 996ebc09c36SJim Ingham 997b547278cSGreg Clayton #pragma mark CommandObjectCommandsDelete 998b547278cSGreg Clayton //------------------------------------------------------------------------- 999b547278cSGreg Clayton // CommandObjectCommandsDelete 1000b547278cSGreg Clayton //------------------------------------------------------------------------- 1001b547278cSGreg Clayton 1002b547278cSGreg Clayton class CommandObjectCommandsDelete : public CommandObjectParsed 1003b547278cSGreg Clayton { 1004b547278cSGreg Clayton public: 1005b547278cSGreg Clayton CommandObjectCommandsDelete (CommandInterpreter &interpreter) : 1006b547278cSGreg Clayton CommandObjectParsed(interpreter, 1007b547278cSGreg Clayton "command delete", 1008b547278cSGreg Clayton "Allow the user to delete user-defined regular expression, python or multi-word commands.", 10096e3d8e7fSEugene Zelenko nullptr) 1010b547278cSGreg Clayton { 1011b547278cSGreg Clayton CommandArgumentEntry arg; 1012b547278cSGreg Clayton CommandArgumentData alias_arg; 1013b547278cSGreg Clayton 1014b547278cSGreg Clayton // Define the first (and only) variant of this arg. 1015b547278cSGreg Clayton alias_arg.arg_type = eArgTypeCommandName; 1016b547278cSGreg Clayton alias_arg.arg_repetition = eArgRepeatPlain; 1017b547278cSGreg Clayton 1018b547278cSGreg Clayton // There is only one variant this argument could be; put it into the argument entry. 1019b547278cSGreg Clayton arg.push_back (alias_arg); 1020b547278cSGreg Clayton 1021b547278cSGreg Clayton // Push the data for the first argument into the m_arguments vector. 1022b547278cSGreg Clayton m_arguments.push_back (arg); 1023b547278cSGreg Clayton } 1024b547278cSGreg Clayton 10256e3d8e7fSEugene Zelenko ~CommandObjectCommandsDelete() override = default; 1026b547278cSGreg Clayton 1027b547278cSGreg Clayton protected: 1028b547278cSGreg Clayton bool 102913d21e9aSBruce Mitchener DoExecute (Args& args, CommandReturnObject &result) override 1030b547278cSGreg Clayton { 1031b547278cSGreg Clayton CommandObject::CommandMap::iterator pos; 1032b547278cSGreg Clayton 1033b547278cSGreg Clayton if (args.GetArgumentCount() != 0) 1034b547278cSGreg Clayton { 1035b547278cSGreg Clayton const char *command_name = args.GetArgumentAtIndex(0); 1036b547278cSGreg Clayton if (m_interpreter.CommandExists (command_name)) 1037b547278cSGreg Clayton { 1038b547278cSGreg Clayton if (m_interpreter.RemoveCommand (command_name)) 1039b547278cSGreg Clayton { 1040b547278cSGreg Clayton result.SetStatus (eReturnStatusSuccessFinishNoResult); 1041b547278cSGreg Clayton } 1042b547278cSGreg Clayton else 1043b547278cSGreg Clayton { 1044b547278cSGreg Clayton result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 1045b547278cSGreg Clayton command_name); 1046b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 1047b547278cSGreg Clayton } 1048b547278cSGreg Clayton } 1049b547278cSGreg Clayton else 1050b547278cSGreg Clayton { 105146d4aa21SEnrico Granata StreamString error_msg_stream; 105246d4aa21SEnrico Granata const bool generate_apropos = true; 105346d4aa21SEnrico Granata const bool generate_type_lookup = false; 105446d4aa21SEnrico Granata CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream, 105546d4aa21SEnrico Granata command_name, 105646d4aa21SEnrico Granata nullptr, 105746d4aa21SEnrico Granata nullptr, 105846d4aa21SEnrico Granata generate_apropos, 105946d4aa21SEnrico Granata generate_type_lookup); 106046d4aa21SEnrico Granata result.AppendErrorWithFormat ("%s", error_msg_stream.GetData()); 1061b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 1062b547278cSGreg Clayton } 1063b547278cSGreg Clayton } 1064b547278cSGreg Clayton else 1065b547278cSGreg Clayton { 1066b547278cSGreg Clayton result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ()); 1067b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 1068b547278cSGreg Clayton } 1069b547278cSGreg Clayton 1070b547278cSGreg Clayton return result.Succeeded(); 1071b547278cSGreg Clayton } 1072b547278cSGreg Clayton }; 1073b547278cSGreg Clayton 1074de164aaaSGreg Clayton //------------------------------------------------------------------------- 1075de164aaaSGreg Clayton // CommandObjectCommandsAddRegex 1076de164aaaSGreg Clayton //------------------------------------------------------------------------- 10775a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex 1078de164aaaSGreg Clayton 107944d93782SGreg Clayton class CommandObjectCommandsAddRegex : 108044d93782SGreg Clayton public CommandObjectParsed, 1081ea508635SGreg Clayton public IOHandlerDelegateMultiline 1082de164aaaSGreg Clayton { 1083de164aaaSGreg Clayton public: 1084de164aaaSGreg Clayton CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) : 10855a988416SJim Ingham CommandObjectParsed (interpreter, 10860e5e5a79SGreg Clayton "command regex", 1087de164aaaSGreg Clayton "Allow the user to create a regular expression command.", 10880e5e5a79SGreg Clayton "command regex <cmd-name> [s/<regex>/<subst>/ ...]"), 1089ea508635SGreg Clayton IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand), 1090de164aaaSGreg Clayton m_options (interpreter) 1091de164aaaSGreg Clayton { 1092ea671fbdSKate Stone SetHelpLong(R"( 1093ea671fbdSKate Stone )" "This command allows the user to create powerful regular expression commands \ 1094ea671fbdSKate Stone with substitutions. The regular expressions and substitutions are specified \ 1095ea671fbdSKate Stone using the regular expression substitution format of:" R"( 1096ea671fbdSKate Stone 1097ea671fbdSKate Stone s/<regex>/<subst>/ 1098ea671fbdSKate Stone 1099ea671fbdSKate Stone )" "<regex> is a regular expression that can use parenthesis to capture regular \ 1100ea671fbdSKate Stone expression input and substitute the captured matches in the output using %1 \ 1101ea671fbdSKate Stone for the first match, %2 for the second, and so on." R"( 1102ea671fbdSKate Stone 1103ea671fbdSKate Stone )" "The regular expressions can all be specified on the command line if more than \ 1104ea671fbdSKate Stone one argument is provided. If just the command name is provided on the command \ 1105ea671fbdSKate Stone line, then the regular expressions and substitutions can be entered on separate \ 1106ea671fbdSKate Stone lines, followed by an empty line to terminate the command definition." R"( 1107ea671fbdSKate Stone 1108ea671fbdSKate Stone EXAMPLES 1109ea671fbdSKate Stone 1110ea671fbdSKate Stone )" "The following example will define a regular expression command named 'f' that \ 1111ea671fbdSKate Stone will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \ 1112ea671fbdSKate Stone a number follows 'f':" R"( 1113ea671fbdSKate Stone 1114ea671fbdSKate Stone (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')" 11150e5e5a79SGreg Clayton ); 1116de164aaaSGreg Clayton } 1117de164aaaSGreg Clayton 11186e3d8e7fSEugene Zelenko ~CommandObjectCommandsAddRegex() override = default; 1119de164aaaSGreg Clayton 11205a988416SJim Ingham protected: 1121ea508635SGreg Clayton void 1122ea508635SGreg Clayton IOHandlerActivated (IOHandler &io_handler) override 112344d93782SGreg Clayton { 112444d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 112544d93782SGreg Clayton if (output_sp) 112644d93782SGreg Clayton { 112744d93782SGreg 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"); 112844d93782SGreg Clayton output_sp->Flush(); 112944d93782SGreg Clayton } 113044d93782SGreg Clayton } 113144d93782SGreg Clayton 1132ea508635SGreg Clayton void 1133ea508635SGreg Clayton IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override 113444d93782SGreg Clayton { 113544d93782SGreg Clayton io_handler.SetIsDone(true); 11366e3d8e7fSEugene Zelenko if (m_regex_cmd_ap) 113744d93782SGreg Clayton { 113844d93782SGreg Clayton StringList lines; 113944d93782SGreg Clayton if (lines.SplitIntoLines (data)) 114044d93782SGreg Clayton { 114144d93782SGreg Clayton const size_t num_lines = lines.GetSize(); 114244d93782SGreg Clayton bool check_only = false; 114344d93782SGreg Clayton for (size_t i=0; i<num_lines; ++i) 114444d93782SGreg Clayton { 114544d93782SGreg Clayton llvm::StringRef bytes_strref (lines[i]); 114644d93782SGreg Clayton Error error = AppendRegexSubstitution (bytes_strref, check_only); 114744d93782SGreg Clayton if (error.Fail()) 114844d93782SGreg Clayton { 114944d93782SGreg Clayton if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) 115044d93782SGreg Clayton { 115144d93782SGreg Clayton StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream(); 115244d93782SGreg Clayton out_stream->Printf("error: %s\n", error.AsCString()); 115344d93782SGreg Clayton } 115444d93782SGreg Clayton } 115544d93782SGreg Clayton } 115644d93782SGreg Clayton } 115744d93782SGreg Clayton if (m_regex_cmd_ap->HasRegexEntries()) 115844d93782SGreg Clayton { 115944d93782SGreg Clayton CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 116044d93782SGreg Clayton m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 116144d93782SGreg Clayton } 116244d93782SGreg Clayton } 116344d93782SGreg Clayton } 116444d93782SGreg Clayton 1165de164aaaSGreg Clayton bool 1166b0a1814fSEric Christopher DoExecute (Args& command, CommandReturnObject &result) override 1167de164aaaSGreg Clayton { 11685a988416SJim Ingham const size_t argc = command.GetArgumentCount(); 11690e5e5a79SGreg Clayton if (argc == 0) 1170de164aaaSGreg Clayton { 117169c12ccbSJason Molenda result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n"); 11720e5e5a79SGreg Clayton result.SetStatus (eReturnStatusFailed); 11730e5e5a79SGreg Clayton } 11740e5e5a79SGreg Clayton else 11750e5e5a79SGreg Clayton { 11760e5e5a79SGreg Clayton Error error; 11775a988416SJim Ingham const char *name = command.GetArgumentAtIndex(0); 1178de164aaaSGreg Clayton m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter, 1179de164aaaSGreg Clayton name, 1180de164aaaSGreg Clayton m_options.GetHelp (), 1181de164aaaSGreg Clayton m_options.GetSyntax (), 1182b547278cSGreg Clayton 10, 1183b547278cSGreg Clayton 0, 1184b547278cSGreg Clayton true)); 11850e5e5a79SGreg Clayton 11860e5e5a79SGreg Clayton if (argc == 1) 11870e5e5a79SGreg Clayton { 118844d93782SGreg Clayton Debugger &debugger = m_interpreter.GetDebugger(); 1189e30f11d9SKate Stone bool color_prompt = debugger.GetUseColor(); 119044d93782SGreg Clayton const bool multiple_lines = true; // Get multiple lines 119144d93782SGreg Clayton IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger, 1192e30f11d9SKate Stone IOHandler::Type::Other, 119373d80faaSGreg Clayton "lldb-regex", // Name of input reader for history 1194ea508635SGreg Clayton "> ", // Prompt 11956e3d8e7fSEugene Zelenko nullptr, // Continuation prompt 119644d93782SGreg Clayton multiple_lines, 1197e30f11d9SKate Stone color_prompt, 1198f6913cd7SGreg Clayton 0, // Don't show line numbers 119944d93782SGreg Clayton *this)); 120044d93782SGreg Clayton 120144d93782SGreg Clayton if (io_handler_sp) 1202de164aaaSGreg Clayton { 120344d93782SGreg Clayton debugger.PushIOHandler(io_handler_sp); 1204de164aaaSGreg Clayton result.SetStatus (eReturnStatusSuccessFinishNoResult); 1205de164aaaSGreg Clayton } 1206de164aaaSGreg Clayton } 1207de164aaaSGreg Clayton else 1208de164aaaSGreg Clayton { 12090e5e5a79SGreg Clayton for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) 12100e5e5a79SGreg Clayton { 12115a988416SJim Ingham llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx)); 121244d93782SGreg Clayton bool check_only = false; 121344d93782SGreg Clayton error = AppendRegexSubstitution (arg_strref, check_only); 12140e5e5a79SGreg Clayton if (error.Fail()) 12150e5e5a79SGreg Clayton break; 12160e5e5a79SGreg Clayton } 12170e5e5a79SGreg Clayton 12180e5e5a79SGreg Clayton if (error.Success()) 12190e5e5a79SGreg Clayton { 12200e5e5a79SGreg Clayton AddRegexCommandToInterpreter(); 12210e5e5a79SGreg Clayton } 12220e5e5a79SGreg Clayton } 12230e5e5a79SGreg Clayton if (error.Fail()) 12240e5e5a79SGreg Clayton { 12250e5e5a79SGreg Clayton result.AppendError (error.AsCString()); 1226de164aaaSGreg Clayton result.SetStatus (eReturnStatusFailed); 1227de164aaaSGreg Clayton } 12280e5e5a79SGreg Clayton } 12290e5e5a79SGreg Clayton 1230de164aaaSGreg Clayton return result.Succeeded(); 1231de164aaaSGreg Clayton } 1232de164aaaSGreg Clayton 12330e5e5a79SGreg Clayton Error 123444d93782SGreg Clayton AppendRegexSubstitution (const llvm::StringRef ®ex_sed, bool check_only) 1235de164aaaSGreg Clayton { 12360e5e5a79SGreg Clayton Error error; 12370e5e5a79SGreg Clayton 12386e3d8e7fSEugene Zelenko if (!m_regex_cmd_ap) 1239de164aaaSGreg Clayton { 12400e5e5a79SGreg Clayton error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'", 12410e5e5a79SGreg Clayton (int)regex_sed.size(), 12420e5e5a79SGreg Clayton regex_sed.data()); 12430e5e5a79SGreg Clayton return error; 1244de164aaaSGreg Clayton } 12450e5e5a79SGreg Clayton 12460e5e5a79SGreg Clayton size_t regex_sed_size = regex_sed.size(); 12470e5e5a79SGreg Clayton 12480e5e5a79SGreg Clayton if (regex_sed_size <= 1) 12490e5e5a79SGreg Clayton { 12500e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'", 12510e5e5a79SGreg Clayton (int)regex_sed.size(), 12520e5e5a79SGreg Clayton regex_sed.data()); 12530e5e5a79SGreg Clayton return error; 12540e5e5a79SGreg Clayton } 12550e5e5a79SGreg Clayton 12560e5e5a79SGreg Clayton if (regex_sed[0] != 's') 12570e5e5a79SGreg Clayton { 12580e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'", 12590e5e5a79SGreg Clayton (int)regex_sed.size(), 12600e5e5a79SGreg Clayton regex_sed.data()); 12610e5e5a79SGreg Clayton return error; 12620e5e5a79SGreg Clayton } 12630e5e5a79SGreg Clayton const size_t first_separator_char_pos = 1; 12640e5e5a79SGreg Clayton // use the char that follows 's' as the regex separator character 12650e5e5a79SGreg Clayton // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" 12660e5e5a79SGreg Clayton const char separator_char = regex_sed[first_separator_char_pos]; 12670e5e5a79SGreg Clayton const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1); 12680e5e5a79SGreg Clayton 12690e5e5a79SGreg Clayton if (second_separator_char_pos == std::string::npos) 12700e5e5a79SGreg Clayton { 1271ea508635SGreg Clayton error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'", 12720e5e5a79SGreg Clayton separator_char, 12730e5e5a79SGreg Clayton (int)(regex_sed.size() - first_separator_char_pos - 1), 1274ea508635SGreg Clayton regex_sed.data() + (first_separator_char_pos + 1), 1275ea508635SGreg Clayton (int)regex_sed.size(), 1276ea508635SGreg Clayton regex_sed.data()); 12770e5e5a79SGreg Clayton return error; 12780e5e5a79SGreg Clayton } 12790e5e5a79SGreg Clayton 12800e5e5a79SGreg Clayton const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1); 12810e5e5a79SGreg Clayton 12820e5e5a79SGreg Clayton if (third_separator_char_pos == std::string::npos) 12830e5e5a79SGreg Clayton { 1284ea508635SGreg Clayton error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'", 12850e5e5a79SGreg Clayton separator_char, 12860e5e5a79SGreg Clayton (int)(regex_sed.size() - second_separator_char_pos - 1), 1287ea508635SGreg Clayton regex_sed.data() + (second_separator_char_pos + 1), 1288ea508635SGreg Clayton (int)regex_sed.size(), 1289ea508635SGreg Clayton regex_sed.data()); 12900e5e5a79SGreg Clayton return error; 12910e5e5a79SGreg Clayton } 12920e5e5a79SGreg Clayton 12930e5e5a79SGreg Clayton if (third_separator_char_pos != regex_sed_size - 1) 12940e5e5a79SGreg Clayton { 12950e5e5a79SGreg Clayton // Make sure that everything that follows the last regex 12960e5e5a79SGreg Clayton // separator char 12970e5e5a79SGreg Clayton if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) 12980e5e5a79SGreg Clayton { 12990e5e5a79SGreg Clayton error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'", 13000e5e5a79SGreg Clayton (int)third_separator_char_pos + 1, 13010e5e5a79SGreg Clayton regex_sed.data(), 13020e5e5a79SGreg Clayton (int)(regex_sed.size() - third_separator_char_pos - 1), 13030e5e5a79SGreg Clayton regex_sed.data() + (third_separator_char_pos + 1)); 13040e5e5a79SGreg Clayton return error; 13050e5e5a79SGreg Clayton } 13060e5e5a79SGreg Clayton } 13070e5e5a79SGreg Clayton else if (first_separator_char_pos + 1 == second_separator_char_pos) 13080e5e5a79SGreg Clayton { 13090e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 13100e5e5a79SGreg Clayton separator_char, 13110e5e5a79SGreg Clayton separator_char, 13120e5e5a79SGreg Clayton separator_char, 13130e5e5a79SGreg Clayton (int)regex_sed.size(), 13140e5e5a79SGreg Clayton regex_sed.data()); 13150e5e5a79SGreg Clayton return error; 13160e5e5a79SGreg Clayton } 13170e5e5a79SGreg Clayton else if (second_separator_char_pos + 1 == third_separator_char_pos) 13180e5e5a79SGreg Clayton { 13190e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 13200e5e5a79SGreg Clayton separator_char, 13210e5e5a79SGreg Clayton separator_char, 13220e5e5a79SGreg Clayton separator_char, 13230e5e5a79SGreg Clayton (int)regex_sed.size(), 13240e5e5a79SGreg Clayton regex_sed.data()); 13250e5e5a79SGreg Clayton return error; 13260e5e5a79SGreg Clayton } 132744d93782SGreg Clayton 13286e3d8e7fSEugene Zelenko if (!check_only) 132944d93782SGreg Clayton { 13300e5e5a79SGreg Clayton std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1)); 13310e5e5a79SGreg Clayton std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1)); 13320e5e5a79SGreg Clayton m_regex_cmd_ap->AddRegexCommand (regex.c_str(), 13330e5e5a79SGreg Clayton subst.c_str()); 133444d93782SGreg Clayton } 13350e5e5a79SGreg Clayton return error; 1336de164aaaSGreg Clayton } 1337de164aaaSGreg Clayton 1338de164aaaSGreg Clayton void 13390e5e5a79SGreg Clayton AddRegexCommandToInterpreter() 1340de164aaaSGreg Clayton { 13416e3d8e7fSEugene Zelenko if (m_regex_cmd_ap) 1342de164aaaSGreg Clayton { 1343de164aaaSGreg Clayton if (m_regex_cmd_ap->HasRegexEntries()) 1344de164aaaSGreg Clayton { 1345de164aaaSGreg Clayton CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 1346de164aaaSGreg Clayton m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 1347de164aaaSGreg Clayton } 1348de164aaaSGreg Clayton } 1349de164aaaSGreg Clayton } 1350de164aaaSGreg Clayton 1351de164aaaSGreg Clayton private: 13527b0992d9SGreg Clayton std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap; 1353de164aaaSGreg Clayton 1354de164aaaSGreg Clayton class CommandOptions : public Options 1355de164aaaSGreg Clayton { 1356de164aaaSGreg Clayton public: 1357de164aaaSGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 1358de164aaaSGreg Clayton Options (interpreter) 1359de164aaaSGreg Clayton { 1360de164aaaSGreg Clayton } 1361de164aaaSGreg Clayton 13626e3d8e7fSEugene Zelenko ~CommandOptions() override = default; 1363de164aaaSGreg Clayton 136413d21e9aSBruce Mitchener Error 136513d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 1366de164aaaSGreg Clayton { 1367de164aaaSGreg Clayton Error error; 13683bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 1369de164aaaSGreg Clayton 1370de164aaaSGreg Clayton switch (short_option) 1371de164aaaSGreg Clayton { 1372de164aaaSGreg Clayton case 'h': 1373de164aaaSGreg Clayton m_help.assign (option_arg); 1374de164aaaSGreg Clayton break; 1375de164aaaSGreg Clayton case 's': 1376de164aaaSGreg Clayton m_syntax.assign (option_arg); 1377de164aaaSGreg Clayton break; 1378de164aaaSGreg Clayton default: 137986edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1380de164aaaSGreg Clayton break; 1381de164aaaSGreg Clayton } 1382de164aaaSGreg Clayton 1383de164aaaSGreg Clayton return error; 1384de164aaaSGreg Clayton } 1385de164aaaSGreg Clayton 1386de164aaaSGreg Clayton void 138713d21e9aSBruce Mitchener OptionParsingStarting () override 1388de164aaaSGreg Clayton { 1389de164aaaSGreg Clayton m_help.clear(); 1390de164aaaSGreg Clayton m_syntax.clear(); 1391de164aaaSGreg Clayton } 1392de164aaaSGreg Clayton 1393de164aaaSGreg Clayton const OptionDefinition* 139413d21e9aSBruce Mitchener GetDefinitions () override 1395de164aaaSGreg Clayton { 1396de164aaaSGreg Clayton return g_option_table; 1397de164aaaSGreg Clayton } 1398de164aaaSGreg Clayton 1399de164aaaSGreg Clayton // Options table: Required for subclasses of Options. 1400de164aaaSGreg Clayton 1401de164aaaSGreg Clayton static OptionDefinition g_option_table[]; 1402de164aaaSGreg Clayton 1403de164aaaSGreg Clayton const char * 1404de164aaaSGreg Clayton GetHelp() 1405de164aaaSGreg Clayton { 14066e3d8e7fSEugene Zelenko return (m_help.empty() ? nullptr : m_help.c_str()); 1407de164aaaSGreg Clayton } 14086e3d8e7fSEugene Zelenko 1409de164aaaSGreg Clayton const char * 1410de164aaaSGreg Clayton GetSyntax () 1411de164aaaSGreg Clayton { 14126e3d8e7fSEugene Zelenko return (m_syntax.empty() ? nullptr : m_syntax.c_str()); 1413de164aaaSGreg Clayton } 14146e3d8e7fSEugene Zelenko 1415de164aaaSGreg Clayton protected: 14166e3d8e7fSEugene Zelenko // Instance variables to hold the values for command options. 14176e3d8e7fSEugene Zelenko 1418de164aaaSGreg Clayton std::string m_help; 1419de164aaaSGreg Clayton std::string m_syntax; 1420de164aaaSGreg Clayton }; 1421de164aaaSGreg Clayton 1422b0a1814fSEric Christopher Options * 1423b0a1814fSEric Christopher GetOptions () override 1424de164aaaSGreg Clayton { 1425de164aaaSGreg Clayton return &m_options; 1426de164aaaSGreg Clayton } 1427de164aaaSGreg Clayton 14285a988416SJim Ingham CommandOptions m_options; 1429de164aaaSGreg Clayton }; 1430de164aaaSGreg Clayton 1431de164aaaSGreg Clayton OptionDefinition 1432de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = 1433de164aaaSGreg Clayton { 14346e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command."}, 14356e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, 14366e3d8e7fSEugene Zelenko { 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr } 1437de164aaaSGreg Clayton }; 1438de164aaaSGreg Clayton 14395a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw 1440223383edSEnrico Granata { 1441223383edSEnrico Granata public: 1442223383edSEnrico Granata CommandObjectPythonFunction (CommandInterpreter &interpreter, 1443223383edSEnrico Granata std::string name, 14440a305db7SEnrico Granata std::string funct, 1445735152e3SEnrico Granata std::string help, 14460a305db7SEnrico Granata ScriptedCommandSynchronicity synch) : 14475a988416SJim Ingham CommandObjectRaw(interpreter, 1448223383edSEnrico Granata name.c_str(), 14496e3d8e7fSEugene Zelenko nullptr, 14506e3d8e7fSEugene Zelenko nullptr), 14510a305db7SEnrico Granata m_function_name(funct), 1452fac939e9SEnrico Granata m_synchro(synch), 1453fac939e9SEnrico Granata m_fetched_help_long(false) 1454223383edSEnrico Granata { 1455735152e3SEnrico Granata if (!help.empty()) 1456735152e3SEnrico Granata SetHelp(help.c_str()); 1457735152e3SEnrico Granata else 1458735152e3SEnrico Granata { 1459735152e3SEnrico Granata StreamString stream; 1460735152e3SEnrico Granata stream.Printf("For more information run 'help %s'",name.c_str()); 1461735152e3SEnrico Granata SetHelp(stream.GetData()); 1462735152e3SEnrico Granata } 1463223383edSEnrico Granata } 1464223383edSEnrico Granata 14656e3d8e7fSEugene Zelenko ~CommandObjectPythonFunction() override = default; 1466223383edSEnrico Granata 146713d21e9aSBruce Mitchener bool 146813d21e9aSBruce Mitchener IsRemovable () const override 14695a988416SJim Ingham { 14705a988416SJim Ingham return true; 14715a988416SJim Ingham } 14725a988416SJim Ingham 14735a988416SJim Ingham const std::string& 14745a988416SJim Ingham GetFunctionName () 14755a988416SJim Ingham { 14765a988416SJim Ingham return m_function_name; 14775a988416SJim Ingham } 14785a988416SJim Ingham 14795a988416SJim Ingham ScriptedCommandSynchronicity 14805a988416SJim Ingham GetSynchronicity () 14815a988416SJim Ingham { 14825a988416SJim Ingham return m_synchro; 14835a988416SJim Ingham } 14845a988416SJim Ingham 148513d21e9aSBruce Mitchener const char * 148613d21e9aSBruce Mitchener GetHelpLong () override 1487fac939e9SEnrico Granata { 1488fac939e9SEnrico Granata if (!m_fetched_help_long) 1489fac939e9SEnrico Granata { 1490fac939e9SEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1491fac939e9SEnrico Granata if (scripter) 1492fac939e9SEnrico Granata { 1493fac939e9SEnrico Granata std::string docstring; 1494fac939e9SEnrico Granata m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring); 1495fac939e9SEnrico Granata if (!docstring.empty()) 1496bfb75e9bSEnrico Granata SetHelpLong(docstring.c_str()); 1497fac939e9SEnrico Granata } 1498fac939e9SEnrico Granata } 1499fac939e9SEnrico Granata return CommandObjectRaw::GetHelpLong(); 1500fac939e9SEnrico Granata } 1501fac939e9SEnrico Granata 15025a988416SJim Ingham protected: 150313d21e9aSBruce Mitchener bool 150413d21e9aSBruce Mitchener DoExecute (const char *raw_command_line, CommandReturnObject &result) override 1505223383edSEnrico Granata { 1506223383edSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1507223383edSEnrico Granata 1508223383edSEnrico Granata Error error; 1509223383edSEnrico Granata 151070f11f88SJim Ingham result.SetStatus(eReturnStatusInvalid); 151170f11f88SJim Ingham 15126e3d8e7fSEugene Zelenko if (!scripter || !scripter->RunScriptBasedCommand(m_function_name.c_str(), 1513223383edSEnrico Granata raw_command_line, 15140a305db7SEnrico Granata m_synchro, 1515223383edSEnrico Granata result, 151606be059aSEnrico Granata error, 15176e3d8e7fSEugene Zelenko m_exe_ctx)) 1518223383edSEnrico Granata { 1519223383edSEnrico Granata result.AppendError(error.AsCString()); 1520223383edSEnrico Granata result.SetStatus(eReturnStatusFailed); 1521223383edSEnrico Granata } 1522223383edSEnrico Granata else 152370f11f88SJim Ingham { 152470f11f88SJim Ingham // Don't change the status if the command already set it... 152570f11f88SJim Ingham if (result.GetStatus() == eReturnStatusInvalid) 152670f11f88SJim Ingham { 15276e3d8e7fSEugene Zelenko if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0') 1528223383edSEnrico Granata result.SetStatus(eReturnStatusSuccessFinishNoResult); 152970f11f88SJim Ingham else 153070f11f88SJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult); 153170f11f88SJim Ingham } 153270f11f88SJim Ingham } 1533223383edSEnrico Granata 1534223383edSEnrico Granata return result.Succeeded(); 1535223383edSEnrico Granata } 1536223383edSEnrico Granata 15376e3d8e7fSEugene Zelenko private: 15386e3d8e7fSEugene Zelenko std::string m_function_name; 15396e3d8e7fSEugene Zelenko ScriptedCommandSynchronicity m_synchro; 15406e3d8e7fSEugene Zelenko bool m_fetched_help_long; 1541223383edSEnrico Granata }; 1542223383edSEnrico Granata 15439fe00e52SEnrico Granata class CommandObjectScriptingObject : public CommandObjectRaw 15449fe00e52SEnrico Granata { 15459fe00e52SEnrico Granata public: 15469fe00e52SEnrico Granata CommandObjectScriptingObject (CommandInterpreter &interpreter, 15479fe00e52SEnrico Granata std::string name, 15480641ca1aSZachary Turner StructuredData::GenericSP cmd_obj_sp, 15499fe00e52SEnrico Granata ScriptedCommandSynchronicity synch) : 15509fe00e52SEnrico Granata CommandObjectRaw(interpreter, 15519fe00e52SEnrico Granata name.c_str(), 15526e3d8e7fSEugene Zelenko nullptr, 15536e3d8e7fSEugene Zelenko nullptr), 15549fe00e52SEnrico Granata m_cmd_obj_sp(cmd_obj_sp), 15556f79bb2dSEnrico Granata m_synchro(synch), 15566f79bb2dSEnrico Granata m_fetched_help_short(false), 15576f79bb2dSEnrico Granata m_fetched_help_long(false) 15589fe00e52SEnrico Granata { 15599fe00e52SEnrico Granata StreamString stream; 15609fe00e52SEnrico Granata stream.Printf("For more information run 'help %s'",name.c_str()); 15619fe00e52SEnrico Granata SetHelp(stream.GetData()); 1562e87764f2SEnrico Granata if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter()) 1563e87764f2SEnrico Granata GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp)); 15649fe00e52SEnrico Granata } 15659fe00e52SEnrico Granata 15666e3d8e7fSEugene Zelenko ~CommandObjectScriptingObject() override = default; 15679fe00e52SEnrico Granata 156813d21e9aSBruce Mitchener bool 156913d21e9aSBruce Mitchener IsRemovable () const override 15709fe00e52SEnrico Granata { 15719fe00e52SEnrico Granata return true; 15729fe00e52SEnrico Granata } 15739fe00e52SEnrico Granata 15740641ca1aSZachary Turner StructuredData::GenericSP 15759fe00e52SEnrico Granata GetImplementingObject () 15769fe00e52SEnrico Granata { 15779fe00e52SEnrico Granata return m_cmd_obj_sp; 15789fe00e52SEnrico Granata } 15799fe00e52SEnrico Granata 15809fe00e52SEnrico Granata ScriptedCommandSynchronicity 15819fe00e52SEnrico Granata GetSynchronicity () 15829fe00e52SEnrico Granata { 15839fe00e52SEnrico Granata return m_synchro; 15849fe00e52SEnrico Granata } 15859fe00e52SEnrico Granata 158613d21e9aSBruce Mitchener const char * 158713d21e9aSBruce Mitchener GetHelp () override 15886f79bb2dSEnrico Granata { 15896f79bb2dSEnrico Granata if (!m_fetched_help_short) 15906f79bb2dSEnrico Granata { 15916f79bb2dSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 15926f79bb2dSEnrico Granata if (scripter) 15936f79bb2dSEnrico Granata { 15946f79bb2dSEnrico Granata std::string docstring; 15956f79bb2dSEnrico Granata m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring); 15966f79bb2dSEnrico Granata if (!docstring.empty()) 1597bfb75e9bSEnrico Granata SetHelp(docstring.c_str()); 15986f79bb2dSEnrico Granata } 15996f79bb2dSEnrico Granata } 16006f79bb2dSEnrico Granata return CommandObjectRaw::GetHelp(); 16016f79bb2dSEnrico Granata } 16026f79bb2dSEnrico Granata 160313d21e9aSBruce Mitchener const char * 160413d21e9aSBruce Mitchener GetHelpLong () override 16059fe00e52SEnrico Granata { 16066f79bb2dSEnrico Granata if (!m_fetched_help_long) 16076f79bb2dSEnrico Granata { 16086f79bb2dSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 16096f79bb2dSEnrico Granata if (scripter) 16106f79bb2dSEnrico Granata { 16116f79bb2dSEnrico Granata std::string docstring; 16126f79bb2dSEnrico Granata m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring); 16136f79bb2dSEnrico Granata if (!docstring.empty()) 1614bfb75e9bSEnrico Granata SetHelpLong(docstring.c_str()); 16156f79bb2dSEnrico Granata } 16166f79bb2dSEnrico Granata } 16179fe00e52SEnrico Granata return CommandObjectRaw::GetHelpLong(); 16189fe00e52SEnrico Granata } 16199fe00e52SEnrico Granata 16209fe00e52SEnrico Granata protected: 162113d21e9aSBruce Mitchener bool 162213d21e9aSBruce Mitchener DoExecute (const char *raw_command_line, CommandReturnObject &result) override 16239fe00e52SEnrico Granata { 16249fe00e52SEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 16259fe00e52SEnrico Granata 16269fe00e52SEnrico Granata Error error; 16279fe00e52SEnrico Granata 16289fe00e52SEnrico Granata result.SetStatus(eReturnStatusInvalid); 16299fe00e52SEnrico Granata 16306e3d8e7fSEugene Zelenko if (!scripter || !scripter->RunScriptBasedCommand(m_cmd_obj_sp, 16319fe00e52SEnrico Granata raw_command_line, 16329fe00e52SEnrico Granata m_synchro, 16339fe00e52SEnrico Granata result, 16349fe00e52SEnrico Granata error, 16356e3d8e7fSEugene Zelenko m_exe_ctx)) 16369fe00e52SEnrico Granata { 16379fe00e52SEnrico Granata result.AppendError(error.AsCString()); 16389fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 16399fe00e52SEnrico Granata } 16409fe00e52SEnrico Granata else 16419fe00e52SEnrico Granata { 16429fe00e52SEnrico Granata // Don't change the status if the command already set it... 16439fe00e52SEnrico Granata if (result.GetStatus() == eReturnStatusInvalid) 16449fe00e52SEnrico Granata { 16456e3d8e7fSEugene Zelenko if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0') 16469fe00e52SEnrico Granata result.SetStatus(eReturnStatusSuccessFinishNoResult); 16479fe00e52SEnrico Granata else 16489fe00e52SEnrico Granata result.SetStatus(eReturnStatusSuccessFinishResult); 16499fe00e52SEnrico Granata } 16509fe00e52SEnrico Granata } 16519fe00e52SEnrico Granata 16529fe00e52SEnrico Granata return result.Succeeded(); 16539fe00e52SEnrico Granata } 16549fe00e52SEnrico Granata 16556e3d8e7fSEugene Zelenko private: 16566e3d8e7fSEugene Zelenko StructuredData::GenericSP m_cmd_obj_sp; 16576e3d8e7fSEugene Zelenko ScriptedCommandSynchronicity m_synchro; 16586e3d8e7fSEugene Zelenko bool m_fetched_help_short: 1; 16596e3d8e7fSEugene Zelenko bool m_fetched_help_long: 1; 16609fe00e52SEnrico Granata }; 16619fe00e52SEnrico Granata 1662a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1663a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport 1664a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1665a9dbf432SEnrico Granata 16665a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed 1667a9dbf432SEnrico Granata { 16685a988416SJim Ingham public: 16695a988416SJim Ingham CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 16705a988416SJim Ingham CommandObjectParsed(interpreter, 16715a988416SJim Ingham "command script import", 16725a988416SJim Ingham "Import a scripting module in LLDB.", 16736e3d8e7fSEugene Zelenko nullptr), 16745a988416SJim Ingham m_options(interpreter) 16755a988416SJim Ingham { 16765a988416SJim Ingham CommandArgumentEntry arg1; 16775a988416SJim Ingham CommandArgumentData cmd_arg; 16785a988416SJim Ingham 16795a988416SJim Ingham // Define the first (and only) variant of this arg. 16805a988416SJim Ingham cmd_arg.arg_type = eArgTypeFilename; 16813b00e35bSEnrico Granata cmd_arg.arg_repetition = eArgRepeatPlus; 16825a988416SJim Ingham 16835a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 16845a988416SJim Ingham arg1.push_back (cmd_arg); 16855a988416SJim Ingham 16865a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 16875a988416SJim Ingham m_arguments.push_back (arg1); 16885a988416SJim Ingham } 16895a988416SJim Ingham 16906e3d8e7fSEugene Zelenko ~CommandObjectCommandsScriptImport() override = default; 16915a988416SJim Ingham 169213d21e9aSBruce Mitchener int 16935a988416SJim Ingham HandleArgumentCompletion (Args &input, 16945a988416SJim Ingham int &cursor_index, 16955a988416SJim Ingham int &cursor_char_position, 16965a988416SJim Ingham OptionElementVector &opt_element_vector, 16975a988416SJim Ingham int match_start_point, 16985a988416SJim Ingham int max_return_elements, 16995a988416SJim Ingham bool &word_complete, 170013d21e9aSBruce Mitchener StringList &matches) override 17015a988416SJim Ingham { 17025a988416SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 17035a988416SJim Ingham completion_str.erase (cursor_char_position); 17045a988416SJim Ingham 17055a988416SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter, 17065a988416SJim Ingham CommandCompletions::eDiskFileCompletion, 17075a988416SJim Ingham completion_str.c_str(), 17085a988416SJim Ingham match_start_point, 17095a988416SJim Ingham max_return_elements, 17106e3d8e7fSEugene Zelenko nullptr, 17115a988416SJim Ingham word_complete, 17125a988416SJim Ingham matches); 17135a988416SJim Ingham return matches.GetSize(); 17145a988416SJim Ingham } 17155a988416SJim Ingham 171613d21e9aSBruce Mitchener Options * 171713d21e9aSBruce Mitchener GetOptions () override 17185a988416SJim Ingham { 17195a988416SJim Ingham return &m_options; 17205a988416SJim Ingham } 17215a988416SJim Ingham 17225a988416SJim Ingham protected: 17230a305db7SEnrico Granata class CommandOptions : public Options 17240a305db7SEnrico Granata { 17250a305db7SEnrico Granata public: 17260a305db7SEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 17270a305db7SEnrico Granata Options (interpreter) 17280a305db7SEnrico Granata { 17290a305db7SEnrico Granata } 17300a305db7SEnrico Granata 17316e3d8e7fSEugene Zelenko ~CommandOptions() override = default; 17320a305db7SEnrico Granata 173313d21e9aSBruce Mitchener Error 173413d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 17350a305db7SEnrico Granata { 17360a305db7SEnrico Granata Error error; 17373bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 17380a305db7SEnrico Granata 17390a305db7SEnrico Granata switch (short_option) 17400a305db7SEnrico Granata { 17410a305db7SEnrico Granata case 'r': 17420a305db7SEnrico Granata m_allow_reload = true; 17430a305db7SEnrico Granata break; 17440a305db7SEnrico Granata default: 17450a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 17460a305db7SEnrico Granata break; 17470a305db7SEnrico Granata } 17480a305db7SEnrico Granata 17490a305db7SEnrico Granata return error; 17500a305db7SEnrico Granata } 17510a305db7SEnrico Granata 17520a305db7SEnrico Granata void 175313d21e9aSBruce Mitchener OptionParsingStarting () override 17540a305db7SEnrico Granata { 1755e0c70f1bSEnrico Granata m_allow_reload = true; 17560a305db7SEnrico Granata } 17570a305db7SEnrico Granata 17580a305db7SEnrico Granata const OptionDefinition* 175913d21e9aSBruce Mitchener GetDefinitions () override 17600a305db7SEnrico Granata { 17610a305db7SEnrico Granata return g_option_table; 17620a305db7SEnrico Granata } 17630a305db7SEnrico Granata 17640a305db7SEnrico Granata // Options table: Required for subclasses of Options. 17650a305db7SEnrico Granata 17660a305db7SEnrico Granata static OptionDefinition g_option_table[]; 17670a305db7SEnrico Granata 17680a305db7SEnrico Granata // Instance variables to hold the values for command options. 17690a305db7SEnrico Granata 17700a305db7SEnrico Granata bool m_allow_reload; 17710a305db7SEnrico Granata }; 17720a305db7SEnrico Granata 1773a9dbf432SEnrico Granata bool 177413d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 1775a9dbf432SEnrico Granata { 1776a9dbf432SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1777a9dbf432SEnrico Granata { 1778a9dbf432SEnrico Granata result.AppendError ("only scripting language supported for module importing is currently Python"); 1779a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1780a9dbf432SEnrico Granata return false; 1781a9dbf432SEnrico Granata } 1782a9dbf432SEnrico Granata 17835a988416SJim Ingham size_t argc = command.GetArgumentCount(); 17843b00e35bSEnrico Granata if (0 == argc) 1785a9dbf432SEnrico Granata { 17863b00e35bSEnrico Granata result.AppendError("command script import needs one or more arguments"); 1787a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1788a9dbf432SEnrico Granata return false; 1789a9dbf432SEnrico Granata } 1790a9dbf432SEnrico Granata 17910e978481SEd Maste for (size_t i = 0; 17923b00e35bSEnrico Granata i < argc; 17933b00e35bSEnrico Granata i++) 17943b00e35bSEnrico Granata { 17953b00e35bSEnrico Granata std::string path = command.GetArgumentAtIndex(i); 1796a9dbf432SEnrico Granata Error error; 1797a9dbf432SEnrico Granata 1798c9d645d3SGreg Clayton const bool init_session = true; 1799078551c7SEnrico Granata // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that 1800078551c7SEnrico Granata // commands won't ever be recursively invoked, but it's actually possible to craft 1801078551c7SEnrico Granata // a Python script that does other "command script imports" in __lldb_init_module 1802078551c7SEnrico Granata // the real fix is to have recursive commands possible with a CommandInvocation object 1803078551c7SEnrico Granata // separate from the CommandObject itself, so that recursive command invocations 1804078551c7SEnrico Granata // won't stomp on each other (wrt to execution contents, options, and more) 1805078551c7SEnrico Granata m_exe_ctx.Clear(); 1806a9dbf432SEnrico Granata if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 18070a305db7SEnrico Granata m_options.m_allow_reload, 1808c9d645d3SGreg Clayton init_session, 1809a9dbf432SEnrico Granata error)) 1810a9dbf432SEnrico Granata { 1811a9dbf432SEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1812a9dbf432SEnrico Granata } 1813a9dbf432SEnrico Granata else 1814a9dbf432SEnrico Granata { 1815a9dbf432SEnrico Granata result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1816a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1817a9dbf432SEnrico Granata } 18183b00e35bSEnrico Granata } 1819a9dbf432SEnrico Granata 1820a9dbf432SEnrico Granata return result.Succeeded(); 1821a9dbf432SEnrico Granata } 18220a305db7SEnrico Granata 18235a988416SJim Ingham CommandOptions m_options; 1824a9dbf432SEnrico Granata }; 1825223383edSEnrico Granata 18260a305db7SEnrico Granata OptionDefinition 18270a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 18280a305db7SEnrico Granata { 18296e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, nullptr, 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."}, 18306e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 18310a305db7SEnrico Granata }; 18320a305db7SEnrico Granata 1833223383edSEnrico Granata //------------------------------------------------------------------------- 1834223383edSEnrico Granata // CommandObjectCommandsScriptAdd 1835223383edSEnrico Granata //------------------------------------------------------------------------- 1836223383edSEnrico Granata 183744d93782SGreg Clayton class CommandObjectCommandsScriptAdd : 183844d93782SGreg Clayton public CommandObjectParsed, 183944d93782SGreg Clayton public IOHandlerDelegateMultiline 1840223383edSEnrico Granata { 18415a988416SJim Ingham public: 18425a988416SJim Ingham CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 18435a988416SJim Ingham CommandObjectParsed(interpreter, 18445a988416SJim Ingham "command script add", 18455a988416SJim Ingham "Add a scripted function as an LLDB command.", 18466e3d8e7fSEugene Zelenko nullptr), 1847c3d874a5SGreg Clayton IOHandlerDelegateMultiline ("DONE"), 18485a988416SJim Ingham m_options (interpreter) 18495a988416SJim Ingham { 18505a988416SJim Ingham CommandArgumentEntry arg1; 18515a988416SJim Ingham CommandArgumentData cmd_arg; 18525a988416SJim Ingham 18535a988416SJim Ingham // Define the first (and only) variant of this arg. 18545a988416SJim Ingham cmd_arg.arg_type = eArgTypeCommandName; 18555a988416SJim Ingham cmd_arg.arg_repetition = eArgRepeatPlain; 18565a988416SJim Ingham 18575a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 18585a988416SJim Ingham arg1.push_back (cmd_arg); 18595a988416SJim Ingham 18605a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 18615a988416SJim Ingham m_arguments.push_back (arg1); 18625a988416SJim Ingham } 18635a988416SJim Ingham 18646e3d8e7fSEugene Zelenko ~CommandObjectCommandsScriptAdd() override = default; 18655a988416SJim Ingham 186613d21e9aSBruce Mitchener Options * 186713d21e9aSBruce Mitchener GetOptions () override 18685a988416SJim Ingham { 18695a988416SJim Ingham return &m_options; 18705a988416SJim Ingham } 18715a988416SJim Ingham 18725a988416SJim Ingham protected: 1873223383edSEnrico Granata class CommandOptions : public Options 1874223383edSEnrico Granata { 1875223383edSEnrico Granata public: 1876223383edSEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 18779fe00e52SEnrico Granata Options (interpreter), 18789fe00e52SEnrico Granata m_class_name(), 18799fe00e52SEnrico Granata m_funct_name(), 18809fe00e52SEnrico Granata m_short_help(), 18819fe00e52SEnrico Granata m_synchronicity(eScriptedCommandSynchronicitySynchronous) 1882223383edSEnrico Granata { 1883223383edSEnrico Granata } 1884223383edSEnrico Granata 18856e3d8e7fSEugene Zelenko ~CommandOptions() override = default; 1886223383edSEnrico Granata 188713d21e9aSBruce Mitchener Error 188813d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 1889223383edSEnrico Granata { 1890223383edSEnrico Granata Error error; 18913bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 1892223383edSEnrico Granata 1893223383edSEnrico Granata switch (short_option) 1894223383edSEnrico Granata { 1895223383edSEnrico Granata case 'f': 1896735152e3SEnrico Granata if (option_arg) 1897735152e3SEnrico Granata m_funct_name.assign(option_arg); 1898735152e3SEnrico Granata break; 18999fe00e52SEnrico Granata case 'c': 19009fe00e52SEnrico Granata if (option_arg) 19019fe00e52SEnrico Granata m_class_name.assign(option_arg); 19029fe00e52SEnrico Granata break; 1903735152e3SEnrico Granata case 'h': 1904735152e3SEnrico Granata if (option_arg) 1905735152e3SEnrico Granata m_short_help.assign(option_arg); 1906223383edSEnrico Granata break; 19070a305db7SEnrico Granata case 's': 190844d93782SGreg Clayton m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 19090a305db7SEnrico Granata if (!error.Success()) 19100a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 19110a305db7SEnrico Granata break; 1912223383edSEnrico Granata default: 191386edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1914223383edSEnrico Granata break; 1915223383edSEnrico Granata } 1916223383edSEnrico Granata 1917223383edSEnrico Granata return error; 1918223383edSEnrico Granata } 1919223383edSEnrico Granata 1920223383edSEnrico Granata void 192113d21e9aSBruce Mitchener OptionParsingStarting () override 1922223383edSEnrico Granata { 19239fe00e52SEnrico Granata m_class_name.clear(); 1924735152e3SEnrico Granata m_funct_name.clear(); 1925735152e3SEnrico Granata m_short_help.clear(); 192644d93782SGreg Clayton m_synchronicity = eScriptedCommandSynchronicitySynchronous; 1927223383edSEnrico Granata } 1928223383edSEnrico Granata 1929223383edSEnrico Granata const OptionDefinition* 193013d21e9aSBruce Mitchener GetDefinitions () override 1931223383edSEnrico Granata { 1932223383edSEnrico Granata return g_option_table; 1933223383edSEnrico Granata } 1934223383edSEnrico Granata 1935223383edSEnrico Granata // Options table: Required for subclasses of Options. 1936223383edSEnrico Granata 1937223383edSEnrico Granata static OptionDefinition g_option_table[]; 1938223383edSEnrico Granata 1939223383edSEnrico Granata // Instance variables to hold the values for command options. 1940223383edSEnrico Granata 19419fe00e52SEnrico Granata std::string m_class_name; 1942223383edSEnrico Granata std::string m_funct_name; 1943735152e3SEnrico Granata std::string m_short_help; 194444d93782SGreg Clayton ScriptedCommandSynchronicity m_synchronicity; 1945223383edSEnrico Granata }; 1946223383edSEnrico Granata 194713d21e9aSBruce Mitchener void 194813d21e9aSBruce Mitchener IOHandlerActivated (IOHandler &io_handler) override 1949223383edSEnrico Granata { 195044d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 195144d93782SGreg Clayton if (output_sp) 1952223383edSEnrico Granata { 195344d93782SGreg Clayton output_sp->PutCString(g_python_command_instructions); 195444d93782SGreg Clayton output_sp->Flush(); 1955223383edSEnrico Granata } 1956223383edSEnrico Granata } 1957223383edSEnrico Granata 1958223383edSEnrico Granata 195913d21e9aSBruce Mitchener void 196013d21e9aSBruce Mitchener IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override 1961223383edSEnrico Granata { 196244d93782SGreg Clayton StreamFileSP error_sp = io_handler.GetErrorStreamFile(); 196344d93782SGreg Clayton 196444d93782SGreg Clayton ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 196544d93782SGreg Clayton if (interpreter) 196644d93782SGreg Clayton { 196744d93782SGreg Clayton 196844d93782SGreg Clayton StringList lines; 196944d93782SGreg Clayton lines.SplitIntoLines(data); 197044d93782SGreg Clayton if (lines.GetSize() > 0) 197144d93782SGreg Clayton { 1972a73b7df7SEnrico Granata std::string funct_name_str; 197344d93782SGreg Clayton if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str)) 1974223383edSEnrico Granata { 1975a73b7df7SEnrico Granata if (funct_name_str.empty()) 1976223383edSEnrico Granata { 197744d93782SGreg Clayton error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n"); 197844d93782SGreg Clayton error_sp->Flush(); 1979223383edSEnrico Granata } 198044d93782SGreg Clayton else 198144d93782SGreg Clayton { 1982223383edSEnrico Granata // everything should be fine now, let's add this alias 1983223383edSEnrico Granata 1984223383edSEnrico Granata CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter, 1985223383edSEnrico Granata m_cmd_name, 1986a73b7df7SEnrico Granata funct_name_str.c_str(), 1987735152e3SEnrico Granata m_short_help, 198844d93782SGreg Clayton m_synchronicity)); 1989223383edSEnrico Granata 19900a305db7SEnrico Granata if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 1991223383edSEnrico Granata { 199244d93782SGreg Clayton error_sp->Printf ("error: unable to add selected command, didn't add python command.\n"); 199344d93782SGreg Clayton error_sp->Flush(); 1994223383edSEnrico Granata } 1995223383edSEnrico Granata } 199644d93782SGreg Clayton } 199744d93782SGreg Clayton else 199844d93782SGreg Clayton { 199944d93782SGreg Clayton error_sp->Printf ("error: unable to create function, didn't add python command.\n"); 200044d93782SGreg Clayton error_sp->Flush(); 200144d93782SGreg Clayton } 200244d93782SGreg Clayton } 200344d93782SGreg Clayton else 200444d93782SGreg Clayton { 200544d93782SGreg Clayton error_sp->Printf ("error: empty function, didn't add python command.\n"); 200644d93782SGreg Clayton error_sp->Flush(); 200744d93782SGreg Clayton } 200844d93782SGreg Clayton } 200944d93782SGreg Clayton else 201044d93782SGreg Clayton { 201144d93782SGreg Clayton error_sp->Printf ("error: script interpreter missing, didn't add python command.\n"); 201244d93782SGreg Clayton error_sp->Flush(); 201344d93782SGreg Clayton } 201444d93782SGreg Clayton 201544d93782SGreg Clayton io_handler.SetIsDone(true); 201644d93782SGreg Clayton } 2017223383edSEnrico Granata 20185a988416SJim Ingham protected: 2019223383edSEnrico Granata bool 202013d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 2021223383edSEnrico Granata { 202299f0b8f9SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 202399f0b8f9SEnrico Granata { 202499f0b8f9SEnrico Granata result.AppendError ("only scripting language supported for scripted commands is currently Python"); 202599f0b8f9SEnrico Granata result.SetStatus (eReturnStatusFailed); 202699f0b8f9SEnrico Granata return false; 202799f0b8f9SEnrico Granata } 202899f0b8f9SEnrico Granata 20295a988416SJim Ingham size_t argc = command.GetArgumentCount(); 2030223383edSEnrico Granata 2031223383edSEnrico Granata if (argc != 1) 2032223383edSEnrico Granata { 2033223383edSEnrico Granata result.AppendError ("'command script add' requires one argument"); 2034223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2035223383edSEnrico Granata return false; 2036223383edSEnrico Granata } 2037223383edSEnrico Granata 2038735152e3SEnrico Granata // Store the options in case we get multi-line input 203944d93782SGreg Clayton m_cmd_name = command.GetArgumentAtIndex(0); 2040735152e3SEnrico Granata m_short_help.assign(m_options.m_short_help); 204144d93782SGreg Clayton m_synchronicity = m_options.m_synchronicity; 2042223383edSEnrico Granata 20439fe00e52SEnrico Granata if (m_options.m_class_name.empty()) 20449fe00e52SEnrico Granata { 2045223383edSEnrico Granata if (m_options.m_funct_name.empty()) 2046223383edSEnrico Granata { 204744d93782SGreg Clayton m_interpreter.GetPythonCommandsFromIOHandler(" ", // Prompt 204844d93782SGreg Clayton *this, // IOHandlerDelegate 204944d93782SGreg Clayton true, // Run IOHandler in async mode 20506e3d8e7fSEugene Zelenko nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 2051223383edSEnrico Granata } 2052223383edSEnrico Granata else 2053223383edSEnrico Granata { 20540a305db7SEnrico Granata CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 205544d93782SGreg Clayton m_cmd_name, 20560a305db7SEnrico Granata m_options.m_funct_name, 2057735152e3SEnrico Granata m_options.m_short_help, 205844d93782SGreg Clayton m_synchronicity)); 205944d93782SGreg Clayton if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 2060223383edSEnrico Granata { 2061223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 2062223383edSEnrico Granata } 2063223383edSEnrico Granata else 2064223383edSEnrico Granata { 2065223383edSEnrico Granata result.AppendError("cannot add command"); 2066223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2067223383edSEnrico Granata } 2068223383edSEnrico Granata } 20699fe00e52SEnrico Granata } 20709fe00e52SEnrico Granata else 20719fe00e52SEnrico Granata { 20729fe00e52SEnrico Granata ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter(); 20739fe00e52SEnrico Granata if (!interpreter) 20749fe00e52SEnrico Granata { 20759fe00e52SEnrico Granata result.AppendError("cannot find ScriptInterpreter"); 20769fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 20779fe00e52SEnrico Granata return false; 20789fe00e52SEnrico Granata } 20799fe00e52SEnrico Granata 20809fe00e52SEnrico Granata auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str()); 20819fe00e52SEnrico Granata if (!cmd_obj_sp) 20829fe00e52SEnrico Granata { 20839fe00e52SEnrico Granata result.AppendError("cannot create helper object"); 20849fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 20859fe00e52SEnrico Granata return false; 20869fe00e52SEnrico Granata } 20879fe00e52SEnrico Granata 20889fe00e52SEnrico Granata CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter, 20899fe00e52SEnrico Granata m_cmd_name, 20909fe00e52SEnrico Granata cmd_obj_sp, 20919fe00e52SEnrico Granata m_synchronicity)); 20929fe00e52SEnrico Granata if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 20939fe00e52SEnrico Granata { 20949fe00e52SEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 20959fe00e52SEnrico Granata } 20969fe00e52SEnrico Granata else 20979fe00e52SEnrico Granata { 20989fe00e52SEnrico Granata result.AppendError("cannot add command"); 20999fe00e52SEnrico Granata result.SetStatus (eReturnStatusFailed); 21009fe00e52SEnrico Granata } 21019fe00e52SEnrico Granata } 2102223383edSEnrico Granata 2103223383edSEnrico Granata return result.Succeeded(); 2104223383edSEnrico Granata } 21055a988416SJim Ingham 21065a988416SJim Ingham CommandOptions m_options; 210744d93782SGreg Clayton std::string m_cmd_name; 2108735152e3SEnrico Granata std::string m_short_help; 210944d93782SGreg Clayton ScriptedCommandSynchronicity m_synchronicity; 2110223383edSEnrico Granata }; 2111223383edSEnrico Granata 21120a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] = 21130a305db7SEnrico Granata { 21140a305db7SEnrico Granata { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 21150a305db7SEnrico Granata { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 21160a305db7SEnrico Granata { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 21176e3d8e7fSEugene Zelenko { 0, nullptr, nullptr } 21180a305db7SEnrico Granata }; 21190a305db7SEnrico Granata 2120223383edSEnrico Granata OptionDefinition 2121223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 2122223383edSEnrico Granata { 21236e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 21246e3d8e7fSEugene Zelenko { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."}, 21256e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command."}, 21266e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."}, 21276e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 2128223383edSEnrico Granata }; 2129223383edSEnrico Granata 2130223383edSEnrico Granata //------------------------------------------------------------------------- 2131223383edSEnrico Granata // CommandObjectCommandsScriptList 2132223383edSEnrico Granata //------------------------------------------------------------------------- 2133223383edSEnrico Granata 21345a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed 2135223383edSEnrico Granata { 2136223383edSEnrico Granata public: 2137223383edSEnrico Granata CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 21385a988416SJim Ingham CommandObjectParsed(interpreter, 2139223383edSEnrico Granata "command script list", 2140223383edSEnrico Granata "List defined scripted commands.", 21416e3d8e7fSEugene Zelenko nullptr) 2142223383edSEnrico Granata { 2143223383edSEnrico Granata } 2144223383edSEnrico Granata 21456e3d8e7fSEugene Zelenko ~CommandObjectCommandsScriptList() override = default; 2146223383edSEnrico Granata 2147223383edSEnrico Granata bool 214813d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 2149223383edSEnrico Granata { 2150223383edSEnrico Granata m_interpreter.GetHelp(result, 2151223383edSEnrico Granata CommandInterpreter::eCommandTypesUserDef); 2152223383edSEnrico Granata 2153223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2154223383edSEnrico Granata 2155223383edSEnrico Granata return true; 2156223383edSEnrico Granata } 2157223383edSEnrico Granata }; 2158223383edSEnrico Granata 2159223383edSEnrico Granata //------------------------------------------------------------------------- 2160223383edSEnrico Granata // CommandObjectCommandsScriptClear 2161223383edSEnrico Granata //------------------------------------------------------------------------- 2162223383edSEnrico Granata 21635a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed 2164223383edSEnrico Granata { 2165223383edSEnrico Granata public: 2166223383edSEnrico Granata CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 21675a988416SJim Ingham CommandObjectParsed(interpreter, 2168223383edSEnrico Granata "command script clear", 2169223383edSEnrico Granata "Delete all scripted commands.", 21706e3d8e7fSEugene Zelenko nullptr) 2171223383edSEnrico Granata { 2172223383edSEnrico Granata } 2173223383edSEnrico Granata 21746e3d8e7fSEugene Zelenko ~CommandObjectCommandsScriptClear() override = default; 2175223383edSEnrico Granata 21765a988416SJim Ingham protected: 2177223383edSEnrico Granata bool 217813d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 2179223383edSEnrico Granata { 2180223383edSEnrico Granata m_interpreter.RemoveAllUser(); 2181223383edSEnrico Granata 2182223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2183223383edSEnrico Granata 2184223383edSEnrico Granata return true; 2185223383edSEnrico Granata } 2186223383edSEnrico Granata }; 2187223383edSEnrico Granata 2188223383edSEnrico Granata //------------------------------------------------------------------------- 2189223383edSEnrico Granata // CommandObjectCommandsScriptDelete 2190223383edSEnrico Granata //------------------------------------------------------------------------- 2191223383edSEnrico Granata 21925a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed 2193223383edSEnrico Granata { 2194223383edSEnrico Granata public: 2195223383edSEnrico Granata CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 21965a988416SJim Ingham CommandObjectParsed(interpreter, 2197223383edSEnrico Granata "command script delete", 2198223383edSEnrico Granata "Delete a scripted command.", 21996e3d8e7fSEugene Zelenko nullptr) 2200223383edSEnrico Granata { 2201223383edSEnrico Granata CommandArgumentEntry arg1; 2202223383edSEnrico Granata CommandArgumentData cmd_arg; 2203223383edSEnrico Granata 2204223383edSEnrico Granata // Define the first (and only) variant of this arg. 2205223383edSEnrico Granata cmd_arg.arg_type = eArgTypeCommandName; 2206223383edSEnrico Granata cmd_arg.arg_repetition = eArgRepeatPlain; 2207223383edSEnrico Granata 2208223383edSEnrico Granata // There is only one variant this argument could be; put it into the argument entry. 2209223383edSEnrico Granata arg1.push_back (cmd_arg); 2210223383edSEnrico Granata 2211223383edSEnrico Granata // Push the data for the first argument into the m_arguments vector. 2212223383edSEnrico Granata m_arguments.push_back (arg1); 2213223383edSEnrico Granata } 2214223383edSEnrico Granata 22156e3d8e7fSEugene Zelenko ~CommandObjectCommandsScriptDelete() override = default; 2216223383edSEnrico Granata 22175a988416SJim Ingham protected: 2218223383edSEnrico Granata bool 221913d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 2220223383edSEnrico Granata { 2221223383edSEnrico Granata 22225a988416SJim Ingham size_t argc = command.GetArgumentCount(); 2223223383edSEnrico Granata 2224223383edSEnrico Granata if (argc != 1) 2225223383edSEnrico Granata { 2226223383edSEnrico Granata result.AppendError ("'command script delete' requires one argument"); 2227223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2228223383edSEnrico Granata return false; 2229223383edSEnrico Granata } 2230223383edSEnrico Granata 22315a988416SJim Ingham const char* cmd_name = command.GetArgumentAtIndex(0); 2232223383edSEnrico Granata 2233223383edSEnrico Granata if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 2234223383edSEnrico Granata { 2235223383edSEnrico Granata m_interpreter.RemoveUser(cmd_name); 2236223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2237223383edSEnrico Granata } 2238223383edSEnrico Granata else 2239223383edSEnrico Granata { 2240223383edSEnrico Granata result.AppendErrorWithFormat ("command %s not found", cmd_name); 2241223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2242223383edSEnrico Granata } 2243223383edSEnrico Granata 2244223383edSEnrico Granata return result.Succeeded(); 2245223383edSEnrico Granata } 2246223383edSEnrico Granata }; 2247223383edSEnrico Granata 2248223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript 2249223383edSEnrico Granata 2250223383edSEnrico Granata //------------------------------------------------------------------------- 2251223383edSEnrico Granata // CommandObjectMultiwordCommandsScript 2252223383edSEnrico Granata //------------------------------------------------------------------------- 2253223383edSEnrico Granata 2254223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 2255223383edSEnrico Granata { 2256223383edSEnrico Granata public: 2257223383edSEnrico Granata CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 2258223383edSEnrico Granata CommandObjectMultiword (interpreter, 2259223383edSEnrico Granata "command script", 2260223383edSEnrico Granata "A set of commands for managing or customizing script commands.", 2261223383edSEnrico Granata "command script <subcommand> [<subcommand-options>]") 2262223383edSEnrico Granata { 2263223383edSEnrico Granata LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 2264223383edSEnrico Granata LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 2265223383edSEnrico Granata LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 2266223383edSEnrico Granata LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 2267a9dbf432SEnrico Granata LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 2268223383edSEnrico Granata } 2269223383edSEnrico Granata 22706e3d8e7fSEugene Zelenko ~CommandObjectMultiwordCommandsScript() override = default; 2271223383edSEnrico Granata }; 2272223383edSEnrico Granata 2273ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands 2274ebc09c36SJim Ingham 2275ebc09c36SJim Ingham //------------------------------------------------------------------------- 2276ebc09c36SJim Ingham // CommandObjectMultiwordCommands 2277ebc09c36SJim Ingham //------------------------------------------------------------------------- 2278ebc09c36SJim Ingham 2279ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 2280a7015092SGreg Clayton CommandObjectMultiword (interpreter, 22810e5e5a79SGreg Clayton "command", 22823f4c09c1SCaroline Tice "A set of commands for managing or customizing the debugger commands.", 22830e5e5a79SGreg Clayton "command <subcommand> [<subcommand-options>]") 2284ebc09c36SJim Ingham { 2285a7015092SGreg Clayton LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 2286a7015092SGreg Clayton LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 2287a7015092SGreg Clayton LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 2288b547278cSGreg Clayton LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter))); 2289de164aaaSGreg Clayton LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 2290a5a97ebeSJim Ingham LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 2291223383edSEnrico Granata LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 2292ebc09c36SJim Ingham } 2293ebc09c36SJim Ingham 22946e3d8e7fSEugene Zelenko CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands() = default; 2295