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