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