summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp72
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h5
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp7
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h2
4 files changed, 53 insertions, 33 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index d082a2739a..41ebc95708 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -378,6 +378,34 @@ Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
static bool quitLockRefEnabled = true;
#endif
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+// Check whether the command line arguments match those passed to main()
+// by comparing to the global __argv/__argc (MS extension).
+// Deep comparison is required since argv/argc is rebuilt by WinMain for
+// GUI apps or when using MinGW due to its globbing.
+static inline bool isArgvModified(int argc, char **argv)
+{
+ if (__argc != argc)
+ return true;
+ if (__argv == argv)
+ return false;
+ for (int a = 0; a < argc; ++a) {
+ if (argv[a] != __argv[a] && strcmp(argv[a], __argv[a]))
+ return true;
+ }
+ return false;
+}
+
+static inline bool contains(int argc, char **argv, const char *needle)
+{
+ for (int a = 0; a < argc; ++a) {
+ if (!strcmp(argv[a], needle))
+ return true;
+ }
+ return false;
+}
+#endif // Q_OS_WIN && !Q_OS_WINRT
+
QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
:
#ifndef QT_NO_QOBJECT
@@ -385,9 +413,8 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
#endif
argc(aargc)
, argv(aargv)
-#ifdef Q_OS_WIN
- , origArgc(aargc)
- , origArgv(new char *[aargc])
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+ , modifiedArgv(false)
#endif
, application_type(QCoreApplicationPrivate::Tty)
#ifndef QT_NO_QOBJECT
@@ -404,9 +431,9 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
argc = 0;
argv = (char **)&empty;
}
-#ifdef Q_OS_WIN
- std::copy(argv, argv + argc, origArgv);
-#endif
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+ modifiedArgv = isArgvModified(argc, argv);
+#endif // Q_OS_WIN && !Q_OS_WINRT
#ifndef QT_NO_QOBJECT
QCoreApplicationPrivate::is_app_closing = false;
@@ -431,9 +458,6 @@ QCoreApplicationPrivate::~QCoreApplicationPrivate()
#ifndef QT_NO_QOBJECT
cleanupThreadData();
#endif
-#ifdef Q_OS_WIN
- delete [] origArgv;
-#endif
QCoreApplicationPrivate::clearApplicationFilePath();
}
@@ -2131,10 +2155,11 @@ qint64 QCoreApplication::applicationPid()
Latin1 locale. Most modern Unix systems do not have this limitation, as they are
Unicode-based.
- On NT-based Windows, this limitation does not apply either.
- On Windows, the arguments() are not built from the contents of argv/argc, as
- the content does not support Unicode. Instead, the arguments() are constructed
- from the return value of
+ On Windows, the list is built from the argc and argv parameters only if
+ modified argv/argc parameters are passed to the constructor. In that case,
+ encoding problems might occur.
+
+ Otherwise, the arguments() are constructed from the return value of
\l{http://msdn2.microsoft.com/en-us/library/ms683156(VS.85).aspx}{GetCommandLine()}.
As a result of this, the string given by arguments().at(0) might not be
the program name on Windows, depending on how the application was started.
@@ -2169,21 +2194,20 @@ QStringList QCoreApplication::arguments()
}
#endif // Q_OS_WINCE
- char ** const origArgv = self->d_func()->origArgv;
- const int origArgc = self->d_func()->origArgc;
- char ** const avEnd = av + ac;
-
- const QStringList allArguments = qWinCmdArgs(cmdline);
- Q_ASSERT(allArguments.size() == origArgc);
- for (int i = 0; i < origArgc; ++i)
- if (std::find(av, avEnd, origArgv[i]) != avEnd)
- list.push_back(allArguments.at(i));
+ if (!self->d_func()->modifiedArgv) {
+ const QStringList allArguments = qWinCmdArgs(cmdline);
+ Q_ASSERT(allArguments.size() == __argc);
+ for (int i = 0; i < __argc; ++i) {
+ if (contains(ac, av, __argv[i]))
+ list.append(allArguments.at(i));
+ }
+ return list;
+ } // Fall back to rebuilding from argv/argc when a modified argv was passed.
+#endif // defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-#else
for (int a = 0; a < ac; ++a) {
list << QString::fromLocal8Bit(av[a]);
}
-#endif
return list;
}
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index a3a0eaa68c..2b03fe2382 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -115,9 +115,8 @@ public:
int &argc;
char **argv;
-#ifdef Q_OS_WIN
- int origArgc;
- char **origArgv; // store unmodified arguments for QCoreApplication::arguments()
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+ bool modifiedArgv;
#endif
void appendApplicationPathToLibraryPaths(void);
diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
index 442d9db85c..6ffe2bc6fe 100644
--- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
+++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
@@ -109,11 +109,11 @@ void tst_QCoreApplication::qAppName()
QCOMPARE(QCoreApplication::applicationName(), QString::fromLatin1(appName));
}
-// "QCoreApplication::arguments() always parses arguments from actual command line on Windows
-// making this test invalid."
-#ifndef Q_OS_WIN
void tst_QCoreApplication::argc()
{
+#if defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
+ QSKIP("QCoreApplication::arguments() parses arguments from actual command line on this platform.");
+#endif
{
int argc = 1;
char *argv[] = { const_cast<char*>(QTest::currentAppName()) };
@@ -150,7 +150,6 @@ void tst_QCoreApplication::argc()
QCOMPARE(app.arguments().count(), 1);
}
}
-#endif
class EventGenerator : public QObject
{
diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h
index 6f09399654..33b7084809 100644
--- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h
+++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h
@@ -43,9 +43,7 @@ private slots:
void sendEventsOnProcessEvents(); // this must be the first test
void getSetCheck();
void qAppName();
-#ifndef Q_OS_WIN
void argc();
-#endif
void postEvent();
void removePostedEvents();
#ifndef QT_NO_THREAD