1*0fca6ea1SDimitry Andric //===-- CommandObjectScripting.cpp ----------------------------------------===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric 9*0fca6ea1SDimitry Andric #include "CommandObjectScripting.h" 10*0fca6ea1SDimitry Andric #include "lldb/Core/Debugger.h" 11*0fca6ea1SDimitry Andric #include "lldb/DataFormatters/DataVisualization.h" 12*0fca6ea1SDimitry Andric #include "lldb/Host/Config.h" 13*0fca6ea1SDimitry Andric #include "lldb/Host/OptionParser.h" 14*0fca6ea1SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h" 15*0fca6ea1SDimitry Andric #include "lldb/Interpreter/CommandOptionArgumentTable.h" 16*0fca6ea1SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h" 17*0fca6ea1SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h" 18*0fca6ea1SDimitry Andric #include "lldb/Interpreter/ScriptInterpreter.h" 19*0fca6ea1SDimitry Andric #include "lldb/Utility/Args.h" 20*0fca6ea1SDimitry Andric 21*0fca6ea1SDimitry Andric using namespace lldb; 22*0fca6ea1SDimitry Andric using namespace lldb_private; 23*0fca6ea1SDimitry Andric 24*0fca6ea1SDimitry Andric #define LLDB_OPTIONS_scripting_run 25*0fca6ea1SDimitry Andric #include "CommandOptions.inc" 26*0fca6ea1SDimitry Andric 27*0fca6ea1SDimitry Andric class CommandObjectScriptingRun : public CommandObjectRaw { 28*0fca6ea1SDimitry Andric public: 29*0fca6ea1SDimitry Andric CommandObjectScriptingRun(CommandInterpreter &interpreter) 30*0fca6ea1SDimitry Andric : CommandObjectRaw( 31*0fca6ea1SDimitry Andric interpreter, "scripting run", 32*0fca6ea1SDimitry Andric "Invoke the script interpreter with provided code and display any " 33*0fca6ea1SDimitry Andric "results. Start the interactive interpreter if no code is " 34*0fca6ea1SDimitry Andric "supplied.", 35*0fca6ea1SDimitry Andric "scripting run [--language <scripting-language> --] " 36*0fca6ea1SDimitry Andric "[<script-code>]") {} 37*0fca6ea1SDimitry Andric 38*0fca6ea1SDimitry Andric ~CommandObjectScriptingRun() override = default; 39*0fca6ea1SDimitry Andric 40*0fca6ea1SDimitry Andric Options *GetOptions() override { return &m_options; } 41*0fca6ea1SDimitry Andric 42*0fca6ea1SDimitry Andric class CommandOptions : public Options { 43*0fca6ea1SDimitry Andric public: 44*0fca6ea1SDimitry Andric CommandOptions() = default; 45*0fca6ea1SDimitry Andric ~CommandOptions() override = default; 46*0fca6ea1SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 47*0fca6ea1SDimitry Andric ExecutionContext *execution_context) override { 48*0fca6ea1SDimitry Andric Status error; 49*0fca6ea1SDimitry Andric const int short_option = m_getopt_table[option_idx].val; 50*0fca6ea1SDimitry Andric 51*0fca6ea1SDimitry Andric switch (short_option) { 52*0fca6ea1SDimitry Andric case 'l': 53*0fca6ea1SDimitry Andric language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum( 54*0fca6ea1SDimitry Andric option_arg, GetDefinitions()[option_idx].enum_values, 55*0fca6ea1SDimitry Andric eScriptLanguageNone, error); 56*0fca6ea1SDimitry Andric if (!error.Success()) 57*0fca6ea1SDimitry Andric error.SetErrorStringWithFormat("unrecognized value for language '%s'", 58*0fca6ea1SDimitry Andric option_arg.str().c_str()); 59*0fca6ea1SDimitry Andric break; 60*0fca6ea1SDimitry Andric default: 61*0fca6ea1SDimitry Andric llvm_unreachable("Unimplemented option"); 62*0fca6ea1SDimitry Andric } 63*0fca6ea1SDimitry Andric 64*0fca6ea1SDimitry Andric return error; 65*0fca6ea1SDimitry Andric } 66*0fca6ea1SDimitry Andric 67*0fca6ea1SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override { 68*0fca6ea1SDimitry Andric language = lldb::eScriptLanguageNone; 69*0fca6ea1SDimitry Andric } 70*0fca6ea1SDimitry Andric 71*0fca6ea1SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 72*0fca6ea1SDimitry Andric return llvm::ArrayRef(g_scripting_run_options); 73*0fca6ea1SDimitry Andric } 74*0fca6ea1SDimitry Andric 75*0fca6ea1SDimitry Andric lldb::ScriptLanguage language = lldb::eScriptLanguageNone; 76*0fca6ea1SDimitry Andric }; 77*0fca6ea1SDimitry Andric 78*0fca6ea1SDimitry Andric protected: 79*0fca6ea1SDimitry Andric void DoExecute(llvm::StringRef command, 80*0fca6ea1SDimitry Andric CommandReturnObject &result) override { 81*0fca6ea1SDimitry Andric // Try parsing the language option but when the command contains a raw part 82*0fca6ea1SDimitry Andric // separated by the -- delimiter. 83*0fca6ea1SDimitry Andric OptionsWithRaw raw_args(command); 84*0fca6ea1SDimitry Andric if (raw_args.HasArgs()) { 85*0fca6ea1SDimitry Andric if (!ParseOptions(raw_args.GetArgs(), result)) 86*0fca6ea1SDimitry Andric return; 87*0fca6ea1SDimitry Andric command = raw_args.GetRawPart(); 88*0fca6ea1SDimitry Andric } 89*0fca6ea1SDimitry Andric 90*0fca6ea1SDimitry Andric lldb::ScriptLanguage language = 91*0fca6ea1SDimitry Andric (m_options.language == lldb::eScriptLanguageNone) 92*0fca6ea1SDimitry Andric ? m_interpreter.GetDebugger().GetScriptLanguage() 93*0fca6ea1SDimitry Andric : m_options.language; 94*0fca6ea1SDimitry Andric 95*0fca6ea1SDimitry Andric if (language == lldb::eScriptLanguageNone) { 96*0fca6ea1SDimitry Andric result.AppendError( 97*0fca6ea1SDimitry Andric "the script-lang setting is set to none - scripting not available"); 98*0fca6ea1SDimitry Andric return; 99*0fca6ea1SDimitry Andric } 100*0fca6ea1SDimitry Andric 101*0fca6ea1SDimitry Andric ScriptInterpreter *script_interpreter = 102*0fca6ea1SDimitry Andric GetDebugger().GetScriptInterpreter(true, language); 103*0fca6ea1SDimitry Andric 104*0fca6ea1SDimitry Andric if (script_interpreter == nullptr) { 105*0fca6ea1SDimitry Andric result.AppendError("no script interpreter"); 106*0fca6ea1SDimitry Andric return; 107*0fca6ea1SDimitry Andric } 108*0fca6ea1SDimitry Andric 109*0fca6ea1SDimitry Andric // Script might change Python code we use for formatting. Make sure we keep 110*0fca6ea1SDimitry Andric // up to date with it. 111*0fca6ea1SDimitry Andric DataVisualization::ForceUpdate(); 112*0fca6ea1SDimitry Andric 113*0fca6ea1SDimitry Andric if (command.empty()) { 114*0fca6ea1SDimitry Andric script_interpreter->ExecuteInterpreterLoop(); 115*0fca6ea1SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult); 116*0fca6ea1SDimitry Andric return; 117*0fca6ea1SDimitry Andric } 118*0fca6ea1SDimitry Andric 119*0fca6ea1SDimitry Andric // We can do better when reporting the status of one-liner script execution. 120*0fca6ea1SDimitry Andric if (script_interpreter->ExecuteOneLine(command, &result)) 121*0fca6ea1SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult); 122*0fca6ea1SDimitry Andric else 123*0fca6ea1SDimitry Andric result.SetStatus(eReturnStatusFailed); 124*0fca6ea1SDimitry Andric } 125*0fca6ea1SDimitry Andric 126*0fca6ea1SDimitry Andric private: 127*0fca6ea1SDimitry Andric CommandOptions m_options; 128*0fca6ea1SDimitry Andric }; 129*0fca6ea1SDimitry Andric 130*0fca6ea1SDimitry Andric #pragma mark CommandObjectMultiwordScripting 131*0fca6ea1SDimitry Andric 132*0fca6ea1SDimitry Andric // CommandObjectMultiwordScripting 133*0fca6ea1SDimitry Andric 134*0fca6ea1SDimitry Andric CommandObjectMultiwordScripting::CommandObjectMultiwordScripting( 135*0fca6ea1SDimitry Andric CommandInterpreter &interpreter) 136*0fca6ea1SDimitry Andric : CommandObjectMultiword( 137*0fca6ea1SDimitry Andric interpreter, "scripting", 138*0fca6ea1SDimitry Andric "Commands for operating on the scripting functionnalities.", 139*0fca6ea1SDimitry Andric "scripting <subcommand> [<subcommand-options>]") { 140*0fca6ea1SDimitry Andric LoadSubCommand("run", 141*0fca6ea1SDimitry Andric CommandObjectSP(new CommandObjectScriptingRun(interpreter))); 142*0fca6ea1SDimitry Andric } 143*0fca6ea1SDimitry Andric 144*0fca6ea1SDimitry Andric CommandObjectMultiwordScripting::~CommandObjectMultiwordScripting() = default; 145