From d6414f46b015bd065fbfa20084855b1ba8c0a83d Mon Sep 17 00:00:00 2001 From: John Parent Date: Mon, 1 Jun 2026 11:16:04 -0400 Subject: [PATCH 1/6] tools: allow help and argless invocation to invoke underlying tool help Signed-off-by: John Parent --- src/ld.cxx | 5 +++++ src/linker_invocation.cxx | 11 ++++++++++- src/linker_invocation.h | 2 ++ src/main.cxx | 9 +++++---- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/ld.cxx b/src/ld.cxx index c3fbc76..b6472ac 100644 --- a/src/ld.cxx +++ b/src/ld.cxx @@ -47,6 +47,11 @@ DWORD LdInvocation::InvokeToolchain() { } catch (const FileIOError& e) { return ExitConditions::FILE_IO_FAILURE; } + // If there are no arguments (or the argument is just "/?") + // just print help and return + if(this->inputs.empty() || link_run.isHelp()) { + return ToolChainInvocation::InvokeToolchain(); + } try { link_run.makeRsp(); diff --git a/src/linker_invocation.cxx b/src/linker_invocation.cxx index e7b7b4f..07fe2e7 100644 --- a/src/linker_invocation.cxx +++ b/src/linker_invocation.cxx @@ -78,6 +78,9 @@ void LinkerInvocation::ProcessTokens(const std::string &normal_token, const std: this->piped_args_.end()) { this->piped_args_.at(normal_token).emplace_back(token); } + else if (normal_token == "?") { + this->is_help_ = true; + } } @@ -113,7 +116,9 @@ void LinkerInvocation::Parse() { // /NAME // if no /NAME // first input file (post rc expansion) - + if (this->is_help_ || this->input_files_.empty()) { + return; + } this->processDefFile(); std::string const ext = this->is_exe_ ? ".exe" : ".dll"; if (this->output_.empty()) { @@ -318,3 +323,7 @@ std::string LinkerInvocation::get_mangled_out() const { bool LinkerInvocation::IsExeLink() const { return this->is_exe_ || endswith(this->get_out(), ".exe"); } + +bool LinkerInvocation::isHelp() const { + return this->is_help_; +} diff --git a/src/linker_invocation.h b/src/linker_invocation.h index 2a41639..b0f6dba 100644 --- a/src/linker_invocation.h +++ b/src/linker_invocation.h @@ -24,6 +24,7 @@ class LinkerInvocation { StrList get_input_files() const; std::string get_lib_link_args() const; bool makeRsp(); + bool isHelp() const; private: void ProcessTokens(const std::string &normal_token, const std::string& token); @@ -40,6 +41,7 @@ class LinkerInvocation { StrList input_files_; StrList tokens_; bool is_exe_; + bool is_help_; std::map piped_args_ = { {"export", {}}, {"include", {}}, {"libpath", {}}, {"ltcg", {}}, {"machine", {}}, {"nodefaultlib", {}}, diff --git a/src/main.cxx b/src/main.cxx index 7fa7708..c29ab21 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -19,11 +19,12 @@ #include int main(int argc, const char* argv[]) { - - if (CheckAndPrintHelp(argv, argc)) { + const bool is_relocate = IsRelocate(argv[0]); + const bool is_report = IsReport(argv[0]); + if ((is_relocate || is_report) && CheckAndPrintHelp(argv, argc)) { return 0; } - if (IsRelocate(argv[0])) { + if (is_relocate) { std::map patch_args = ParseRelocate(argv + 1, argc - 1); if (patch_args.empty()) { @@ -90,7 +91,7 @@ int main(int argc, const char* argv[]) { std::cerr << "Library rename failed\n"; return ExitConditions::RENAME_FAILURE; } - } else if (IsReport(argv[0])) { + } else if (is_report) { std::map report_args = ParseReport(argc - 1, argv + 1); if (report_args.empty()) { From ae2dbfa601fb7f42d76997fadfc81840ec7c30be Mon Sep 17 00:00:00 2001 From: John Parent Date: Mon, 1 Jun 2026 11:24:52 -0400 Subject: [PATCH 2/6] preserve --help option Signed-off-by: John Parent --- src/commandline.cxx | 6 +++--- src/commandline.h | 2 +- src/main.cxx | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/commandline.cxx b/src/commandline.cxx index df2bff1..9d977e0 100644 --- a/src/commandline.cxx +++ b/src/commandline.cxx @@ -178,11 +178,11 @@ std::map ParseReport(int argc, const char** args) { return opts; } -bool CheckAndPrintHelp(const char** arg, int argc) { - if (argc < 2) { +bool CheckAndPrintHelp(const char** arg, bool no_args, bool is_report, bool is_relocate) { + if (no_args && (is_relocate || is_report)) { return print_help(); } - if (strcmp(arg[1], "--help") == 0 || strcmp(arg[1], "-h") == 0) { + if (!no_args && (strcmp(arg[1], "--help") == 0 || strcmp(arg[1], "-h") == 0)) { return print_help(); } return false; diff --git a/src/commandline.h b/src/commandline.h index 28c93e2..d0e1cd5 100644 --- a/src/commandline.h +++ b/src/commandline.h @@ -19,4 +19,4 @@ std::map ParseRelocate(const char** args, int argc); std::map ParseReport(int argc, const char** args); // Writes CLI help message to stdout -bool CheckAndPrintHelp(const char** arg, int argc); \ No newline at end of file +bool CheckAndPrintHelp(const char** arg, bool no_args, bool is_report, bool is_relocate); \ No newline at end of file diff --git a/src/main.cxx b/src/main.cxx index c29ab21..9b704be 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -21,7 +21,8 @@ int main(int argc, const char* argv[]) { const bool is_relocate = IsRelocate(argv[0]); const bool is_report = IsReport(argv[0]); - if ((is_relocate || is_report) && CheckAndPrintHelp(argv, argc)) { + const bool no_args = argc < 2; + if (CheckAndPrintHelp(argv, no_args, is_report, is_relocate)) { return 0; } if (is_relocate) { From 26fd529f9307545a6b0182c1db277b9aa5432fc7 Mon Sep 17 00:00:00 2001 From: John Parent Date: Mon, 1 Jun 2026 21:44:21 -0400 Subject: [PATCH 3/6] default init "is_help" Signed-off-by: John Parent --- src/linker_invocation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/linker_invocation.h b/src/linker_invocation.h index b0f6dba..7429351 100644 --- a/src/linker_invocation.h +++ b/src/linker_invocation.h @@ -40,8 +40,8 @@ class LinkerInvocation { StrList command_files_; StrList input_files_; StrList tokens_; - bool is_exe_; - bool is_help_; + bool is_exe_ = true; + bool is_help_ = false; std::map piped_args_ = { {"export", {}}, {"include", {}}, {"libpath", {}}, {"ltcg", {}}, {"machine", {}}, {"nodefaultlib", {}}, From 55dea5ef684dc164f1e8f3310ebacb349249f0e4 Mon Sep 17 00:00:00 2001 From: John Parent Date: Thu, 18 Jun 2026 11:49:57 -0400 Subject: [PATCH 4/6] Correct "file inputs" check Signed-off-by: John Parent --- src/ld.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ld.cxx b/src/ld.cxx index b6472ac..e209571 100644 --- a/src/ld.cxx +++ b/src/ld.cxx @@ -49,7 +49,7 @@ DWORD LdInvocation::InvokeToolchain() { } // If there are no arguments (or the argument is just "/?") // just print help and return - if(this->inputs.empty() || link_run.isHelp()) { + if(link_run.get_input_files().empty() || link_run.isHelp()) { return ToolChainInvocation::InvokeToolchain(); } From 2bd5447110e824310cdc504cb1698bac50afc06c Mon Sep 17 00:00:00 2001 From: John Parent Date: Tue, 23 Jun 2026 16:24:34 -0400 Subject: [PATCH 5/6] cleanup redundancy Signed-off-by: John Parent --- src/commandline.cxx | 8 ++------ src/commandline.h | 2 +- src/main.cxx | 29 +---------------------------- 3 files changed, 4 insertions(+), 35 deletions(-) diff --git a/src/commandline.cxx b/src/commandline.cxx index 9d977e0..19aa24e 100644 --- a/src/commandline.cxx +++ b/src/commandline.cxx @@ -113,10 +113,6 @@ bool IsRelocate(const char* arg) { return CLICheck(arg, "relocate"); } -bool IsReport(const char* arg) { - return CLICheck(arg, "report"); -} - /** * Parse the command line arguments supportin the relocate command */ @@ -178,8 +174,8 @@ std::map ParseReport(int argc, const char** args) { return opts; } -bool CheckAndPrintHelp(const char** arg, bool no_args, bool is_report, bool is_relocate) { - if (no_args && (is_relocate || is_report)) { +bool CheckAndPrintHelp(const char** arg, bool no_args, bool is_relocate) { + if (no_args && is_relocate) { return print_help(); } if (!no_args && (strcmp(arg[1], "--help") == 0 || strcmp(arg[1], "-h") == 0)) { diff --git a/src/commandline.h b/src/commandline.h index d0e1cd5..c3df0e7 100644 --- a/src/commandline.h +++ b/src/commandline.h @@ -19,4 +19,4 @@ std::map ParseRelocate(const char** args, int argc); std::map ParseReport(int argc, const char** args); // Writes CLI help message to stdout -bool CheckAndPrintHelp(const char** arg, bool no_args, bool is_report, bool is_relocate); \ No newline at end of file +bool CheckAndPrintHelp(const char** arg, bool no_args, bool is_relocate); \ No newline at end of file diff --git a/src/main.cxx b/src/main.cxx index 9b704be..dcd4f88 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -20,9 +20,8 @@ int main(int argc, const char* argv[]) { const bool is_relocate = IsRelocate(argv[0]); - const bool is_report = IsReport(argv[0]); const bool no_args = argc < 2; - if (CheckAndPrintHelp(argv, no_args, is_report, is_relocate)) { + if (CheckAndPrintHelp(argv, no_args, is_relocate)) { return 0; } if (is_relocate) { @@ -92,32 +91,6 @@ int main(int argc, const char* argv[]) { std::cerr << "Library rename failed\n"; return ExitConditions::RENAME_FAILURE; } - } else if (is_report) { - std::map report_args = - ParseReport(argc - 1, argv + 1); - if (report_args.empty()) { - std::cerr << "Unable to parse command line for reporting\n" - << "run command with --help flag for accepted command " - "line arguments\n"; - return ExitConditions::CLI_FAILURE; - } - if (report_args.find("pe") != report_args.end()) { - try { - LibRename portable_executable(report_args.at("pe"), - std::string(), false, true); - portable_executable.ExecuteRename(); - } catch (const NameTooLongError& e) { - std::cerr - << "Unable to parse command line for reporting\n" - << "run command with --help flag for accepted command " - "line arguments\n"; - return ExitConditions::CLI_FAILURE; - } - } else { - CoffReaderWriter coff_reader(report_args.at("coff")); - CoffParser coff(&coff_reader); - return static_cast(reportCoff(coff)); - } } else { // Ensure required variables are set if (!ValidateSpackEnv()) { From 9575ab8ecfbf22110584a0957d5e7eb89c360f94 Mon Sep 17 00:00:00 2001 From: John Parent Date: Tue, 23 Jun 2026 18:09:23 -0400 Subject: [PATCH 6/6] CLeanup redundant code Signed-off-by: John Parent --- src/commandline.cxx | 21 --------------------- src/commandline.h | 8 -------- 2 files changed, 29 deletions(-) diff --git a/src/commandline.cxx b/src/commandline.cxx index 19aa24e..ece87cf 100644 --- a/src/commandline.cxx +++ b/src/commandline.cxx @@ -153,27 +153,6 @@ std::map ParseRelocate(const char** args, int argc) { return opts; } -std::map ParseReport(int argc, const char** args) { - std::map opts; - for (int i = 0; i < argc; ++i) { - if (endswith(std::string(args[i]), ".dll") || - endswith(std::string(args[i]), ".exe")) { - if (redefinedArgCheck(opts, "pe", "pe")) { - opts.clear(); - return opts; - } - opts.insert(std::pair("pe", args[i])); - } else if (endswith(std::string(args[i]), ".lib")) { - if (redefinedArgCheck(opts, "coff", "coff")) { - opts.clear(); - return opts; - } - opts.insert(std::pair("coff", args[i])); - } - } - return opts; -} - bool CheckAndPrintHelp(const char** arg, bool no_args, bool is_relocate) { if (no_args && is_relocate) { return print_help(); diff --git a/src/commandline.h b/src/commandline.h index c3df0e7..2e2ac03 100644 --- a/src/commandline.h +++ b/src/commandline.h @@ -6,17 +6,9 @@ // of this executable bool IsRelocate(const char* arg); -// Determines if a command line invocation is for the report form of this -// Executable -bool IsReport(const char* arg); - // Parses the command line for an invocation of the relocate command // and returns the arguments mapped from argument name to value std::map ParseRelocate(const char** args, int argc); -// Parses the command line for an invocation of the report command -// adn returns the arguments mappedfrom argument name to value -std::map ParseReport(int argc, const char** args); - // Writes CLI help message to stdout bool CheckAndPrintHelp(const char** arg, bool no_args, bool is_relocate); \ No newline at end of file