diff --git a/cmake/scripts/argparse2help.py b/cmake/scripts/argparse2help.py index b406b3cbdf4cd..d7032bd34f67f 100644 --- a/cmake/scripts/argparse2help.py +++ b/cmake/scripts/argparse2help.py @@ -18,6 +18,9 @@ def write_header(parser, fileName): splitPath = sys.argv[2].split("/") file.write("#ifndef ROOT_{}\n".format(splitPath[len(splitPath)-1].partition(".")[0])) file.write("#define ROOT_{}\n".format(splitPath[len(splitPath)-1].partition(".")[0])) + file.write("constexpr static const char kCommandLineShortHelp[] = R\"RAW(\n") + file.write(parser.format_usage() + "\n") + file.write(")RAW\";\n\n") file.write("constexpr static const char kCommandLineOptionsHelp[] = R\"RAW(\n") file.write(parser.format_usage() + "\n") if parser.description is not None: diff --git a/main/src/hadd.cxx b/main/src/hadd.cxx index 1b6c904ef2dad..d27ebd1efe0cc 100644 --- a/main/src/hadd.cxx +++ b/main/src/hadd.cxx @@ -230,6 +230,7 @@ struct HAddArgs { bool fDebug; bool fKeepCompressionAsIs; bool fUseFirstInputCompression; + bool fHelp; std::optional fWorkingDir; std::optional fNProcesses; @@ -565,6 +566,10 @@ static std::optional ParseArgs(int argc, char **argv) PARSE_FLAG(FlagToggle, arg, "k", args.fSkipErrors); PARSE_FLAG(FlagToggle, arg, "O", args.fReoptimize); PARSE_FLAG(FlagToggle, arg, "dbg", args.fDebug); + // Accept --help, -help and -h as "help" + PARSE_FLAG(FlagToggle, arg, "-help", args.fHelp); + PARSE_FLAG(FlagToggle, arg, "help", args.fHelp); + PARSE_FLAG(FlagToggle, arg, "h", args.fHelp); PARSE_FLAG(FlagArg, argc, argv, argIdx, "d", args.fWorkingDir); PARSE_FLAG(FlagArg, argc, argv, argIdx, "j", args.fNProcesses, {0}); PARSE_FLAG(FlagArg, argc, argv, argIdx, "Ltype", args.fObjectFilterType, {}, ConvertFilterType); @@ -653,16 +658,16 @@ static Int_t ParseFilterFile(const std::optional &filterFileName, int main(int argc, char **argv) { - if (argc < 3 || "-h" == std::string(argv[1]) || "--help" == std::string(argv[1])) { - fprintf(stderr, kCommandLineOptionsHelp); - return (argc == 2 && ("-h" == std::string(argv[1]) || "--help" == std::string(argv[1]))) ? 0 : 1; - } - const auto argsOpt = ParseArgs(argc, argv); if (!argsOpt) return 1; const HAddArgs &args = *argsOpt; + if (args.fHelp) { + fputs(kCommandLineOptionsHelp, stderr); + return 0; + } + ROOT::TIOFeatures features = args.fFeatures.value_or(ROOT::TIOFeatures{}); Int_t maxopenedfiles = args.fMaxOpenedFiles.value_or(0); gHaddVerbosity = args.fVerbosity.value_or(kDefaultHaddVerbosity); @@ -705,10 +710,12 @@ int main(int argc, char **argv) const char *targetname = 0; if (!args.fOutputArgIdx) { Err() << "missing output file.\n"; + fputs(kCommandLineShortHelp, stderr); return 1; } if (!args.fFirstInputIdx) { Err() << "missing input file.\n"; + fputs(kCommandLineShortHelp, stderr); return 1; } targetname = argv[args.fOutputArgIdx]; diff --git a/roottest/root/io/hadd/CMakeLists.txt b/roottest/root/io/hadd/CMakeLists.txt index d1c78b1d10604..ec676439d2256 100644 --- a/roottest/root/io/hadd/CMakeLists.txt +++ b/roottest/root/io/hadd/CMakeLists.txt @@ -77,6 +77,16 @@ ROOTTEST_ADD_TEST(test_MergeFilterWhitelist ################################################################ # argument parsing tests # ################################################################ +ROOTTEST_ADD_TEST(test_hadd_args_missing_output + COMMAND ${ROOT_hadd_CMD} + PASSREGEX "Error in : missing output file." +) + +ROOTTEST_ADD_TEST(test_hadd_args_missing_input + COMMAND ${ROOT_hadd_CMD} foo.root + PASSREGEX "Error in : missing input file." +) + ROOTTEST_ADD_TEST(test_hadd_args_gen_input COPY_TO_BUILDDIR hadd_gen_input_tree.C hadd_args_verify.C PRECMD ${CMAKE_COMMAND} -E rm -f hadd_args_in.root @@ -84,6 +94,24 @@ ROOTTEST_ADD_TEST(test_hadd_args_gen_input FIXTURES_SETUP root-io-hadd-test_hadd_args_gen_input-fixture ) +ROOTTEST_ADD_TEST(test_hadd_args_help_short + FIXTURES_REQUIRED root-io-hadd-test_hadd_args_gen_input-fixture + COMMAND ${ROOT_hadd_CMD} -n0 hadd_args_n0_out.root hadd_args_in.root -h + PASSREGEX "usage: hadd" +) + +ROOTTEST_ADD_TEST(test_hadd_args_help_long + FIXTURES_REQUIRED root-io-hadd-test_hadd_args_gen_input-fixture + COMMAND ${ROOT_hadd_CMD} -n0 hadd_args_n0_out.root hadd_args_in.root -help + PASSREGEX "usage: hadd" +) + +ROOTTEST_ADD_TEST(test_hadd_args_help_long2 + FIXTURES_REQUIRED root-io-hadd-test_hadd_args_gen_input-fixture + COMMAND ${ROOT_hadd_CMD} -n0 hadd_args_n0_out.root hadd_args_in.root --help + PASSREGEX "usage: hadd" +) + ROOTTEST_ADD_TEST(test_hadd_args_n0 FIXTURES_REQUIRED root-io-hadd-test_hadd_args_gen_input-fixture PRECMD ${CMAKE_COMMAND} -E rm -f hadd_args_n0_out.root