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