File 0004-Add-additional-includes-fro-aarch64.patch of Package rstudio
From 5372d9de56b8e7fa7040a22e52bc2a7a30064cc0 Mon Sep 17 00:00:00 2001
From: Sebastian Csar <sacsar@gmail.com>
Date: Sun, 13 Jul 2025 19:09:34 -0700
Subject: [PATCH 4/8] Add additional includes fro aarch64
---
src/cpp/core/HtmlUtils.cpp | 50 ++---
src/cpp/r/session/RStdCallbacks.cpp | 284 +++++++++++++---------------
2 files changed, 153 insertions(+), 181 deletions(-)
diff --git a/src/cpp/core/HtmlUtils.cpp b/src/cpp/core/HtmlUtils.cpp
index 9623da6fa7..17975e9a7d 100644
--- a/src/cpp/core/HtmlUtils.cpp
+++ b/src/cpp/core/HtmlUtils.cpp
@@ -17,9 +17,10 @@
#include <core/system/System.hpp>
-#include <boost/format.hpp>
#include <boost/algorithm/string/predicate.hpp>
+#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
+#include <boost/format.hpp>
#include <core/Base64.hpp>
#include <core/FileSerializer.hpp>
@@ -29,10 +30,12 @@
using namespace boost::placeholders;
-namespace rstudio {
-namespace core {
-namespace html_utils {
-
+namespace rstudio
+{
+namespace core
+{
+namespace html_utils
+{
HTML::HTML(const std::string& text, bool isHTML)
{
@@ -42,7 +45,6 @@ HTML::HTML(const std::string& text, bool isHTML)
text_ = text;
}
-
std::string defaultTitle(const std::string& htmlContent)
{
boost::regex re("<[Hh]([1-6]).*?>(.*?)</[Hh]\\1>");
@@ -53,17 +55,15 @@ std::string defaultTitle(const std::string& htmlContent)
return "";
}
-
Base64ImageFilter::Base64ImageFilter(const FilePath& basePath)
- : boost::iostreams::regex_filter(
- boost::regex(
- R"((<\s*[Ii][Mm][Gg] [^\>]*[Ss][Rr][Cc]\s*=\s*)(["'])(.*?)(\2))"),
- boost::bind(&Base64ImageFilter::toBase64Image, this, _1)),
- basePath_(basePath)
+ : boost::iostreams::regex_filter(
+ boost::regex(
+ R"((<\s*[Ii][Mm][Gg] [^\>]*[Ss][Rr][Cc]\s*=\s*)(["'])(.*?)(\2))"),
+ boost::bind(&Base64ImageFilter::toBase64Image, this, _1)),
+ basePath_(basePath)
{
}
-
std::string Base64ImageFilter::toBase64Image(const boost::cmatch& match)
{
// extract image reference
@@ -77,7 +77,7 @@ std::string Base64ImageFilter::toBase64Image(const boost::cmatch& match)
FilePath imagePath = basePath_.completeChildPath(imgRef);
if (imagePath.exists() &&
boost::algorithm::starts_with(imagePath.getMimeContentType(), "image/"))
- {
+ {
std::string imageBase64;
Error error = core::base64::encode(imagePath, &imageBase64);
if (!error)
@@ -98,10 +98,10 @@ std::string Base64ImageFilter::toBase64Image(const boost::cmatch& match)
// convert fonts to base64
CssUrlFilter::CssUrlFilter(const FilePath& basePath)
- : boost::iostreams::regex_filter(
- boost::regex("url\\('([^'']+)'\\)"),
- boost::bind(&CssUrlFilter::toBase64Url, this, _1)),
- basePath_(basePath)
+ : boost::iostreams::regex_filter(
+ boost::regex("url\\('([^'']+)'\\)"),
+ boost::bind(&CssUrlFilter::toBase64Url, this, _1)),
+ basePath_(basePath)
{
}
@@ -190,7 +190,6 @@ void HtmlPreserver::preserve(std::string* pInput)
// update the position
pos = end + 1;
-
}
else
{
@@ -219,24 +218,17 @@ void HtmlPreserver::preserve(std::string* pInput)
// return the modified input
*pInput = modifiedInput;
-
}
void HtmlPreserver::restore(std::string* pOutput)
{
for (const auto& preserve : preserved_)
{
- boost::algorithm::replace_first(*pOutput,
- preserve.first,
- preserve.second);
+ boost::algorithm::replace_first(
+ *pOutput, preserve.first, preserve.second);
}
}
-
-
} // namespace html_utils
-} // namespace core
+} // namespace core
} // namespace rstudio
-
-
-
diff --git a/src/cpp/r/session/RStdCallbacks.cpp b/src/cpp/r/session/RStdCallbacks.cpp
index 72b66f2953..36abaebaaa 100644
--- a/src/cpp/r/session/RStdCallbacks.cpp
+++ b/src/cpp/r/session/RStdCallbacks.cpp
@@ -19,18 +19,19 @@
#include <iostream>
+#include <boost/bind.hpp>
+#include <boost/bind/bind.hpp>
#include <boost/function.hpp>
#include <boost/regex.hpp>
-#include <boost/bind/bind.hpp>
#include <core/FileSerializer.hpp>
#include <core/RegexUtils.hpp>
+#include <r/RCntxtUtils.hpp>
#include <r/RExec.hpp>
#include <r/ROptions.hpp>
#include <r/RSourceManager.hpp>
#include <r/RUtil.hpp>
-#include <r/RCntxtUtils.hpp>
#include <r/session/RClientState.hpp>
#include <r/session/RConsoleActions.hpp>
#include <r/session/RConsoleHistory.hpp>
@@ -38,30 +39,35 @@
#include <r/session/RSessionState.hpp>
#include <r/session/RSuspend.hpp>
-#include "RInit.hpp"
#include "REmbedded.hpp"
-#include "RStdCallbacks.hpp"
+#include "RInit.hpp"
#include "RQuit.hpp"
+#include "RStdCallbacks.hpp"
#include "graphics/RGraphicsDevDesc.hpp"
-#include "graphics/RGraphicsUtils.hpp"
#include "graphics/RGraphicsDevice.hpp"
#include "graphics/RGraphicsPlotManager.hpp"
+#include "graphics/RGraphicsUtils.hpp"
#include <Rembedded.h>
-extern "C" {
-RS_IMPORT SA_TYPE SaveAction;
+extern "C"
+{
+ RS_IMPORT SA_TYPE SaveAction;
}
using namespace rstudio::core;
using namespace boost::placeholders;
-namespace rstudio {
-namespace r {
-namespace session {
+namespace rstudio
+{
+namespace r
+{
+namespace session
+{
-namespace {
+namespace
+{
// have we completed our one-time initialization yet?
bool s_initialized = false;
@@ -104,7 +110,7 @@ SA_TYPE saveAsk()
{
// end user prompt
std::string wsPath = FilePath::createAliasedPath(
- rSaveGlobalEnvironmentFilePath(), utils::userHomePath());
+ rSaveGlobalEnvironmentFilePath(), utils::userHomePath());
std::string prompt = "Save workspace image to " + wsPath + "? [y/n";
// The Rf_jump_to_top_level doesn't work (freezes the process) with
// 64-bit mingw due to the way it does stack unwinding. Since this is
@@ -118,11 +124,13 @@ SA_TYPE saveAsk()
// input buffer
std::vector<CONSOLE_BUFFER_CHAR> inputBuffer(512, 0);
- while(true)
+ while (true)
{
// read input
- RReadConsole(prompt.c_str(), &(inputBuffer[0]),
- gsl::narrow_cast<int>(inputBuffer.size()), 0);
+ RReadConsole(prompt.c_str(),
+ &(inputBuffer[0]),
+ gsl::narrow_cast<int>(inputBuffer.size()),
+ 0);
std::string input(1, inputBuffer[0]);
boost::algorithm::to_lower(input);
@@ -137,7 +145,7 @@ SA_TYPE saveAsk()
#endif
}
}
- catch(JumpToTopException)
+ catch (JumpToTopException)
{
Rf_jump_to_toplevel();
}
@@ -146,34 +154,33 @@ SA_TYPE saveAsk()
return SA_SAVE;
}
-void doHistoryFileOperation(SEXP args,
+void doHistoryFileOperation(SEXP args,
boost::function<Error(const FilePath&)> fileOp)
{
// validate filename argument
SEXP file = CAR(args);
if (!sexp::isString(file) || sexp::length(file) < 1)
throw r::exec::RErrorException("invalid 'file' argument");
-
+
// calculate full path to history file
- FilePath historyFilePath(R_ExpandFileName(Rf_translateChar(STRING_ELT(file,
- 0))));
+ FilePath historyFilePath(
+ R_ExpandFileName(Rf_translateChar(STRING_ELT(file, 0))));
// perform operation
Error error = fileOp(historyFilePath);
if (error)
throw r::exec::RErrorException(error.getMessage());
}
-
-bool consoleInputHook(const std::string& prompt,
- const std::string& input)
+
+bool consoleInputHook(const std::string& prompt, const std::string& input)
{
// only check for quit when we're at the default prompt
if (!r::session::utils::isDefaultPrompt(prompt))
return true;
// check for user quit invocation
- boost::regex re("^\\s*(q|quit)\\s*\\(.*$");
- boost::smatch match;
- if (regex_utils::match(input, match, re))
+ boost::regex re("^\\s*(q|quit)\\s*\\(.*$");
+ boost::smatch match;
+ if (regex_utils::match(input, match, re))
{
if (!s_callbacks.handleUnsavedChanges())
{
@@ -219,12 +226,13 @@ Error saveDefaultGlobalEnvironment()
// suppress interrupts which occur during saving
r::exec::IgnoreInterruptsScope ignoreInterrupts;
-
+
// save global environment
- std::string path = string_utils::utf8ToSystem(globalEnvPath.getAbsolutePath());
- Error error = r::exec::executeSafely(
- boost::bind(R_SaveGlobalEnvToFile, path.c_str()));
-
+ std::string path =
+ string_utils::utf8ToSystem(globalEnvPath.getAbsolutePath());
+ Error error =
+ r::exec::executeSafely(boost::bind(R_SaveGlobalEnvToFile, path.c_str()));
+
if (error)
{
return error;
@@ -235,36 +243,19 @@ Error saveDefaultGlobalEnvironment()
}
}
-
-
} // anonymous namespace
-bool imageIsDirty()
-{
- return R_DirtyImage != 0;
-}
+bool imageIsDirty() { return R_DirtyImage != 0; }
-void setImageDirty(bool imageDirty)
-{
- R_DirtyImage = imageDirty ? 1 : 0;
-}
+void setImageDirty(bool imageDirty) { R_DirtyImage = imageDirty ? 1 : 0; }
-void setRCallbacks(const RCallbacks& callbacks)
-{
- s_callbacks = callbacks;
-}
+void setRCallbacks(const RCallbacks& callbacks) { s_callbacks = callbacks; }
-RCallbacks& rCallbacks()
-{
- return s_callbacks;
-}
+RCallbacks& rCallbacks() { return s_callbacks; }
-InternalCallbacks* stdInternalCallbacks()
-{
- return &s_internalCallbacks;
-}
+InternalCallbacks* stdInternalCallbacks() { return &s_internalCallbacks; }
-int RReadConsole(const char *pmt,
+int RReadConsole(const char* pmt,
CONSOLE_BUFFER_CHAR* buf,
int buflen,
int hist)
@@ -284,7 +275,7 @@ int RReadConsole(const char *pmt,
// never having to start from scratch
r::exec::IgnoreInterruptsScope ignoreInterrupts;
- // attempt to initialize
+ // attempt to initialize
Error initError;
Error error = r::exec::executeSafely<Error>(initialize, &initError);
if (error || initError)
@@ -294,18 +285,18 @@ int RReadConsole(const char *pmt,
// log the error if it was unexpected
LOG_ERROR(error);
-
+
// terminate the session (use suicide so that no special
// termination code runs -- i.e. call to setAbnormalEnd(false)
// or call to client::quitSession)
rSuicideError(error);
}
-
+
// reset the prompt to whatever the default is after we've
// fully initialized (and restored suspended options)
prompt = r::options::getOption<std::string>("prompt");
- // ensure only one initialization
+ // ensure only one initialization
s_initialized = true;
}
@@ -331,7 +322,7 @@ int RReadConsole(const char *pmt,
// c++ stack unwinding to occur before jumping
throw r::exec::InterruptException();
}
-
+
// handle EOF. note that we only want to return 0 here if we
// know that the session is waiting for input; otherwise we'll
// end up quitting R altogether! this effectively implies that
@@ -348,7 +339,7 @@ int RReadConsole(const char *pmt,
// refresh source if necessary (no-op in production)
r::sourceManager().reloadIfNecessary();
-
+
// ensure that our input fits within the buffer
std::string::size_type maxLen = buflen - 2; // for \n\0
rInput = string_utils::utf8ToSystem(rInput, true);
@@ -356,15 +347,18 @@ int RReadConsole(const char *pmt,
{
// print a loud warning when we're about to truncate input
std::cerr << std::endl;
- std::cerr << "WARNING: Truncating console input of length " << rInput.length() << "." << std::endl;
- std::cerr << "The maximum number of characters accepted by R in a single line of input is " << buflen - 2 << "." << std::endl;
+ std::cerr << "WARNING: Truncating console input of length "
+ << rInput.length() << "." << std::endl;
+ std::cerr << "The maximum number of characters accepted by R in "
+ "a single line of input is "
+ << buflen - 2 << "." << std::endl;
std::cerr << std::endl;
-
+
rInput.resize(maxLen);
}
-
+
std::string::size_type inputLen = rInput.length();
-
+
// add to console actions and history (if requested). note that
// we add the user's input rather than any transformed input we
// created as a result of a shell escape
@@ -377,7 +371,7 @@ int RReadConsole(const char *pmt,
throw r::exec::InterruptException();
// copy to buffer and add terminators
- rInput.copy((char*)buf, maxLen);
+ rInput.copy((char*) buf, maxLen);
buf[inputLen] = '\n';
buf[inputLen + 1] = '\0';
}
@@ -390,7 +384,7 @@ int RReadConsole(const char *pmt,
return 0;
}
}
- catch(r::exec::InterruptException&)
+ catch (r::exec::InterruptException&)
{
// set interrupts pending
r::exec::setInterruptsPending(true);
@@ -416,32 +410,33 @@ int RReadConsole(const char *pmt,
// buffer not ready
return 0;
}
- catch(const std::exception& e)
+ catch (const std::exception& e)
{
std::string msg = std::string("Unexpected exception: ") + e.what();
LOG_ERROR_MESSAGE(msg);
rSuicide(msg);
}
- catch(...)
+ catch (...)
{
std::string msg = "Unknown exception";
LOG_ERROR_MESSAGE(msg);
rSuicide(msg);
}
-
+
return 0; // keep compiler happy
}
-
+
void RShowMessage(const char* msg)
{
- try
+ try
{
s_callbacks.showMessage(msg);
}
CATCH_UNEXPECTED_EXCEPTION
}
-namespace {
+namespace
+{
bool isOutputSuppressed()
{
@@ -450,18 +445,15 @@ bool isOutputSuppressed()
} // end anonymous namespace
-void RWriteConsoleEx(const char *buf, int buflen, int otype)
+void RWriteConsoleEx(const char* buf, int buflen, int otype)
{
try
{
if (isOutputSuppressed())
return;
-
- bool isInterruptOutput =
- r::exec::getWasInterrupted() &&
- otype == 1 &&
- buflen == 1 &&
- buf[0] == '\n';
+
+ bool isInterruptOutput = r::exec::getWasInterrupted() && otype == 1 &&
+ buflen == 1 && buf[0] == '\n';
if (isInterruptOutput)
{
@@ -479,25 +471,22 @@ void RWriteConsoleEx(const char *buf, int buflen, int otype)
CATCH_UNEXPECTED_EXCEPTION
}
-void RResetConsole()
-{
- s_callbacks.consoleReset();
-}
+void RResetConsole() { s_callbacks.consoleReset(); }
// NOTE: Win32 doesn't receive this callback
int REditFile(const char* file)
{
- try
+ try
{
return s_callbacks.editFile(r::util::fixPath(file));
}
CATCH_UNEXPECTED_EXCEPTION
-
+
// error if we got this far
return 1;
}
-void RBusy(int which)
+void RBusy(int which)
{
try
{
@@ -509,29 +498,29 @@ void RBusy(int which)
// invoke callback
s_callbacks.busy(which == 1);
}
- CATCH_UNEXPECTED_EXCEPTION
+ CATCH_UNEXPECTED_EXCEPTION
}
// NOTE: Win32 doesn't receive this callback
-int RChooseFile (int newFile, char *buf, int len)
+int RChooseFile(int newFile, char* buf, int len)
{
- try
+ try
{
FilePath filePath = s_callbacks.chooseFile(newFile == TRUE);
if (!filePath.isEmpty())
{
// get absolute path
std::string absolutePath = filePath.getAbsolutePath();
-
+
// trunate file if it is too long
std::string::size_type maxLen = len - 1;
if (absolutePath.length() > maxLen)
absolutePath.resize(maxLen);
-
+
// copy the file to the buffer
absolutePath.copy(buf, maxLen);
buf[absolutePath.length()] = '\0';
-
+
// return the length of the filepath buffer
return gsl::narrow_cast<int>(absolutePath.length());
}
@@ -545,18 +534,18 @@ int RChooseFile (int newFile, char *buf, int len)
// error if we got this far
return 0;
}
-
+
// NOTE: Win32 doesn't receive this callback
-int RShowFiles (int nfile,
- const char **file,
- const char **headers,
- const char *wtitle,
- Rboolean del,
- const char *pager)
+int RShowFiles(int nfile,
+ const char** file,
+ const char** headers,
+ const char* wtitle,
+ Rboolean del,
+ const char* pager)
{
- try
+ try
{
- for (int i=0; i<nfile; i++)
+ for (int i = 0; i < nfile; i++)
{
// determine file path and title
std::string fixedPath = r::util::fixPath(file[i]);
@@ -566,24 +555,24 @@ int RShowFiles (int nfile,
std::string title(headers[i]);
if (title.empty())
title = wtitle;
-
+
// show file
s_callbacks.showFile(title, filePath, del);
}
else
{
- throw r::exec::RErrorException(
- "File " + fixedPath + " does not exist.");
+ throw r::exec::RErrorException("File " + fixedPath +
+ " does not exist.");
}
}
}
- catch(r::exec::RErrorException& e)
+ catch (r::exec::RErrorException& e)
{
r::exec::error(e.message());
}
CATCH_UNEXPECTED_EXCEPTION
-
+
// NOTE: the documentation doesn't indicate what to return and do_fileshow
// in platform.c doesn't check the return value s
return 0;
@@ -593,30 +582,33 @@ void Rloadhistory(SEXP call, SEXP op, SEXP args, SEXP env)
{
try
{
- doHistoryFileOperation(args, boost::bind(&ConsoleHistory::loadFromFile,
- &consoleHistory(), _1, true));
-
+ doHistoryFileOperation(
+ args,
+ boost::bind(
+ &ConsoleHistory::loadFromFile, &consoleHistory(), _1, true));
+
s_callbacks.consoleHistoryReset();
}
- catch(r::exec::RErrorException& e)
+ catch (r::exec::RErrorException& e)
{
r::exec::errorCall(call, e.message());
}
}
-
+
void Rsavehistory(SEXP call, SEXP op, SEXP args, SEXP env)
{
try
{
- doHistoryFileOperation(args, boost::bind(&ConsoleHistory::saveToFile,
- &consoleHistory(), _1));
+ doHistoryFileOperation(
+ args,
+ boost::bind(&ConsoleHistory::saveToFile, &consoleHistory(), _1));
}
- catch(r::exec::RErrorException& e)
+ catch (r::exec::RErrorException& e)
{
r::exec::errorCall(call, e.message());
}
}
-
+
void Raddhistory(SEXP call, SEXP op, SEXP args, SEXP env)
{
try
@@ -626,10 +618,10 @@ void Raddhistory(SEXP call, SEXP op, SEXP args, SEXP env)
Error error = sexp::extract(CAR(args), &commands);
if (error)
throw r::exec::RErrorException(error.getMessage());
-
+
// append them
ConsoleHistory& history = consoleHistory();
- std::for_each(commands.begin(),
+ std::for_each(commands.begin(),
commands.end(),
boost::bind(&ConsoleHistory::add, &history, _1, true));
}
@@ -639,12 +631,12 @@ void Raddhistory(SEXP call, SEXP op, SEXP args, SEXP env)
}
}
-
// NOTE: Win32 doesn't receive this callback
void RSuicide(const char* s)
{
- // We need to write this to stderr so the parent process (rstudio) can pick up the error message and display it
- // to the user in case the session log file is not accessible.
+ // We need to write this to stderr so the parent process (rstudio) can pick
+ // up the error message and display it to the user in case the session log
+ // file is not accessible.
std::cerr << s << std::endl;
s_callbacks.suicide(s);
s_internalCallbacks.suicide(s);
@@ -655,8 +647,8 @@ void rSuicide(const std::string& msg)
// log abort message if we are in desktop mode
if (!utils::isServerMode())
{
- FilePath abendLogPath = utils::logPath().completePath(
- "rsession_abort_msg.log");
+ FilePath abendLogPath =
+ utils::logPath().completePath("rsession_abort_msg.log");
Error error = core::writeStringToFile(abendLogPath, msg);
if (error)
LOG_ERROR(error);
@@ -692,9 +684,9 @@ void RCleanUp(SA_TYPE saveact, int status, int runLast)
// set to default if requested
if (saveact == SA_DEFAULT)
saveact = SaveAction;
-
+
// prompt user to resolve SA_SAVEASK into SA_SAVE or SA_NOSAVE
- if (saveact == SA_SAVEASK)
+ if (saveact == SA_SAVEASK)
{
if (imageIsDirty() || !utils::alwaysSaveHistory())
saveact = saveAsk(); // can Rf_jump_to_toplevel()
@@ -709,7 +701,7 @@ void RCleanUp(SA_TYPE saveact, int status, int runLast)
// run last if requested (can throw error)
if (runLast)
R_dot_Last();
-
+
// save history if we either always save history or saveact == SA_SAVE
if (utils::alwaysSaveHistory() || saveact == SA_SAVE)
{
@@ -725,19 +717,19 @@ void RCleanUp(SA_TYPE saveact, int status, int runLast)
// attempt save if the image is dirty
if (imageIsDirty())
{
- // attempt to save global environment. raise error (longjmp
+ // attempt to save global environment. raise error (longjmp
// back to REPL) if there was a problem saving
Error error = saveDefaultGlobalEnvironment();
if (error)
r::exec::error(r::endUserErrorMessage(error));
}
-
+
// update state
- saveact = SA_NOSAVE; // prevent R from saving
+ saveact = SA_NOSAVE; // prevent R from saving
}
-
+
// since we've successfully completed the session we can safely
- // remove any serialized session remaining on disk. note that if
+ // remove any serialized session remaining on disk. note that if
// we do not successfully destroy the session then this would cause
// data loss when the previous session is read rather than the
// contents of .RData. therefore, we refuse to quit if we can't
@@ -753,7 +745,7 @@ void RCleanUp(SA_TYPE saveact, int status, int runLast)
// clear display
r::session::graphics::display().clear();
-
+
// notify client that the session has been quit
s_callbacks.quit();
}
@@ -761,14 +753,14 @@ void RCleanUp(SA_TYPE saveact, int status, int runLast)
// allow client to cleanup
bool terminatedNormally = saveact != SA_SUICIDE;
s_callbacks.cleanup(terminatedNormally);
-
+
// call internal cleanup (never .runLast because we do it above)
// NOTE: may want to replace RCleanUp entirely so that the client
// can see any errors which occur during cleanup in the console
// (they aren't seen now because the handling of quit obstructs them)
s_internalCallbacks.cleanUp(saveact, status, FALSE);
}
- CATCH_UNEXPECTED_EXCEPTION
+ CATCH_UNEXPECTED_EXCEPTION
}
// set save action
@@ -793,31 +785,19 @@ void setSaveAction(int saveAction)
}
}
-namespace utils {
-
-SuppressOutputInScope::SuppressOutputInScope()
+namespace utils
{
- s_suppressOutput += 1;
-}
-SuppressOutputInScope::~SuppressOutputInScope()
-{
- s_suppressOutput -= 1;
-}
+SuppressOutputInScope::SuppressOutputInScope() { s_suppressOutput += 1; }
-ShowOutputInScope::ShowOutputInScope()
-{
- s_forceOutput += 1;
-}
+SuppressOutputInScope::~SuppressOutputInScope() { s_suppressOutput -= 1; }
-ShowOutputInScope::~ShowOutputInScope()
-{
- s_forceOutput -= 1;
-}
+ShowOutputInScope::ShowOutputInScope() { s_forceOutput += 1; }
+
+ShowOutputInScope::~ShowOutputInScope() { s_forceOutput -= 1; }
} // namespace utils
} // namespace session
} // namespace r
} // namespace rstudio
-
--
2.50.1