[education/rkward] rkward: The old 8.3 hack for supporting paths with spaces on Windows no longer works.
Thomas Friedrichsmeier
null at kde.org
Mon Oct 3 08:19:26 BST 2022
Git commit 25ad8f62eaa9af31761f75d29c054b99530b7260 by Thomas Friedrichsmeier.
Committed on 03/10/2022 at 07:18.
Pushed by tfry into branch 'master'.
The old 8.3 hack for supporting paths with spaces on Windows no longer works.
Try something new (needs more testing).
M +4 -4 rkward/main.cpp
M +0 -19 rkward/misc/rkcommonfunctions.cpp
M +0 -2 rkward/misc/rkcommonfunctions.h
M +11 -1 rkward/rbackend/rkfrontendtransmitter.cpp
M +2 -2 rkward/rbackend/rkrinterface.cpp
https://invent.kde.org/education/rkward/commit/25ad8f62eaa9af31761f75d29c054b99530b7260
diff --git a/rkward/main.cpp b/rkward/main.cpp
index 92a0613f..e0e755d9 100644
--- a/rkward/main.cpp
+++ b/rkward/main.cpp
@@ -344,10 +344,10 @@ int main (int argc, char *argv[]) {
}
#endif
// This is _not_ the same path adjustment as above: Make sure to add the current dir to the path, before launching R and backend.
- QStringList syspaths = QString (qgetenv ("PATH")).split (PATH_VAR_SEP);
- if (!syspaths.contains (app.applicationDirPath ())) {
- syspaths.prepend (RKCommonFunctions::windowsShellScriptSafeCommand (app.applicationDirPath ()));
- qputenv ("PATH", syspaths.join (PATH_VAR_SEP).toLocal8Bit ());
+ QStringList syspaths = QString(qgetenv("PATH")).split(PATH_VAR_SEP);
+ if (!syspaths.contains(app.applicationDirPath())) {
+ syspaths.prepend(app.applicationDirPath());
+ qputenv("PATH", syspaths.join(PATH_VAR_SEP).toLocal8Bit());
}
// Handle --reuse option, by placing a dbus-call to existing RKWard process (if any) and exiting
diff --git a/rkward/misc/rkcommonfunctions.cpp b/rkward/misc/rkcommonfunctions.cpp
index db3f0375..42142019 100644
--- a/rkward/misc/rkcommonfunctions.cpp
+++ b/rkward/misc/rkcommonfunctions.cpp
@@ -249,25 +249,6 @@ namespace RKCommonFunctions {
return (i18n ("<p><em>Note:</em> This setting does not take effect until you restart RKWard.</p>"));
}
-#ifdef Q_OS_WIN
-# include <windows.h>
-# include <QTemporaryFile>
-#endif
- QString windowsShellScriptSafeCommand (const QString &orig) {
-#ifdef Q_OS_WIN
- // credits to http://erasmusjam.wordpress.com/2012/10/01/get-8-3-windows-short-path-names-in-a-qt-application/
- QByteArray input (sizeof (wchar_t) * (orig.size()+1), '\0');
- // wchar_t input[orig.size()+1]; -- No: MSVC (2013) does not support variable length arrays. Oh dear...
- orig.toWCharArray ((wchar_t*) input.data ());
- long length = GetShortPathName ((wchar_t*) input.data (), NULL, 0);
- QByteArray output (sizeof (wchar_t) * (length), '\0');
- GetShortPathName ((wchar_t*) input.data (), (wchar_t*) output.data (), length);
- return QString::fromWCharArray ((wchar_t*) output.data (), length-1);
-#else
- return orig;
-#endif
- }
-
QLabel* wordWrappedLabel (const QString& text) {
QLabel* ret = new QLabel (text);
ret->setWordWrap (true);
diff --git a/rkward/misc/rkcommonfunctions.h b/rkward/misc/rkcommonfunctions.h
index e9f1e939..e5dd1257 100644
--- a/rkward/misc/rkcommonfunctions.h
+++ b/rkward/misc/rkcommonfunctions.h
@@ -49,8 +49,6 @@ namespace RKCommonFunctions {
/** simultaneously sets tool tips and what's this tips on up to three QWidgets */
void setTips (const QString &tip, QWidget *first, QWidget *second=0, QWidget *third=0);
QString noteSettingsTakesEffectAfterRestart ();
-/** Passing commands as part of arguments to windows shell scripts will fail miserably for paths with spaces or special characters. Transform to short path names for safety. No-op on sane platforms.*/
- QString windowsShellScriptSafeCommand (const QString &orig);
/** create a QLabel that has wordwarp enabled, in a single line of code. */
QLabel* wordWrappedLabel (const QString &text);
diff --git a/rkward/rbackend/rkfrontendtransmitter.cpp b/rkward/rbackend/rkfrontendtransmitter.cpp
index db49c694..c99822b8 100644
--- a/rkward/rbackend/rkfrontendtransmitter.cpp
+++ b/rkward/rbackend/rkfrontendtransmitter.cpp
@@ -110,7 +110,16 @@ void RKFrontendTransmitter::run () {
exec(); // To actually show the transmission error
return;
}
- args.append(RKCommonFunctions::windowsShellScriptSafeCommand(backend_executable));
+
+#ifdef Q_OS_WIN
+ // Needed for paths with spaces. R CMD is too simple to deal with those, even if we provide proper quoting.
+ // So rather we need to work from a relative path with all spaces eliminated
+ QFileInfo bfi(backend_executable);
+ backend->setWorkingDirectory(bfi.absolutePath());
+ args.append(bfi.fileName());
+#else
+ args.append(backend_executable);
+#endif
args.append ("--debug-level=" + QString::number (RK_Debug::RK_Debug_Level));
// NOTE: QProcess quotes its arguments, *but* properly passing all spaces and quotes through the R CMD wrapper, seems near(?) impossible on Windows. Instead, we use percent encoding, internally.
@@ -138,6 +147,7 @@ void RKFrontendTransmitter::run () {
// What appears to function as a workaround is start a dummy process, before that.
QProcess dummy;
QStringList dummyargs = args;
+ dummy.setWorkingDirectory(backend->workingDirectory());
dummyargs.removeAt(dummyargs.size()-4); // the --server-name. With this empty, the backend will exit
dummy.start(RKSessionVars::RBinary(), dummyargs, QIODevice::ReadOnly);
dummy.waitForFinished();
diff --git a/rkward/rbackend/rkrinterface.cpp b/rkward/rbackend/rkrinterface.cpp
index f52282ad..a24194ab 100644
--- a/rkward/rbackend/rkrinterface.cpp
+++ b/rkward/rbackend/rkrinterface.cpp
@@ -417,8 +417,8 @@ void RInterface::handleRequest (RBackendRequest* request) {
// initialize output file
RKOutputDirectory::getCurrentOutput(chain);
-#ifdef Q_OS_MACOS
- // On MacOS, the backend is started from inside R home to allow resolution of dynamic libs. Re-set to frontend wd, here.
+#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
+ // On MacOS and Windows, the backend is started with different working directories set, for hackish reasons (see rkfrontendtransmitter.cpp). Fix that, here.
runStartupCommand(new RCommand("setwd (" + RKRSharedFunctionality::quote(QDir::currentPath()) + ")\n", RCommand::App | RCommand::Sync), chain, runtimeopt_callback);
#endif
// Workaround for https://bugs.kde.org/show_bug.cgi?id=421958
More information about the rkward-tracker
mailing list