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