diff options
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 9 | ||||
-rw-r--r-- | src/corelib/io/qloggingcategory.cpp | 293 | ||||
-rw-r--r-- | src/corelib/io/qloggingcategory.h | 74 | ||||
-rw-r--r-- | src/corelib/io/qloggingregistry.cpp | 8 | ||||
-rw-r--r-- | src/corelib/io/qprocess_unix.cpp | 3 | ||||
-rw-r--r-- | src/corelib/io/qurlidna.cpp | 5 |
6 files changed, 385 insertions, 7 deletions
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index a7517b4c7f..46d8101e20 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -511,7 +511,14 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea if (slash) { const QByteArray chunk = QFile::encodeName(dirName.left(slash)); if (QT_MKDIR(chunk.constData(), 0777) != 0) { - if (errno == EEXIST) { + if (errno == EEXIST +#if defined(Q_OS_QNX) + // On QNX the QNet (VFS paths of other hosts mounted under a directory + // such as /net) mountpoint returns ENOENT, despite existing. stat() + // on the QNet mountpoint returns successfully and reports S_IFDIR. + || errno == ENOENT +#endif + ) { QT_STATBUF st; if (QT_STAT(chunk.constData(), &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR) continue; diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 562cf25964..80acee6ad1 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -107,7 +107,8 @@ QLoggingCategory::QLoggingCategory(const char *category) : name(0), enabledDebug(false), enabledWarning(true), - enabledCritical(true) + enabledCritical(true), + enabledTrace(false) { bool isDefaultCategory = (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0); @@ -122,7 +123,8 @@ QLoggingCategory::QLoggingCategory(const char *category) } if (QLoggingRegistry *reg = QLoggingRegistry::instance()) - reg->registerCategory(this);} + reg->registerCategory(this); +} /*! Destructs a QLoggingCategory object @@ -164,6 +166,7 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const case QtDebugMsg: return enabledDebug; case QtWarningMsg: return enabledWarning; case QtCriticalMsg: return enabledCritical; + case QtTraceMsg: return enabledTrace; case QtFatalMsg: return true; default: break; } @@ -177,6 +180,10 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const change e.g. the settings of another objects for the same category name. \note QtFatalMsg cannot be changed. It will always return true. + + Example: + + \snippet qtracer/ftracer.cpp 5 */ void QLoggingCategory::setEnabled(QtMsgType type, bool enable) { @@ -184,6 +191,7 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable) case QtDebugMsg: enabledDebug = enable; break; case QtWarningMsg: enabledWarning = enable; break; case QtCriticalMsg: enabledCritical = enable; break; + case QtTraceMsg: enabledTrace = enable; break; case QtFatalMsg: default: break; } @@ -319,12 +327,61 @@ void QLoggingCategory::setFilterRules(const QString &rules) \snippet qloggingcategory/main.cpp 12 \note Arguments are not processed if critical output for the category is not - enabled, so do not reply on any side effects. + enabled, so do not rely on any side effects. \sa qCritical() */ /*! + \relates QLoggingCategory + \macro qCTrace(category) + \since 5.2 + + Returns an output stream for trace messages in the logging category + \a category. + + The macro expands to code that first checks whether + \l QLoggingCategory::isEnabled() evaluates for trace output to \c{true}. + If so, the stream arguments are processed and sent to the tracers + registered with the category. + + \note Arguments are not processed if trace output for the category is not + enabled, so do not rely on any side effects. + + Example: + + \snippet qtracer/ftracer.cpp 6 + + \sa qCTraceGuard() +*/ + +/*! + \relates QLoggingCategory + \macro qCTraceGuard(category) + \since 5.2 + + The macro expands to code that creates a guard object with automatic + storage. The guard constructor checks whether + \l QLoggingCategory::isEnabled() evaluates for trace output to \c{true}. + If so, the stream arguments are processed and the \c{start()} + functions of the tracers registered with the \a category are called. + + The guard destructor also checks whether the category is enabled for + tracing and if so, the \c{end()} + functions of the tracers registered with the \a category are called. + + \note Arguments are always processed, even if trace output for the + category is disabled. They will, however, in that case not be passed + to the \c{record()} functions of the registered tracers. + + Example: + + \snippet qtracer/ftracer.cpp 4 + + \sa qCTrace() +*/ + +/*! \macro Q_DECLARE_LOGGING_CATEGORY(name) \relates QLoggingCategory \since 5.2 @@ -349,4 +406,234 @@ void QLoggingCategory::setFilterRules(const QString &rules) This macro must be used outside of a class or method. */ + +/*! + \class QTracer + \inmodule QtCore + \since 5.2 + + \brief The QTracer class provides an interface for handling + trace events associated with a logging category. + + \c QTracer objects are registered with logging categories. + Multiple \c QTracer objects + can be registered with the same category, and the same + \c QTracer object can be registered with different categories. + + If code containing \c qCTrace is executed, and the associated + logging category is enabled for tracing, all \c QTracer objects + that are registered with the category are notified. + + \c QTracer objects +*/ + +/*! + \fn QTracer::QTracer() + + Constructs a tracer object. + + Example: + + \snippet qtracer/ftracer.cpp 2 +*/ + +/*! + \fn QTracer::~QTracer() + + Destroys the tracer object. +*/ + +/*! + Registers this tracer for the \a category. + + The tracer will later be notified of messages of type + \c QtTraceMsg, as long as that message type + is enabled in the category. + + Example: + + \snippet qtracer/ftracer.cpp 1 + \codeline + \snippet qtracer/ftracer.cpp 7 +*/ + +void QTracer::addToCategory(QLoggingCategory &category) +{ + category.tracers.append(this); +} + +/*! + \fn void QTracer::start() + + This function is invoked when a tracing activity starts, + typically from the constructor of a \c QTraceGuard object + defined by \c qCTrace() or \c qCTraceGuard(). + + The base implementation does nothing. \c QTracer subclasses + are advised to override it if needed. + + \sa qCTrace(), qCTraceGuard() +*/ + +/*! + \fn void QTracer::end() + + This function is invoked when a tracing activity ends, + typically from the destructor of a \c QTraceGuard object + defined by \c qCTrace() or \c qCTraceGuard(). + + The base implementation does nothing. It is common for + \c QTracer subclasses to override it to perform flushing + of collected data. + + \sa qCTrace(), qCTraceGuard() +*/ + +/*! + \fn void QTracer::record(int data) + + This function is invoked during a tracing activity to + pass integer \a data to the \c QTracer object. + + Example: + + \snippet qtracer/ftracer.cpp 3 +*/ + +/*! + \fn void QTracer::record(const char *data) + + This function is invoked during a tracing activity to + pass string \a data to the \c QTracer object. +*/ + +/*! + \fn void QTracer::record(const QVariant &data) + + This function is invoked during a tracing activity to + pass abitrary (non-integer, non-string) \a data to + the \c QTracer object. +*/ + +/*! + \class QTraceGuard + \since 5.2 + \inmodule QtCore + + \brief The QTraceGuard class facilitates notifications to + \c QTracer objects. + + \c QTraceGuard objects are typically implicitly created on the + stack when using the \c qCTrace or \c qCTraceGuard macros and + are associated to a \c QLoggingCategory. + + The constructor of a \c QTraceGuard objects checks whether + its associated category is enabled, and if so, informs all + \c QTracer objects registered with the category that a + tracing activity starts. + + The destructor of a \c QTraceGuard objects checks whether + its associated category is enabled, and if so, informs all + \c QTracer objects registered with the category that a + tracing activity ended. + + A \c QTraceGuard object created by \c qCTrace will be destroyed + at the end of the full expression, a guard created by + \c qCTraceGuard at the end of the block containing the macro. + + During the lifetime of a QTraceGuard object, its \c operator<<() + can be used to pass additional data to the active tracers. + The fast path handles only \c int and \c{const char *} data, + but it is possible to use arbitrary values wrapped in \c QVariants. + + \sa QTracer +*/ + +/*! + \fn QTraceGuard::QTraceGuard(QLoggingCategory &category) + \internal + + Constructs a trace guard object relaying to \a category. +*/ + +/*! + \fn QTraceGuard::~QTraceGuard() + \internal + + Destroys the trace guard object. +*/ + +/*! + \internal + + Calls \c start() on all registered tracers. +*/ + +void QTraceGuard::start() +{ + QLoggingCategory::Tracers &tracers = target->tracers; + for (int i = tracers.size(); --i >= 0; ) + tracers.at(i)->start(); +} + +/*! + \internal + + Calls \c end() on all registered tracers. +*/ + +void QTraceGuard::end() +{ + QLoggingCategory::Tracers &tracers = target->tracers; + for (int i = tracers.size(); --i >= 0; ) + tracers.at(i)->end(); +} + + +/*! + \internal + + This function is called for int parameters passed to the + qCTrace stream. +*/ + +QTraceGuard &QTraceGuard::operator<<(int msg) +{ + QLoggingCategory::Tracers &tracers = target->tracers; + for (int i = tracers.size(); --i >= 0; ) + tracers.at(i)->record(msg); + return *this; +} + +/*! + \internal + + This function is called for string parameters passed to the + qCTrace stream. +*/ + +QTraceGuard &QTraceGuard::operator<<(const char *msg) +{ + QLoggingCategory::Tracers &tracers = target->tracers; + for (int i = tracers.size(); --i >= 0; ) + tracers.at(i)->record(msg); + return *this; +} + + +/*! + \internal + + This function is called for QVariant parameters passed to the + qCTrace stream. +*/ + +QTraceGuard &QTraceGuard::operator<<(const QVariant &msg) +{ + QLoggingCategory::Tracers &tracers = target->tracers; + for (int i = tracers.size(); --i >= 0; ) + tracers.at(i)->record(msg); + return *this; +} + QT_END_NAMESPACE diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h index 90111c96fa..23b25b5e3f 100644 --- a/src/corelib/io/qloggingcategory.h +++ b/src/corelib/io/qloggingcategory.h @@ -44,9 +44,13 @@ #include <QtCore/qglobal.h> #include <QtCore/qdebug.h> +#include <QtCore/qvector.h> QT_BEGIN_NAMESPACE +class QTracer; +class QTraceGuard; + class Q_CORE_EXPORT QLoggingCategory { Q_DISABLE_COPY(QLoggingCategory) @@ -76,13 +80,18 @@ public: static void setFilterRules(const QString &rules); private: + friend class QLoggingRegistry; + friend class QTraceGuard; + friend class QTracer; + const char *name; bool enabledDebug; bool enabledWarning; bool enabledCritical; - - friend class QLoggingRegistry; + bool enabledTrace; + typedef QVector<QTracer *> Tracers; + Tracers tracers; }; template <> @@ -103,6 +112,56 @@ inline bool QLoggingCategory::isEnabled<QtCriticalMsg>() const return enabledCritical; } +template <> +inline bool QLoggingCategory::isEnabled<QtTraceMsg>() const +{ + return enabledTrace; +} + +class Q_CORE_EXPORT QTracer +{ + Q_DISABLE_COPY(QTracer) +public: + QTracer() {} + virtual ~QTracer() {} + + void addToCategory(QLoggingCategory &category); + + virtual void start() {} + virtual void end() {} + virtual void record(int) {} + virtual void record(const char *) {} + virtual void record(const QVariant &) {} +}; + +class Q_CORE_EXPORT QTraceGuard +{ + Q_DISABLE_COPY(QTraceGuard) +public: + QTraceGuard(QLoggingCategory &category) + { + target = category.isEnabled<QtTraceMsg>() ? &category : 0; + if (target) + start(); + } + + ~QTraceGuard() + { + if (target) + end(); + } + + QTraceGuard &operator<<(int msg); + QTraceGuard &operator<<(const char *msg); + QTraceGuard &operator<<(const QVariant &msg); + +private: + void start(); + void end(); + + QLoggingCategory *target; +}; + #define Q_DECLARE_LOGGING_CATEGORY(name) \ extern QLoggingCategory &name(); @@ -123,6 +182,17 @@ inline bool QLoggingCategory::isEnabled<QtCriticalMsg>() const #define qCCritical(category) \ for (bool enabled = category().isEnabled<QtCriticalMsg>(); enabled; enabled = false) \ QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).critical() +#define qCTrace(category) \ + for (bool enabled = category.isEnabled<QtTraceMsg>(); enabled; enabled = false) \ + QTraceGuard(category) + + +#define Q_TRACE_GUARD_NAME_HELPER(line) qTraceGuard ## line +#define Q_TRACE_GUARD_NAME(line) Q_TRACE_GUARD_NAME_HELPER(line) + +#define qCTraceGuard(category) \ + QTraceGuard Q_TRACE_GUARD_NAME(__LINE__)(category); + #if defined(QT_NO_DEBUG_OUTPUT) # undef qCDebug diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp index a82e6f65f4..885b51709d 100644 --- a/src/corelib/io/qloggingregistry.cpp +++ b/src/corelib/io/qloggingregistry.cpp @@ -86,6 +86,9 @@ int QLoggingRule::pass(const QString &categoryName, QtMsgType msgType) const case QtCriticalMsg: fullCategory += QLatin1String(".critical"); break; + case QtTraceMsg: + fullCategory += QLatin1String(".trace"); + break; default: break; } @@ -288,6 +291,7 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat) bool debug = (cat->categoryName() == qtDefaultCategoryName); bool warning = true; bool critical = true; + bool trace = true; QString categoryName = QLatin1String(cat->categoryName()); QLoggingRegistry *reg = QLoggingRegistry::instance(); @@ -301,11 +305,15 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat) filterpass = item.pass(categoryName, QtCriticalMsg); if (filterpass != 0) critical = (filterpass > 0); + filterpass = item.pass(categoryName, QtTraceMsg); + if (filterpass != 0) + trace = (filterpass > 0); } cat->setEnabled(QtDebugMsg, debug); cat->setEnabled(QtWarningMsg, warning); cat->setEnabled(QtCriticalMsg, critical); + cat->setEnabled(QtTraceMsg, trace); } diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index eab3890beb..3c6d294916 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -141,7 +141,8 @@ static void qt_sa_sigchld_sigaction(int signum, siginfo_t *info, void *context) if (qt_sa_old_sigchld_handler.sa_flags & SA_SIGINFO) { void (*oldAction)(int, siginfo_t *, void *) = vsa->sa_sigaction; - oldAction(signum, info, context); + if (oldAction) + oldAction(signum, info, context); } else { void (*oldAction)(int) = vsa->sa_handler; diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp index ee95e590f9..988d076025 100644 --- a/src/corelib/io/qurlidna.cpp +++ b/src/corelib/io/qurlidna.cpp @@ -61,6 +61,11 @@ struct NameprepCaseFoldingEntry { ushort mapping[4]; }; +#if defined(Q_CC_MSVC) && _MSC_VER < 1600 +inline bool operator<(const NameprepCaseFoldingEntry &one, const NameprepCaseFoldingEntry &other) +{ return one.uc < other.uc; } +#endif + inline bool operator<(uint one, const NameprepCaseFoldingEntry &other) { return one < other.uc; } |