diff options
Diffstat (limited to 'src/corelib/kernel/qcoreapplication.cpp')
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 102 |
1 files changed, 63 insertions, 39 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index aea82fd48b..18a379f8b9 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -48,7 +48,6 @@ #include <qhash.h> #include <qmutex.h> #include <private/qloggingregistry_p.h> -#include <private/qprocess_p.h> #include <qstandardpaths.h> #include <qtextcodec.h> #ifndef QT_NO_QOBJECT @@ -323,7 +322,7 @@ QCoreApplication *QCoreApplication::self = 0; uint QCoreApplicationPrivate::attribs = (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents); struct QCoreApplicationData { - QCoreApplicationData() { + QCoreApplicationData() Q_DECL_NOTHROW { #ifndef QT_NO_LIBRARY app_libpaths = 0; #endif @@ -384,6 +383,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 @@ -391,9 +418,9 @@ 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) + , origArgc(0) + , origArgv(Q_NULLPTR) #endif , application_type(QCoreApplicationPrivate::Tty) #ifndef QT_NO_QOBJECT @@ -410,9 +437,13 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint argc = 0; argv = (char **)∅ } -#ifdef Q_OS_WIN - std::copy(argv, argv + argc, origArgv); -#endif +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + if (!isArgvModified(argc, argv)) { + origArgc = argc; + origArgv = new char *[argc]; + std::copy(argv, argv + argc, origArgv); + } +#endif // Q_OS_WIN && !Q_OS_WINRT #ifndef QT_NO_QOBJECT QCoreApplicationPrivate::is_app_closing = false; @@ -437,7 +468,7 @@ QCoreApplicationPrivate::~QCoreApplicationPrivate() #ifndef QT_NO_QOBJECT cleanupThreadData(); #endif -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) delete [] origArgv; #endif QCoreApplicationPrivate::clearApplicationFilePath(); @@ -744,14 +775,6 @@ void QCoreApplication::init() d->appendApplicationPathToLibraryPaths(); #endif -#ifndef QT_NO_QOBJECT -#if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS)) - // Make sure the process manager thread object is created in the main - // thread. - QProcessPrivate::initializeProcessManager(); -#endif -#endif - #ifdef QT_EVAL extern void qt_core_eval_init(QCoreApplicationPrivate::Type); qt_core_eval_init(d->application_type); @@ -2158,10 +2181,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. @@ -2196,21 +2220,21 @@ 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)); + const QCoreApplicationPrivate *d = self->d_func(); + if (d->origArgv) { + const QStringList allArguments = qWinCmdArgs(cmdline); + Q_ASSERT(allArguments.size() == d->origArgc); + for (int i = 0; i < d->origArgc; ++i) { + if (contains(ac, av, d->origArgv[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; } |