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