| 1 | // Copyright (C) 2016 The Qt Company Ltd. | 
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only | 
| 3 |  | 
| 4 | #ifndef QLOGGINGREGISTRY_P_H | 
| 5 | #define QLOGGINGREGISTRY_P_H | 
| 6 |  | 
| 7 | // | 
| 8 | //  W A R N I N G | 
| 9 | //  ------------- | 
| 10 | // | 
| 11 | // This file is not part of the Qt API.  It exists for the convenience | 
| 12 | // of a number of Qt sources files.  This header file may change from | 
| 13 | // version to version without notice, or even be removed. | 
| 14 | // | 
| 15 | // We mean it. | 
| 16 | // | 
| 17 |  | 
| 18 | #include <QtCore/private/qglobal_p.h> | 
| 19 | #include <QtCore/qloggingcategory.h> | 
| 20 | #include <QtCore/qlist.h> | 
| 21 | #include <QtCore/qhash.h> | 
| 22 | #include <QtCore/qmutex.h> | 
| 23 | #include <QtCore/qstring.h> | 
| 24 | #include <QtCore/qtextstream.h> | 
| 25 |  | 
| 26 | #include <map> | 
| 27 |  | 
| 28 | class tst_QLoggingRegistry; | 
| 29 |  | 
| 30 | QT_BEGIN_NAMESPACE | 
| 31 |  | 
| 32 | #define Q_LOGGING_CATEGORY_WITH_ENV_OVERRIDE(name, env, categoryName) \ | 
| 33 |     const QLoggingCategory &name() \ | 
| 34 |     { \ | 
| 35 |         static constexpr char cname[] = categoryName;                               \ | 
| 36 |         static_assert(cname[0] == 'q' && cname[1] == 't' && cname[2] == '.'         \ | 
| 37 |                       && cname[4] != '\0', "Category name must start with 'qt.'");  \ | 
| 38 |         static const QLoggingCategoryWithEnvironmentOverride category(cname, env);  \ | 
| 39 |         return category;                                                            \ | 
| 40 |     } | 
| 41 |  | 
| 42 | class Q_AUTOTEST_EXPORT QLoggingRule | 
| 43 | { | 
| 44 | public: | 
| 45 |     QLoggingRule(); | 
| 46 |     QLoggingRule(QStringView pattern, bool enabled); | 
| 47 |     int pass(QLatin1StringView categoryName, QtMsgType type) const; | 
| 48 |  | 
| 49 |     enum PatternFlag { | 
| 50 |         FullText = 0x1, | 
| 51 |         LeftFilter = 0x2, | 
| 52 |         RightFilter = 0x4, | 
| 53 |         MidFilter = LeftFilter | RightFilter | 
| 54 |     }; | 
| 55 |     Q_DECLARE_FLAGS(PatternFlags, PatternFlag) | 
| 56 |  | 
| 57 |     QString category; | 
| 58 |     int messageType = -1; | 
| 59 |     PatternFlags flags; | 
| 60 |     bool enabled = false; | 
| 61 |  | 
| 62 | private: | 
| 63 |     void parse(QStringView pattern); | 
| 64 | }; | 
| 65 |  | 
| 66 | Q_DECLARE_OPERATORS_FOR_FLAGS(QLoggingRule::PatternFlags) | 
| 67 | Q_DECLARE_TYPEINFO(QLoggingRule, Q_RELOCATABLE_TYPE); | 
| 68 |  | 
| 69 | class Q_AUTOTEST_EXPORT QLoggingSettingsParser | 
| 70 | { | 
| 71 | public: | 
| 72 |     void setImplicitRulesSection(bool inRulesSection) { m_inRulesSection = inRulesSection; } | 
| 73 |  | 
| 74 |     void setContent(QStringView content); | 
| 75 |     void setContent(QTextStream &stream); | 
| 76 |  | 
| 77 |     QList<QLoggingRule> rules() const { return _rules; } | 
| 78 |  | 
| 79 | private: | 
| 80 |     void parseNextLine(QStringView line); | 
| 81 |  | 
| 82 | private: | 
| 83 |     bool m_inRulesSection = false; | 
| 84 |     QList<QLoggingRule> _rules; | 
| 85 | }; | 
| 86 |  | 
| 87 | class Q_AUTOTEST_EXPORT QLoggingRegistry | 
| 88 | { | 
| 89 |     Q_DISABLE_COPY_MOVE(QLoggingRegistry) | 
| 90 | public: | 
| 91 |     QLoggingRegistry(); | 
| 92 |  | 
| 93 |     void initializeRules(); | 
| 94 |  | 
| 95 |     void registerCategory(QLoggingCategory *category, QtMsgType enableForLevel); | 
| 96 |     void unregisterCategory(QLoggingCategory *category); | 
| 97 |  | 
| 98 | #ifndef QT_BUILD_INTERNAL | 
| 99 |     Q_CORE_EXPORT   // always export from QtCore | 
| 100 | #endif | 
| 101 |     void registerEnvironmentOverrideForCategory(const char *categoryName, const char *environment); | 
| 102 |  | 
| 103 |     void setApiRules(const QString &content); | 
| 104 |  | 
| 105 |     QLoggingCategory::CategoryFilter | 
| 106 |     installFilter(QLoggingCategory::CategoryFilter filter); | 
| 107 |  | 
| 108 |     static QLoggingRegistry *instance(); | 
| 109 |  | 
| 110 | private: | 
| 111 |     void updateRules(); | 
| 112 |  | 
| 113 |     static void defaultCategoryFilter(QLoggingCategory *category); | 
| 114 |  | 
| 115 |     enum RuleSet { | 
| 116 |         // sorted by order in which defaultCategoryFilter considers them: | 
| 117 |         QtConfigRules, | 
| 118 |         ConfigRules, | 
| 119 |         ApiRules, | 
| 120 |         EnvironmentRules, | 
| 121 |  | 
| 122 |         NumRuleSets | 
| 123 |     }; | 
| 124 |  | 
| 125 |     QMutex registryMutex; | 
| 126 |  | 
| 127 |     // protected by mutex: | 
| 128 |     QList<QLoggingRule> ruleSets[NumRuleSets]; | 
| 129 |     QHash<QLoggingCategory *, QtMsgType> categories; | 
| 130 |     QLoggingCategory::CategoryFilter categoryFilter; | 
| 131 |     std::map<QByteArrayView, const char *> qtCategoryEnvironmentOverrides; | 
| 132 |  | 
| 133 |     friend class ::tst_QLoggingRegistry; | 
| 134 | }; | 
| 135 |  | 
| 136 | class QLoggingCategoryWithEnvironmentOverride : public QLoggingCategory | 
| 137 | { | 
| 138 | public: | 
| 139 |     QLoggingCategoryWithEnvironmentOverride(const char *category, const char *env) | 
| 140 |         : QLoggingCategory(registerOverride(categoryName: category, environment: env), QtInfoMsg) | 
| 141 |     {} | 
| 142 |  | 
| 143 | private: | 
| 144 |     static const char *registerOverride(const char *categoryName, const char *environment) | 
| 145 |     { | 
| 146 |         QLoggingRegistry *c = QLoggingRegistry::instance(); | 
| 147 |         if (c) | 
| 148 |             c->registerEnvironmentOverrideForCategory(categoryName, environment); | 
| 149 |         return categoryName; | 
| 150 |     } | 
| 151 | }; | 
| 152 |  | 
| 153 | QT_END_NAMESPACE | 
| 154 |  | 
| 155 | #endif // QLOGGINGREGISTRY_P_H | 
| 156 |  |