brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 4e7aa02 Raw
164 lines · cpp
1//===-- CommandPlugins.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "CommandPlugins.h"10#include "Handler/ResponseHandler.h"11#include "JSONUtils.h"12#include "lldb/API/SBStream.h"13 14using namespace lldb_dap;15 16bool StartDebuggingCommand::DoExecute(lldb::SBDebugger debugger, char **command,17                                      lldb::SBCommandReturnObject &result) {18  // Command format like: `start-debugging <launch|attach> <configuration>`19  if (!command) {20    result.SetError("Invalid use of start-debugging, expected format "21                    "`start-debugging <launch|attach> <configuration>`.");22    return false;23  }24 25  if (!command[0] || llvm::StringRef(command[0]).empty()) {26    result.SetError("start-debugging request type missing.");27    return false;28  }29 30  if (!command[1] || llvm::StringRef(command[1]).empty()) {31    result.SetError("start-debugging debug configuration missing.");32    return false;33  }34 35  llvm::StringRef request{command[0]};36  std::string raw_configuration{command[1]};37 38  llvm::Expected<llvm::json::Value> configuration =39      llvm::json::parse(raw_configuration);40 41  if (!configuration) {42    llvm::Error err = configuration.takeError();43    std::string msg = "Failed to parse json configuration: " +44                      llvm::toString(std::move(err)) + "\n\n" +45                      raw_configuration;46    result.SetError(msg.c_str());47    return false;48  }49 50  dap.SendReverseRequest<LogFailureResponseHandler>(51      "startDebugging",52      llvm::json::Object{{"request", request},53                         {"configuration", std::move(*configuration)}});54 55  result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);56 57  return true;58}59 60bool ReplModeCommand::DoExecute(lldb::SBDebugger debugger, char **command,61                                lldb::SBCommandReturnObject &result) {62  // Command format like: `repl-mode <variable|command|auto>?`63  // If a new mode is not specified report the current mode.64  if (!command || llvm::StringRef(command[0]).empty()) {65    std::string mode;66    switch (dap.repl_mode) {67    case ReplMode::Variable:68      mode = "variable";69      break;70    case ReplMode::Command:71      mode = "command";72      break;73    case ReplMode::Auto:74      mode = "auto";75      break;76    }77 78    result.Printf("lldb-dap repl-mode %s.\n", mode.c_str());79    result.SetStatus(lldb::eReturnStatusSuccessFinishResult);80 81    return true;82  }83 84  llvm::StringRef new_mode{command[0]};85 86  if (new_mode == "variable") {87    dap.repl_mode = ReplMode::Variable;88  } else if (new_mode == "command") {89    dap.repl_mode = ReplMode::Command;90  } else if (new_mode == "auto") {91    dap.repl_mode = ReplMode::Auto;92  } else {93    lldb::SBStream error_message;94    error_message.Printf("Invalid repl-mode '%s'. Expected one of 'variable', "95                         "'command' or 'auto'.\n",96                         new_mode.data());97    result.SetError(error_message.GetData());98    return false;99  }100 101  result.Printf("lldb-dap repl-mode %s set.\n", new_mode.data());102  result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);103  return true;104}105 106/// Sends a DAP event with an optional body.107///108/// https://code.visualstudio.com/api/references/vscode-api#debug.onDidReceiveDebugSessionCustomEvent109bool SendEventCommand::DoExecute(lldb::SBDebugger debugger, char **command,110                                 lldb::SBCommandReturnObject &result) {111  // Command format like: `send-event <name> <body>?`112  if (!command || !command[0] || llvm::StringRef(command[0]).empty()) {113    result.SetError("Not enough arguments found, expected format "114                    "`lldb-dap send-event <name> <body>?`.");115    return false;116  }117 118  llvm::StringRef name{command[0]};119  // Events that are stateful and should be handled by lldb-dap internally.120  const std::array internal_events{"breakpoint", "capabilities", "continued",121                                   "exited",     "initialize",   "loadedSource",122                                   "module",     "process",      "stopped",123                                   "terminated", "thread"};124  if (llvm::is_contained(internal_events, name)) {125    std::string msg =126        llvm::formatv("Invalid use of lldb-dap send-event, event \"{0}\" "127                      "should be handled by lldb-dap internally.",128                      name)129            .str();130    result.SetError(msg.c_str());131    return false;132  }133 134  llvm::json::Object event(CreateEventObject(name));135 136  if (command[1] && !llvm::StringRef(command[1]).empty()) {137    // See if we have unused arguments.138    if (command[2]) {139      result.SetError(140          "Additional arguments found, expected `lldb-dap send-event "141          "<name> <body>?`.");142      return false;143    }144 145    llvm::StringRef raw_body{command[1]};146 147    llvm::Expected<llvm::json::Value> body = llvm::json::parse(raw_body);148 149    if (!body) {150      llvm::Error err = body.takeError();151      std::string msg = "Failed to parse custom event body: " +152                        llvm::toString(std::move(err));153      result.SetError(msg.c_str());154      return false;155    }156 157    event.try_emplace("body", std::move(*body));158  }159 160  dap.SendJSON(llvm::json::Value(std::move(event)));161  result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);162  return true;163}164