xref: /freebsd-src/contrib/llvm-project/lldb/source/Commands/CommandObjectScripting.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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