[Lldb-commits] [lldb] c47e0e2 - [lldb-vscode] Use libOption with tablegen to parse command line options.
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Fri Feb 21 08:15:18 PST 2020
Author: Ivan Hernandez
Date: 2020-02-21T08:15:06-08:00
New Revision: c47e0e2d37d32ec56c760f1a2c9740d69c370b57
URL: https://github.com/llvm/llvm-project/commit/c47e0e2d37d32ec56c760f1a2c9740d69c370b57
DIFF: https://github.com/llvm/llvm-project/commit/c47e0e2d37d32ec56c760f1a2c9740d69c370b57.diff
LOG: [lldb-vscode] Use libOption with tablegen to parse command line options.
This change will bring lldb-vscode in line with how several other llvm
tools process command line arguments and make it easier to add future
options.
Differential revision: https://reviews.llvm.org/D74798
Added:
lldb/test/Shell/VSCode/TestOptions.test
lldb/tools/lldb-vscode/Options.td
Modified:
lldb/test/Shell/helper/toolchain.py
lldb/tools/lldb-vscode/CMakeLists.txt
lldb/tools/lldb-vscode/lldb-vscode.cpp
Removed:
################################################################################
diff --git a/lldb/test/Shell/VSCode/TestOptions.test b/lldb/test/Shell/VSCode/TestOptions.test
new file mode 100644
index 000000000000..05588ecd9df6
--- /dev/null
+++ b/lldb/test/Shell/VSCode/TestOptions.test
@@ -0,0 +1,8 @@
+# RUN: lldb-vscode --help | FileCheck %s
+# CHECK: -g
+# CHECK: --help
+# CHECK: -h
+# CHECK: --port
+# CHECK: -p
+# CHECK: --wait-for-debugger
+
diff --git a/lldb/test/Shell/helper/toolchain.py b/lldb/test/Shell/helper/toolchain.py
index a5ccfd8b8898..a4bd9f20feb1 100644
--- a/lldb/test/Shell/helper/toolchain.py
+++ b/lldb/test/Shell/helper/toolchain.py
@@ -62,6 +62,7 @@ def use_lldb_substitutions(config):
unresolved='ignore'),
'lldb-test',
'lldb-instr',
+ 'lldb-vscode',
ToolSubst('%build',
command="'" + sys.executable + "'",
extra_args=build_script_args)
diff --git a/lldb/tools/lldb-vscode/CMakeLists.txt b/lldb/tools/lldb-vscode/CMakeLists.txt
index b527addb6ba9..edf0aaa78d97 100644
--- a/lldb/tools/lldb-vscode/CMakeLists.txt
+++ b/lldb/tools/lldb-vscode/CMakeLists.txt
@@ -20,6 +20,9 @@ endif()
# We need to include the llvm components we depend on manually, as liblldb does
# not re-export those.
set(LLVM_LINK_COMPONENTS Support)
+set(LLVM_TARGET_DEFINITIONS Options.td)
+tablegen(LLVM Options.inc -gen-opt-parser-defs)
+add_public_tablegen_target(LLDBVSCodeOptionsTableGen)
add_lldb_tool(lldb-vscode
lldb-vscode.cpp
BreakpointBase.cpp
@@ -37,6 +40,7 @@ add_lldb_tool(lldb-vscode
${extra_libs}
LINK_COMPONENTS
+ Option
Support
)
diff --git a/lldb/tools/lldb-vscode/Options.td b/lldb/tools/lldb-vscode/Options.td
new file mode 100644
index 000000000000..87cfb5199b42
--- /dev/null
+++ b/lldb/tools/lldb-vscode/Options.td
@@ -0,0 +1,25 @@
+include "llvm/Option/OptParser.td"
+
+class F<string name>: Flag<["--", "-"], name>;
+class S<string name>: Separate<["--", "-"], name>;
+class R<list<string> prefixes, string name>
+ : Option<prefixes, name, KIND_REMAINING_ARGS>;
+
+def help: F<"help">,
+ HelpText<"Prints out the usage information for the LLDB VSCode tool.">;
+def: Flag<["-"], "h">,
+ Alias<help>,
+ HelpText<"Alias for --help">;
+
+def wait_for_debugger: F<"wait-for-debugger">,
+ HelpText<"Pause the program at startup.">;
+def: Flag<["-"], "g">,
+ Alias<wait_for_debugger>,
+ HelpText<"Alias for --wait-for-debugger">;
+
+def port: Separate<["--", "-"], "port">,
+ MetaVarName<"<port>">,
+ HelpText<"Communicate with the lldb-vscode tool over the defined port.">;
+def: Separate<["-"], "p">,
+ Alias<port>,
+ HelpText<"Alias for --port">;
diff --git a/lldb/tools/lldb-vscode/lldb-vscode.cpp b/lldb/tools/lldb-vscode/lldb-vscode.cpp
index 29aa2f4e55d9..080ef5b40c01 100644
--- a/lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ b/lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -41,8 +41,12 @@
#include <thread>
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "JSONUtils.h"
@@ -64,6 +68,33 @@ constexpr const char *dev_null_path = "/dev/null";
using namespace lldb_vscode;
namespace {
+enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ OPT_##ID,
+#include "Options.inc"
+#undef OPTION
+};
+
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#include "Options.inc"
+#undef PREFIX
+
+static const llvm::opt::OptTable::Info InfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ {PREFIX, NAME, HELPTEXT, \
+ METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
+ PARAM, FLAGS, OPT_##GROUP, \
+ OPT_##ALIAS, ALIASARGS, VALUES},
+#include "Options.inc"
+#undef OPTION
+};
+class LLDBVSCodeOptTable : public llvm::opt::OptTable {
+public:
+ LLDBVSCodeOptTable() : OptTable(InfoTable, true) {}
+};
typedef void (*RequestCallback)(const llvm::json::Object &command);
@@ -2719,31 +2750,69 @@ const std::map<std::string, RequestCallback> &GetRequestHandlers() {
} // anonymous namespace
+static void printHelp(LLDBVSCodeOptTable &table, llvm::StringRef tool_name) {
+ std::string usage_str = tool_name.str() + "options";
+ table.PrintHelp(llvm::outs(), usage_str.c_str(), "LLDB VSCode", false);
+
+ std::string examples = R"___(
+EXAMPLES:
+ The debug adapter can be started in two modes.
+
+ Running lldb-vscode without any arguments will start communicating with the
+ parent over stdio. Passing a port number causes lldb-vscode to start listening
+ for connections on that port.
+
+ lldb-vscode -p <port>
+
+ Passing --wait-for-debugger will pause the process at startup and wait for a
+ debugger to attach to the process.
+
+ lldb-vscode -g
+ )___";
+ llvm::outs() << examples;
+}
+
int main(int argc, char *argv[]) {
// Initialize LLDB first before we do anything.
lldb::SBDebugger::Initialize();
- if (argc == 2) {
- const char *arg = argv[1];
+ int portno = -1;
+
+ LLDBVSCodeOptTable T;
+ unsigned MAI, MAC;
+ llvm::ArrayRef<const char *> ArgsArr = llvm::makeArrayRef(argv + 1, argc);
+ llvm::opt::InputArgList input_args = T.ParseArgs(ArgsArr, MAI, MAC);
+
+ if (input_args.hasArg(OPT_help)) {
+ printHelp(T, llvm::sys::path::filename(argv[0]));
+ return 0;
+ }
+
+ if (auto *arg = input_args.getLastArg(OPT_port)) {
+ auto optarg = arg->getValue();
+ char *remainder;
+ portno = strtol(optarg, &remainder, 0);
+ if (remainder == optarg || *remainder != '\0') {
+ fprintf(stderr, "'%s' is not a valid port number.\n", optarg);
+ exit(1);
+ }
+ }
+
#if !defined(_WIN32)
- if (strcmp(arg, "-g") == 0) {
- printf("Paused waiting for debugger to attach (pid = %i)...\n", getpid());
- pause();
- } else {
-#else
- {
+ if (input_args.hasArg(OPT_wait_for_debugger)) {
+ printf("Paused waiting for debugger to attach (pid = %i)...\n", getpid());
+ pause();
+ }
#endif
- int portno = atoi(arg);
- printf("Listening on port %i...\n", portno);
- SOCKET socket_fd = AcceptConnection(portno);
- if (socket_fd >= 0) {
- g_vsc.input.descriptor = StreamDescriptor::from_socket(socket_fd, true);
- g_vsc.output.descriptor =
- StreamDescriptor::from_socket(socket_fd, false);
- } else {
- exit(1);
- }
+ if (portno != -1) {
+ printf("Listening on port %i...\n", portno);
+ SOCKET socket_fd = AcceptConnection(portno);
+ if (socket_fd >= 0) {
+ g_vsc.input.descriptor = StreamDescriptor::from_socket(socket_fd, true);
+ g_vsc.output.descriptor = StreamDescriptor::from_socket(socket_fd, false);
+ } else {
+ exit(1);
}
} else {
g_vsc.input.descriptor = StreamDescriptor::from_file(fileno(stdin), false);
More information about the lldb-commits
mailing list