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