QLoggingRegistry: replace QTextStream and QFile with <stdio.h>
This is to avoid the need to use QFile (which is a QObject) in this early code, especially since QObject itself may use category-logging. Task-number: QTBUG-135326 Change-Id: Idc05974d06c2c0a973f6fffdadcc0ecbf76c5cbc Reviewed-by: Kai Köhne <kai.koehne@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
b99671c945
commit
e30774649a
@ -6,12 +6,12 @@
|
|||||||
#include <QtCore/qfile.h>
|
#include <QtCore/qfile.h>
|
||||||
#include <QtCore/qlibraryinfo.h>
|
#include <QtCore/qlibraryinfo.h>
|
||||||
#include <QtCore/private/qlocking_p.h>
|
#include <QtCore/private/qlocking_p.h>
|
||||||
|
#include <QtCore/qscopedvaluerollback.h>
|
||||||
#include <QtCore/qstandardpaths.h>
|
#include <QtCore/qstandardpaths.h>
|
||||||
#include <QtCore/qstringtokenizer.h>
|
#include <QtCore/qstringtokenizer.h>
|
||||||
#include <QtCore/qtextstream.h>
|
|
||||||
#include <QtCore/qdir.h>
|
#include <QtCore/qdir.h>
|
||||||
#include <QtCore/qcoreapplication.h>
|
#include <QtCore/qcoreapplication.h>
|
||||||
#include <QtCore/qscopedvaluerollback.h>
|
#include <qplatformdefs.h>
|
||||||
|
|
||||||
#if QT_CONFIG(settings)
|
#if QT_CONFIG(settings)
|
||||||
#include <QtCore/qsettings.h>
|
#include <QtCore/qsettings.h>
|
||||||
@ -163,12 +163,39 @@ void QLoggingSettingsParser::setContent(QStringView content, char16_t separator)
|
|||||||
\internal
|
\internal
|
||||||
Parses configuration from \a stream.
|
Parses configuration from \a stream.
|
||||||
*/
|
*/
|
||||||
void QLoggingSettingsParser::setContent(QTextStream &stream)
|
void QLoggingSettingsParser::setContent(FILE *stream)
|
||||||
{
|
{
|
||||||
_rules.clear();
|
_rules.clear();
|
||||||
QString line;
|
|
||||||
while (stream.readLineInto(&line))
|
constexpr size_t ChunkSize = 240;
|
||||||
parseNextLine(qToStringViewIgnoringNull(line));
|
QByteArray buffer(ChunkSize, Qt::Uninitialized);
|
||||||
|
auto readline = [&](FILE *stream) {
|
||||||
|
// Read one line into the buffer
|
||||||
|
|
||||||
|
// fgets() always writes the terminating null into the buffer, so we'll
|
||||||
|
// allow it to write to the QByteArray's null (thus the off by 1).
|
||||||
|
char *s = fgets(buffer.begin(), buffer.size() + 1, stream);
|
||||||
|
if (!s)
|
||||||
|
return QByteArrayView{};
|
||||||
|
|
||||||
|
qsizetype len = strlen(s);
|
||||||
|
while (len == buffer.size()) {
|
||||||
|
// need to grow the buffer
|
||||||
|
buffer.resizeForOverwrite(buffer.size() + ChunkSize);
|
||||||
|
s = fgets(buffer.end() - ChunkSize, ChunkSize + 1, stream);
|
||||||
|
if (!s)
|
||||||
|
break;
|
||||||
|
len += strlen(s);
|
||||||
|
}
|
||||||
|
QByteArrayView result(buffer.constBegin(), len);
|
||||||
|
if (result.endsWith('\n'))
|
||||||
|
result.chop(1);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
QByteArrayView line;
|
||||||
|
while (!(line = readline(stream)).isNull())
|
||||||
|
parseNextLine(QString::fromUtf8(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -262,19 +289,38 @@ static bool qtLoggingDebug()
|
|||||||
|
|
||||||
static QList<QLoggingRule> loadRulesFromFile(const QString &filePath)
|
static QList<QLoggingRule> loadRulesFromFile(const QString &filePath)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(!filePath.isEmpty());
|
||||||
if (qtLoggingDebug()) {
|
if (qtLoggingDebug()) {
|
||||||
debugMsg("Checking \"%s\" for rules",
|
debugMsg("Checking \"%s\" for rules",
|
||||||
QDir::toNativeSeparators(filePath).toUtf8().constData());
|
QDir::toNativeSeparators(filePath).toUtf8().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile file(filePath);
|
// We bypass QFile here because QFile is a QObject.
|
||||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (Q_UNLIKELY(filePath.at(0) == u':')) {
|
||||||
QTextStream stream(&file);
|
if (qtLoggingDebug()) {
|
||||||
|
warnMsg("Attempted to load config rules from Qt resource path \"%ls\"",
|
||||||
|
qUtf16Printable(filePath));
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// text mode: let the runtime do CRLF translation
|
||||||
|
FILE *f = _wfopen(reinterpret_cast<const wchar_t *>(filePath.constBegin()), L"rtN");
|
||||||
|
#else
|
||||||
|
FILE *f = QT_FOPEN(QFile::encodeName(filePath).constBegin(), "re");
|
||||||
|
#endif
|
||||||
|
if (f) {
|
||||||
QLoggingSettingsParser parser;
|
QLoggingSettingsParser parser;
|
||||||
parser.setContent(stream);
|
parser.setContent(f);
|
||||||
|
fclose(f);
|
||||||
if (qtLoggingDebug())
|
if (qtLoggingDebug())
|
||||||
debugMsg("Loaded %td rules", static_cast<ptrdiff_t>(parser.rules().size()));
|
debugMsg("Loaded %td rules from \"%ls\"", static_cast<ptrdiff_t>(parser.rules().size()),
|
||||||
|
qUtf16Printable(filePath));
|
||||||
return parser.rules();
|
return parser.rules();
|
||||||
|
} else if (int err = errno; err != ENOENT) {
|
||||||
|
warnMsg("Failed to load file \"%ls\": %ls", qUtf16Printable(filePath),
|
||||||
|
qUtf16Printable(qt_error_string(err)));
|
||||||
}
|
}
|
||||||
return QList<QLoggingRule>();
|
return QList<QLoggingRule>();
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ public:
|
|||||||
void setImplicitRulesSection(bool inRulesSection) { m_inRulesSection = inRulesSection; }
|
void setImplicitRulesSection(bool inRulesSection) { m_inRulesSection = inRulesSection; }
|
||||||
|
|
||||||
void setContent(QStringView content, char16_t separator = u'\n');
|
void setContent(QStringView content, char16_t separator = u'\n');
|
||||||
void setContent(QTextStream &stream);
|
void setContent(FILE *stream);
|
||||||
|
|
||||||
QList<QLoggingRule> rules() const { return _rules; }
|
QList<QLoggingRule> rules() const { return _rules; }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user