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" 2745d0e238SEnrico 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 { 43445d0e238SEnrico Granata protected: 43545d0e238SEnrico Granata class CommandOptions : public OptionGroup 43645d0e238SEnrico Granata { 437ebc09c36SJim Ingham public: 43845d0e238SEnrico Granata CommandOptions () : 43945d0e238SEnrico Granata OptionGroup(), 44045d0e238SEnrico Granata m_help(), 44145d0e238SEnrico Granata m_long_help() 44245d0e238SEnrico Granata {} 44345d0e238SEnrico Granata 44445d0e238SEnrico Granata ~CommandOptions() override = default; 44545d0e238SEnrico Granata 44645d0e238SEnrico Granata uint32_t 44745d0e238SEnrico Granata GetNumDefinitions () override 44845d0e238SEnrico Granata { 44945d0e238SEnrico Granata return 3; 45045d0e238SEnrico Granata } 45145d0e238SEnrico Granata 45245d0e238SEnrico Granata const OptionDefinition* 45345d0e238SEnrico Granata GetDefinitions () override 45445d0e238SEnrico Granata { 45545d0e238SEnrico Granata return g_option_table; 45645d0e238SEnrico Granata } 45745d0e238SEnrico Granata 45845d0e238SEnrico Granata Error 45945d0e238SEnrico Granata SetOptionValue (CommandInterpreter &interpreter, 46045d0e238SEnrico Granata uint32_t option_idx, 46145d0e238SEnrico Granata const char *option_value) override 46245d0e238SEnrico Granata { 46345d0e238SEnrico Granata Error error; 46445d0e238SEnrico Granata 46545d0e238SEnrico Granata const int short_option = g_option_table[option_idx].short_option; 46645d0e238SEnrico Granata 46745d0e238SEnrico Granata switch (short_option) 46845d0e238SEnrico Granata { 46945d0e238SEnrico Granata case 'h': 47045d0e238SEnrico Granata m_help.SetCurrentValue(option_value); 47145d0e238SEnrico Granata m_help.SetOptionWasSet(); 47245d0e238SEnrico Granata break; 47345d0e238SEnrico Granata 47445d0e238SEnrico Granata case 'H': 47545d0e238SEnrico Granata m_long_help.SetCurrentValue(option_value); 47645d0e238SEnrico Granata m_long_help.SetOptionWasSet(); 47745d0e238SEnrico Granata break; 47845d0e238SEnrico Granata 47945d0e238SEnrico Granata default: 48045d0e238SEnrico Granata error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 48145d0e238SEnrico Granata break; 48245d0e238SEnrico Granata } 48345d0e238SEnrico Granata 48445d0e238SEnrico Granata return error; 48545d0e238SEnrico Granata } 48645d0e238SEnrico Granata 48745d0e238SEnrico Granata void 48845d0e238SEnrico Granata OptionParsingStarting (CommandInterpreter &interpreter) override 48945d0e238SEnrico Granata { 49045d0e238SEnrico Granata m_help.Clear(); 49145d0e238SEnrico Granata m_long_help.Clear(); 49245d0e238SEnrico Granata } 49345d0e238SEnrico Granata 49445d0e238SEnrico Granata // Options table: Required for subclasses of Options. 49545d0e238SEnrico Granata 49645d0e238SEnrico Granata static OptionDefinition g_option_table[]; 49745d0e238SEnrico Granata OptionValueString m_help; 49845d0e238SEnrico Granata OptionValueString m_long_help; 49945d0e238SEnrico Granata }; 50045d0e238SEnrico Granata 50145d0e238SEnrico Granata OptionGroupOptions m_option_group; 50245d0e238SEnrico Granata CommandOptions m_command_options; 50345d0e238SEnrico Granata 50445d0e238SEnrico Granata public: 50545d0e238SEnrico Granata Options * 50645d0e238SEnrico Granata GetOptions () override 50745d0e238SEnrico Granata { 50845d0e238SEnrico Granata return &m_option_group; 50945d0e238SEnrico Granata } 51045d0e238SEnrico 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.", 51545d0e238SEnrico Granata nullptr), 51645d0e238SEnrico Granata m_option_group(interpreter), 51745d0e238SEnrico Granata m_command_options() 518ebc09c36SJim Ingham { 51945d0e238SEnrico Granata m_option_group.Append(&m_command_options); 52045d0e238SEnrico Granata m_option_group.Finalize(); 52145d0e238SEnrico 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 { 63245d0e238SEnrico Granata if (!raw_command_line || !raw_command_line[0]) 63345d0e238SEnrico Granata { 634*d72e412fSEnrico Granata result.AppendError ("'command alias' requires at least two arguments"); 63545d0e238SEnrico Granata return false; 63645d0e238SEnrico Granata } 63745d0e238SEnrico Granata 63845d0e238SEnrico Granata m_option_group.NotifyOptionParsingStarting(); 63945d0e238SEnrico Granata 64045d0e238SEnrico Granata const char * remainder = nullptr; 64145d0e238SEnrico Granata 64245d0e238SEnrico Granata if (raw_command_line[0] == '-') 64345d0e238SEnrico Granata { 64445d0e238SEnrico Granata // We have some options and these options MUST end with --. 64545d0e238SEnrico Granata const char *end_options = nullptr; 64645d0e238SEnrico Granata const char *s = raw_command_line; 64745d0e238SEnrico Granata while (s && s[0]) 64845d0e238SEnrico Granata { 64945d0e238SEnrico Granata end_options = ::strstr (s, "--"); 65045d0e238SEnrico Granata if (end_options) 65145d0e238SEnrico Granata { 65245d0e238SEnrico Granata end_options += 2; // Get past the "--" 65345d0e238SEnrico Granata if (::isspace (end_options[0])) 65445d0e238SEnrico Granata { 65545d0e238SEnrico Granata remainder = end_options; 65645d0e238SEnrico Granata while (::isspace (*remainder)) 65745d0e238SEnrico Granata ++remainder; 65845d0e238SEnrico Granata break; 65945d0e238SEnrico Granata } 66045d0e238SEnrico Granata } 66145d0e238SEnrico Granata s = end_options; 66245d0e238SEnrico Granata } 66345d0e238SEnrico Granata 66445d0e238SEnrico Granata if (end_options) 66545d0e238SEnrico Granata { 66645d0e238SEnrico Granata Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line)); 66745d0e238SEnrico Granata if (!ParseOptions (args, result)) 66845d0e238SEnrico Granata return false; 66945d0e238SEnrico Granata 67045d0e238SEnrico Granata Error error (m_option_group.NotifyOptionParsingFinished()); 67145d0e238SEnrico Granata if (error.Fail()) 67245d0e238SEnrico Granata { 67345d0e238SEnrico Granata result.AppendError (error.AsCString()); 67445d0e238SEnrico Granata result.SetStatus (eReturnStatusFailed); 67545d0e238SEnrico Granata return false; 67645d0e238SEnrico Granata } 67745d0e238SEnrico Granata } 67845d0e238SEnrico Granata } 67945d0e238SEnrico Granata if (nullptr == remainder) 68045d0e238SEnrico Granata remainder = raw_command_line; 68145d0e238SEnrico Granata 68245d0e238SEnrico Granata std::string raw_command_string (remainder); 68345d0e238SEnrico 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 { 689*d72e412fSEnrico Granata result.AppendError ("'command 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); 697*d72e412fSEnrico Granata if (alias_command.size() > 1 && 698*d72e412fSEnrico Granata alias_command[0] == '-') 699*d72e412fSEnrico Granata { 700*d72e412fSEnrico Granata result.AppendError("aliases starting with a dash are not supported"); 701*d72e412fSEnrico Granata if (alias_command == "--help" || alias_command == "--long-help") 702*d72e412fSEnrico Granata { 703*d72e412fSEnrico Granata result.AppendWarning("if trying to pass options to 'command alias' add a -- at the end of the options"); 704*d72e412fSEnrico Granata } 705*d72e412fSEnrico Granata result.SetStatus (eReturnStatusFailed); 706*d72e412fSEnrico Granata return false; 707*d72e412fSEnrico Granata } 708844d2303SCaroline Tice 709844d2303SCaroline Tice // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which 710844d2303SCaroline Tice // does the stripping itself. 711844d2303SCaroline Tice size_t pos = raw_command_string.find (alias_command); 712844d2303SCaroline Tice if (pos == 0) 713844d2303SCaroline Tice { 714844d2303SCaroline Tice raw_command_string = raw_command_string.substr (alias_command.size()); 715844d2303SCaroline Tice pos = raw_command_string.find_first_not_of (' '); 716844d2303SCaroline Tice if ((pos != std::string::npos) && (pos > 0)) 717844d2303SCaroline Tice raw_command_string = raw_command_string.substr (pos); 718844d2303SCaroline Tice } 719844d2303SCaroline Tice else 720844d2303SCaroline Tice { 721844d2303SCaroline Tice result.AppendError ("Error parsing command string. No alias created."); 722844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 723844d2303SCaroline Tice return false; 724844d2303SCaroline Tice } 725844d2303SCaroline Tice 726844d2303SCaroline Tice 727844d2303SCaroline Tice // Verify that the command is alias-able. 728844d2303SCaroline Tice if (m_interpreter.CommandExists (alias_command.c_str())) 729844d2303SCaroline Tice { 730844d2303SCaroline Tice result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 731844d2303SCaroline Tice alias_command.c_str()); 732844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 733844d2303SCaroline Tice return false; 734844d2303SCaroline Tice } 735844d2303SCaroline Tice 736844d2303SCaroline Tice // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string. 737844d2303SCaroline Tice // raw_command_string is returned with the name of the command object stripped off the front. 738*d72e412fSEnrico Granata std::string original_raw_command_string(raw_command_string); 739844d2303SCaroline Tice CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string); 740844d2303SCaroline Tice 741844d2303SCaroline Tice if (!cmd_obj) 742844d2303SCaroline Tice { 743*d72e412fSEnrico Granata result.AppendErrorWithFormat ("invalid command given to 'command alias'. '%s' does not begin with a valid command." 744*d72e412fSEnrico Granata " No alias created.", original_raw_command_string.c_str()); 745844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 746844d2303SCaroline Tice return false; 747844d2303SCaroline Tice } 748844d2303SCaroline Tice else if (!cmd_obj->WantsRawCommandString ()) 749844d2303SCaroline Tice { 750844d2303SCaroline Tice // Note that args was initialized with the original command, and has not been updated to this point. 751844d2303SCaroline Tice // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias. 7525a988416SJim Ingham return HandleAliasingNormalCommand (args, result); 753844d2303SCaroline Tice } 754844d2303SCaroline Tice else 755844d2303SCaroline Tice { 7565a988416SJim Ingham return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result); 7575a988416SJim Ingham } 7585a988416SJim Ingham return result.Succeeded(); 7595a988416SJim Ingham } 7605a988416SJim Ingham 7615a988416SJim Ingham bool 7625a988416SJim Ingham HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result) 7635a988416SJim Ingham { 764844d2303SCaroline Tice // Verify & handle any options/arguments passed to the alias command 765844d2303SCaroline Tice 766844d2303SCaroline Tice OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 767844d2303SCaroline Tice 768212130acSEnrico Granata if (CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false)) 769844d2303SCaroline Tice { 770844d2303SCaroline Tice if (m_interpreter.AliasExists (alias_command.c_str()) 771844d2303SCaroline Tice || m_interpreter.UserCommandExists (alias_command.c_str())) 772844d2303SCaroline Tice { 773844d2303SCaroline Tice result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 774844d2303SCaroline Tice alias_command.c_str()); 775844d2303SCaroline Tice } 77645d0e238SEnrico Granata if (CommandAlias *alias = m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp, raw_command_string.c_str())) 777472362e6SCaroline Tice { 77845d0e238SEnrico Granata if (m_command_options.m_help.OptionWasSet()) 77945d0e238SEnrico Granata alias->SetHelp(m_command_options.m_help.GetCurrentValue()); 78045d0e238SEnrico Granata if (m_command_options.m_long_help.OptionWasSet()) 78145d0e238SEnrico Granata alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue()); 782844d2303SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 783844d2303SCaroline Tice } 784472362e6SCaroline Tice else 785472362e6SCaroline Tice { 786472362e6SCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 787472362e6SCaroline Tice result.SetStatus (eReturnStatusFailed); 788472362e6SCaroline Tice } 789212130acSEnrico Granata 790212130acSEnrico Granata } 791212130acSEnrico Granata else 792212130acSEnrico Granata { 793212130acSEnrico Granata result.AppendError ("Unable to create requested alias.\n"); 794212130acSEnrico Granata result.SetStatus (eReturnStatusFailed); 795212130acSEnrico Granata } 796212130acSEnrico Granata 797844d2303SCaroline Tice return result.Succeeded (); 798844d2303SCaroline Tice } 799ebc09c36SJim Ingham 800ebc09c36SJim Ingham bool 8015a988416SJim Ingham HandleAliasingNormalCommand (Args& args, CommandReturnObject &result) 802ebc09c36SJim Ingham { 803867b185dSCaroline Tice size_t argc = args.GetArgumentCount(); 804ebc09c36SJim Ingham 805ebc09c36SJim Ingham if (argc < 2) 806ebc09c36SJim Ingham { 807*d72e412fSEnrico Granata result.AppendError ("'command alias' requires at least two arguments"); 808ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 809ebc09c36SJim Ingham return false; 810ebc09c36SJim Ingham } 811ebc09c36SJim Ingham 812ebc09c36SJim Ingham const std::string alias_command = args.GetArgumentAtIndex(0); 813ebc09c36SJim Ingham const std::string actual_command = args.GetArgumentAtIndex(1); 814ebc09c36SJim Ingham 815ebc09c36SJim Ingham args.Shift(); // Shift the alias command word off the argument vector. 816ebc09c36SJim Ingham args.Shift(); // Shift the old command word off the argument vector. 817ebc09c36SJim Ingham 818ebc09c36SJim Ingham // Verify that the command is alias'able, and get the appropriate command object. 819ebc09c36SJim Ingham 820a7015092SGreg Clayton if (m_interpreter.CommandExists (alias_command.c_str())) 821ebc09c36SJim Ingham { 822ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 823ebc09c36SJim Ingham alias_command.c_str()); 824ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 825ebc09c36SJim Ingham } 826ebc09c36SJim Ingham else 827ebc09c36SJim Ingham { 828a7015092SGreg Clayton CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true)); 829ebc09c36SJim Ingham CommandObjectSP subcommand_obj_sp; 830ebc09c36SJim Ingham bool use_subcommand = false; 8316e3d8e7fSEugene Zelenko if (command_obj_sp) 832ebc09c36SJim Ingham { 833ebc09c36SJim Ingham CommandObject *cmd_obj = command_obj_sp.get(); 8346e3d8e7fSEugene Zelenko CommandObject *sub_cmd_obj = nullptr; 835ebc09c36SJim Ingham OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 836ebc09c36SJim Ingham 837844d2303SCaroline Tice while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0) 838ebc09c36SJim Ingham { 839ebc09c36SJim Ingham if (argc >= 3) 840ebc09c36SJim Ingham { 841ebc09c36SJim Ingham const std::string sub_command = args.GetArgumentAtIndex(0); 842ebc09c36SJim Ingham assert (sub_command.length() != 0); 843998255bfSGreg Clayton subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str()); 8446e3d8e7fSEugene Zelenko if (subcommand_obj_sp) 845ebc09c36SJim Ingham { 846ebc09c36SJim Ingham sub_cmd_obj = subcommand_obj_sp.get(); 847ebc09c36SJim Ingham use_subcommand = true; 848ebc09c36SJim Ingham args.Shift(); // Shift the sub_command word off the argument vector. 849844d2303SCaroline Tice cmd_obj = sub_cmd_obj; 850ebc09c36SJim Ingham } 851ebc09c36SJim Ingham else 852ebc09c36SJim Ingham { 853f415eeb4SCaroline Tice result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. " 854f415eeb4SCaroline Tice "Unable to create alias.\n", 855f415eeb4SCaroline Tice sub_command.c_str(), actual_command.c_str()); 856ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 857ebc09c36SJim Ingham return false; 858ebc09c36SJim Ingham } 859ebc09c36SJim Ingham } 860ebc09c36SJim Ingham } 861ebc09c36SJim Ingham 862ebc09c36SJim Ingham // Verify & handle any options/arguments passed to the alias command 863ebc09c36SJim Ingham 864212130acSEnrico Granata std::string args_string; 865212130acSEnrico Granata 866ebc09c36SJim Ingham if (args.GetArgumentCount () > 0) 867ebc09c36SJim Ingham { 868ca90c47eSCaroline Tice CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); 869ebc09c36SJim Ingham if (use_subcommand) 870ca90c47eSCaroline Tice tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false); 871ca90c47eSCaroline Tice 872ca90c47eSCaroline Tice args.GetCommandString (args_string); 873867b185dSCaroline Tice } 874ebc09c36SJim Ingham 875a7015092SGreg Clayton if (m_interpreter.AliasExists (alias_command.c_str()) 876a7015092SGreg Clayton || m_interpreter.UserCommandExists (alias_command.c_str())) 877ebc09c36SJim Ingham { 878ebc09c36SJim Ingham result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 879ebc09c36SJim Ingham alias_command.c_str()); 880ebc09c36SJim Ingham } 881ebc09c36SJim Ingham 88245d0e238SEnrico Granata if (CommandAlias *alias = m_interpreter.AddAlias(alias_command.c_str(), 883212130acSEnrico Granata use_subcommand ? subcommand_obj_sp : command_obj_sp, 884212130acSEnrico Granata args_string.c_str())) 885212130acSEnrico Granata { 88645d0e238SEnrico Granata if (m_command_options.m_help.OptionWasSet()) 88745d0e238SEnrico Granata alias->SetHelp(m_command_options.m_help.GetCurrentValue()); 88845d0e238SEnrico Granata if (m_command_options.m_long_help.OptionWasSet()) 88945d0e238SEnrico Granata alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue()); 890ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 891ebc09c36SJim Ingham } 892ebc09c36SJim Ingham else 893ebc09c36SJim Ingham { 894212130acSEnrico Granata result.AppendError ("Unable to create requested alias.\n"); 895212130acSEnrico Granata result.SetStatus (eReturnStatusFailed); 896212130acSEnrico Granata return false; 897212130acSEnrico Granata } 898212130acSEnrico Granata } 899212130acSEnrico Granata else 900212130acSEnrico Granata { 901ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str()); 902ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 903e7941795SCaroline Tice return false; 904ebc09c36SJim Ingham } 905ebc09c36SJim Ingham } 906ebc09c36SJim Ingham 907ebc09c36SJim Ingham return result.Succeeded(); 908ebc09c36SJim Ingham } 909ebc09c36SJim Ingham }; 910ebc09c36SJim Ingham 91145d0e238SEnrico Granata OptionDefinition 91245d0e238SEnrico Granata CommandObjectCommandsAlias::CommandOptions::g_option_table[] = 91345d0e238SEnrico Granata { 91445d0e238SEnrico Granata { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Help text for this command"}, 91545d0e238SEnrico Granata { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Long help text for this command"}, 91645d0e238SEnrico Granata { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 91745d0e238SEnrico Granata }; 91845d0e238SEnrico Granata 919ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias 920ebc09c36SJim Ingham //------------------------------------------------------------------------- 921ebc09c36SJim Ingham // CommandObjectCommandsUnalias 922ebc09c36SJim Ingham //------------------------------------------------------------------------- 923ebc09c36SJim Ingham 9245a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed 925ebc09c36SJim Ingham { 926ebc09c36SJim Ingham public: 927a7015092SGreg Clayton CommandObjectCommandsUnalias (CommandInterpreter &interpreter) : 9285a988416SJim Ingham CommandObjectParsed(interpreter, 9290e5e5a79SGreg Clayton "command unalias", 93086ddae50SCaroline Tice "Allow the user to remove/delete a user-defined command abbreviation.", 9316e3d8e7fSEugene Zelenko nullptr) 932ebc09c36SJim Ingham { 933405fe67fSCaroline Tice CommandArgumentEntry arg; 934405fe67fSCaroline Tice CommandArgumentData alias_arg; 935405fe67fSCaroline Tice 936405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 937405fe67fSCaroline Tice alias_arg.arg_type = eArgTypeAliasName; 938405fe67fSCaroline Tice alias_arg.arg_repetition = eArgRepeatPlain; 939405fe67fSCaroline Tice 940405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 941405fe67fSCaroline Tice arg.push_back (alias_arg); 942405fe67fSCaroline Tice 943405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 944405fe67fSCaroline Tice m_arguments.push_back (arg); 945ebc09c36SJim Ingham } 946ebc09c36SJim Ingham 9476e3d8e7fSEugene Zelenko ~CommandObjectCommandsUnalias() override = default; 948ebc09c36SJim Ingham 9495a988416SJim Ingham protected: 950ebc09c36SJim Ingham bool 95113d21e9aSBruce Mitchener DoExecute (Args& args, CommandReturnObject &result) override 952ebc09c36SJim Ingham { 953ebc09c36SJim Ingham CommandObject::CommandMap::iterator pos; 954ebc09c36SJim Ingham CommandObject *cmd_obj; 955ebc09c36SJim Ingham 956ebc09c36SJim Ingham if (args.GetArgumentCount() != 0) 957ebc09c36SJim Ingham { 958ebc09c36SJim Ingham const char *command_name = args.GetArgumentAtIndex(0); 959a7015092SGreg Clayton cmd_obj = m_interpreter.GetCommandObject(command_name); 960ebc09c36SJim Ingham if (cmd_obj) 961ebc09c36SJim Ingham { 962a7015092SGreg Clayton if (m_interpreter.CommandExists (command_name)) 963ebc09c36SJim Ingham { 964b547278cSGreg Clayton if (cmd_obj->IsRemovable()) 965b547278cSGreg Clayton { 966b547278cSGreg Clayton result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n", 967b547278cSGreg Clayton command_name); 968b547278cSGreg Clayton } 969b547278cSGreg Clayton else 970b547278cSGreg Clayton { 971ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 972ebc09c36SJim Ingham command_name); 973b547278cSGreg Clayton } 974ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 975ebc09c36SJim Ingham } 976ebc09c36SJim Ingham else 977ebc09c36SJim Ingham { 9786e3d8e7fSEugene Zelenko if (!m_interpreter.RemoveAlias(command_name)) 979ebc09c36SJim Ingham { 980a7015092SGreg Clayton if (m_interpreter.AliasExists (command_name)) 981ebc09c36SJim Ingham result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n", 982ebc09c36SJim Ingham command_name); 983ebc09c36SJim Ingham else 984ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name); 985ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 986ebc09c36SJim Ingham } 987ebc09c36SJim Ingham else 988ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 989ebc09c36SJim Ingham } 990ebc09c36SJim Ingham } 991ebc09c36SJim Ingham else 992ebc09c36SJim Ingham { 993ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a " 994ebc09c36SJim Ingham "current list of commands.\n", 995ebc09c36SJim Ingham command_name); 996ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 997ebc09c36SJim Ingham } 998ebc09c36SJim Ingham } 999ebc09c36SJim Ingham else 1000ebc09c36SJim Ingham { 1001ebc09c36SJim Ingham result.AppendError ("must call 'unalias' with a valid alias"); 1002ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 1003ebc09c36SJim Ingham } 1004ebc09c36SJim Ingham 1005ebc09c36SJim Ingham return result.Succeeded(); 1006ebc09c36SJim Ingham } 1007ebc09c36SJim Ingham }; 1008ebc09c36SJim Ingham 1009b547278cSGreg Clayton #pragma mark CommandObjectCommandsDelete 1010b547278cSGreg Clayton //------------------------------------------------------------------------- 1011b547278cSGreg Clayton // CommandObjectCommandsDelete 1012b547278cSGreg Clayton //------------------------------------------------------------------------- 1013b547278cSGreg Clayton 1014b547278cSGreg Clayton class CommandObjectCommandsDelete : public CommandObjectParsed 1015b547278cSGreg Clayton { 1016b547278cSGreg Clayton public: 1017b547278cSGreg Clayton CommandObjectCommandsDelete (CommandInterpreter &interpreter) : 1018b547278cSGreg Clayton CommandObjectParsed(interpreter, 1019b547278cSGreg Clayton "command delete", 1020b547278cSGreg Clayton "Allow the user to delete user-defined regular expression, python or multi-word commands.", 10216e3d8e7fSEugene Zelenko nullptr) 1022b547278cSGreg Clayton { 1023b547278cSGreg Clayton CommandArgumentEntry arg; 1024b547278cSGreg Clayton CommandArgumentData alias_arg; 1025b547278cSGreg Clayton 1026b547278cSGreg Clayton // Define the first (and only) variant of this arg. 1027b547278cSGreg Clayton alias_arg.arg_type = eArgTypeCommandName; 1028b547278cSGreg Clayton alias_arg.arg_repetition = eArgRepeatPlain; 1029b547278cSGreg Clayton 1030b547278cSGreg Clayton // There is only one variant this argument could be; put it into the argument entry. 1031b547278cSGreg Clayton arg.push_back (alias_arg); 1032b547278cSGreg Clayton 1033b547278cSGreg Clayton // Push the data for the first argument into the m_arguments vector. 1034b547278cSGreg Clayton m_arguments.push_back (arg); 1035b547278cSGreg Clayton } 1036b547278cSGreg Clayton 10376e3d8e7fSEugene Zelenko ~CommandObjectCommandsDelete() override = default; 1038b547278cSGreg Clayton 1039b547278cSGreg Clayton protected: 1040b547278cSGreg Clayton bool 104113d21e9aSBruce Mitchener DoExecute (Args& args, CommandReturnObject &result) override 1042b547278cSGreg Clayton { 1043b547278cSGreg Clayton CommandObject::CommandMap::iterator pos; 1044b547278cSGreg Clayton 1045b547278cSGreg Clayton if (args.GetArgumentCount() != 0) 1046b547278cSGreg Clayton { 1047b547278cSGreg Clayton const char *command_name = args.GetArgumentAtIndex(0); 1048b547278cSGreg Clayton if (m_interpreter.CommandExists (command_name)) 1049b547278cSGreg Clayton { 1050b547278cSGreg Clayton if (m_interpreter.RemoveCommand (command_name)) 1051b547278cSGreg Clayton { 1052b547278cSGreg Clayton result.SetStatus (eReturnStatusSuccessFinishNoResult); 1053b547278cSGreg Clayton } 1054b547278cSGreg Clayton else 1055b547278cSGreg Clayton { 1056b547278cSGreg Clayton result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 1057b547278cSGreg Clayton command_name); 1058b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 1059b547278cSGreg Clayton } 1060b547278cSGreg Clayton } 1061b547278cSGreg Clayton else 1062b547278cSGreg Clayton { 106346d4aa21SEnrico Granata StreamString error_msg_stream; 106446d4aa21SEnrico Granata const bool generate_apropos = true; 106546d4aa21SEnrico Granata const bool generate_type_lookup = false; 106646d4aa21SEnrico Granata CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream, 106746d4aa21SEnrico Granata command_name, 106846d4aa21SEnrico Granata nullptr, 106946d4aa21SEnrico Granata nullptr, 107046d4aa21SEnrico Granata generate_apropos, 107146d4aa21SEnrico Granata generate_type_lookup); 107246d4aa21SEnrico Granata result.AppendErrorWithFormat ("%s", error_msg_stream.GetData()); 1073b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 1074b547278cSGreg Clayton } 1075b547278cSGreg Clayton } 1076b547278cSGreg Clayton else 1077b547278cSGreg Clayton { 1078b547278cSGreg Clayton result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ()); 1079b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 1080b547278cSGreg Clayton } 1081b547278cSGreg Clayton 1082b547278cSGreg Clayton return result.Succeeded(); 1083b547278cSGreg Clayton } 1084b547278cSGreg Clayton }; 1085b547278cSGreg Clayton 1086de164aaaSGreg Clayton //------------------------------------------------------------------------- 1087de164aaaSGreg Clayton // CommandObjectCommandsAddRegex 1088de164aaaSGreg Clayton //------------------------------------------------------------------------- 10895a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex 1090de164aaaSGreg Clayton 109144d93782SGreg Clayton class CommandObjectCommandsAddRegex : 109244d93782SGreg Clayton public CommandObjectParsed, 1093ea508635SGreg Clayton public IOHandlerDelegateMultiline 1094de164aaaSGreg Clayton { 1095de164aaaSGreg Clayton public: 1096de164aaaSGreg Clayton CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) : 10975a988416SJim Ingham CommandObjectParsed (interpreter, 10980e5e5a79SGreg Clayton "command regex", 1099de164aaaSGreg Clayton "Allow the user to create a regular expression command.", 11000e5e5a79SGreg Clayton "command regex <cmd-name> [s/<regex>/<subst>/ ...]"), 1101ea508635SGreg Clayton IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand), 1102de164aaaSGreg Clayton m_options (interpreter) 1103de164aaaSGreg Clayton { 1104ea671fbdSKate Stone SetHelpLong(R"( 1105ea671fbdSKate Stone )" "This command allows the user to create powerful regular expression commands \ 1106ea671fbdSKate Stone with substitutions. The regular expressions and substitutions are specified \ 1107ea671fbdSKate Stone using the regular expression substitution format of:" R"( 1108ea671fbdSKate Stone 1109ea671fbdSKate Stone s/<regex>/<subst>/ 1110ea671fbdSKate Stone 1111ea671fbdSKate Stone )" "<regex> is a regular expression that can use parenthesis to capture regular \ 1112ea671fbdSKate Stone expression input and substitute the captured matches in the output using %1 \ 1113ea671fbdSKate Stone for the first match, %2 for the second, and so on." R"( 1114ea671fbdSKate Stone 1115ea671fbdSKate Stone )" "The regular expressions can all be specified on the command line if more than \ 1116ea671fbdSKate Stone one argument is provided. If just the command name is provided on the command \ 1117ea671fbdSKate Stone line, then the regular expressions and substitutions can be entered on separate \ 1118ea671fbdSKate Stone lines, followed by an empty line to terminate the command definition." R"( 1119ea671fbdSKate Stone 1120ea671fbdSKate Stone EXAMPLES 1121ea671fbdSKate Stone 1122ea671fbdSKate Stone )" "The following example will define a regular expression command named 'f' that \ 1123ea671fbdSKate Stone will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \ 1124ea671fbdSKate Stone a number follows 'f':" R"( 1125ea671fbdSKate Stone 1126ea671fbdSKate Stone (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')" 11270e5e5a79SGreg Clayton ); 1128de164aaaSGreg Clayton } 1129de164aaaSGreg Clayton 11306e3d8e7fSEugene Zelenko ~CommandObjectCommandsAddRegex() override = default; 1131de164aaaSGreg Clayton 11325a988416SJim Ingham protected: 1133ea508635SGreg Clayton void 1134ea508635SGreg Clayton IOHandlerActivated (IOHandler &io_handler) override 113544d93782SGreg Clayton { 113644d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 113744d93782SGreg Clayton if (output_sp) 113844d93782SGreg Clayton { 113944d93782SGreg 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"); 114044d93782SGreg Clayton output_sp->Flush(); 114144d93782SGreg Clayton } 114244d93782SGreg Clayton } 114344d93782SGreg Clayton 1144ea508635SGreg Clayton void 1145ea508635SGreg Clayton IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override 114644d93782SGreg Clayton { 114744d93782SGreg Clayton io_handler.SetIsDone(true); 11486e3d8e7fSEugene Zelenko if (m_regex_cmd_ap) 114944d93782SGreg Clayton { 115044d93782SGreg Clayton StringList lines; 115144d93782SGreg Clayton if (lines.SplitIntoLines (data)) 115244d93782SGreg Clayton { 115344d93782SGreg Clayton const size_t num_lines = lines.GetSize(); 115444d93782SGreg Clayton bool check_only = false; 115544d93782SGreg Clayton for (size_t i=0; i<num_lines; ++i) 115644d93782SGreg Clayton { 115744d93782SGreg Clayton llvm::StringRef bytes_strref (lines[i]); 115844d93782SGreg Clayton Error error = AppendRegexSubstitution (bytes_strref, check_only); 115944d93782SGreg Clayton if (error.Fail()) 116044d93782SGreg Clayton { 116144d93782SGreg Clayton if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) 116244d93782SGreg Clayton { 116344d93782SGreg Clayton StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream(); 116444d93782SGreg Clayton out_stream->Printf("error: %s\n", error.AsCString()); 116544d93782SGreg Clayton } 116644d93782SGreg Clayton } 116744d93782SGreg Clayton } 116844d93782SGreg Clayton } 116944d93782SGreg Clayton if (m_regex_cmd_ap->HasRegexEntries()) 117044d93782SGreg Clayton { 117144d93782SGreg Clayton CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 117244d93782SGreg Clayton m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 117344d93782SGreg Clayton } 117444d93782SGreg Clayton } 117544d93782SGreg Clayton } 117644d93782SGreg Clayton 1177de164aaaSGreg Clayton bool 1178b0a1814fSEric Christopher DoExecute (Args& command, CommandReturnObject &result) override 1179de164aaaSGreg Clayton { 11805a988416SJim Ingham const size_t argc = command.GetArgumentCount(); 11810e5e5a79SGreg Clayton if (argc == 0) 1182de164aaaSGreg Clayton { 118369c12ccbSJason Molenda result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n"); 11840e5e5a79SGreg Clayton result.SetStatus (eReturnStatusFailed); 11850e5e5a79SGreg Clayton } 11860e5e5a79SGreg Clayton else 11870e5e5a79SGreg Clayton { 11880e5e5a79SGreg Clayton Error error; 11895a988416SJim Ingham const char *name = command.GetArgumentAtIndex(0); 1190de164aaaSGreg Clayton m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter, 1191de164aaaSGreg Clayton name, 1192de164aaaSGreg Clayton m_options.GetHelp (), 1193de164aaaSGreg Clayton m_options.GetSyntax (), 1194b547278cSGreg Clayton 10, 1195b547278cSGreg Clayton 0, 1196b547278cSGreg Clayton true)); 11970e5e5a79SGreg Clayton 11980e5e5a79SGreg Clayton if (argc == 1) 11990e5e5a79SGreg Clayton { 120044d93782SGreg Clayton Debugger &debugger = m_interpreter.GetDebugger(); 1201e30f11d9SKate Stone bool color_prompt = debugger.GetUseColor(); 120244d93782SGreg Clayton const bool multiple_lines = true; // Get multiple lines 120344d93782SGreg Clayton IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger, 1204e30f11d9SKate Stone IOHandler::Type::Other, 120573d80faaSGreg Clayton "lldb-regex", // Name of input reader for history 1206ea508635SGreg Clayton "> ", // Prompt 12076e3d8e7fSEugene Zelenko nullptr, // Continuation prompt 120844d93782SGreg Clayton multiple_lines, 1209e30f11d9SKate Stone color_prompt, 1210f6913cd7SGreg Clayton 0, // Don't show line numbers 121144d93782SGreg Clayton *this)); 121244d93782SGreg Clayton 121344d93782SGreg Clayton if (io_handler_sp) 1214de164aaaSGreg Clayton { 121544d93782SGreg Clayton debugger.PushIOHandler(io_handler_sp); 1216de164aaaSGreg Clayton result.SetStatus (eReturnStatusSuccessFinishNoResult); 1217de164aaaSGreg Clayton } 1218de164aaaSGreg Clayton } 1219de164aaaSGreg Clayton else 1220de164aaaSGreg Clayton { 12210e5e5a79SGreg Clayton for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) 12220e5e5a79SGreg Clayton { 12235a988416SJim Ingham llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx)); 122444d93782SGreg Clayton bool check_only = false; 122544d93782SGreg Clayton error = AppendRegexSubstitution (arg_strref, check_only); 12260e5e5a79SGreg Clayton if (error.Fail()) 12270e5e5a79SGreg Clayton break; 12280e5e5a79SGreg Clayton } 12290e5e5a79SGreg Clayton 12300e5e5a79SGreg Clayton if (error.Success()) 12310e5e5a79SGreg Clayton { 12320e5e5a79SGreg Clayton AddRegexCommandToInterpreter(); 12330e5e5a79SGreg Clayton } 12340e5e5a79SGreg Clayton } 12350e5e5a79SGreg Clayton if (error.Fail()) 12360e5e5a79SGreg Clayton { 12370e5e5a79SGreg Clayton result.AppendError (error.AsCString()); 1238de164aaaSGreg Clayton result.SetStatus (eReturnStatusFailed); 1239de164aaaSGreg Clayton } 12400e5e5a79SGreg Clayton } 12410e5e5a79SGreg Clayton 1242de164aaaSGreg Clayton return result.Succeeded(); 1243de164aaaSGreg Clayton } 1244de164aaaSGreg Clayton 12450e5e5a79SGreg Clayton Error 124644d93782SGreg Clayton AppendRegexSubstitution (const llvm::StringRef ®ex_sed, bool check_only) 1247de164aaaSGreg Clayton { 12480e5e5a79SGreg Clayton Error error; 12490e5e5a79SGreg Clayton 12506e3d8e7fSEugene Zelenko if (!m_regex_cmd_ap) 1251de164aaaSGreg Clayton { 12520e5e5a79SGreg Clayton error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'", 12530e5e5a79SGreg Clayton (int)regex_sed.size(), 12540e5e5a79SGreg Clayton regex_sed.data()); 12550e5e5a79SGreg Clayton return error; 1256de164aaaSGreg Clayton } 12570e5e5a79SGreg Clayton 12580e5e5a79SGreg Clayton size_t regex_sed_size = regex_sed.size(); 12590e5e5a79SGreg Clayton 12600e5e5a79SGreg Clayton if (regex_sed_size <= 1) 12610e5e5a79SGreg Clayton { 12620e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'", 12630e5e5a79SGreg Clayton (int)regex_sed.size(), 12640e5e5a79SGreg Clayton regex_sed.data()); 12650e5e5a79SGreg Clayton return error; 12660e5e5a79SGreg Clayton } 12670e5e5a79SGreg Clayton 12680e5e5a79SGreg Clayton if (regex_sed[0] != 's') 12690e5e5a79SGreg Clayton { 12700e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'", 12710e5e5a79SGreg Clayton (int)regex_sed.size(), 12720e5e5a79SGreg Clayton regex_sed.data()); 12730e5e5a79SGreg Clayton return error; 12740e5e5a79SGreg Clayton } 12750e5e5a79SGreg Clayton const size_t first_separator_char_pos = 1; 12760e5e5a79SGreg Clayton // use the char that follows 's' as the regex separator character 12770e5e5a79SGreg Clayton // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" 12780e5e5a79SGreg Clayton const char separator_char = regex_sed[first_separator_char_pos]; 12790e5e5a79SGreg Clayton const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1); 12800e5e5a79SGreg Clayton 12810e5e5a79SGreg Clayton if (second_separator_char_pos == std::string::npos) 12820e5e5a79SGreg Clayton { 1283ea508635SGreg Clayton error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'", 12840e5e5a79SGreg Clayton separator_char, 12850e5e5a79SGreg Clayton (int)(regex_sed.size() - first_separator_char_pos - 1), 1286ea508635SGreg Clayton regex_sed.data() + (first_separator_char_pos + 1), 1287ea508635SGreg Clayton (int)regex_sed.size(), 1288ea508635SGreg Clayton regex_sed.data()); 12890e5e5a79SGreg Clayton return error; 12900e5e5a79SGreg Clayton } 12910e5e5a79SGreg Clayton 12920e5e5a79SGreg Clayton const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1); 12930e5e5a79SGreg Clayton 12940e5e5a79SGreg Clayton if (third_separator_char_pos == std::string::npos) 12950e5e5a79SGreg Clayton { 1296ea508635SGreg Clayton error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'", 12970e5e5a79SGreg Clayton separator_char, 12980e5e5a79SGreg Clayton (int)(regex_sed.size() - second_separator_char_pos - 1), 1299ea508635SGreg Clayton regex_sed.data() + (second_separator_char_pos + 1), 1300ea508635SGreg Clayton (int)regex_sed.size(), 1301ea508635SGreg Clayton regex_sed.data()); 13020e5e5a79SGreg Clayton return error; 13030e5e5a79SGreg Clayton } 13040e5e5a79SGreg Clayton 13050e5e5a79SGreg Clayton if (third_separator_char_pos != regex_sed_size - 1) 13060e5e5a79SGreg Clayton { 13070e5e5a79SGreg Clayton // Make sure that everything that follows the last regex 13080e5e5a79SGreg Clayton // separator char 13090e5e5a79SGreg Clayton if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) 13100e5e5a79SGreg Clayton { 13110e5e5a79SGreg Clayton error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'", 13120e5e5a79SGreg Clayton (int)third_separator_char_pos + 1, 13130e5e5a79SGreg Clayton regex_sed.data(), 13140e5e5a79SGreg Clayton (int)(regex_sed.size() - third_separator_char_pos - 1), 13150e5e5a79SGreg Clayton regex_sed.data() + (third_separator_char_pos + 1)); 13160e5e5a79SGreg Clayton return error; 13170e5e5a79SGreg Clayton } 13180e5e5a79SGreg Clayton } 13190e5e5a79SGreg Clayton else if (first_separator_char_pos + 1 == second_separator_char_pos) 13200e5e5a79SGreg Clayton { 13210e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 13220e5e5a79SGreg Clayton separator_char, 13230e5e5a79SGreg Clayton separator_char, 13240e5e5a79SGreg Clayton separator_char, 13250e5e5a79SGreg Clayton (int)regex_sed.size(), 13260e5e5a79SGreg Clayton regex_sed.data()); 13270e5e5a79SGreg Clayton return error; 13280e5e5a79SGreg Clayton } 13290e5e5a79SGreg Clayton else if (second_separator_char_pos + 1 == third_separator_char_pos) 13300e5e5a79SGreg Clayton { 13310e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 13320e5e5a79SGreg Clayton separator_char, 13330e5e5a79SGreg Clayton separator_char, 13340e5e5a79SGreg Clayton separator_char, 13350e5e5a79SGreg Clayton (int)regex_sed.size(), 13360e5e5a79SGreg Clayton regex_sed.data()); 13370e5e5a79SGreg Clayton return error; 13380e5e5a79SGreg Clayton } 133944d93782SGreg Clayton 13406e3d8e7fSEugene Zelenko if (!check_only) 134144d93782SGreg Clayton { 13420e5e5a79SGreg Clayton std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1)); 13430e5e5a79SGreg Clayton std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1)); 13440e5e5a79SGreg Clayton m_regex_cmd_ap->AddRegexCommand (regex.c_str(), 13450e5e5a79SGreg Clayton subst.c_str()); 134644d93782SGreg Clayton } 13470e5e5a79SGreg Clayton return error; 1348de164aaaSGreg Clayton } 1349de164aaaSGreg Clayton 1350de164aaaSGreg Clayton void 13510e5e5a79SGreg Clayton AddRegexCommandToInterpreter() 1352de164aaaSGreg Clayton { 13536e3d8e7fSEugene Zelenko if (m_regex_cmd_ap) 1354de164aaaSGreg Clayton { 1355de164aaaSGreg Clayton if (m_regex_cmd_ap->HasRegexEntries()) 1356de164aaaSGreg Clayton { 1357de164aaaSGreg Clayton CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 1358de164aaaSGreg Clayton m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 1359de164aaaSGreg Clayton } 1360de164aaaSGreg Clayton } 1361de164aaaSGreg Clayton } 1362de164aaaSGreg Clayton 1363de164aaaSGreg Clayton private: 13647b0992d9SGreg Clayton std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap; 1365de164aaaSGreg Clayton 1366de164aaaSGreg Clayton class CommandOptions : public Options 1367de164aaaSGreg Clayton { 1368de164aaaSGreg Clayton public: 1369de164aaaSGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 1370de164aaaSGreg Clayton Options (interpreter) 1371de164aaaSGreg Clayton { 1372de164aaaSGreg Clayton } 1373de164aaaSGreg Clayton 13746e3d8e7fSEugene Zelenko ~CommandOptions() override = default; 1375de164aaaSGreg Clayton 137613d21e9aSBruce Mitchener Error 137713d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 1378de164aaaSGreg Clayton { 1379de164aaaSGreg Clayton Error error; 13803bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 1381de164aaaSGreg Clayton 1382de164aaaSGreg Clayton switch (short_option) 1383de164aaaSGreg Clayton { 1384de164aaaSGreg Clayton case 'h': 1385de164aaaSGreg Clayton m_help.assign (option_arg); 1386de164aaaSGreg Clayton break; 1387de164aaaSGreg Clayton case 's': 1388de164aaaSGreg Clayton m_syntax.assign (option_arg); 1389de164aaaSGreg Clayton break; 1390de164aaaSGreg Clayton default: 139186edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1392de164aaaSGreg Clayton break; 1393de164aaaSGreg Clayton } 1394de164aaaSGreg Clayton 1395de164aaaSGreg Clayton return error; 1396de164aaaSGreg Clayton } 1397de164aaaSGreg Clayton 1398de164aaaSGreg Clayton void 139913d21e9aSBruce Mitchener OptionParsingStarting () override 1400de164aaaSGreg Clayton { 1401de164aaaSGreg Clayton m_help.clear(); 1402de164aaaSGreg Clayton m_syntax.clear(); 1403de164aaaSGreg Clayton } 1404de164aaaSGreg Clayton 1405de164aaaSGreg Clayton const OptionDefinition* 140613d21e9aSBruce Mitchener GetDefinitions () override 1407de164aaaSGreg Clayton { 1408de164aaaSGreg Clayton return g_option_table; 1409de164aaaSGreg Clayton } 1410de164aaaSGreg Clayton 1411de164aaaSGreg Clayton // Options table: Required for subclasses of Options. 1412de164aaaSGreg Clayton 1413de164aaaSGreg Clayton static OptionDefinition g_option_table[]; 1414de164aaaSGreg Clayton 1415de164aaaSGreg Clayton const char * 1416de164aaaSGreg Clayton GetHelp() 1417de164aaaSGreg Clayton { 14186e3d8e7fSEugene Zelenko return (m_help.empty() ? nullptr : m_help.c_str()); 1419de164aaaSGreg Clayton } 14206e3d8e7fSEugene Zelenko 1421de164aaaSGreg Clayton const char * 1422de164aaaSGreg Clayton GetSyntax () 1423de164aaaSGreg Clayton { 14246e3d8e7fSEugene Zelenko return (m_syntax.empty() ? nullptr : m_syntax.c_str()); 1425de164aaaSGreg Clayton } 14266e3d8e7fSEugene Zelenko 1427de164aaaSGreg Clayton protected: 14286e3d8e7fSEugene Zelenko // Instance variables to hold the values for command options. 14296e3d8e7fSEugene Zelenko 1430de164aaaSGreg Clayton std::string m_help; 1431de164aaaSGreg Clayton std::string m_syntax; 1432de164aaaSGreg Clayton }; 1433de164aaaSGreg Clayton 1434b0a1814fSEric Christopher Options * 1435b0a1814fSEric Christopher GetOptions () override 1436de164aaaSGreg Clayton { 1437de164aaaSGreg Clayton return &m_options; 1438de164aaaSGreg Clayton } 1439de164aaaSGreg Clayton 14405a988416SJim Ingham CommandOptions m_options; 1441de164aaaSGreg Clayton }; 1442de164aaaSGreg Clayton 1443de164aaaSGreg Clayton OptionDefinition 1444de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = 1445de164aaaSGreg Clayton { 14466e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command."}, 14476e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, 14486e3d8e7fSEugene Zelenko { 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr } 1449de164aaaSGreg Clayton }; 1450de164aaaSGreg Clayton 14515a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw 1452223383edSEnrico Granata { 1453223383edSEnrico Granata public: 1454223383edSEnrico Granata CommandObjectPythonFunction (CommandInterpreter &interpreter, 1455223383edSEnrico Granata std::string name, 14560a305db7SEnrico Granata std::string funct, 1457735152e3SEnrico Granata std::string help, 14580a305db7SEnrico Granata ScriptedCommandSynchronicity synch) : 14595a988416SJim Ingham CommandObjectRaw(interpreter, 1460223383edSEnrico Granata name.c_str(), 14616e3d8e7fSEugene Zelenko nullptr, 14626e3d8e7fSEugene Zelenko nullptr), 14630a305db7SEnrico Granata m_function_name(funct), 1464fac939e9SEnrico Granata m_synchro(synch), 1465fac939e9SEnrico Granata m_fetched_help_long(false) 1466223383edSEnrico Granata { 1467735152e3SEnrico Granata if (!help.empty()) 1468735152e3SEnrico Granata SetHelp(help.c_str()); 1469735152e3SEnrico Granata else 1470735152e3SEnrico Granata { 1471735152e3SEnrico Granata StreamString stream; 1472735152e3SEnrico Granata stream.Printf("For more information run 'help %s'",name.c_str()); 1473735152e3SEnrico Granata SetHelp(stream.GetData()); 1474735152e3SEnrico Granata } 1475223383edSEnrico Granata } 1476223383edSEnrico Granata 14776e3d8e7fSEugene Zelenko ~CommandObjectPythonFunction() override = default; 1478223383edSEnrico Granata 147913d21e9aSBruce Mitchener bool 148013d21e9aSBruce Mitchener IsRemovable () const override 14815a988416SJim Ingham { 14825a988416SJim Ingham return true; 14835a988416SJim Ingham } 14845a988416SJim Ingham 14855a988416SJim Ingham const std::string& 14865a988416SJim Ingham GetFunctionName () 14875a988416SJim Ingham { 14885a988416SJim Ingham return m_function_name; 14895a988416SJim Ingham } 14905a988416SJim Ingham 14915a988416SJim Ingham ScriptedCommandSynchronicity 14925a988416SJim Ingham GetSynchronicity () 14935a988416SJim Ingham { 14945a988416SJim Ingham return m_synchro; 14955a988416SJim Ingham } 14965a988416SJim Ingham 149713d21e9aSBruce Mitchener const char * 149813d21e9aSBruce Mitchener GetHelpLong () override 1499fac939e9SEnrico Granata { 1500fac939e9SEnrico Granata if (!m_fetched_help_long) 1501fac939e9SEnrico Granata { 1502fac939e9SEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1503fac939e9SEnrico Granata if (scripter) 1504fac939e9SEnrico Granata { 1505fac939e9SEnrico Granata std::string docstring; 1506fac939e9SEnrico Granata m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring); 1507fac939e9SEnrico Granata if (!docstring.empty()) 1508bfb75e9bSEnrico Granata SetHelpLong(docstring.c_str()); 1509fac939e9SEnrico Granata } 1510fac939e9SEnrico Granata } 1511fac939e9SEnrico Granata return CommandObjectRaw::GetHelpLong(); 1512fac939e9SEnrico Granata } 1513fac939e9SEnrico Granata 15145a988416SJim Ingham protected: 151513d21e9aSBruce Mitchener bool 151613d21e9aSBruce Mitchener DoExecute (const char *raw_command_line, CommandReturnObject &result) override 1517223383edSEnrico Granata { 1518223383edSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1519223383edSEnrico Granata 1520223383edSEnrico Granata Error error; 1521223383edSEnrico Granata 152270f11f88SJim Ingham result.SetStatus(eReturnStatusInvalid); 152370f11f88SJim Ingham 15246e3d8e7fSEugene Zelenko if (!scripter || !scripter->RunScriptBasedCommand(m_function_name.c_str(), 1525223383edSEnrico Granata raw_command_line, 15260a305db7SEnrico Granata m_synchro, 1527223383edSEnrico Granata result, 152806be059aSEnrico Granata error, 15296e3d8e7fSEugene Zelenko m_exe_ctx)) 1530223383edSEnrico Granata { 1531223383edSEnrico Granata result.AppendError(error.AsCString()); 1532223383edSEnrico Granata result.SetStatus(eReturnStatusFailed); 1533223383edSEnrico Granata } 1534223383edSEnrico Granata else 153570f11f88SJim Ingham { 153670f11f88SJim Ingham // Don't change the status if the command already set it... 153770f11f88SJim Ingham if (result.GetStatus() == eReturnStatusInvalid) 153870f11f88SJim Ingham { 15396e3d8e7fSEugene Zelenko if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0') 1540223383edSEnrico Granata result.SetStatus(eReturnStatusSuccessFinishNoResult); 154170f11f88SJim Ingham else 154270f11f88SJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult); 154370f11f88SJim Ingham } 154470f11f88SJim Ingham } 1545223383edSEnrico Granata 1546223383edSEnrico Granata return result.Succeeded(); 1547223383edSEnrico Granata } 1548223383edSEnrico Granata 15496e3d8e7fSEugene Zelenko private: 15506e3d8e7fSEugene Zelenko std::string m_function_name; 15516e3d8e7fSEugene Zelenko ScriptedCommandSynchronicity m_synchro; 15526e3d8e7fSEugene Zelenko bool m_fetched_help_long; 1553223383edSEnrico Granata }; 1554223383edSEnrico Granata 15559fe00e52SEnrico Granata class CommandObjectScriptingObject : public CommandObjectRaw 15569fe00e52SEnrico Granata { 15579fe00e52SEnrico Granata public: 15589fe00e52SEnrico Granata CommandObjectScriptingObject (CommandInterpreter &interpreter, 15599fe00e52SEnrico Granata std::string name, 15600641ca1aSZachary Turner StructuredData::GenericSP cmd_obj_sp, 15619fe00e52SEnrico Granata ScriptedCommandSynchronicity synch) : 15629fe00e52SEnrico Granata CommandObjectRaw(interpreter, 15639fe00e52SEnrico Granata name.c_str(), 15646e3d8e7fSEugene Zelenko nullptr, 15656e3d8e7fSEugene Zelenko nullptr), 15669fe00e52SEnrico Granata m_cmd_obj_sp(cmd_obj_sp), 15676f79bb2dSEnrico Granata m_synchro(synch), 15686f79bb2dSEnrico Granata m_fetched_help_short(false), 15696f79bb2dSEnrico Granata m_fetched_help_long(false) 15709fe00e52SEnrico Granata { 15719fe00e52SEnrico Granata StreamString stream; 15729fe00e52SEnrico Granata stream.Printf("For more information run 'help %s'",name.c_str()); 15739fe00e52SEnrico Granata SetHelp(stream.GetData()); 1574e87764f2SEnrico Granata if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter()) 1575e87764f2SEnrico Granata GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp)); 15769fe00e52SEnrico Granata } 15779fe00e52SEnrico Granata 15786e3d8e7fSEugene Zelenko ~CommandObjectScriptingObject() override = default; 15799fe00e52SEnrico Granata 158013d21e9aSBruce Mitchener bool 158113d21e9aSBruce Mitchener IsRemovable () const override 15829fe00e52SEnrico Granata { 15839fe00e52SEnrico Granata return true; 15849fe00e52SEnrico Granata } 15859fe00e52SEnrico Granata 15860641ca1aSZachary Turner StructuredData::GenericSP 15879fe00e52SEnrico Granata GetImplementingObject () 15889fe00e52SEnrico Granata { 15899fe00e52SEnrico Granata return m_cmd_obj_sp; 15909fe00e52SEnrico Granata } 15919fe00e52SEnrico Granata 15929fe00e52SEnrico Granata ScriptedCommandSynchronicity 15939fe00e52SEnrico Granata GetSynchronicity () 15949fe00e52SEnrico Granata { 15959fe00e52SEnrico Granata return m_synchro; 15969fe00e52SEnrico Granata } 15979fe00e52SEnrico Granata 159813d21e9aSBruce Mitchener const char * 159913d21e9aSBruce Mitchener GetHelp () override 16006f79bb2dSEnrico Granata { 16016f79bb2dSEnrico Granata if (!m_fetched_help_short) 16026f79bb2dSEnrico Granata { 16036f79bb2dSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 16046f79bb2dSEnrico Granata if (scripter) 16056f79bb2dSEnrico Granata { 16066f79bb2dSEnrico Granata std::string docstring; 16076f79bb2dSEnrico Granata m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring); 16086f79bb2dSEnrico Granata if (!docstring.empty()) 1609bfb75e9bSEnrico Granata SetHelp(docstring.c_str()); 16106f79bb2dSEnrico Granata } 16116f79bb2dSEnrico Granata } 16126f79bb2dSEnrico Granata return CommandObjectRaw::GetHelp(); 16136f79bb2dSEnrico Granata } 16146f79bb2dSEnrico Granata 161513d21e9aSBruce Mitchener const char * 161613d21e9aSBruce Mitchener GetHelpLong () override 16179fe00e52SEnrico Granata { 16186f79bb2dSEnrico Granata if (!m_fetched_help_long) 16196f79bb2dSEnrico Granata { 16206f79bb2dSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 16216f79bb2dSEnrico Granata if (scripter) 16226f79bb2dSEnrico Granata { 16236f79bb2dSEnrico Granata std::string docstring; 16246f79bb2dSEnrico Granata m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring); 16256f79bb2dSEnrico Granata if (!docstring.empty()) 1626bfb75e9bSEnrico Granata SetHelpLong(docstring.c_str()); 16276f79bb2dSEnrico Granata } 16286f79bb2dSEnrico Granata } 16299fe00e52SEnrico Granata return CommandObjectRaw::GetHelpLong(); 16309fe00e52SEnrico Granata } 16319fe00e52SEnrico Granata 16329fe00e52SEnrico Granata protected: 163313d21e9aSBruce Mitchener bool 163413d21e9aSBruce Mitchener DoExecute (const char *raw_command_line, CommandReturnObject &result) override 16359fe00e52SEnrico Granata { 16369fe00e52SEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 16379fe00e52SEnrico Granata 16389fe00e52SEnrico Granata Error error; 16399fe00e52SEnrico Granata 16409fe00e52SEnrico Granata result.SetStatus(eReturnStatusInvalid); 16419fe00e52SEnrico Granata 16426e3d8e7fSEugene Zelenko if (!scripter || !scripter->RunScriptBasedCommand(m_cmd_obj_sp, 16439fe00e52SEnrico Granata raw_command_line, 16449fe00e52SEnrico Granata m_synchro, 16459fe00e52SEnrico Granata result, 16469fe00e52SEnrico Granata error, 16476e3d8e7fSEugene Zelenko m_exe_ctx)) 16489fe00e52SEnrico Granata { 16499fe00e52SEnrico Granata result.AppendError(error.AsCString()); 16509fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 16519fe00e52SEnrico Granata } 16529fe00e52SEnrico Granata else 16539fe00e52SEnrico Granata { 16549fe00e52SEnrico Granata // Don't change the status if the command already set it... 16559fe00e52SEnrico Granata if (result.GetStatus() == eReturnStatusInvalid) 16569fe00e52SEnrico Granata { 16576e3d8e7fSEugene Zelenko if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0') 16589fe00e52SEnrico Granata result.SetStatus(eReturnStatusSuccessFinishNoResult); 16599fe00e52SEnrico Granata else 16609fe00e52SEnrico Granata result.SetStatus(eReturnStatusSuccessFinishResult); 16619fe00e52SEnrico Granata } 16629fe00e52SEnrico Granata } 16639fe00e52SEnrico Granata 16649fe00e52SEnrico Granata return result.Succeeded(); 16659fe00e52SEnrico Granata } 16669fe00e52SEnrico Granata 16676e3d8e7fSEugene Zelenko private: 16686e3d8e7fSEugene Zelenko StructuredData::GenericSP m_cmd_obj_sp; 16696e3d8e7fSEugene Zelenko ScriptedCommandSynchronicity m_synchro; 16706e3d8e7fSEugene Zelenko bool m_fetched_help_short: 1; 16716e3d8e7fSEugene Zelenko bool m_fetched_help_long: 1; 16729fe00e52SEnrico Granata }; 16739fe00e52SEnrico Granata 1674a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1675a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport 1676a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1677a9dbf432SEnrico Granata 16785a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed 1679a9dbf432SEnrico Granata { 16805a988416SJim Ingham public: 16815a988416SJim Ingham CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 16825a988416SJim Ingham CommandObjectParsed(interpreter, 16835a988416SJim Ingham "command script import", 16845a988416SJim Ingham "Import a scripting module in LLDB.", 16856e3d8e7fSEugene Zelenko nullptr), 16865a988416SJim Ingham m_options(interpreter) 16875a988416SJim Ingham { 16885a988416SJim Ingham CommandArgumentEntry arg1; 16895a988416SJim Ingham CommandArgumentData cmd_arg; 16905a988416SJim Ingham 16915a988416SJim Ingham // Define the first (and only) variant of this arg. 16925a988416SJim Ingham cmd_arg.arg_type = eArgTypeFilename; 16933b00e35bSEnrico Granata cmd_arg.arg_repetition = eArgRepeatPlus; 16945a988416SJim Ingham 16955a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 16965a988416SJim Ingham arg1.push_back (cmd_arg); 16975a988416SJim Ingham 16985a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 16995a988416SJim Ingham m_arguments.push_back (arg1); 17005a988416SJim Ingham } 17015a988416SJim Ingham 17026e3d8e7fSEugene Zelenko ~CommandObjectCommandsScriptImport() override = default; 17035a988416SJim Ingham 170413d21e9aSBruce Mitchener int 17055a988416SJim Ingham HandleArgumentCompletion (Args &input, 17065a988416SJim Ingham int &cursor_index, 17075a988416SJim Ingham int &cursor_char_position, 17085a988416SJim Ingham OptionElementVector &opt_element_vector, 17095a988416SJim Ingham int match_start_point, 17105a988416SJim Ingham int max_return_elements, 17115a988416SJim Ingham bool &word_complete, 171213d21e9aSBruce Mitchener StringList &matches) override 17135a988416SJim Ingham { 17145a988416SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 17155a988416SJim Ingham completion_str.erase (cursor_char_position); 17165a988416SJim Ingham 17175a988416SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter, 17185a988416SJim Ingham CommandCompletions::eDiskFileCompletion, 17195a988416SJim Ingham completion_str.c_str(), 17205a988416SJim Ingham match_start_point, 17215a988416SJim Ingham max_return_elements, 17226e3d8e7fSEugene Zelenko nullptr, 17235a988416SJim Ingham word_complete, 17245a988416SJim Ingham matches); 17255a988416SJim Ingham return matches.GetSize(); 17265a988416SJim Ingham } 17275a988416SJim Ingham 172813d21e9aSBruce Mitchener Options * 172913d21e9aSBruce Mitchener GetOptions () override 17305a988416SJim Ingham { 17315a988416SJim Ingham return &m_options; 17325a988416SJim Ingham } 17335a988416SJim Ingham 17345a988416SJim Ingham protected: 17350a305db7SEnrico Granata class CommandOptions : public Options 17360a305db7SEnrico Granata { 17370a305db7SEnrico Granata public: 17380a305db7SEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 17390a305db7SEnrico Granata Options (interpreter) 17400a305db7SEnrico Granata { 17410a305db7SEnrico Granata } 17420a305db7SEnrico Granata 17436e3d8e7fSEugene Zelenko ~CommandOptions() override = default; 17440a305db7SEnrico Granata 174513d21e9aSBruce Mitchener Error 174613d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 17470a305db7SEnrico Granata { 17480a305db7SEnrico Granata Error error; 17493bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 17500a305db7SEnrico Granata 17510a305db7SEnrico Granata switch (short_option) 17520a305db7SEnrico Granata { 17530a305db7SEnrico Granata case 'r': 17540a305db7SEnrico Granata m_allow_reload = true; 17550a305db7SEnrico Granata break; 17560a305db7SEnrico Granata default: 17570a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 17580a305db7SEnrico Granata break; 17590a305db7SEnrico Granata } 17600a305db7SEnrico Granata 17610a305db7SEnrico Granata return error; 17620a305db7SEnrico Granata } 17630a305db7SEnrico Granata 17640a305db7SEnrico Granata void 176513d21e9aSBruce Mitchener OptionParsingStarting () override 17660a305db7SEnrico Granata { 1767e0c70f1bSEnrico Granata m_allow_reload = true; 17680a305db7SEnrico Granata } 17690a305db7SEnrico Granata 17700a305db7SEnrico Granata const OptionDefinition* 177113d21e9aSBruce Mitchener GetDefinitions () override 17720a305db7SEnrico Granata { 17730a305db7SEnrico Granata return g_option_table; 17740a305db7SEnrico Granata } 17750a305db7SEnrico Granata 17760a305db7SEnrico Granata // Options table: Required for subclasses of Options. 17770a305db7SEnrico Granata 17780a305db7SEnrico Granata static OptionDefinition g_option_table[]; 17790a305db7SEnrico Granata 17800a305db7SEnrico Granata // Instance variables to hold the values for command options. 17810a305db7SEnrico Granata 17820a305db7SEnrico Granata bool m_allow_reload; 17830a305db7SEnrico Granata }; 17840a305db7SEnrico Granata 1785a9dbf432SEnrico Granata bool 178613d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 1787a9dbf432SEnrico Granata { 1788a9dbf432SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1789a9dbf432SEnrico Granata { 1790a9dbf432SEnrico Granata result.AppendError ("only scripting language supported for module importing is currently Python"); 1791a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1792a9dbf432SEnrico Granata return false; 1793a9dbf432SEnrico Granata } 1794a9dbf432SEnrico Granata 17955a988416SJim Ingham size_t argc = command.GetArgumentCount(); 17963b00e35bSEnrico Granata if (0 == argc) 1797a9dbf432SEnrico Granata { 17983b00e35bSEnrico Granata result.AppendError("command script import needs one or more arguments"); 1799a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1800a9dbf432SEnrico Granata return false; 1801a9dbf432SEnrico Granata } 1802a9dbf432SEnrico Granata 18030e978481SEd Maste for (size_t i = 0; 18043b00e35bSEnrico Granata i < argc; 18053b00e35bSEnrico Granata i++) 18063b00e35bSEnrico Granata { 18073b00e35bSEnrico Granata std::string path = command.GetArgumentAtIndex(i); 1808a9dbf432SEnrico Granata Error error; 1809a9dbf432SEnrico Granata 1810c9d645d3SGreg Clayton const bool init_session = true; 1811078551c7SEnrico Granata // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that 1812078551c7SEnrico Granata // commands won't ever be recursively invoked, but it's actually possible to craft 1813078551c7SEnrico Granata // a Python script that does other "command script imports" in __lldb_init_module 1814078551c7SEnrico Granata // the real fix is to have recursive commands possible with a CommandInvocation object 1815078551c7SEnrico Granata // separate from the CommandObject itself, so that recursive command invocations 1816078551c7SEnrico Granata // won't stomp on each other (wrt to execution contents, options, and more) 1817078551c7SEnrico Granata m_exe_ctx.Clear(); 1818a9dbf432SEnrico Granata if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 18190a305db7SEnrico Granata m_options.m_allow_reload, 1820c9d645d3SGreg Clayton init_session, 1821a9dbf432SEnrico Granata error)) 1822a9dbf432SEnrico Granata { 1823a9dbf432SEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1824a9dbf432SEnrico Granata } 1825a9dbf432SEnrico Granata else 1826a9dbf432SEnrico Granata { 1827a9dbf432SEnrico Granata result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1828a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1829a9dbf432SEnrico Granata } 18303b00e35bSEnrico Granata } 1831a9dbf432SEnrico Granata 1832a9dbf432SEnrico Granata return result.Succeeded(); 1833a9dbf432SEnrico Granata } 18340a305db7SEnrico Granata 18355a988416SJim Ingham CommandOptions m_options; 1836a9dbf432SEnrico Granata }; 1837223383edSEnrico Granata 18380a305db7SEnrico Granata OptionDefinition 18390a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 18400a305db7SEnrico Granata { 18416e3d8e7fSEugene 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."}, 18426e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 18430a305db7SEnrico Granata }; 18440a305db7SEnrico Granata 1845223383edSEnrico Granata //------------------------------------------------------------------------- 1846223383edSEnrico Granata // CommandObjectCommandsScriptAdd 1847223383edSEnrico Granata //------------------------------------------------------------------------- 1848223383edSEnrico Granata 184944d93782SGreg Clayton class CommandObjectCommandsScriptAdd : 185044d93782SGreg Clayton public CommandObjectParsed, 185144d93782SGreg Clayton public IOHandlerDelegateMultiline 1852223383edSEnrico Granata { 18535a988416SJim Ingham public: 18545a988416SJim Ingham CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 18555a988416SJim Ingham CommandObjectParsed(interpreter, 18565a988416SJim Ingham "command script add", 18575a988416SJim Ingham "Add a scripted function as an LLDB command.", 18586e3d8e7fSEugene Zelenko nullptr), 1859c3d874a5SGreg Clayton IOHandlerDelegateMultiline ("DONE"), 18605a988416SJim Ingham m_options (interpreter) 18615a988416SJim Ingham { 18625a988416SJim Ingham CommandArgumentEntry arg1; 18635a988416SJim Ingham CommandArgumentData cmd_arg; 18645a988416SJim Ingham 18655a988416SJim Ingham // Define the first (and only) variant of this arg. 18665a988416SJim Ingham cmd_arg.arg_type = eArgTypeCommandName; 18675a988416SJim Ingham cmd_arg.arg_repetition = eArgRepeatPlain; 18685a988416SJim Ingham 18695a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 18705a988416SJim Ingham arg1.push_back (cmd_arg); 18715a988416SJim Ingham 18725a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 18735a988416SJim Ingham m_arguments.push_back (arg1); 18745a988416SJim Ingham } 18755a988416SJim Ingham 18766e3d8e7fSEugene Zelenko ~CommandObjectCommandsScriptAdd() override = default; 18775a988416SJim Ingham 187813d21e9aSBruce Mitchener Options * 187913d21e9aSBruce Mitchener GetOptions () override 18805a988416SJim Ingham { 18815a988416SJim Ingham return &m_options; 18825a988416SJim Ingham } 18835a988416SJim Ingham 18845a988416SJim Ingham protected: 1885223383edSEnrico Granata class CommandOptions : public Options 1886223383edSEnrico Granata { 1887223383edSEnrico Granata public: 1888223383edSEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 18899fe00e52SEnrico Granata Options (interpreter), 18909fe00e52SEnrico Granata m_class_name(), 18919fe00e52SEnrico Granata m_funct_name(), 18929fe00e52SEnrico Granata m_short_help(), 18939fe00e52SEnrico Granata m_synchronicity(eScriptedCommandSynchronicitySynchronous) 1894223383edSEnrico Granata { 1895223383edSEnrico Granata } 1896223383edSEnrico Granata 18976e3d8e7fSEugene Zelenko ~CommandOptions() override = default; 1898223383edSEnrico Granata 189913d21e9aSBruce Mitchener Error 190013d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 1901223383edSEnrico Granata { 1902223383edSEnrico Granata Error error; 19033bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 1904223383edSEnrico Granata 1905223383edSEnrico Granata switch (short_option) 1906223383edSEnrico Granata { 1907223383edSEnrico Granata case 'f': 1908735152e3SEnrico Granata if (option_arg) 1909735152e3SEnrico Granata m_funct_name.assign(option_arg); 1910735152e3SEnrico Granata break; 19119fe00e52SEnrico Granata case 'c': 19129fe00e52SEnrico Granata if (option_arg) 19139fe00e52SEnrico Granata m_class_name.assign(option_arg); 19149fe00e52SEnrico Granata break; 1915735152e3SEnrico Granata case 'h': 1916735152e3SEnrico Granata if (option_arg) 1917735152e3SEnrico Granata m_short_help.assign(option_arg); 1918223383edSEnrico Granata break; 19190a305db7SEnrico Granata case 's': 192044d93782SGreg Clayton m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 19210a305db7SEnrico Granata if (!error.Success()) 19220a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 19230a305db7SEnrico Granata break; 1924223383edSEnrico Granata default: 192586edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1926223383edSEnrico Granata break; 1927223383edSEnrico Granata } 1928223383edSEnrico Granata 1929223383edSEnrico Granata return error; 1930223383edSEnrico Granata } 1931223383edSEnrico Granata 1932223383edSEnrico Granata void 193313d21e9aSBruce Mitchener OptionParsingStarting () override 1934223383edSEnrico Granata { 19359fe00e52SEnrico Granata m_class_name.clear(); 1936735152e3SEnrico Granata m_funct_name.clear(); 1937735152e3SEnrico Granata m_short_help.clear(); 193844d93782SGreg Clayton m_synchronicity = eScriptedCommandSynchronicitySynchronous; 1939223383edSEnrico Granata } 1940223383edSEnrico Granata 1941223383edSEnrico Granata const OptionDefinition* 194213d21e9aSBruce Mitchener GetDefinitions () override 1943223383edSEnrico Granata { 1944223383edSEnrico Granata return g_option_table; 1945223383edSEnrico Granata } 1946223383edSEnrico Granata 1947223383edSEnrico Granata // Options table: Required for subclasses of Options. 1948223383edSEnrico Granata 1949223383edSEnrico Granata static OptionDefinition g_option_table[]; 1950223383edSEnrico Granata 1951223383edSEnrico Granata // Instance variables to hold the values for command options. 1952223383edSEnrico Granata 19539fe00e52SEnrico Granata std::string m_class_name; 1954223383edSEnrico Granata std::string m_funct_name; 1955735152e3SEnrico Granata std::string m_short_help; 195644d93782SGreg Clayton ScriptedCommandSynchronicity m_synchronicity; 1957223383edSEnrico Granata }; 1958223383edSEnrico Granata 195913d21e9aSBruce Mitchener void 196013d21e9aSBruce Mitchener IOHandlerActivated (IOHandler &io_handler) override 1961223383edSEnrico Granata { 196244d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 196344d93782SGreg Clayton if (output_sp) 1964223383edSEnrico Granata { 196544d93782SGreg Clayton output_sp->PutCString(g_python_command_instructions); 196644d93782SGreg Clayton output_sp->Flush(); 1967223383edSEnrico Granata } 1968223383edSEnrico Granata } 1969223383edSEnrico Granata 1970223383edSEnrico Granata 197113d21e9aSBruce Mitchener void 197213d21e9aSBruce Mitchener IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override 1973223383edSEnrico Granata { 197444d93782SGreg Clayton StreamFileSP error_sp = io_handler.GetErrorStreamFile(); 197544d93782SGreg Clayton 197644d93782SGreg Clayton ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 197744d93782SGreg Clayton if (interpreter) 197844d93782SGreg Clayton { 197944d93782SGreg Clayton 198044d93782SGreg Clayton StringList lines; 198144d93782SGreg Clayton lines.SplitIntoLines(data); 198244d93782SGreg Clayton if (lines.GetSize() > 0) 198344d93782SGreg Clayton { 1984a73b7df7SEnrico Granata std::string funct_name_str; 198544d93782SGreg Clayton if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str)) 1986223383edSEnrico Granata { 1987a73b7df7SEnrico Granata if (funct_name_str.empty()) 1988223383edSEnrico Granata { 198944d93782SGreg Clayton error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n"); 199044d93782SGreg Clayton error_sp->Flush(); 1991223383edSEnrico Granata } 199244d93782SGreg Clayton else 199344d93782SGreg Clayton { 1994223383edSEnrico Granata // everything should be fine now, let's add this alias 1995223383edSEnrico Granata 1996223383edSEnrico Granata CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter, 1997223383edSEnrico Granata m_cmd_name, 1998a73b7df7SEnrico Granata funct_name_str.c_str(), 1999735152e3SEnrico Granata m_short_help, 200044d93782SGreg Clayton m_synchronicity)); 2001223383edSEnrico Granata 20020a305db7SEnrico Granata if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 2003223383edSEnrico Granata { 200444d93782SGreg Clayton error_sp->Printf ("error: unable to add selected command, didn't add python command.\n"); 200544d93782SGreg Clayton error_sp->Flush(); 2006223383edSEnrico Granata } 2007223383edSEnrico Granata } 200844d93782SGreg Clayton } 200944d93782SGreg Clayton else 201044d93782SGreg Clayton { 201144d93782SGreg Clayton error_sp->Printf ("error: unable to create function, didn't add python command.\n"); 201244d93782SGreg Clayton error_sp->Flush(); 201344d93782SGreg Clayton } 201444d93782SGreg Clayton } 201544d93782SGreg Clayton else 201644d93782SGreg Clayton { 201744d93782SGreg Clayton error_sp->Printf ("error: empty function, didn't add python command.\n"); 201844d93782SGreg Clayton error_sp->Flush(); 201944d93782SGreg Clayton } 202044d93782SGreg Clayton } 202144d93782SGreg Clayton else 202244d93782SGreg Clayton { 202344d93782SGreg Clayton error_sp->Printf ("error: script interpreter missing, didn't add python command.\n"); 202444d93782SGreg Clayton error_sp->Flush(); 202544d93782SGreg Clayton } 202644d93782SGreg Clayton 202744d93782SGreg Clayton io_handler.SetIsDone(true); 202844d93782SGreg Clayton } 2029223383edSEnrico Granata 20305a988416SJim Ingham protected: 2031223383edSEnrico Granata bool 203213d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 2033223383edSEnrico Granata { 203499f0b8f9SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 203599f0b8f9SEnrico Granata { 203699f0b8f9SEnrico Granata result.AppendError ("only scripting language supported for scripted commands is currently Python"); 203799f0b8f9SEnrico Granata result.SetStatus (eReturnStatusFailed); 203899f0b8f9SEnrico Granata return false; 203999f0b8f9SEnrico Granata } 204099f0b8f9SEnrico Granata 20415a988416SJim Ingham size_t argc = command.GetArgumentCount(); 2042223383edSEnrico Granata 2043223383edSEnrico Granata if (argc != 1) 2044223383edSEnrico Granata { 2045223383edSEnrico Granata result.AppendError ("'command script add' requires one argument"); 2046223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2047223383edSEnrico Granata return false; 2048223383edSEnrico Granata } 2049223383edSEnrico Granata 2050735152e3SEnrico Granata // Store the options in case we get multi-line input 205144d93782SGreg Clayton m_cmd_name = command.GetArgumentAtIndex(0); 2052735152e3SEnrico Granata m_short_help.assign(m_options.m_short_help); 205344d93782SGreg Clayton m_synchronicity = m_options.m_synchronicity; 2054223383edSEnrico Granata 20559fe00e52SEnrico Granata if (m_options.m_class_name.empty()) 20569fe00e52SEnrico Granata { 2057223383edSEnrico Granata if (m_options.m_funct_name.empty()) 2058223383edSEnrico Granata { 205944d93782SGreg Clayton m_interpreter.GetPythonCommandsFromIOHandler(" ", // Prompt 206044d93782SGreg Clayton *this, // IOHandlerDelegate 206144d93782SGreg Clayton true, // Run IOHandler in async mode 20626e3d8e7fSEugene Zelenko nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 2063223383edSEnrico Granata } 2064223383edSEnrico Granata else 2065223383edSEnrico Granata { 20660a305db7SEnrico Granata CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 206744d93782SGreg Clayton m_cmd_name, 20680a305db7SEnrico Granata m_options.m_funct_name, 2069735152e3SEnrico Granata m_options.m_short_help, 207044d93782SGreg Clayton m_synchronicity)); 207144d93782SGreg Clayton if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 2072223383edSEnrico Granata { 2073223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 2074223383edSEnrico Granata } 2075223383edSEnrico Granata else 2076223383edSEnrico Granata { 2077223383edSEnrico Granata result.AppendError("cannot add command"); 2078223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2079223383edSEnrico Granata } 2080223383edSEnrico Granata } 20819fe00e52SEnrico Granata } 20829fe00e52SEnrico Granata else 20839fe00e52SEnrico Granata { 20849fe00e52SEnrico Granata ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter(); 20859fe00e52SEnrico Granata if (!interpreter) 20869fe00e52SEnrico Granata { 20879fe00e52SEnrico Granata result.AppendError("cannot find ScriptInterpreter"); 20889fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 20899fe00e52SEnrico Granata return false; 20909fe00e52SEnrico Granata } 20919fe00e52SEnrico Granata 20929fe00e52SEnrico Granata auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str()); 20939fe00e52SEnrico Granata if (!cmd_obj_sp) 20949fe00e52SEnrico Granata { 20959fe00e52SEnrico Granata result.AppendError("cannot create helper object"); 20969fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 20979fe00e52SEnrico Granata return false; 20989fe00e52SEnrico Granata } 20999fe00e52SEnrico Granata 21009fe00e52SEnrico Granata CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter, 21019fe00e52SEnrico Granata m_cmd_name, 21029fe00e52SEnrico Granata cmd_obj_sp, 21039fe00e52SEnrico Granata m_synchronicity)); 21049fe00e52SEnrico Granata if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 21059fe00e52SEnrico Granata { 21069fe00e52SEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 21079fe00e52SEnrico Granata } 21089fe00e52SEnrico Granata else 21099fe00e52SEnrico Granata { 21109fe00e52SEnrico Granata result.AppendError("cannot add command"); 21119fe00e52SEnrico Granata result.SetStatus (eReturnStatusFailed); 21129fe00e52SEnrico Granata } 21139fe00e52SEnrico Granata } 2114223383edSEnrico Granata 2115223383edSEnrico Granata return result.Succeeded(); 2116223383edSEnrico Granata } 21175a988416SJim Ingham 21185a988416SJim Ingham CommandOptions m_options; 211944d93782SGreg Clayton std::string m_cmd_name; 2120735152e3SEnrico Granata std::string m_short_help; 212144d93782SGreg Clayton ScriptedCommandSynchronicity m_synchronicity; 2122223383edSEnrico Granata }; 2123223383edSEnrico Granata 21240a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] = 21250a305db7SEnrico Granata { 21260a305db7SEnrico Granata { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 21270a305db7SEnrico Granata { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 21280a305db7SEnrico Granata { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 21296e3d8e7fSEugene Zelenko { 0, nullptr, nullptr } 21300a305db7SEnrico Granata }; 21310a305db7SEnrico Granata 2132223383edSEnrico Granata OptionDefinition 2133223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 2134223383edSEnrico Granata { 21356e3d8e7fSEugene 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."}, 21366e3d8e7fSEugene 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."}, 21376e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command."}, 21386e3d8e7fSEugene 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."}, 21396e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 2140223383edSEnrico Granata }; 2141223383edSEnrico Granata 2142223383edSEnrico Granata //------------------------------------------------------------------------- 2143223383edSEnrico Granata // CommandObjectCommandsScriptList 2144223383edSEnrico Granata //------------------------------------------------------------------------- 2145223383edSEnrico Granata 21465a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed 2147223383edSEnrico Granata { 2148223383edSEnrico Granata public: 2149223383edSEnrico Granata CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 21505a988416SJim Ingham CommandObjectParsed(interpreter, 2151223383edSEnrico Granata "command script list", 2152223383edSEnrico Granata "List defined scripted commands.", 21536e3d8e7fSEugene Zelenko nullptr) 2154223383edSEnrico Granata { 2155223383edSEnrico Granata } 2156223383edSEnrico Granata 21576e3d8e7fSEugene Zelenko ~CommandObjectCommandsScriptList() override = default; 2158223383edSEnrico Granata 2159223383edSEnrico Granata bool 216013d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 2161223383edSEnrico Granata { 2162223383edSEnrico Granata m_interpreter.GetHelp(result, 2163223383edSEnrico Granata CommandInterpreter::eCommandTypesUserDef); 2164223383edSEnrico Granata 2165223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2166223383edSEnrico Granata 2167223383edSEnrico Granata return true; 2168223383edSEnrico Granata } 2169223383edSEnrico Granata }; 2170223383edSEnrico Granata 2171223383edSEnrico Granata //------------------------------------------------------------------------- 2172223383edSEnrico Granata // CommandObjectCommandsScriptClear 2173223383edSEnrico Granata //------------------------------------------------------------------------- 2174223383edSEnrico Granata 21755a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed 2176223383edSEnrico Granata { 2177223383edSEnrico Granata public: 2178223383edSEnrico Granata CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 21795a988416SJim Ingham CommandObjectParsed(interpreter, 2180223383edSEnrico Granata "command script clear", 2181223383edSEnrico Granata "Delete all scripted commands.", 21826e3d8e7fSEugene Zelenko nullptr) 2183223383edSEnrico Granata { 2184223383edSEnrico Granata } 2185223383edSEnrico Granata 21866e3d8e7fSEugene Zelenko ~CommandObjectCommandsScriptClear() override = default; 2187223383edSEnrico Granata 21885a988416SJim Ingham protected: 2189223383edSEnrico Granata bool 219013d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 2191223383edSEnrico Granata { 2192223383edSEnrico Granata m_interpreter.RemoveAllUser(); 2193223383edSEnrico Granata 2194223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2195223383edSEnrico Granata 2196223383edSEnrico Granata return true; 2197223383edSEnrico Granata } 2198223383edSEnrico Granata }; 2199223383edSEnrico Granata 2200223383edSEnrico Granata //------------------------------------------------------------------------- 2201223383edSEnrico Granata // CommandObjectCommandsScriptDelete 2202223383edSEnrico Granata //------------------------------------------------------------------------- 2203223383edSEnrico Granata 22045a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed 2205223383edSEnrico Granata { 2206223383edSEnrico Granata public: 2207223383edSEnrico Granata CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 22085a988416SJim Ingham CommandObjectParsed(interpreter, 2209223383edSEnrico Granata "command script delete", 2210223383edSEnrico Granata "Delete a scripted command.", 22116e3d8e7fSEugene Zelenko nullptr) 2212223383edSEnrico Granata { 2213223383edSEnrico Granata CommandArgumentEntry arg1; 2214223383edSEnrico Granata CommandArgumentData cmd_arg; 2215223383edSEnrico Granata 2216223383edSEnrico Granata // Define the first (and only) variant of this arg. 2217223383edSEnrico Granata cmd_arg.arg_type = eArgTypeCommandName; 2218223383edSEnrico Granata cmd_arg.arg_repetition = eArgRepeatPlain; 2219223383edSEnrico Granata 2220223383edSEnrico Granata // There is only one variant this argument could be; put it into the argument entry. 2221223383edSEnrico Granata arg1.push_back (cmd_arg); 2222223383edSEnrico Granata 2223223383edSEnrico Granata // Push the data for the first argument into the m_arguments vector. 2224223383edSEnrico Granata m_arguments.push_back (arg1); 2225223383edSEnrico Granata } 2226223383edSEnrico Granata 22276e3d8e7fSEugene Zelenko ~CommandObjectCommandsScriptDelete() override = default; 2228223383edSEnrico Granata 22295a988416SJim Ingham protected: 2230223383edSEnrico Granata bool 223113d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 2232223383edSEnrico Granata { 2233223383edSEnrico Granata 22345a988416SJim Ingham size_t argc = command.GetArgumentCount(); 2235223383edSEnrico Granata 2236223383edSEnrico Granata if (argc != 1) 2237223383edSEnrico Granata { 2238223383edSEnrico Granata result.AppendError ("'command script delete' requires one argument"); 2239223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2240223383edSEnrico Granata return false; 2241223383edSEnrico Granata } 2242223383edSEnrico Granata 22435a988416SJim Ingham const char* cmd_name = command.GetArgumentAtIndex(0); 2244223383edSEnrico Granata 2245223383edSEnrico Granata if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 2246223383edSEnrico Granata { 2247223383edSEnrico Granata m_interpreter.RemoveUser(cmd_name); 2248223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2249223383edSEnrico Granata } 2250223383edSEnrico Granata else 2251223383edSEnrico Granata { 2252223383edSEnrico Granata result.AppendErrorWithFormat ("command %s not found", cmd_name); 2253223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2254223383edSEnrico Granata } 2255223383edSEnrico Granata 2256223383edSEnrico Granata return result.Succeeded(); 2257223383edSEnrico Granata } 2258223383edSEnrico Granata }; 2259223383edSEnrico Granata 2260223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript 2261223383edSEnrico Granata 2262223383edSEnrico Granata //------------------------------------------------------------------------- 2263223383edSEnrico Granata // CommandObjectMultiwordCommandsScript 2264223383edSEnrico Granata //------------------------------------------------------------------------- 2265223383edSEnrico Granata 2266223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 2267223383edSEnrico Granata { 2268223383edSEnrico Granata public: 2269223383edSEnrico Granata CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 2270223383edSEnrico Granata CommandObjectMultiword (interpreter, 2271223383edSEnrico Granata "command script", 2272223383edSEnrico Granata "A set of commands for managing or customizing script commands.", 2273223383edSEnrico Granata "command script <subcommand> [<subcommand-options>]") 2274223383edSEnrico Granata { 2275223383edSEnrico Granata LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 2276223383edSEnrico Granata LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 2277223383edSEnrico Granata LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 2278223383edSEnrico Granata LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 2279a9dbf432SEnrico Granata LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 2280223383edSEnrico Granata } 2281223383edSEnrico Granata 22826e3d8e7fSEugene Zelenko ~CommandObjectMultiwordCommandsScript() override = default; 2283223383edSEnrico Granata }; 2284223383edSEnrico Granata 2285ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands 2286ebc09c36SJim Ingham 2287ebc09c36SJim Ingham //------------------------------------------------------------------------- 2288ebc09c36SJim Ingham // CommandObjectMultiwordCommands 2289ebc09c36SJim Ingham //------------------------------------------------------------------------- 2290ebc09c36SJim Ingham 2291ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 2292a7015092SGreg Clayton CommandObjectMultiword (interpreter, 22930e5e5a79SGreg Clayton "command", 22943f4c09c1SCaroline Tice "A set of commands for managing or customizing the debugger commands.", 22950e5e5a79SGreg Clayton "command <subcommand> [<subcommand-options>]") 2296ebc09c36SJim Ingham { 2297a7015092SGreg Clayton LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 2298a7015092SGreg Clayton LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 2299a7015092SGreg Clayton LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 2300b547278cSGreg Clayton LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter))); 2301de164aaaSGreg Clayton LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 2302a5a97ebeSJim Ingham LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 2303223383edSEnrico Granata LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 2304ebc09c36SJim Ingham } 2305ebc09c36SJim Ingham 23066e3d8e7fSEugene Zelenko CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands() = default; 2307