QCoreApplication: No longer hardcode arguments to be filtered out.

On Windows, Unicode command line arguments are re-created from
the original command line filtering out the known arguments.
To avoid having to hard-code all arguments of derived application
classes, keep the original argv-array and use that to verify if
an argument is still present.

Task-number: QTBUG-25724
Change-Id: I5d7bbd9530b1b74e1dcd22a0edc4f323ef687d23
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Friedemann Kleint 2012-05-16 09:39:39 +02:00 committed by Qt by Nokia
parent 83f796d273
commit 420b62f202
2 changed files with 40 additions and 29 deletions

View File

@ -278,8 +278,18 @@ Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
static bool quitLockRefEnabled = true;
QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
: QObjectPrivate(), argc(aargc), argv(aargv), application_type(0), eventFilter(0),
in_exec(false), aboutToQuitEmitted(false), threadData_clean(false)
: QObjectPrivate()
, argc(aargc)
, argv(aargv)
#ifdef Q_OS_WIN
, origArgc(aargc)
, origArgv(new char *[aargc])
#endif
, application_type(0)
, eventFilter(0)
, in_exec(false)
, aboutToQuitEmitted(false)
, threadData_clean(false)
{
app_compile_version = flags & 0xffffff;
static const char *const empty = "";
@ -289,8 +299,10 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
}
QCoreApplicationPrivate::is_app_closing = false;
#ifdef Q_OS_UNIX
#if defined(Q_OS_UNIX)
qt_application_thread_id = QThread::currentThreadId();
#elif defined(Q_OS_WIN)
qCopy(argv, argv + argc, origArgv);
#endif
// note: this call to QThread::currentThread() may end up setting theMainThread!
@ -301,6 +313,9 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
QCoreApplicationPrivate::~QCoreApplicationPrivate()
{
cleanupThreadData();
#ifdef Q_OS_WIN
delete [] origArgv;
#endif
}
void QCoreApplicationPrivate::cleanupThreadData()
@ -1867,7 +1882,15 @@ QStringList QCoreApplication::arguments()
qWarning("QCoreApplication::arguments: Please instantiate the QApplication object first");
return list;
}
const int ac = self->d_func()->argc;
char ** const av = self->d_func()->argv;
list.reserve(ac);
#ifdef Q_OS_WIN
// On Windows, it is possible to pass Unicode arguments on
// the command line. To restore those, we split the command line
// and filter out arguments that were deleted by derived application
// classes by index.
QString cmdline = QString::fromWCharArray(GetCommandLine());
#if defined(Q_OS_WINCE)
@ -1878,33 +1901,17 @@ QStringList QCoreApplication::arguments()
}
#endif // Q_OS_WINCE
list = qWinCmdArgs(cmdline);
if (self->d_func()->application_type) { // GUI app? Skip known - see qapplication.cpp
QStringList stripped;
for (int a = 0; a < list.count(); ++a) {
QString arg = list.at(a);
QByteArray l1arg = arg.toLatin1();
if (l1arg == "-qdevel" ||
l1arg == "-qdebug" ||
l1arg == "-reverse" ||
l1arg == "-stylesheet" ||
l1arg == "-widgetcount")
;
else if (l1arg.startsWith("-style=") ||
l1arg.startsWith("-qmljsdebugger="))
;
else if (l1arg == "-style" ||
l1arg == "-session" ||
l1arg == "-testability")
++a;
else
stripped += arg;
}
list = stripped;
}
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 (qFind(av, avEnd, origArgv[i]) != avEnd)
list.push_back(allArguments.at(i));
#else
const int ac = self->d_func()->argc;
char ** const av = self->d_func()->argv;
for (int a = 0; a < ac; ++a) {
list << QString::fromLocal8Bit(av[a]);
}

View File

@ -109,6 +109,10 @@ public:
#endif
int &argc;
char **argv;
#ifdef Q_OS_WIN
int origArgc;
char **origArgv; // store unmodified arguments for QCoreApplication::arguments()
#endif
void appendApplicationPathToLibraryPaths(void);
void cleanupThreadData();