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 | |