Skip to content
Merged
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
8 changes: 4 additions & 4 deletions Base/Testing/Cpp/ctkAppLauncherEnvironmentTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,24 @@ void ctkAppLauncherEnvironmentTester::cleanup()
QStringList originalEnvKeys = ctkAppLauncherEnvironment::envKeys(this->OriginalEnv);
foreach(const QString& varName, originalEnvKeys)
{
qputenv(varName.toLatin1(), this->OriginalEnv.value(varName).toLatin1());
qputenv(varName.toLocal8Bit(), this->OriginalEnv.value(varName).toLocal8Bit());
}
}

// ----------------------------------------------------------------------------
void ctkAppLauncherEnvironmentTester::setEnv(const QString& name, const QString& value)
{
qputenv(name.toLatin1(), value.toLatin1());
qputenv(name.toLocal8Bit(), value.toLocal8Bit());
this->VariableNames.insert(name);
}

// ----------------------------------------------------------------------------
void ctkAppLauncherEnvironmentTester::unsetEnv(const QString& name)
{
#if defined(_MSC_VER)
qputenv(name.toLatin1(), QString("").toLatin1());
qputenv(name.toLocal8Bit(), QString().toLocal8Bit());
#else
unsetenv(name.toLatin1());
unsetenv(name.toLocal8Bit());
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion Base/ctkAppArguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ void ctkChar2DArray::setValues(const QStringList& list)
{
QString item = d->List.at(index);
d->Values[index] = new char[item.size() + 1];
qstrcpy(d->Values[index], item.toLatin1().data());
qstrcpy(d->Values[index], item.toLocal8Bit().data());
}
}

Expand Down
6 changes: 3 additions & 3 deletions Base/ctkAppLauncherEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,9 @@ void ctkAppLauncherEnvironment::updateCurrentEnvironment(const QProcessEnvironme
foreach(const QString& varName, variablesToUnset)
{
#if defined(Q_OS_WIN32)
bool success = qputenv(varName.toLatin1(), QString("").toLatin1());
bool success = qputenv(varName.toLocal8Bit(), QString().toLocal8Bit());
#else
bool success = unsetenv(varName.toLatin1()) == EXIT_SUCCESS;
bool success = unsetenv(varName.toLocal8Bit()) == EXIT_SUCCESS;
#endif
if (!success)
{
Expand All @@ -180,7 +180,7 @@ void ctkAppLauncherEnvironment::updateCurrentEnvironment(const QProcessEnvironme
foreach(const QString& varName, envKeys)
{
QString varValue = environment.value(varName);
bool success = qputenv(varName.toLatin1(), varValue.toLatin1());
bool success = qputenv(varName.toLocal8Bit(), varValue.toLocal8Bit());
if (!success)
{
qWarning() << "Failed to set environment variable"
Expand Down
138 changes: 51 additions & 87 deletions Base/ctkCommandLineParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,106 +819,70 @@ void ctkCommandLineParser::setStrictModeEnabled(bool strictMode)
this->Internal->StrictMode = strictMode;
}

#if defined (_WIN32)
// --------------------------------------------------------------------------
void ctkCommandLineParser::convertWindowsCommandLineToUnixArguments(
const char *cmd_line, int *argc, char ***argv)
PWSTR cmd_line, int* argc, char*** argv)
{
if (!cmd_line || !argc || !argv)
{
return;
}

// A space delimites an argument except when it is inside a quote

(*argc) = 1;

size_t cmd_line_len = strlen(cmd_line);

size_t i;
for (i = 0; i < cmd_line_len; i++)
{
while (isspace(cmd_line[i]) && i < cmd_line_len)
{
i++;
}
if (i < cmd_line_len)
{
if (cmd_line[i] == '\"')
{
i++;
while (cmd_line[i] != '\"' && i < cmd_line_len)
{
i++;
}
(*argc)++;
}
else
{
while (!isspace(cmd_line[i]) && i < cmd_line_len)
{
i++;
}
(*argc)++;
}
}
}

(*argv) = new char* [(*argc) + 1];
(*argv)[(*argc)] = NULL;

// Set the first arg to be the exec name

(*argv)[0] = new char [1024];
#ifdef _WIN32
::GetModuleFileName(0, (*argv)[0], 1024);
#else
(*argv)[0][0] = '\0';
#endif

// Allocate the others

int j;
for (j = 1; j < (*argc); j++)
*argc = 0;
*argv = nullptr;

// Split the command line to separate arguments
int numArgs = 0;
LPWSTR* wideArgs = nullptr;
// If cmd_line is an empty string then CommandLineToArgvW function returns the path to the current executable file,
// so we need to check if the string is empty.
if (lstrlenW(cmd_line) > 0)
{
wideArgs = CommandLineToArgvW(cmd_line, &numArgs);
if (wideArgs == nullptr)
{
(*argv)[j] = new char [cmd_line_len + 10];
return;
}
}

// Grab the args

size_t pos;
int argc_idx = 1;
// Allocate space for pointers in argv
(*argc) = numArgs + 1; // +1 because the first argument is the executable name
(*argv) = new char* [numArgs + 1];
for (int i = 0; i < numArgs + 1; i++)
{
(*argv)[i] = nullptr;
}

for (i = 0; i < cmd_line_len; i++)
if (wideArgs)
{
// Convert each argument to UTF8 and save it in argv
for (int i = 0; i < numArgs; ++i)
{
while (isspace(cmd_line[i]) && i < cmd_line_len)
BOOL lpUsedDefaultChar = false;
// Get length
int utf8length = WideCharToMultiByte(CP_UTF8, 0, wideArgs[i], -1, NULL, 0, NULL, &lpUsedDefaultChar);
char* utf8buffer = new char[utf8length + 1];
int retval = WideCharToMultiByte(CP_UTF8, 0, wideArgs[i], -1, utf8buffer, utf8length, NULL, &lpUsedDefaultChar);
if (!SUCCEEDED(retval))
{
i++;
}
if (i < cmd_line_len)
{
if (cmd_line[i] == '\"')
{
i++;
pos = i;
while (cmd_line[i] != '\"' && i < cmd_line_len)
{
i++;
}
memcpy((*argv)[argc_idx], &cmd_line[pos], i - pos);
(*argv)[argc_idx][i - pos] = '\0';
argc_idx++;
}
else
{
pos = i;
while (!isspace(cmd_line[i]) && i < cmd_line_len)
{
i++;
}
memcpy((*argv)[argc_idx], &cmd_line[pos], i - pos);
(*argv)[argc_idx][i - pos] = '\0';
argc_idx++;
}
// set to empty string in case of encoding error
utf8buffer[0] = '\0';
continue;
}
utf8buffer[utf8length] = '\0'; // Make sure the string is null-terminated
(*argv)[i + 1] = utf8buffer; // +1 because the first argument is the executable name
}
LocalFree(wideArgs);
}

// Get the application name
wchar_t wideBuffer[MAX_PATH];
DWORD wideLength = GetModuleFileNameW(NULL, wideBuffer, MAX_PATH);
// Convert the wide string to UTF-8
int utf8length = WideCharToMultiByte(CP_UTF8, 0, wideBuffer, wideLength, NULL, 0, NULL, NULL);
char* utf8buffer = new char[utf8length + 1];
WideCharToMultiByte(CP_UTF8, 0, wideBuffer, wideLength, utf8buffer, utf8length, NULL, NULL);
utf8buffer[utf8length] = '\0'; // Make sure the string is null-terminated
(*argv)[0] = utf8buffer;
}
#endif
10 changes: 9 additions & 1 deletion Base/ctkCommandLineParser.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#ifndef __ctkCommandLineParser_h
#define __ctkCommandLineParser_h

#if defined (_WIN32)
#include <windows.h>
#endif

// Qt includes
#include <QString>
#include <QStringList>
Expand Down Expand Up @@ -383,14 +387,18 @@ class /*CTK_CORE_EXPORT*/ ctkCommandLineParser
*/
void setStrictModeEnabled(bool strictMode);

#if defined (_WIN32)
/**
* Convert windows-style arguments given as a command-line string
* into more traditional argc/argv arguments.
* If an argument is failed to be retrieved (for example, due to character encoding error)
* then the corresponding argv pointer is set to point to an empty string.
*
* @note argv[0] will be assigned the executable name using the ::GetModuleFileName function.
*/
static void convertWindowsCommandLineToUnixArguments(
const char *cmd_line, int *argc, char ***argv);
PWSTR cmd_line, int* argc, char*** argv);
#endif

private:
class ctkInternal;
Expand Down
4 changes: 2 additions & 2 deletions Base/ctkTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ static void mouseEvent(QTest::MouseAction action, QWidget *widget, Qt::MouseButt
{
static const char *mouseActionNames[] =
{ "MousePress", "MouseRelease", "MouseClick", "MouseDClick", "MouseMove" };
QString warning = QString::fromLatin1("Mouse event \"%1\" not accepted by receiving widget");
QTest::qWarn(warning.arg(QString::fromLatin1(mouseActionNames[static_cast<int>(action)])).toLatin1());
QString warning = QLatin1String("Mouse event \"%1\" not accepted by receiving widget");
QTest::qWarn(warning.arg(QLatin1String(mouseActionNames[static_cast<int>(action)])).toLocal8Bit());
}
}

Expand Down
12 changes: 10 additions & 2 deletions Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,23 @@ int appLauncherMain(int argc, char** argv)

// --------------------------------------------------------------------------
#ifndef CTKAPPLAUNCHER_WITHOUT_CONSOLE_IO_SUPPORT
// NOTE: On Windows, wmain should be used to allow non-ASCII characters in command-line arguments
int main(int argc, char *argv[])
{
// Uncomment the next two lines to stop at application start (to give a chance to connect with a debugger)
// std::cout << "Attach debugger and hit Enter" << std::endl;
// std::cin.get();

return appLauncherMain(argc, argv);
}
#elif defined Q_OS_WIN32
int __stdcall WinMain(HINSTANCE hInstance,
int __stdcall wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd)
PWSTR lpCmdLine, int nShowCmd)
{
// Uncomment the next line to stop at application start (to give a chance to connect with a debugger)
// int msgboxID = MessageBox(NULL, "Attach your debugger", "Debug", MB_ICONWARNING);

Q_UNUSED(hInstance);
Q_UNUSED(hPrevInstance);
Q_UNUSED(nShowCmd);
Expand Down
Loading