diff --git a/core/rint/src/TRint.cxx b/core/rint/src/TRint.cxx index b5b0e6a6e830a..83c258382ce2e 100644 --- a/core/rint/src/TRint.cxx +++ b/core/rint/src/TRint.cxx @@ -41,7 +41,7 @@ #include "TTabCom.h" #include #include - +#include #include "Getline.h" #include "strlcpy.h" #include "snprintf.h" @@ -146,6 +146,16 @@ TRint::TRint(const char *appClassName, Int_t *argc, char **argv, void *options, TApplication(appClassName, argc, argv, options, numOptions), fCaughtSignal(-1) { + + if (*argc > 1) { + // Early exit if there are remaining unrecognized options + for (auto n = 1; n < *argc; n++) { + std::cerr << "root: unrecognized option '" << argv[n] << "'\n"; + } + std::cerr << "Try 'root --help' for more information.\n"; + TApplication::Terminate(0); + } + fNcmd = 0; fDefaultPrompt = "root [%d] "; fInterrupt = kFALSE; diff --git a/core/rint/test/CMakeLists.txt b/core/rint/test/CMakeLists.txt index c72b38e164e23..4518dae395996 100644 --- a/core/rint/test/CMakeLists.txt +++ b/core/rint/test/CMakeLists.txt @@ -5,3 +5,5 @@ # For the list of contributors see $ROOTSYS/README/CREDITS. ROOT_ADD_GTEST(TTabComTests TTabComTests.cxx LIBRARIES Rint) +ROOT_ADD_GTEST(TRintTests TRintTests.cxx LIBRARIES Rint) + diff --git a/core/rint/test/TRintTests.cxx b/core/rint/test/TRintTests.cxx new file mode 100644 index 0000000000000..444e2d4b8a832 --- /dev/null +++ b/core/rint/test/TRintTests.cxx @@ -0,0 +1,43 @@ +#include +#include + +#include "gtest/gtest.h" + +#include "TRint.h" + +using testing::internal::CaptureStderr; +using testing::internal::GetCapturedStderr; + +TEST(TRint, UnrecognizedOptions) +{ + // Create array of options. + // We need to create it as a dynamic array for the following reasons: + // - TRint constructor accepts a char** so we construct directly that type + // - TRint will modify this array, removing recognized options and leaving + // only unrecognized ones, so we can't create an std::vector and pass its + // data to TRint directly. + int argc{4}; + char **argv = new char *[argc]; + argv[0] = const_cast("-q"); + argv[1] = const_cast("-z"); + argv[2] = const_cast("--nonexistingoption"); + argv[3] = const_cast("-b"); + + CaptureStderr(); + // Unrecognized options will be printed to stderr + TRint app{"App", &argc, argv}; + std::string trinterr = GetCapturedStderr(); + + const std::string expected{"root: unrecognized option '-z'\n" + "root: unrecognized option '--nonexistingoption'\n" + "Try 'root --help' for more information.\n"}; + + EXPECT_EQ(trinterr, expected); + + // Properly delete the array + for (int i = 0; i < argc; i++) { + delete[] argv[i]; + } + delete[] argv; + argv = nullptr; +}