summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/qendian.qdoc2
-rw-r--r--src/corelib/global/qfeatures.txt7
-rw-r--r--src/corelib/global/qglobal.cpp10
-rw-r--r--src/corelib/global/qglobal.h6
-rw-r--r--src/corelib/global/qnamespace.h16
-rw-r--r--src/corelib/global/qnamespace.qdoc18
-rw-r--r--src/corelib/io/qfile.cpp22
-rw-r--r--src/corelib/io/qfsfileengine.cpp2
-rw-r--r--src/corelib/io/qfsfileengine_p.h4
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp72
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp278
-rw-r--r--src/corelib/io/qprocess.cpp394
-rw-r--r--src/corelib/io/qprocess.h39
-rw-r--r--src/corelib/io/qprocess_p.h19
-rw-r--r--src/corelib/io/qprocess_unix.cpp26
-rw-r--r--src/corelib/io/qprocess_win.cpp19
-rw-r--r--src/corelib/io/qresource.cpp6
-rw-r--r--src/corelib/kernel/qabstractitemmodel.cpp11
-rw-r--r--src/corelib/kernel/qcore_symbian_p.h6
-rw-r--r--src/corelib/kernel/qcore_unix_p.h3
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp7
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp21
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian_p.h7
-rw-r--r--src/corelib/kernel/qvariant.cpp68
-rw-r--r--src/corelib/kernel/qvariant.h5
-rw-r--r--src/corelib/plugin/qlibrary.cpp29
-rw-r--r--src/corelib/statemachine/qeventtransition.cpp6
-rw-r--r--src/corelib/statemachine/qeventtransition.h6
-rw-r--r--src/corelib/tools/qalgorithms.qdoc4
-rw-r--r--src/corelib/tools/qbytearray.h1
-rw-r--r--src/corelib/tools/qregexp.cpp35
31 files changed, 839 insertions, 310 deletions
diff --git a/src/corelib/global/qendian.qdoc b/src/corelib/global/qendian.qdoc
index e0ef662ca..949f7b88c 100644
--- a/src/corelib/global/qendian.qdoc
+++ b/src/corelib/global/qendian.qdoc
@@ -42,7 +42,7 @@
/*!
\headerfile <QtEndian>
\title Endian Conversion Functions
- \ingroup classlists
+ \ingroup funclists
\brief The <QtEndian> header provides functions to convert between
little and big endian representations of numbers.
*/
diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt
index 9408a5b21..3a6c0500e 100644
--- a/src/corelib/global/qfeatures.txt
+++ b/src/corelib/global/qfeatures.txt
@@ -1143,13 +1143,6 @@ Requires: UNDOSTACK LISTVIEW
Name: QUndoView
SeeAlso: ???
-Feature: SCRIPT
-Description: Provides support for the QtScript module
-Section: Utilities
-Requires: TEXTDATE DATESTRING PROPERTIES
-Name: QtScript
-SeeAlso: ???
-
Feature: ACCESSIBILITY
Description: Provides accessibility support.
Section: Utilities
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index c4fbc4996..d7ae78f5f 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -408,13 +408,13 @@ QT_BEGIN_NAMESPACE
/*!
\headerfile <QtGlobal>
\title Global Qt Declarations
- \ingroup classlists
+ \ingroup funclists
- \brief The <QtGlobal> header provides basic declarations and
- is included by all other Qt headers.
+ \brief The <QtGlobal> header file includes the fundamental global
+ declarations. It is included by most other Qt header files.
- The declarations include \l {types}, \l functions and
- \l macros.
+ The global declarations include \l{types}, \l{functions} and
+ \l{macros}.
The type definitions are partly convenience definitions for basic
types (some of which guarantee certain bit-sizes on all platforms
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 7dbbc1b79..93cc30f70 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1325,6 +1325,12 @@ class QDataStream;
# else
# define Q_GUI_EXPORT_INLINE inline
# endif
+#elif defined(Q_CC_RVCT)
+// we force RVCT not to export inlines by passing --visibility_inlines_hidden
+// so we need to just inline it, rather than exporting and inlining
+// note: this affects the contents of the DEF files (ie. these functions do not appear)
+# define Q_CORE_EXPORT_INLINE inline
+# define Q_GUI_EXPORT_INLINE inline
#else
# define Q_CORE_EXPORT_INLINE Q_CORE_EXPORT inline
# define Q_GUI_EXPORT_INLINE Q_GUI_EXPORT inline
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index f86ffd35f..ab9a3ca4a 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1445,6 +1445,17 @@ public:
RightToLeft
};
+ enum AnchorPoint {
+ AnchorLeft = 0,
+ AnchorHorizontalCenter,
+ AnchorRight,
+ AnchorTop,
+ AnchorVerticalCenter,
+ AnchorBottom
+ };
+
+
+
enum DropAction {
CopyAction = 0x1,
MoveAction = 0x2,
@@ -1580,6 +1591,11 @@ public:
Uninitialized
};
+ enum CoordinateSystem {
+ DeviceCoordinates,
+ LogicalCoordinates
+ };
+
enum TouchPointState {
TouchPointPressed = 0x01,
TouchPointMoved = 0x02,
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 319e2cef4..657e3673e 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -2422,6 +2422,24 @@
*/
/*!
+ \enum Qt::AnchorPoint
+
+ Specifies a side of a layout item that can be anchored. This is used by
+ QGraphicsAnchorLayout.
+
+ \value AnchorLeft The left side of a layout item.
+ \value AnchorHorizontalCenter A "virtual" side that is centered between the left and the
+ right side of a layout item.
+ \value AnchorRight The right side of a layout item.
+ \value AnchorTop The top side of a layout item.
+ \value AnchorVerticalCenter A "virtual" side that is centered between the top and the
+ bottom side of a layout item.
+ \value AnchorBottom The bottom side of a layout item.
+
+ \sa QGraphicsAnchorLayout
+*/
+
+/*!
\enum Qt::InputMethodHint
\value ImhNone No hints.
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 5e1a5e741..026c1fd99 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -52,10 +52,6 @@
# include "qcoreapplication.h"
#endif
-#if !defined(Q_OS_WINCE)
-#include <errno.h>
-#endif
-
#ifdef QT_NO_QOBJECT
#define tr(X) QString::fromLatin1(X)
#endif
@@ -653,11 +649,7 @@ QFile::remove()
unsetError();
return true;
}
-#if defined(Q_OS_WIN)
- d->setError(QFile::RemoveError, GetLastError());
-#else
- d->setError(QFile::RemoveError, errno);
-#endif
+ d->setError(QFile::RemoveError, fileEngine()->errorString());
}
return false;
}
@@ -812,7 +804,7 @@ QFile::link(const QString &linkName)
unsetError();
return true;
}
- d->setError(QFile::RenameError, errno);
+ d->setError(QFile::RenameError, fileEngine()->errorString());
return false;
}
@@ -1258,7 +1250,7 @@ QFile::resize(qint64 sz)
unsetError();
return true;
}
- d->setError(QFile::ResizeError, errno);
+ d->setError(QFile::ResizeError, fileEngine()->errorString());
return false;
}
@@ -1322,7 +1314,7 @@ QFile::setPermissions(Permissions permissions)
unsetError();
return true;
}
- d->setError(QFile::PermissionsError, errno);
+ d->setError(QFile::PermissionsError, fileEngine()->errorString());
return false;
}
@@ -1478,7 +1470,7 @@ bool QFile::seek(qint64 off)
d->setError(err, fileEngine()->errorString());
return false;
}
- d->error = NoError;
+ unsetError();
return true;
}
@@ -1506,7 +1498,7 @@ qint64 QFile::readLineData(char *data, qint64 maxlen)
qint64 QFile::readData(char *data, qint64 len)
{
Q_D(QFile);
- d->error = NoError;
+ unsetError();
if (!d->ensureFlushed())
return -1;
@@ -1588,7 +1580,7 @@ qint64
QFile::writeData(const char *data, qint64 len)
{
Q_D(QFile);
- d->error = NoError;
+ unsetError();
d->lastWasWrite = true;
bool buffered = !(d->openMode & Unbuffered);
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 3d109d137..1ca19cfc4 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -109,7 +109,7 @@ void QFSFileEnginePrivate::init()
{
is_sequential = 0;
tried_stat = 0;
-#ifdef Q_OS_UNIX
+#if !defined(Q_OS_WINCE)
need_lstat = 1;
is_link = 0;
#endif
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index 15cbf5cb3..b245dcaf7 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -137,10 +137,11 @@ public:
mutable uint is_sequential : 2;
mutable uint could_stat : 1;
mutable uint tried_stat : 1;
-#ifdef Q_OS_UNIX
+#if !defined(Q_OS_WINCE)
mutable uint need_lstat : 1;
mutable uint is_link : 1;
#endif
+
bool doStat() const;
bool isSymlink() const;
@@ -161,7 +162,6 @@ protected:
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
QAbstractFileEngine::FileFlags getPermissions() const;
- QString getLink() const;
#endif
};
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index 62edb0ef2..4a485bb2a 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -393,7 +393,10 @@ bool QFSFileEnginePrivate::nativeIsSequential() const
bool QFSFileEngine::remove()
{
Q_D(QFSFileEngine);
- return unlink(d->nativeFilePath.constData()) == 0;
+ bool ret = unlink(d->nativeFilePath.constData()) == 0;
+ if (!ret)
+ setError(QFile::RemoveError, qt_error_string(errno));
+ return ret;
}
bool QFSFileEngine::copy(const QString &newName)
@@ -421,6 +424,7 @@ bool QFSFileEngine::copy(const QString &newName)
return (err == KErrNone);
#else
// ### Add copy code for Unix here
+ setError(QFile::UnspecifiedError, QLatin1String("Not implemented!"));
return false;
#endif
}
@@ -428,13 +432,19 @@ bool QFSFileEngine::copy(const QString &newName)
bool QFSFileEngine::rename(const QString &newName)
{
Q_D(QFSFileEngine);
- return ::rename(d->nativeFilePath.constData(), QFile::encodeName(newName).constData()) == 0;
+ bool ret = ::rename(d->nativeFilePath.constData(), QFile::encodeName(newName).constData()) == 0;
+ if (!ret)
+ setError(QFile::RenameError, qt_error_string(errno));
+ return ret;
}
bool QFSFileEngine::link(const QString &newName)
{
Q_D(QFSFileEngine);
- return ::symlink(d->nativeFilePath.constData(), QFile::encodeName(newName).constData()) == 0;
+ bool ret = ::symlink(d->nativeFilePath.constData(), QFile::encodeName(newName).constData()) == 0;
+ if (!ret)
+ setError(QFile::RenameError, qt_error_string(errno));
+ return ret;
}
qint64 QFSFileEnginePrivate::nativeSize() const
@@ -583,21 +593,21 @@ QString QFSFileEngine::homePath()
QString QFSFileEngine::rootPath()
{
#if defined(Q_OS_SYMBIAN)
- return QString::fromLatin1("C:/");
+ return QLatin1String("C:/");
#else
- return QString::fromLatin1("/");
+ return QLatin1String("/");
#endif
}
QString QFSFileEngine::tempPath()
{
#ifdef Q_OS_SYMBIAN
- QString temp = QDir::currentPath().left(2);
- temp += QString::fromLatin1( "/system/temp/");
+ QString temp = QDir::currentPath().left(2);
+ temp += QLatin1String("/system/temp/");
#else
- QString temp = QFile::decodeName(qgetenv("TMPDIR"));
- if (temp.isEmpty())
- temp = QString::fromLatin1("/tmp/");
+ QString temp = QFile::decodeName(qgetenv("TMPDIR"));
+ if (temp.isEmpty())
+ temp = QLatin1String("/tmp/");
#endif
return temp;
}
@@ -620,7 +630,7 @@ QFileInfoList QFSFileEngine::drives()
qWarning("QDir::drives: Getting drives failed");
}
#else
- ret.append(rootPath());
+ ret.append(QFileInfo(rootPath()));
#endif
return ret;
}
@@ -767,11 +777,11 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const
else if (exists && (d->st.st_mode & S_IFMT) == S_IFDIR)
ret |= DirectoryType;
#if !defined(QWS) && defined(Q_OS_MAC)
- if((ret & DirectoryType) && (type & BundleType)) {
+ if ((ret & DirectoryType) && (type & BundleType)) {
QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath),
kCFURLPOSIXPathStyle, true);
UInt32 type, creator;
- if(CFBundleGetPackageInfoInDirectory(url, &type, &creator))
+ if (CFBundleGetPackageInfoInDirectory(url, &type, &creator))
ret |= BundleType;
}
#endif
@@ -932,9 +942,9 @@ QString QFSFileEngine::fileName(FileName file) const
#if !defined(QWS) && defined(Q_OS_MAC)
QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath),
kCFURLPOSIXPathStyle, true);
- if(CFDictionaryRef dict = CFBundleCopyInfoDictionaryForURL(url)) {
- if(CFTypeRef name = (CFTypeRef)CFDictionaryGetValue(dict, kCFBundleNameKey)) {
- if(CFGetTypeID(name) == CFStringGetTypeID())
+ if (CFDictionaryRef dict = CFBundleCopyInfoDictionaryForURL(url)) {
+ if (CFTypeRef name = (CFTypeRef)CFDictionaryGetValue(dict, kCFBundleNameKey)) {
+ if (CFGetTypeID(name) == CFStringGetTypeID())
return QCFString::toQString((CFStringRef)name);
}
}
@@ -1142,6 +1152,7 @@ QString QFSFileEngine::owner(FileOwner own) const
bool QFSFileEngine::setPermissions(uint perms)
{
Q_D(QFSFileEngine);
+ bool ret = false;
mode_t mode = 0;
if (perms & ReadOwnerPerm)
mode |= S_IRUSR;
@@ -1168,18 +1179,27 @@ bool QFSFileEngine::setPermissions(uint perms)
if (perms & ExeOtherPerm)
mode |= S_IXOTH;
if (d->fd != -1)
- return !fchmod(d->fd, mode);
- return !::chmod(d->nativeFilePath.constData(), mode);
+ ret = fchmod(d->fd, mode) == 0;
+ else
+ ret = ::chmod(d->nativeFilePath.constData(), mode) == 0;
+ if (!ret)
+ setError(QFile::PermissionsError, qt_error_string(errno));
+ return ret;
}
bool QFSFileEngine::setSize(qint64 size)
{
Q_D(QFSFileEngine);
+ bool ret = false;
if (d->fd != -1)
- return !QT_FTRUNCATE(d->fd, size);
- if (d->fh)
- return !QT_FTRUNCATE(QT_FILENO(d->fh), size);
- return !QT_TRUNCATE(d->nativeFilePath.constData(), size);
+ ret = QT_FTRUNCATE(d->fd, size) == 0;
+ else if (d->fh)
+ ret = QT_FTRUNCATE(QT_FILENO(d->fh), size) == 0;
+ else
+ ret = QT_TRUNCATE(d->nativeFilePath.constData(), size) == 0;
+ if (!ret)
+ setError(QFile::ResizeError, qt_error_string(errno));
+ return ret;
}
QDateTime QFSFileEngine::fileTime(FileTime time) const
@@ -1201,14 +1221,14 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
{
Q_Q(QFSFileEngine);
Q_UNUSED(flags);
- if (offset < 0) {
- q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
- return 0;
- }
if (openMode == QIODevice::NotOpen) {
q->setError(QFile::PermissionsError, qt_error_string(int(EACCES)));
return 0;
}
+ if (offset < 0) {
+ q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
+ return 0;
+ }
int access = 0;
if (openMode & QIODevice::ReadOnly) access |= PROT_READ;
if (openMode & QIODevice::WriteOnly) access |= PROT_WRITE;
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index e01b42b7a..f1f69e7dc 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -55,6 +55,7 @@
#if !defined(Q_OS_WINCE)
# include <sys/types.h>
# include <direct.h>
+# include <winioctl.h>
#else
# include <types.h>
#endif
@@ -88,6 +89,37 @@ typedef INT_PTR intptr_t;
# define INVALID_FILE_ATTRIBUTES (DWORD (-1))
#endif
+#if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) && !defined(Q_OS_WINCE)
+typedef struct _REPARSE_DATA_BUFFER {
+ ULONG ReparseTag;
+ USHORT ReparseDataLength;
+ USHORT Reserved;
+ union {
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ ULONG Flags;
+ WCHAR PathBuffer[1];
+ } SymbolicLinkReparseBuffer;
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ WCHAR PathBuffer[1];
+ } MountPointReparseBuffer;
+ struct {
+ UCHAR DataBuffer[1];
+ } GenericReparseBuffer;
+ };
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+
+# define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
+# define MAXIMUM_REPARSE_DATA_BUFFER_SIZE 16384
+#endif
+
QT_BEGIN_NAMESPACE
static QString readLink(const QString &link);
@@ -122,7 +154,7 @@ QT_END_INCLUDE_NAMESPACE
void QFSFileEnginePrivate::resolveLibs()
{
static bool triedResolve = false;
- if(!triedResolve) {
+ if (!triedResolve) {
// need to resolve the security info functions
// protect initialization
@@ -130,7 +162,7 @@ void QFSFileEnginePrivate::resolveLibs()
QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve));
// check triedResolve again, since another thread may have already
// done the initialization
- if(triedResolve) {
+ if (triedResolve) {
// another thread did initialize the security function pointers,
// so we shouldn't do it again.
return;
@@ -219,7 +251,7 @@ bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringL
if (resolveUNCLibs()) {
SHARE_INFO_1 *BufPtr, *p;
DWORD res;
- DWORD er=0,tr=0,resume=0, i;
+ DWORD er = 0, tr = 0, resume = 0, i;
do {
res = ptrNetShareEnum((wchar_t*)server.utf16(), 1, (LPBYTE *)&BufPtr, DWORD(-1), &er, &tr, &resume);
if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) {
@@ -231,7 +263,7 @@ bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringL
}
}
ptrNetApiBufferFree(BufPtr);
- } while (res==ERROR_MORE_DATA);
+ } while (res == ERROR_MORE_DATA);
return res == ERROR_SUCCESS;
}
return false;
@@ -780,21 +812,30 @@ bool QFSFileEnginePrivate::nativeIsSequential() const
bool QFSFileEngine::remove()
{
Q_D(QFSFileEngine);
- return ::DeleteFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16()) != 0;
+ bool ret = ::DeleteFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16()) != 0;
+ if (!ret)
+ setError(QFile::RemoveError, qt_error_string());
+ return ret;
}
bool QFSFileEngine::copy(const QString &copyName)
{
Q_D(QFSFileEngine);
- return ::CopyFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(),
- (wchar_t*)QFSFileEnginePrivate::longFileName(copyName).utf16(), true) != 0;
+ bool ret = ::CopyFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(),
+ (wchar_t*)QFSFileEnginePrivate::longFileName(copyName).utf16(), true) != 0;
+ if (!ret)
+ setError(QFile::CopyError, qt_error_string());
+ return ret;
}
bool QFSFileEngine::rename(const QString &newName)
{
Q_D(QFSFileEngine);
- return ::MoveFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(),
- (wchar_t*)QFSFileEnginePrivate::longFileName(newName).utf16()) != 0;
+ bool ret = ::MoveFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(),
+ (wchar_t*)QFSFileEnginePrivate::longFileName(newName).utf16()) != 0;
+ if (!ret)
+ setError(QFile::RenameError, qt_error_string());
+ return ret;
}
static inline bool mkDir(const QString &path)
@@ -884,7 +925,7 @@ bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) con
for (int slash=0; slash != -1; oldslash = slash) {
slash = dirName.indexOf(QDir::separator(), oldslash+1);
if (slash == -1) {
- if(oldslash == dirName.length())
+ if (oldslash == dirName.length())
break;
slash = dirName.length();
}
@@ -939,8 +980,8 @@ bool QFSFileEngine::setCurrentPath(const QString &path)
#if !defined(Q_OS_WINCE)
return ::SetCurrentDirectory((wchar_t*)path.utf16()) != 0;
#else
- qfsPrivateCurrentDir = QFSFileEnginePrivate::longFileName(path);
- return true;
+ qfsPrivateCurrentDir = QFSFileEnginePrivate::longFileName(path);
+ return true;
#endif
}
@@ -978,9 +1019,9 @@ QString QFSFileEngine::currentPath(const QString &fileName)
ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters.
return QDir::fromNativeSeparators(ret);
#else
- Q_UNUSED(fileName);
- if (qfsPrivateCurrentDir.isEmpty())
- qfsPrivateCurrentDir = QCoreApplication::applicationDirPath();
+ Q_UNUSED(fileName);
+ if (qfsPrivateCurrentDir.isEmpty())
+ qfsPrivateCurrentDir = QCoreApplication::applicationDirPath();
return QDir::fromNativeSeparators(qfsPrivateCurrentDir);
#endif
@@ -1012,15 +1053,15 @@ QString QFSFileEngine::homePath()
}
}
#endif
- if(ret.isEmpty() || !QFile::exists(ret)) {
+ if (ret.isEmpty() || !QFile::exists(ret)) {
ret = QString::fromLocal8Bit(qgetenv("USERPROFILE").constData());
- if(ret.isEmpty() || !QFile::exists(ret)) {
+ if (ret.isEmpty() || !QFile::exists(ret)) {
ret = QString::fromLocal8Bit(qgetenv("HOMEDRIVE").constData()) + QString::fromLocal8Bit(qgetenv("HOMEPATH").constData());
- if(ret.isEmpty() || !QFile::exists(ret)) {
+ if (ret.isEmpty() || !QFile::exists(ret)) {
ret = QString::fromLocal8Bit(qgetenv("HOME").constData());
- if(ret.isEmpty() || !QFile::exists(ret)) {
+ if (ret.isEmpty() || !QFile::exists(ret)) {
#if defined(Q_OS_WINCE)
- ret = QString::fromLatin1("\\My Documents");
+ ret = QLatin1String("\\My Documents");
if (!QFile::exists(ret))
#endif
ret = rootPath();
@@ -1034,12 +1075,12 @@ QString QFSFileEngine::homePath()
QString QFSFileEngine::rootPath()
{
#if defined(Q_OS_WINCE)
- QString ret = QString::fromLatin1("/");
+ QString ret = QLatin1String("/");
#elif defined(Q_FS_FAT)
QString ret = QString::fromLatin1(qgetenv("SystemDrive").constData());
- if(ret.isEmpty())
+ if (ret.isEmpty())
ret = QLatin1String("c:");
- ret += QLatin1Char('/');
+ ret.append(QLatin1Char('/'));
#elif defined(Q_OS_OS2EMX)
char dir[4];
_abspath(dir, QLatin1String("/"), _MAX_PATH);
@@ -1050,20 +1091,23 @@ QString QFSFileEngine::rootPath()
QString QFSFileEngine::tempPath()
{
- wchar_t tempPath[MAX_PATH];
- int success = GetTempPath(MAX_PATH, tempPath);
- QString ret = QString::fromWCharArray(tempPath);
-
- if (ret.isEmpty() || !success) {
+ QString ret;
+ {
+ wchar_t tempPath[MAX_PATH];
+ if (GetTempPath(MAX_PATH, tempPath))
+ ret = QString::fromWCharArray(tempPath);
+ if (!ret.isEmpty()) {
+ while (ret.endsWith(QLatin1Char('\\')))
+ ret.chop(1);
+ ret = QDir::fromNativeSeparators(ret);
+ }
+ }
+ if (ret.isEmpty()) {
#if !defined(Q_OS_WINCE)
- ret = QString::fromLatin1("c:/tmp");
+ ret = QLatin1String("c:/tmp");
#else
- ret = QString::fromLatin1("\\Temp");
+ ret = QLatin1String("/Temp");
#endif
- } else {
- ret = QDir::fromNativeSeparators(ret);
- while (ret.at(ret.length()-1) == QLatin1Char('/'))
- ret = ret.left(ret.length()-1);
}
return ret;
}
@@ -1076,21 +1120,21 @@ QFileInfoList QFSFileEngine::drives()
quint32 driveBits = (quint32) GetLogicalDrives() & 0x3ffffff;
#elif defined(Q_OS_OS2EMX)
quint32 driveBits, cur;
- if(DosQueryCurrentDisk(&cur,&driveBits) != NO_ERROR)
+ if (DosQueryCurrentDisk(&cur, &driveBits) != NO_ERROR)
exit(1);
driveBits &= 0x3ffffff;
#endif
char driveName[] = "A:/";
- while(driveBits) {
- if(driveBits & 1)
- ret.append(QString::fromLatin1(driveName));
+ while (driveBits) {
+ if (driveBits & 1)
+ ret.append(QFileInfo(QLatin1String(driveName)));
driveName[0]++;
driveBits = driveBits >> 1;
}
return ret;
#else
- ret.append(QString::fromLatin1("/"));
+ ret.append(QFileInfo(QLatin1String("/")));
return ret;
#endif
}
@@ -1103,10 +1147,11 @@ bool QFSFileEnginePrivate::doStat() const
if (filePath.isEmpty())
return could_stat;
+
QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath;
fname = fixIfRelativeUncPath(fname);
- UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
+ UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
if (fd != -1) {
#if !defined(Q_OS_WINCE)
@@ -1195,12 +1240,51 @@ bool QFSFileEnginePrivate::doStat() const
#endif
}
}
+
SetErrorMode(oldmode);
}
return could_stat;
}
+static QString readSymLink(const QString &link)
+{
+ QString result;
+#if !defined(Q_OS_WINCE)
+ HANDLE handle = CreateFile((wchar_t*)QFSFileEnginePrivate::longFileName(link).utf16(),
+ FILE_READ_EA,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ 0,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
+ 0);
+ if (handle != INVALID_HANDLE_VALUE) {
+ DWORD bufsize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
+ REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER*)qMalloc(bufsize);
+ DWORD retsize = 0;
+ if (::DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, 0, 0, rdb, bufsize, &retsize, 0)) {
+ if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
+ int length = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
+ int offset = rdb->MountPointReparseBuffer.SubstituteNameOffset / sizeof(wchar_t);
+ const wchar_t* PathBuffer = &rdb->MountPointReparseBuffer.PathBuffer[offset];
+ result = QString::fromWCharArray(PathBuffer, length);
+ } else {
+ int length = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
+ int offset = rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t);
+ const wchar_t* PathBuffer = &rdb->SymbolicLinkReparseBuffer.PathBuffer[offset];
+ result = QString::fromWCharArray(PathBuffer, length);
+ }
+ // cut-off "//?/" and "/??/"
+ if (result.size() > 4 && result.at(0) == QLatin1Char('\\') && result.at(2) == QLatin1Char('?') && result.at(3) == QLatin1Char('\\'))
+ result = result.mid(4);
+ }
+ qFree(rdb);
+ CloseHandle(handle);
+ }
+#endif // Q_OS_WINCE
+ return result;
+}
+
static QString readLink(const QString &link)
{
#if !defined(Q_OS_WINCE)
@@ -1224,11 +1308,11 @@ static QString readLink(const QString &link)
if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface.
IPersistFile *ppf;
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
- if(SUCCEEDED(hres)) {
+ if (SUCCEEDED(hres)) {
hres = ppf->Load((LPOLESTR)link.utf16(), STGM_READ);
//The original path of the link is retrieved. If the file/folder
//was moved, the return value still have the old path.
- if(SUCCEEDED(hres)) {
+ if (SUCCEEDED(hres)) {
if (psl->GetPath(szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY) == NOERROR)
ret = QString::fromWCharArray(szGotPath);
}
@@ -1258,14 +1342,6 @@ static QString readLink(const QString &link)
#endif // Q_OS_WINCE
}
-/*!
- \internal
-*/
-QString QFSFileEnginePrivate::getLink() const
-{
- return readLink(filePath);
-}
-
bool QFSFileEngine::link(const QString &newName)
{
#if !defined(Q_OS_WINCE)
@@ -1303,8 +1379,11 @@ bool QFSFileEngine::link(const QString &newName)
}
psl->Release();
}
- if(neededCoInit)
- CoUninitialize();
+ if (!ret)
+ setError(QFile::RenameError, qt_error_string());
+
+ if (neededCoInit)
+ CoUninitialize();
return ret;
#else
@@ -1319,7 +1398,10 @@ bool QFSFileEngine::link(const QString &newName)
// Need to append on our own
orgName.prepend(QLatin1Char('"'));
orgName.append(QLatin1Char('"'));
- return SUCCEEDED(SHCreateShortcut((wchar_t*)linkName.utf16(), (wchar_t*)orgName.utf16()));
+ bool ret = SUCCEEDED(SHCreateShortcut((wchar_t*)linkName.utf16(), (wchar_t*)orgName.utf16()));
+ if (!ret)
+ setError(QFile::RenameError, qt_error_string());
+ return ret;
#endif // Q_OS_WINCE
}
@@ -1425,6 +1507,41 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const
}
/*!
+ \internal
+*/
+bool QFSFileEnginePrivate::isSymlink() const
+{
+#if !defined(Q_OS_WINCE)
+ if (need_lstat) {
+ need_lstat = false;
+ is_link = false;
+
+ if (fileAttrib & FILE_ATTRIBUTE_REPARSE_POINT) {
+ QString path = QDir::toNativeSeparators(filePath);
+ // path for the FindFirstFile should not end with a trailing slash
+ while (path.endsWith(QLatin1Char('\\')))
+ path.chop(1);
+
+ WIN32_FIND_DATA findData;
+ HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(),
+ &findData);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ ::FindClose(hFind);
+ if ((findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
+ && (findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT
+ || findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
+ is_link = true;
+ }
+ }
+ }
+ }
+ return is_link;
+#else
+ return false;
+#endif // Q_OS_WINCE
+}
+
+/*!
\reimp
*/
QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::FileFlags type) const
@@ -1434,6 +1551,9 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil
// Force a stat, so that we're guaranteed to get up-to-date results
if (type & Refresh) {
d->tried_stat = 0;
+#if !defined(Q_OS_WINCE)
+ d->need_lstat = 1;
+#endif
}
if (type & PermsMask) {
@@ -1457,7 +1577,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil
ret |= FileType;
}
} else if (d->doStat()) {
- if (d->fileAttrib & FILE_ATTRIBUTE_REPARSE_POINT)
+ if ((type & LinkType) && d->isSymlink())
ret |= LinkType;
if (d->fileAttrib & FILE_ATTRIBUTE_DIRECTORY) {
ret |= DirectoryType;
@@ -1485,32 +1605,32 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil
QString QFSFileEngine::fileName(FileName file) const
{
Q_D(const QFSFileEngine);
- if(file == BaseName) {
+ if (file == BaseName) {
int slash = d->filePath.lastIndexOf(QLatin1Char('/'));
- if(slash == -1) {
+ if (slash == -1) {
int colon = d->filePath.lastIndexOf(QLatin1Char(':'));
- if(colon != -1)
+ if (colon != -1)
return d->filePath.mid(colon + 1);
return d->filePath;
}
return d->filePath.mid(slash + 1);
- } else if(file == PathName) {
- if(!d->filePath.size())
+ } else if (file == PathName) {
+ if (!d->filePath.size())
return d->filePath;
int slash = d->filePath.lastIndexOf(QLatin1Char('/'));
- if(slash == -1) {
- if(d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':'))
+ if (slash == -1) {
+ if (d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':'))
return d->filePath.left(2);
return QString(QLatin1Char('.'));
} else {
- if(!slash)
+ if (!slash)
return QString(QLatin1Char('/'));
- if(slash == 2 && d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':'))
+ if (slash == 2 && d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':'))
slash++;
return d->filePath.left(slash);
}
- } else if(file == AbsoluteName || file == AbsolutePathName) {
+ } else if (file == AbsoluteName || file == AbsolutePathName) {
QString ret;
if (!isRelativePath()) {
@@ -1524,7 +1644,7 @@ QString QFSFileEngine::fileName(FileName file) const
ret = d->filePath;
}
#else
- ret = d->filePath;
+ ret = d->filePath;
#endif
} else {
ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + d->filePath);
@@ -1553,7 +1673,7 @@ QString QFSFileEngine::fileName(FileName file) const
return ret.left(slash > 0 ? slash : 1);
}
return ret;
- } else if(file == CanonicalName || file == CanonicalPathName) {
+ } else if (file == CanonicalName || file == CanonicalPathName) {
if (!(fileFlags(ExistsFlag) & ExistsFlag))
return QString();
@@ -1567,9 +1687,14 @@ QString QFSFileEngine::fileName(FileName file) const
ret = ret.left(slash);
}
return ret;
- } else if(file == LinkName) {
- return QDir::fromNativeSeparators(d->getLink());
- } else if(file == BundleName) {
+ } else if (file == LinkName) {
+ QString ret;
+ if (d->filePath.endsWith(QLatin1String(".lnk")))
+ ret = readLink(d->filePath);
+ else if (d->doStat() && d->isSymlink())
+ ret = readSymLink(d->filePath);
+ return QDir::fromNativeSeparators(ret);
+ } else if (file == BundleName) {
return QString();
}
return d->filePath;
@@ -1643,7 +1768,9 @@ bool QFSFileEngine::setPermissions(uint perms)
if (mode == 0) // not supported
return false;
- ret = ::_wchmod((wchar_t*)d->longFileName(d->filePath).utf16(), mode) == 0;
+ ret = ::_wchmod((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), mode) == 0;
+ if (!ret)
+ setError(QFile::PermissionsError, qt_error_string(errno));
return ret;
}
@@ -1675,7 +1802,10 @@ bool QFSFileEngine::setSize(qint64 size)
// resize file on disk
QFile file(d->filePath);
if (file.open(QFile::ReadWrite)) {
- return file.resize(size);
+ bool ret = file.resize(size);
+ if (!ret)
+ setError(QFile::ResizeError, file.errorString());
+ return ret;
}
}
return false;
@@ -1778,11 +1908,11 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
Q_Q(QFSFileEngine);
Q_UNUSED(flags);
if (openMode == QFile::NotOpen) {
- q->setError(QFile::PermissionsError, qt_error_string());
+ q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
return 0;
}
if (offset == 0 && size == 0) {
- q->setError(QFile::UnspecifiedError, qt_error_string());
+ q->setError(QFile::UnspecifiedError, qt_error_string(ERROR_INVALID_PARAMETER));
return 0;
}
@@ -1864,7 +1994,7 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
{
Q_Q(QFSFileEngine);
if (!maps.contains(ptr)) {
- q->setError(QFile::PermissionsError, qt_error_string());
+ q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
return false;
}
uchar *start = ptr - maps[ptr].first;
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 18ed67633..057492d6d 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -101,27 +101,294 @@ QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
-static QHash<QString, QString> environmentHashFromList(const QStringList &environment)
+/*!
+ \class QProcessEnvironment
+
+ \brief The QProcessEnvironment class holds the environment variables that
+ can be passed to a program.
+
+ \ingroup io
+ \ingroup misc
+ \mainclass
+ \reentrant
+ \since 4.6
+
+ A process's environment is composed of a set of key=value pairs known as
+ environment variables. The QProcessEnvironment class wraps that concept
+ and allows easy manipulation of those variables. It's meant to be used
+ along with QProcess, to set the environment for child processes. It
+ cannot be used to change the current process's environment.
+
+ The environment of the calling process can be obtained using
+ QProcessEnvironment::systemEnvironment().
+
+ On Unix systems, the variable names are case-sensitive. For that reason,
+ this class will not touch the names of the variables. Note as well that
+ Unix environment allows both variable names and contents to contain arbitrary
+ binary data (except for the NUL character), but this is not supported by
+ QProcessEnvironment. This class only supports names and values that are
+ encodable by the current locale settings (see QTextCodec::codecForLocale).
+
+ On Windows, the variable names are case-insensitive. Therefore,
+ QProcessEnvironment will always uppercase the names and do case-insensitive
+ comparisons.
+
+ On Windows CE, the concept of environment does not exist. This class will
+ keep the values set for compatibility with other platforms, but the values
+ set will have no effect on the processes being created.
+
+ \sa QProcess, QProcess::systemEnvironment(), QProcess::setProcessEnvironment()
+*/
+#ifdef Q_OS_WIN
+static inline QProcessEnvironmentPrivate::Unit prepareName(const QString &name)
+{ return name.toUpper(); }
+static inline QProcessEnvironmentPrivate::Unit prepareName(const QByteArray &name)
+{ return QString::fromLocal8Bit(name).toUpper(); }
+static inline QString nameToString(const QProcessEnvironmentPrivate::Unit &name)
+{ return name; }
+static inline QProcessEnvironmentPrivate::Unit prepareValue(const QString &value)
+{ return value; }
+static inline QProcessEnvironmentPrivate::Unit prepareValue(const QByteArray &value)
+{ return QString::fromLocal8Bit(value); }
+static inline QString valueToString(const QProcessEnvironmentPrivate::Unit &value)
+{ return value; }
+static inline QByteArray valueToByteArray(const QProcessEnvironmentPrivate::Unit &value)
+{ return value.toLocal8Bit(); }
+#else
+static inline QProcessEnvironmentPrivate::Unit prepareName(const QByteArray &name)
+{ return name; }
+static inline QProcessEnvironmentPrivate::Unit prepareName(const QString &name)
+{ return name.toLocal8Bit(); }
+static inline QString nameToString(const QProcessEnvironmentPrivate::Unit &name)
+{ return QString::fromLocal8Bit(name); }
+static inline QProcessEnvironmentPrivate::Unit prepareValue(const QByteArray &value)
+{ return value; }
+static inline QProcessEnvironmentPrivate::Unit prepareValue(const QString &value)
+{ return value.toLocal8Bit(); }
+static inline QString valueToString(const QProcessEnvironmentPrivate::Unit &value)
+{ return QString::fromLocal8Bit(value); }
+static inline QByteArray valueToByteArray(const QProcessEnvironmentPrivate::Unit &value)
+{ return value; }
+#endif
+
+template<> void QSharedDataPointer<QProcessEnvironmentPrivate>::detach()
+{
+ if (d && d->ref == 1)
+ return;
+ QProcessEnvironmentPrivate *x = (d ? new QProcessEnvironmentPrivate(*d)
+ : new QProcessEnvironmentPrivate);
+ x->ref.ref();
+ if (d && !d->ref.deref())
+ delete d;
+ d = x;
+}
+
+QStringList QProcessEnvironmentPrivate::toList() const
{
- QHash<QString, QString> result;
- QStringList::ConstIterator it = environment.constBegin(),
- end = environment.constEnd();
+ QStringList result;
+ QHash<Unit, Unit>::ConstIterator it = hash.constBegin(),
+ end = hash.constEnd();
for ( ; it != end; ++it) {
- int equals = it->indexOf(QLatin1Char('='));
+ QString data = nameToString(it.key());
+ QString value = valueToString(it.value());
+ data.reserve(data.length() + value.length() + 1);
+ data.append(QLatin1Char('='));
+ data.append(value);
+ result << data;
+ }
+ return result;
+}
+QProcessEnvironment QProcessEnvironmentPrivate::fromList(const QStringList &list)
+{
+ QProcessEnvironment env;
+ QStringList::ConstIterator it = list.constBegin(),
+ end = list.constEnd();
+ for ( ; it != end; ++it) {
+ int pos = it->indexOf(QLatin1Char('='));
+ if (pos < 1)
+ continue;
+
+ QString value = it->mid(pos + 1);
QString name = *it;
- QString value;
- if (equals != -1) {
- name.truncate(equals);
-#ifdef Q_OS_WIN
- name = name.toUpper();
-#endif
- value = it->mid(equals + 1);
- }
- result.insert(name, value);
+ name.truncate(pos);
+ env.insert(name, value);
}
+ return env;
+}
- return result;
+/*!
+ Creates a new QProcessEnvironment object. This constructor creates an
+ empty environment. If set on a QProcess, this will cause the current
+ environment variables to be removed.
+*/
+QProcessEnvironment::QProcessEnvironment()
+ : d(0)
+{
+}
+
+/*!
+ Frees the resources associated with this QProcessEnvironment object.
+*/
+QProcessEnvironment::~QProcessEnvironment()
+{
+}
+
+/*!
+ Creates a QProcessEnvironment object that is a copy of \a other.
+*/
+QProcessEnvironment::QProcessEnvironment(const QProcessEnvironment &other)
+ : d(other.d)
+{
+}
+
+/*!
+ Copies the contents of the \a other QProcessEnvironment object into this
+ one.
+*/
+QProcessEnvironment &QProcessEnvironment::operator=(const QProcessEnvironment &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \fn bool QProcessEnvironment::operator !=(const QProcessEnvironment &other) const
+
+ Returns true if this and the \a other QProcessEnvironment objects are different.
+
+ \sa operator==()
+*/
+
+/*!
+ Returns true if this and the \a other QProcessEnvironment objects are equal.
+
+ Two QProcessEnvironment objects are considered equal if they have the same
+ set of key=value pairs. The comparison of keys is done case-sensitive on
+ platforms where the environment is case-sensitive.
+
+ \sa operator!=(), contains()
+*/
+bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const
+{
+ return d->hash == other.d->hash;
+}
+
+/*!
+ Returns true if this QProcessEnvironment object is empty: that is
+ there are no key=value pairs set.
+
+ \sa clear(), systemEnvironment(), insert()
+*/
+bool QProcessEnvironment::isEmpty() const
+{
+ return d ? d->hash.isEmpty() : true;
+}
+
+/*!
+ Removes all key=value pairs from this QProcessEnvironment object, making
+ it empty.
+
+ \sa isEmpty(), systemEnvironment()
+*/
+void QProcessEnvironment::clear()
+{
+ if (d)
+ d->hash.clear();
+}
+
+/*!
+ Returns true if the environment variable of name \a name is found in
+ this QProcessEnvironment object.
+
+ On Windows, variable names are case-insensitive, so the key is converted
+ to uppercase before searching. On other systems, names are case-sensitive
+ so no trasformation is applied.
+
+ \sa insert(), value()
+*/
+bool QProcessEnvironment::contains(const QString &name) const
+{
+ return d ? d->hash.contains(prepareName(name)) : false;
+}
+
+/*!
+ Inserts the environment variable of name \a name and contents \a value
+ into this QProcessEnvironment object. If that variable already existed,
+ it is replaced by the new value.
+
+ On Windows, variable names are case-insensitive, so this function always
+ uppercases the variable name before inserting. On other systems, names
+ are case-sensitive, so no transformation is applied.
+
+ On most systems, inserting a variable with no contents will have the
+ same effect for applications as if the variable had not been set at all.
+ However, to guarantee that there are no incompatibilities, to remove a
+ variable, please use the remove() function.
+
+ \sa contains(), remove(), value()
+*/
+void QProcessEnvironment::insert(const QString &name, const QString &value)
+{
+ d->hash.insert(prepareName(name), prepareValue(value));
+}
+
+/*!
+ Removes the environment variable identified by \a name from this
+ QProcessEnvironment object. If that variable did not exist before,
+ nothing happens.
+
+ On Windows, variable names are case-insensitive, so the key is converted
+ to uppercase before searching. On other systems, names are case-sensitive
+ so no trasformation is applied.
+
+ \sa contains(), insert(), value()
+*/
+void QProcessEnvironment::remove(const QString &name)
+{
+ if (d)
+ d->hash.remove(prepareName(name));
+}
+
+/*!
+ Searches this QProcessEnvironment object for a variable identified by
+ \a name and returns its value. If the variable is not found in this object,
+ then \a defaultValue is returned instead.
+
+ On Windows, variable names are case-insensitive, so the key is converted
+ to uppercase before searching. On other systems, names are case-sensitive
+ so no trasformation is applied.
+
+ \sa contains(), insert(), remove()
+*/
+QString QProcessEnvironment::value(const QString &name, const QString &defaultValue) const
+{
+ if (!d)
+ return defaultValue;
+
+ QProcessEnvironmentPrivate::Hash::ConstIterator it = d->hash.constFind(prepareName(name));
+ if (it == d->hash.constEnd())
+ return defaultValue;
+
+ return valueToString(it.value());
+}
+
+/*!
+ Converts this QProcessEnvironment object into a list of strings, one for
+ each environment variable that is set. The environment variable's name
+ and its value are separated by an equal character ('=').
+
+ The QStringList contents returned by this function are suitable for use
+ with the QProcess::setEnvironment function. However, it is recommended
+ to use QProcess::setProcessEnvironment instead since that will avoid
+ unnecessary copying of the data.
+
+ \sa systemEnvironment(), QProcess::systemEnvironment(), QProcess::environment(),
+ QProcess::setEnvironment()
+*/
+QStringList QProcessEnvironment::toStringList() const
+{
+ return d ? d->toList() : QStringList();
}
void QProcessPrivate::Channel::clear()
@@ -451,7 +718,6 @@ QProcessPrivate::QProcessPrivate()
sequenceNumber = 0;
exitCode = 0;
exitStatus = QProcess::NormalExit;
- environment = 0;
startupSocketNotifier = 0;
deathNotifier = 0;
notifier = 0;
@@ -482,7 +748,6 @@ QProcessPrivate::QProcessPrivate()
*/
QProcessPrivate::~QProcessPrivate()
{
- delete environment;
if (stdinChannel.process)
stdinChannel.process->stdoutChannel.clear();
if (stdoutChannel.process)
@@ -1235,6 +1500,7 @@ QProcess::ProcessState QProcess::state() const
}
/*!
+ \deprecated
Sets the environment that QProcess will use when starting a process to the
\a environment specified which consists of a list of key=value pairs.
@@ -1243,14 +1509,18 @@ QProcess::ProcessState QProcess::state() const
\snippet doc/src/snippets/qprocess-environment/main.cpp 0
- \sa environment(), systemEnvironment(), setEnvironmentHash()
+ \note This function is less efficient than the setProcessEnvironment()
+ function.
+
+ \sa environment(), setProcessEnvironment(), systemEnvironment()
*/
void QProcess::setEnvironment(const QStringList &environment)
{
- setEnvironmentHash(environmentHashFromList(environment));
+ setProcessEnvironment(QProcessEnvironmentPrivate::fromList(environment));
}
/*!
+ \deprecated
Returns the environment that QProcess will use when starting a
process, or an empty QStringList if no environment has been set
using setEnvironment() or setEnvironmentHash(). If no environment
@@ -1259,67 +1529,50 @@ void QProcess::setEnvironment(const QStringList &environment)
\note The environment settings are ignored on Windows CE and Symbian,
as there is no concept of an environment.
- \sa environmentHash(), setEnvironment(), systemEnvironment()
+ \sa processEnvironment(), setEnvironment(), systemEnvironment()
*/
QStringList QProcess::environment() const
{
Q_D(const QProcess);
-
- QStringList result;
- if (!d->environment)
- return result;
-
- QHash<QString, QString>::ConstIterator it = d->environment->constBegin(),
- end = d->environment->constEnd();
- for ( ; it != end; ++it) {
- QString data = it.key();
- data.reserve(data.length() + it.value().length() + 1);
- data.append(QLatin1Char('='));
- data.append(it.value());
- result << data;
- }
- return result;
+ return d->environment.toStringList();
}
/*!
- \since 4.5
+ \since 4.6
Sets the environment that QProcess will use when starting a process to the
- \a environment hash map.
+ \a environment object.
For example, the following code adds the \c{C:\\BIN} directory to the list of
executable paths (\c{PATHS}) on Windows and sets \c{TMPDIR}:
\snippet doc/src/snippets/qprocess-environment/main.cpp 1
- \sa environment(), systemEnvironmentHash(), setEnvironment()
+ Note how, on Windows, environment variable names are case-insensitive.
+
+ \sa processEnvironment(), QProcessEnvironment::systemEnvironment(), setEnvironment()
*/
-void QProcess::setEnvironmentHash(const QHash<QString, QString> &environment)
+void QProcess::setProcessEnvironment(const QProcessEnvironment &environment)
{
Q_D(QProcess);
- if (!d->environment)
- d->environment = new QHash<QString, QString>(environment);
- else
- *d->environment = environment;
+ d->environment = environment;
}
/*!
- \since 4.5
+ \since 4.6
Returns the environment that QProcess will use when starting a
- process, or an empty QHash if no environment has been set using
- setEnvironment() or setEnvironmentHash(). If no environment has
+ process, or an empty object if no environment has been set using
+ setEnvironment() or setProcessEnvironment(). If no environment has
been set, the environment of the calling process will be used.
\note The environment settings are ignored on Windows CE,
as there is no concept of an environment.
- \sa setEnvironmentHash(), setEnvironment(), systemEnvironmentHash()
+ \sa setProcessEnvironment(), setEnvironment(), QProcessEnvironment::isValid()
*/
-QHash<QString, QString> QProcess::environmentHash() const
+QProcessEnvironment QProcess::processEnvironment() const
{
Q_D(const QProcess);
- if (d->environment)
- return *d->environment;
- return QHash<QString, QString>();
+ return d->environment;
}
/*!
@@ -1924,7 +2177,16 @@ QT_END_INCLUDE_NAMESPACE
\snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 8
- \sa systemEnvironmentHash(), environment(), setEnvironment()
+ This function does not cache the system environment. Therefore, it's
+ possible to obtain an updated version of the environment if low-level C
+ library functions like \tt setenv ot \tt putenv have been called.
+
+ However, note that repeated calls to this function will recreate the
+ list of environment variables, which is a non-trivial operation.
+
+ \note For new code, it is recommended to use QProcessEvironment::systemEnvironment()
+
+ \sa QProcessEnvironment::systemEnvironment(), environment(), setEnvironment()
*/
QStringList QProcess::systemEnvironment()
{
@@ -1937,15 +2199,33 @@ QStringList QProcess::systemEnvironment()
}
/*!
- \since 4.5
+ \since 4.6
+
+ Returns the environment of the calling process as a QProcessEnvironment.
- Returns the environment of the calling process as a QHash.
+ This function does not cache the system environment. Therefore, it's
+ possible to obtain an updated version of the environment if low-level C
+ library functions like \tt setenv ot \tt putenv have been called.
- \sa systemEnvironment(), environmentHash(), setEnvironmentHash()
+ However, note that repeated calls to this function will recreate the
+ QProcessEnvironment object, which is a non-trivial operation.
+
+ \sa QProcess::systemEnvironment()
*/
-QHash<QString, QString> QProcess::systemEnvironmentHash()
+QProcessEnvironment QProcessEnvironment::systemEnvironment()
{
- return environmentHashFromList(systemEnvironment());
+ QProcessEnvironment env;
+ const char *entry;
+ for (int count = 0; (entry = environ[count]); ++count) {
+ const char *equal = strchr(entry, '=');
+ if (!equal)
+ continue;
+
+ QByteArray name(entry, equal - entry);
+ QByteArray value(equal + 1);
+ env.insert(QString::fromLocal8Bit(name), QString::fromLocal8Bit(value));
+ }
+ return env;
}
/*!
diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h
index 5faca5c6e..e0c7efb92 100644
--- a/src/corelib/io/qprocess.h
+++ b/src/corelib/io/qprocess.h
@@ -44,6 +44,7 @@
#include <QtCore/qiodevice.h>
#include <QtCore/qstringlist.h>
+#include <QtCore/qshareddata.h>
QT_BEGIN_HEADER
@@ -53,8 +54,6 @@ QT_MODULE(Core)
#ifndef QT_NO_PROCESS
-template <class Key, class T> class QHash;
-
#if (!defined(Q_OS_WIN32) && !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)) || defined(qdoc)
typedef qint64 Q_PID;
#elif defined(Q_OS_SYMBIAN)
@@ -69,6 +68,37 @@ QT_BEGIN_NAMESPACE
#endif
class QProcessPrivate;
+class QProcessEnvironmentPrivate;
+
+class Q_CORE_EXPORT QProcessEnvironment
+{
+public:
+ QProcessEnvironment();
+ QProcessEnvironment(const QProcessEnvironment &other);
+ ~QProcessEnvironment();
+ QProcessEnvironment &operator=(const QProcessEnvironment &other);
+
+ bool operator==(const QProcessEnvironment &other) const;
+ inline bool operator!=(const QProcessEnvironment &other) const
+ { return !(*this == other); }
+
+ bool isEmpty() const;
+ void clear();
+
+ bool contains(const QString &name) const;
+ void insert(const QString &name, const QString &value);
+ void remove(const QString &name);
+ QString value(const QString &name, const QString &defaultValue = QString()) const;
+
+ QStringList toStringList() const;
+
+ static QProcessEnvironment systemEnvironment();
+
+private:
+ friend class QProcessPrivate;
+ friend class QProcessEnvironmentPrivate;
+ QSharedDataPointer<QProcessEnvironmentPrivate> d;
+};
class Q_CORE_EXPORT QProcess : public QIODevice
{
@@ -128,8 +158,8 @@ public:
void setEnvironment(const QStringList &environment);
QStringList environment() const;
- void setEnvironmentHash(const QHash<QString, QString> &environment);
- QHash<QString, QString> environmentHash() const;
+ void setProcessEnvironment(const QProcessEnvironment &environment);
+ QProcessEnvironment processEnvironment() const;
QProcess::ProcessError error() const;
QProcess::ProcessState state() const;
@@ -165,7 +195,6 @@ public:
static bool startDetached(const QString &program);
static QStringList systemEnvironment();
- static QHash<QString, QString> systemEnvironmentHash();
public Q_SLOTS:
void terminate();
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index 34797b9a9..62a2ecc08 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -55,6 +55,8 @@
#include "QtCore/qprocess.h"
#include "QtCore/qstringlist.h"
+#include "QtCore/qhash.h"
+#include "QtCore/qshareddata.h"
#include "private/qringbuffer_p.h"
#include "private/qiodevice_p.h"
@@ -76,6 +78,21 @@ class QWindowsPipeWriter;
class QWinEventNotifier;
class QTimer;
+class QProcessEnvironmentPrivate: public QSharedData
+{
+public:
+#ifdef Q_OS_WIN
+ typedef QString Unit;
+#else
+ typedef QByteArray Unit;
+#endif
+ typedef QHash<Unit, Unit> Hash;
+ Hash hash;
+
+ static QProcessEnvironment fromList(const QStringList &list);
+ QStringList toList() const;
+};
+
class QProcessPrivate : public QIODevicePrivate
{
public:
@@ -161,7 +178,7 @@ public:
QString program;
QStringList arguments;
- QHash<QString, QString> *environment;
+ QProcessEnvironment environment;
QRingBuffer outputReadBuffer;
QRingBuffer errorReadBuffer;
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index d28cdc4f5..dfeeb71cf 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -458,11 +458,11 @@ bool QProcessPrivate::createChannel(Channel &channel)
}
}
-static char **_q_dupEnvironment(const QHash<QString, QString> *environment, int *envc)
+static char **_q_dupEnvironment(const QHash<QByteArray, QByteArray> &environment, int *envc)
{
*envc = 0;
- if (!environment)
- return 0; // use the default environment
+ if (environment.isEmpty())
+ return 0;
// if LD_LIBRARY_PATH exists in the current environment, but
// not in the environment list passed by the programmer, then
@@ -474,17 +474,17 @@ static char **_q_dupEnvironment(const QHash<QString, QString> *environment, int
#endif
const QByteArray envLibraryPath = qgetenv(libraryPath);
bool needToAddLibraryPath = !envLibraryPath.isEmpty() &&
- !environment->contains(QLatin1String(libraryPath));
+ !environment.contains(libraryPath);
- char **envp = new char *[environment->count() + 2];
- envp[environment->count()] = 0;
- envp[environment->count() + 1] = 0;
+ char **envp = new char *[environment.count() + 2];
+ envp[environment.count()] = 0;
+ envp[environment.count() + 1] = 0;
- QHash<QString, QString>::ConstIterator it = environment->constBegin();
- const QHash<QString, QString>::ConstIterator end = environment->constEnd();
+ QHash<QByteArray, QByteArray>::ConstIterator it = environment.constBegin();
+ const QHash<QByteArray, QByteArray>::ConstIterator end = environment.constEnd();
for ( ; it != end; ++it) {
- QByteArray key = it.key().toLocal8Bit();
- QByteArray value = it.value().toLocal8Bit();
+ QByteArray key = it.key();
+ QByteArray value = it.value();
key.reserve(key.length() + 1 + value.length());
key.append('=');
key.append(value);
@@ -590,7 +590,9 @@ void QProcessPrivate::startProcess()
// Duplicate the environment.
int envc = 0;
- char **envp = _q_dupEnvironment(environment, &envc);
+ char **envp = 0;
+ if (environment.d.constData())
+ envp = _q_dupEnvironment(environment.d.constData()->hash, &envc);
// Encode the working directory if it's non-empty, otherwise just pass 0.
const char *workingDirPtr = 0;
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index acb169f75..8ece6ecf0 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -278,17 +278,17 @@ static QString qt_create_commandline(const QString &program, const QStringList &
return args;
}
-static QByteArray qt_create_environment(const QHash<QString, QString> *environment)
+static QByteArray qt_create_environment(const QHash<QString, QString> &environment)
{
QByteArray envlist;
- if (environment) {
- QHash<QString, QString> copy = *environment;
+ if (!environment.isEmpty()) {
+ QHash<QString, QString> copy = environment;
// add PATH if necessary (for DLL loading)
if (!copy.contains(QLatin1String("PATH"))) {
QByteArray path = qgetenv("PATH");
if (!path.isEmpty())
- copy.insert(QLatin1String("PATH"), QString::fromLocal8Bit(path));
+ copy.insert(QLatin1String("PATH"), QString::fromLocal8Bit(path));
}
// add systemroot if needed
@@ -362,7 +362,9 @@ void QProcessPrivate::startProcess()
QString args = qt_create_commandline(QString(), arguments);
#else
QString args = qt_create_commandline(program, arguments);
- QByteArray envlist = qt_create_environment(environment);
+ QByteArray envlist;
+ if (environment.d.constData())
+ envlist = qt_create_environment(environment.d.constData()->hash);
#endif
#if defined QPROCESS_DEBUG
@@ -393,9 +395,13 @@ void QProcessPrivate::startProcess()
};
success = CreateProcess(0, (wchar_t*)args.utf16(),
0, 0, TRUE, dwCreationFlags,
- environment ? envlist.data() : 0,
+ environment.isEmpty() ? 0 : envlist.data(),
workingDirectory.isEmpty() ? 0 : (wchar_t*)QDir::toNativeSeparators(workingDirectory).utf16(),
&startupInfo, pid);
+ if (!success) {
+ // Capture the error string before we do CloseHandle below
+ q->setErrorString(QProcess::tr("Process failed to start: %1").arg(qt_error_string()));
+ }
if (stdinChannel.pipe[0] != INVALID_Q_PIPE) {
CloseHandle(stdinChannel.pipe[0]);
@@ -414,7 +420,6 @@ void QProcessPrivate::startProcess()
if (!success) {
cleanup();
processError = QProcess::FailedToStart;
- q->setErrorString(QProcess::tr("Process failed to start"));
emit q->error(processError);
q->setProcessState(QProcess::NotRunning);
return;
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index ab4a7b746..ff1a31f58 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1485,11 +1485,7 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory
{
Q_Q(QResourceFileEngine);
Q_UNUSED(flags);
- if (!resource.isValid()
- || offset < 0
- || size < 0
- || offset + size > resource.size()
- || (size == 0)) {
+ if (offset < 0 || size <= 0 || !resource.isValid() || offset + size > resource.size()) {
q->setError(QFile::UnspecifiedError, QString());
return 0;
}
diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp
index 17af60db7..3b7059b0d 100644
--- a/src/corelib/kernel/qabstractitemmodel.cpp
+++ b/src/corelib/kernel/qabstractitemmodel.cpp
@@ -1216,7 +1216,16 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
layoutChanged() after changing the layout.
Subclasses should update any persistent model indexes before emitting
- layoutChanged().
+ layoutChanged(). In other words, when the structure changes:
+
+ \list
+ \o Call beginLayoutChanged()
+ \o Remember the QModelIndex that will change
+ \o Update your internal data
+ \o Call changePersistentIndex()
+ \o Call endLayoutChanged()
+ \endlist
+
\sa layoutAboutToBeChanged(), dataChanged(), headerDataChanged(), reset(),
changePersistentIndex()
diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h
index 60bf95e68..6d3616f19 100644
--- a/src/corelib/kernel/qcore_symbian_p.h
+++ b/src/corelib/kernel/qcore_symbian_p.h
@@ -95,6 +95,12 @@ static inline TPtrC qt_QString2TPtrC( const QString& string )
return TPtrC16(static_cast<const TUint16*>(string.utf16()), string.length());
}
+/*!
+ \internal
+ This class is a wrapper around the Symbian HBufC descriptor class.
+ It makes sure that the heap allocated HBufC class is freed when it is
+ destroyed.
+*/
class Q_CORE_EXPORT QHBufC
{
public:
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index c83c24ba2..698b05b73 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -274,7 +274,8 @@ static inline int qt_safe_close(int fd)
#undef QT_CLOSE
#define QT_CLOSE qt_safe_close
-// Open C does not (yet?) implement these on Symbian OS and VxWorks doesn't have processes
+// - Open C does not (yet?) implement these on Symbian OS
+// - VxWorks doesn't have processes
#if !defined(Q_OS_SYMBIAN) && !defined(Q_OS_VXWORKS)
static inline int qt_safe_execve(const char *filename, char *const argv[],
char *const envp[])
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index dd3027b55..6d88d92e6 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -490,7 +490,7 @@ QCoreApplication::QCoreApplication(int &argc, char **argv)
{
init();
QCoreApplicationPrivate::eventDispatcher->startingUp();
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) && defined(Q_OS_SYMBIAN)
+#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
// Refresh factoryloader, as text codecs are requested during lib path
// resolving process and won't be therefore properly loaded.
// Unknown if this is symbian specific issue.
@@ -1768,9 +1768,8 @@ bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
function also assumes that the current directory has not been
changed by the application.
- In Symbian this function will return the application private directory
- in C-drive, not the path to executable itself, as those are always in
- /sys/bin.
+ In Symbian this function will return the application private directory,
+ not the path to executable itself, as those are always in \c {/sys/bin}.
\sa applicationFilePath()
*/
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index d7b9d925b..881e54644 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -184,7 +184,7 @@ QWakeUpActiveObject::~QWakeUpActiveObject()
void QWakeUpActiveObject::DoCancel()
{
- if (iStatus.Int() & KRequestPending) {
+ if (iStatus.Int() == KRequestPending) {
TRequestStatus *status = &iStatus;
QEventDispatcherSymbian::RequestComplete(status, KErrNone);
}
@@ -214,7 +214,7 @@ void QTimerActiveObject::DoCancel()
m_rTimer.Cancel();
m_rTimer.Close();
} else {
- if (iStatus.Int() & KRequestPending) {
+ if (iStatus.Int() == KRequestPending) {
TRequestStatus *status = &iStatus;
QEventDispatcherSymbian::RequestComplete(status, KErrNone);
}
@@ -225,6 +225,7 @@ void QTimerActiveObject::RunL()
{
int error;
QT_TRYCATCH_ERROR(error, Run());
+ // All Symbian error codes are negative.
if (error < 0) {
CActiveScheduler::Current()->Error(error); // stop and report here, as this timer will be deleted on scope exit
}
@@ -275,7 +276,7 @@ void QTimerActiveObject::Start()
}
SymbianTimerInfo::SymbianTimerInfo()
-: timerAO(0)
+ : timerAO(0)
{
}
@@ -300,7 +301,7 @@ QCompleteDeferredAOs::~QCompleteDeferredAOs()
void QCompleteDeferredAOs::complete()
{
- if (iStatus.Int() & KRequestPending) {
+ if (iStatus.Int() == KRequestPending) {
TRequestStatus *status = &iStatus;
QEventDispatcherSymbian::RequestComplete(status, KErrNone);
}
@@ -308,7 +309,7 @@ void QCompleteDeferredAOs::complete()
void QCompleteDeferredAOs::DoCancel()
{
- if (iStatus.Int() & KRequestPending) {
+ if (iStatus.Int() == KRequestPending) {
TRequestStatus *status = &iStatus;
QEventDispatcherSymbian::RequestComplete(status, KErrNone);
}
@@ -369,10 +370,8 @@ void QSelectThread::run()
int ret;
int savedSelectErrno;
- //do {
- ret = qt_socket_select(maxfd, &readfds, &writefds, &exceptionfds, 0);
- savedSelectErrno = errno;
- //} while (ret == 0);
+ ret = qt_socket_select(maxfd, &readfds, &writefds, &exceptionfds, 0);
+ savedSelectErrno = errno;
char buffer;
@@ -405,7 +404,6 @@ void QSelectThread::run()
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptionfds);
- {
for (QHash<QSocketNotifier *, TRequestStatus *>::const_iterator i = m_AOStatuses.begin();
i != m_AOStatuses.end(); ++i) {
@@ -434,7 +432,6 @@ void QSelectThread::run()
}
} // end for
- }
// traversed all, so update
updateActivatedNotifiers(QSocketNotifier::Read, &readfds);
@@ -581,7 +578,7 @@ QSocketActiveObject::~QSocketActiveObject()
void QSocketActiveObject::DoCancel()
{
- if (iStatus.Int() & KRequestPending) {
+ if (iStatus.Int() == KRequestPending) {
TRequestStatus *status = &iStatus;
QEventDispatcherSymbian::RequestComplete(status, KErrNone);
}
diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h
index 69912d000..021de1358 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian_p.h
+++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h
@@ -281,13 +281,9 @@ private:
};
#ifdef QT_DEBUG
-// EActive is defined to 1 and ERequestPending to 2, but they are both private.
-// A little dangerous to rely on, but it is only for debugging.
-# define REQUEST_STATUS_ACTIVE_AND_PENDING 3
# define VERIFY_PENDING_REQUEST_STATUS \
- Q_ASSERT(status->Int() & REQUEST_STATUS_ACTIVE_AND_PENDING == REQUEST_STATUS_ACTIVE_AND_PENDING);
+ Q_ASSERT(status->Int() == KRequestPending);
#else
-# define REQUEST_STATUS_ACTIVE_AND_PENDING
# define VERIFY_PENDING_REQUEST_STATUS
#endif
@@ -304,7 +300,6 @@ inline void QEventDispatcherSymbian::RequestComplete(RThread &threadHandle, TReq
threadHandle.RequestComplete(status, reason);
}
-#undef REQUEST_STATUS_ACTIVE_AND_PENDING
#undef VERIFY_PENDING_REQUEST_STATUS
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index ebd2e3031..a16ece123 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -156,16 +156,7 @@ static void construct(QVariant::Private *x, const void *copy)
x->data.b = copy ? *static_cast<const bool *>(copy) : false;
break;
case QVariant::Double:
-#if defined(Q_CC_RVCT)
- // Using trinary operator with 64bit constants crashes when ran on Symbian device
- if (copy){
- x->data.d = *static_cast<const double*>(copy);
- } else {
- x->data.d = 0.0;
- }
-#else
x->data.d = copy ? *static_cast<const double*>(copy) : 0.0;
-#endif
break;
case QMetaType::Float:
x->data.f = copy ? *static_cast<const float*>(copy) : 0.0f;
@@ -174,37 +165,22 @@ static void construct(QVariant::Private *x, const void *copy)
x->data.o = copy ? *static_cast<QObject *const*>(copy) : 0;
break;
case QVariant::LongLong:
-#if defined(Q_CC_RVCT)
- // Using trinary operator with 64bit constants crashes when ran on Symbian device
- if (copy){
- x->data.ll = *static_cast<const qlonglong *>(copy);
- } else {
- x->data.ll = Q_INT64_C(0);
- }
-#else
x->data.ll = copy ? *static_cast<const qlonglong *>(copy) : Q_INT64_C(0);
-#endif
break;
case QVariant::ULongLong:
-#if defined(Q_CC_RVCT)
- // Using trinary operator with 64bit constants crashes when ran on Symbian device
- if (copy){
- x->data.ull = *static_cast<const qulonglong *>(copy);
- } else {
- x->data.ull = Q_UINT64_C(0);
- }
-#else
x->data.ull = copy ? *static_cast<const qulonglong *>(copy) : Q_UINT64_C(0);
-#endif
break;
case QVariant::Invalid:
case QVariant::UserType:
break;
default:
- x->is_shared = true;
- x->data.shared = new QVariant::PrivateShared(QMetaType::construct(x->type, copy));
- if (!x->data.shared->ptr)
+ void *ptr = QMetaType::construct(x->type, copy);
+ if (!ptr) {
x->type = QVariant::Invalid;
+ } else {
+ x->is_shared = true;
+ x->data.shared = new QVariant::PrivateShared(ptr);
+ }
break;
}
x->is_null = !copy;
@@ -483,15 +459,17 @@ static bool compare(const QVariant::Private *a, const QVariant::Private *b)
if (!QMetaType::isRegistered(a->type))
qFatal("QVariant::compare: type %d unknown to QVariant.", a->type);
+ const void *a_ptr = a->is_shared ? a->data.shared->ptr : &(a->data.ptr);
+ const void *b_ptr = b->is_shared ? b->data.shared->ptr : &(b->data.ptr);
+
/* The reason we cannot place this test in a case branch above for the types
* QMetaType::VoidStar, QMetaType::QObjectStar and so forth, is that it wouldn't include
* user defined pointer types. */
const char *const typeName = QMetaType::typeName(a->type);
if (typeName[qstrlen(typeName) - 1] == '*')
- return *static_cast<void **>(a->data.shared->ptr) ==
- *static_cast<void **>(b->data.shared->ptr);
+ return *static_cast<void *const *>(a_ptr) == *static_cast<void *const *>(b_ptr);
- return a->data.shared->ptr == b->data.shared->ptr;
+ return a_ptr == b_ptr;
}
/*!
@@ -1398,7 +1376,7 @@ void QVariant::create(int type, const void *copy)
QVariant::~QVariant()
{
- if (d.type > Char && d.type != QMetaType::Float && d.type != QMetaType::QObjectStar && (!d.is_shared || !d.data.shared->ref.deref()))
+ if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char && d.type < UserType))
handler->clear(&d);
}
@@ -1414,7 +1392,7 @@ QVariant::QVariant(const QVariant &p)
{
if (d.is_shared) {
d.data.shared->ref.ref();
- } else if (p.d.type > Char && p.d.type != QMetaType::Float && p.d.type != QMetaType::QObjectStar) {
+ } else if (p.d.type > Char && p.d.type < QVariant::UserType) {
handler->construct(&d, p.constData());
d.is_null = p.d.is_null;
}
@@ -1654,6 +1632,22 @@ QVariant::QVariant(Type type)
{ create(type, 0); }
QVariant::QVariant(int typeOrUserType, const void *copy)
{ create(typeOrUserType, copy); d.is_null = false; }
+
+/*! \internal
+ flags is true if it is a pointer type
+ */
+QVariant::QVariant(int typeOrUserType, const void *copy, uint flags)
+{
+ if (flags) { //type is a pointer type
+ d.type = typeOrUserType;
+ d.data.ptr = *reinterpret_cast<void *const*>(copy);
+ d.is_null = false;
+ } else {
+ create(typeOrUserType, copy);
+ d.is_null = false;
+ }
+}
+
QVariant::QVariant(int val)
{ d.is_null = false; d.type = Int; d.data.i = val; }
QVariant::QVariant(uint val)
@@ -1770,7 +1764,7 @@ QVariant& QVariant::operator=(const QVariant &variant)
if (variant.d.is_shared) {
variant.d.data.shared->ref.ref();
d = variant.d;
- } else if (variant.d.type > Char && variant.d.type != QMetaType::Float && variant.d.type != QMetaType::QObjectStar) {
+ } else if (variant.d.type > Char && variant.d.type < UserType) {
d.type = variant.d.type;
handler->construct(&d, variant.constData());
d.is_null = variant.d.is_null;
@@ -1824,7 +1818,7 @@ const char *QVariant::typeName() const
*/
void QVariant::clear()
{
- if (!d.is_shared || !d.data.shared->ref.deref())
+ if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type < UserType && d.type > Char))
handler->clear(&d);
d.type = Invalid;
d.is_null = true;
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index d6a704ea3..97af54ba6 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -174,6 +174,7 @@ class Q_CORE_EXPORT QVariant
~QVariant();
QVariant(Type type);
QVariant(int typeOrUserType, const void *copy);
+ QVariant(int typeOrUserType, const void *copy, uint flags);
QVariant(const QVariant &other);
#ifndef QT_NO_DATASTREAM
@@ -445,7 +446,7 @@ inline bool qvariant_cast_helper(const QVariant &v, QVariant::Type tp, void *ptr
template <typename T>
inline QVariant qVariantFromValue(const T &t)
{
- return QVariant(qMetaTypeId<T>(reinterpret_cast<T *>(0)), &t);
+ return QVariant(qMetaTypeId<T>(reinterpret_cast<T *>(0)), &t, QTypeInfo<T>::isPointer);
}
template <>
@@ -464,7 +465,7 @@ inline void qVariantSetValue(QVariant &v, const T &t)
old->~T();
new (old) T(t); //call the copy constructor
} else {
- v = QVariant(type, &t);
+ v = QVariant(type, &t, QTypeInfo<T>::isPointer);
}
}
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 3a5bb5527..5cf65131c 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -421,7 +421,23 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB
#endif // Q_OS_UNIX && !Q_OS_MAC && !defined(Q_OS_SYMBIAN) && !defined(QT_NO_PLUGIN_CHECK)
typedef QMap<QString, QLibraryPrivate*> LibraryMap;
-Q_GLOBAL_STATIC(LibraryMap, libraryMap)
+
+struct LibraryData {
+ LibraryData() : settings(0) { }
+ ~LibraryData() {
+ delete settings;
+ }
+
+ QSettings *settings;
+ LibraryMap libraryMap;
+};
+
+Q_GLOBAL_STATIC(LibraryData, libraryData)
+
+static LibraryMap *libraryMap()
+{
+ return &(libraryData()->libraryMap);
+}
QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version)
:pHnd(0), fileName(canonicalFileName), fullVersion(version), instance(0), qt_version(0),
@@ -614,10 +630,12 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
.arg(fileName);
QStringList reg;
#ifndef QT_NO_SETTINGS
- QScopedPointer<QSettings> madeSettings;
if (!settings) {
- settings = new QSettings(QSettings::UserScope, QLatin1String("Trolltech"));
- madeSettings.reset(settings);
+ settings = libraryData()->settings;
+ if (!settings) {
+ settings = new QSettings(QSettings::UserScope, QLatin1String("Trolltech"));
+ libraryData()->settings = settings;
+ }
}
reg = settings->value(regkey).toStringList();
#endif
@@ -709,9 +727,6 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
settings->setValue(regkey, queried);
#endif
}
-#ifndef QT_NO_SETTINGS
- madeSettings.reset();
-#endif
if (!success) {
if (errorString.isEmpty()){
diff --git a/src/corelib/statemachine/qeventtransition.cpp b/src/corelib/statemachine/qeventtransition.cpp
index e2d1f6975..89dabdefb 100644
--- a/src/corelib/statemachine/qeventtransition.cpp
+++ b/src/corelib/statemachine/qeventtransition.cpp
@@ -92,7 +92,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \property QEventTransition::eventObject
+ \property QEventTransition::eventSource
\brief the event source that this event transition is associated with
*/
@@ -205,7 +205,7 @@ void QEventTransition::setEventType(QEvent::Type type)
/*!
Returns the event source associated with this event transition.
*/
-QObject *QEventTransition::eventObject() const
+QObject *QEventTransition::eventSource() const
{
Q_D(const QEventTransition);
return d->object;
@@ -215,7 +215,7 @@ QObject *QEventTransition::eventObject() const
Sets the event source associated with this event transition to be the given
\a object.
*/
-void QEventTransition::setEventObject(QObject *object)
+void QEventTransition::setEventSource(QObject *object)
{
Q_D(QEventTransition);
if (d->object == object)
diff --git a/src/corelib/statemachine/qeventtransition.h b/src/corelib/statemachine/qeventtransition.h
index 6cf6a9640..941bfa505 100644
--- a/src/corelib/statemachine/qeventtransition.h
+++ b/src/corelib/statemachine/qeventtransition.h
@@ -57,15 +57,15 @@ class QEventTransitionPrivate;
class Q_CORE_EXPORT QEventTransition : public QAbstractTransition
{
Q_OBJECT
- Q_PROPERTY(QObject* eventObject READ eventObject WRITE setEventObject)
+ Q_PROPERTY(QObject* eventSource READ eventSource WRITE setEventSource)
Q_PROPERTY(QEvent::Type eventType READ eventType WRITE setEventType)
public:
QEventTransition(QState *sourceState = 0);
QEventTransition(QObject *object, QEvent::Type type, QState *sourceState = 0);
~QEventTransition();
- QObject *eventObject() const;
- void setEventObject(QObject *object);
+ QObject *eventSource() const;
+ void setEventSource(QObject *object);
QEvent::Type eventType() const;
void setEventType(QEvent::Type type);
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index f7b7798ef..771c544bd 100644
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -42,9 +42,9 @@
/*!
\headerfile <QtAlgorithms>
\title Generic Algorithms
- \ingroup classlists
+ \ingroup funclists
- \brief The <QtAlgorithms> header provides generic template-based algorithms.
+ \brief The <QtAlgorithms> header includes the generic, template-based algorithms.
Qt provides a number of global template functions in \c
<QtAlgorithms> that work on containers and perform well-know
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index 4c4f8fb14..300188dbd 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -321,6 +321,7 @@ public:
// stl compatibility
typedef const char & const_reference;
typedef char & reference;
+ typedef char value_type;
void push_back(char c);
void push_back(const char *c);
void push_back(const QByteArray &a);
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index 3cec0bf24..5e952ee64 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -1262,28 +1262,35 @@ struct QRegExpLookahead
};
#endif
-QRegExpEngine::QRegExpEngine(const QRegExpEngineKey &key)
- : cs(key.cs), greedyQuantifiers(key.patternSyntax == QRegExp::RegExp2),
- xmlSchemaExtensions(false)
-{
- setup();
-
- QString rx;
+/*! \internal
+ convert the pattern string to the RegExp syntax.
- switch (key.patternSyntax) {
- case QRegExp::Wildcard:
+ This is also used by QScriptEngine::newRegExp to convert to a pattern that JavaScriptCore can understan
+ */
+Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &pattern, QRegExp::PatternSyntax patternSyntax)
+{
+ switch (patternSyntax) {
#ifndef QT_NO_REGEXP_WILDCARD
- rx = wc2rx(key.pattern);
-#endif
+ case QRegExp::Wildcard:
+ return wc2rx(pattern);
break;
+#endif
case QRegExp::FixedString:
- rx = QRegExp::escape(key.pattern);
+ return QRegExp::escape(pattern);
break;
case QRegExp::W3CXmlSchema11:
- xmlSchemaExtensions = true;
default:
- rx = key.pattern;
+ return pattern;
}
+}
+
+QRegExpEngine::QRegExpEngine(const QRegExpEngineKey &key)
+ : cs(key.cs), greedyQuantifiers(key.patternSyntax == QRegExp::RegExp2),
+ xmlSchemaExtensions(key.patternSyntax == QRegExp::W3CXmlSchema11)
+{
+ setup();
+
+ QString rx = qt_regexp_toCanonical(key.pattern, key.patternSyntax);
valid = (parse(rx.unicode(), rx.length()) == rx.length());
if (!valid) {