Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/xinterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,12 @@ __get_cxx_version ()
auto cout_strbuf = std::cout.rdbuf();
auto cerr_strbuf = std::cerr.rdbuf();

std::unique_ptr<xnull> nullbuf;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::unique_ptr" is directly included [misc-include-cleaner]

src/xinterpreter.cpp:21:

- #ifndef EMSCRIPTEN
+ #include <memory>
+ #ifndef EMSCRIPTEN

if (config.silent)
{
auto null = xnull();
std::cout.rdbuf(&null);
std::cerr.rdbuf(&null);
nullbuf = std::make_unique<xnull>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::make_unique" is directly included [misc-include-cleaner]

            nullbuf = std::make_unique<xnull>();
                           ^

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can always allocate xnull before checking for the config.silent property and redirect only if this is needed. That would avoid a dynamic allocation here. Also we could take the opportunity of fixing this issue to write a small RAII object to perform the redirection.

std::cout.rdbuf(nullbuf.get());
std::cerr.rdbuf(nullbuf.get());
}

std::string err;
Expand Down
41 changes: 41 additions & 0 deletions test/test_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1136,3 +1136,44 @@ TEST_CASE("C and C++ stdout/stderr capture")
REQUIRE(captured_err.find("C stderr") != std::string::npos);
REQUIRE(captured_err.find("C++ stderr") != std::string::npos);
}

TEST_CASE("Silent mode suppresses C and C++ stdout/stderr")
{
std::vector<const char*> Args = {};
xcpp::interpreter interpreter((int)Args.size(), Args.data());

xeus::execute_request_config config;
// forcing silent as true
config.silent = true;
config.store_history = false;
config.allow_stdin = false;

nl::json header = nl::json::object();
xeus::xrequest_context::guid_list id = {};
xeus::xrequest_context context(header, id);

std::promise<nl::json> promise;
auto callback = [&promise](nl::json result) { promise.set_value(result); };

StreamRedirectRAII cout_redirect(std::cout);
StreamRedirectRAII cerr_redirect(std::cerr);

std::string code = R"(
#include <stdio.h>
#include <iostream>
printf("C stdout\n");
fprintf(stderr, "C stderr\n");
std::cout << "C++ stdout\n";
std::cerr << "C++ stderr\n";
)";

interpreter.execute_request(context, callback, code, config, nl::json::object());
(void)promise.get_future().get();

std::string captured_out = cout_redirect.getCaptured();
std::string captured_err = cerr_redirect.getCaptured();

// Nothing should reach the redirected streams in silent mode
REQUIRE(captured_out.empty());
REQUIRE(captured_err.empty());
}