8#include <QtCore/qdebug.h>
9#include <QtCore/qdir.h>
10#include <QtCore/qregularexpression.h>
24QRegularExpression *
Location::s_spuriousRegExp =
nullptr;
27
28
29
30
31
32
33
34
35
38
39
46
47
48
56
57
58
66
67
68
74 QStack<StackEntry> *oldStk = m_stk;
76 m_stkBottom = other.m_stkBottom;
77 if (other.m_stk ==
nullptr) {
79 m_stkTop = &m_stkBottom;
81 m_stk =
new QStack<StackEntry>(*other.m_stk);
82 m_stkTop = &m_stk->top();
84 m_stkDepth = other.m_stkDepth;
91
92
93
94
97 if (m_stkTop->m_lineNo < 1) {
98 m_stkTop->m_lineNo = 1;
99 m_stkTop->m_columnNo = 1;
104
105
106
107
108
109
110
113 if (ch == QLatin1Char(
'\n')) {
114 m_stkTop->m_lineNo++;
115 m_stkTop->m_columnNo = 1;
116 }
else if (ch == QLatin1Char(
'\t')) {
117 m_stkTop->m_columnNo = 1 + s_tabSize * (m_stkTop->m_columnNo + s_tabSize - 1) / s_tabSize;
119 m_stkTop->m_columnNo++;
124
125
126
127
128
131 if (m_stkDepth++ >= 1) {
132 if (m_stk ==
nullptr)
133 m_stk =
new QStack<StackEntry>;
134 m_stk->push(StackEntry());
135 m_stkTop = &m_stk->top();
138 m_stkTop->m_filePath = filePath;
139 m_stkTop->m_lineNo = INT_MIN;
140 m_stkTop->m_columnNo = 1;
144
145
146
147
148
151 if (--m_stkDepth == 0) {
152 m_stkBottom = StackEntry();
157 if (m_stk->isEmpty()) {
160 m_stkTop = &m_stkBottom;
162 m_stkTop = &m_stk->top();
168
169
170
171
172
175
176
177
178
179
182
183
184
187 QFileInfo fi(filePath());
188 return fi.fileName();
192
193
194
197 QString fp = filePath();
198 return (fp.isEmpty() ? fp : fp.mid(fp.lastIndexOf(
'.') + 1));
202
203
204
205
206
209
210
211
212
213
216
217
218
219
222 const auto &config = Config::instance();
223 if (!config.preparing() || config.singleExec())
224 emitMessage(Warning, message, details);
228
229
230
231
234 const auto &config = Config::instance();
235 if (!config.preparing() || config.singleExec())
236 emitMessage(Error, message, details);
240
241
242
243
246 if (s_warningLimit < 0 || s_warningCount <= s_warningLimit)
249 Location().emitMessage(
251 QStringLiteral(
"Documentation warnings (%1) exceeded the limit (%2) for '%3'.")
252 .arg(QString::number(s_warningCount), QString::number(s_warningLimit),
255 return s_warningCount;
259
260
261
262
265 emitMessage(Error, message, details);
266 information(message);
267 information(details);
268 information(
"Aborting");
273
274
275
276
277
278
279
280
281
284 const auto &config = Config::instance();
285 if ((!config.preparing() || config.singleExec()) && !s_reports.contains(message)) {
286 emitMessage(Report, message, details);
287 s_reports << message;
292
293
294
295
296
299 Config &config = Config::instance();
301 s_programName = config.programName();
305 if (qEnvironmentVariableIsSet(
"QDOC_ENABLE_WARNINGLIMIT")
310 if (regExp.isValid()) {
311 s_spuriousRegExp =
new QRegularExpression(regExp);
314 .warning(QStringLiteral(
"Invalid regular expression '%1'")
315 .arg(regExp.pattern()));
320
321
322
323
326 delete s_spuriousRegExp;
327 s_spuriousRegExp =
nullptr;
331
332
335 printf(
"%s\n", message.toLatin1().data());
340
341
344 Location().fatal(QStringLiteral(
"Internal error (%1)").arg(hint),
345 QStringLiteral(
"There is a bug in %1. Seek advice from your local"
347 .arg(s_programName, s_programName));
351
352
353
354
355void Location::emitMessage(MessageType type,
const QString &message,
const QString &details)
const
357 if (type == Warning && s_spuriousRegExp !=
nullptr) {
358 auto match = s_spuriousRegExp->match(message, 0, QRegularExpression::NormalMatch,
359 QRegularExpression::AnchorAtOffsetMatchOption);
360 if (match.hasMatch() && match.capturedLength() == message.size())
364 QString result = message;
365 if (!details.isEmpty())
366 result +=
"\n[" + details + QLatin1Char(
']');
367 result.replace(
"\n",
"\n ");
370 result.prepend(QStringLiteral(
": error: "));
371 else if (type == Warning) {
372 result.prepend(QStringLiteral(
": warning: "));
377 result.prepend(QStringLiteral(
": (qdoc) error: "));
378 else if (type == Warning) {
379 result.prepend(QStringLiteral(
": (qdoc) warning: "));
384 result.prepend(toString());
385 fprintf(stderr,
"%s\n", result.toLatin1().data());
390
391
392
404 QString blah = QStringLiteral(
"In file included from ");
411 str += QStringLiteral(
",\n");
414 str += QStringLiteral(
":\n");
423 QDir path(filePath());
424 QString str = path.absolutePath();
426 str += QLatin1Char(
':');
427 str += QString::number(lineNo());
430 str += QLatin1String(
" (etc.)");
The Config class contains the configuration variables for controlling how qdoc produces documentation...
The Location class provides a way to mark a location in a file.
QString fileName() const
Returns the file name part of the file path, ie the current file.
void fatal(const QString &message, const QString &details=QString()) const
Writes message and details to stderr as a formatted error message and then exits the program.
QString fileSuffix() const
Returns the suffix of the file name.
Location(const Location &other)
The copy constructor copies the contents of other into this Location using the assignment operator.
void error(const QString &message, const QString &details=QString()) const
Writes message and details to stderr as a formatted error message.
int lineNo() const
Returns the current line number.
static int exitCode()
Returns the error code QDoc should exit with; EXIT_SUCCESS or the number of documentation warnings if...
void report(const QString &message, const QString &details=QString()) const
Writes message and details to stderr as a formatted report message.
QString toString() const
Converts the location to a string to be prepended to error messages.
static void initialize()
Gets several parameters from the config, including tab size, program name, and a regular expression t...
Location()
Constructs an empty location.
void push(const QString &filePath)
Pushes filePath onto the file position stack.
void start()
If the file position on top of the stack has a line number less than 1, set its line number to 1 and ...
void warning(const QString &message, const QString &details=QString()) const
Writes message and details to stderr as a formatted warning message.
void advance(QChar ch)
Advance the current file position, using ch to decide how to do that.
Location & operator=(const Location &other)
The assignment operator does a deep copy of the entire state of other into this Location.
bool isEmpty() const
Returns true if there is no file name set yet; returns false otherwise.
static void terminate()
Apparently, all this does is delete the regular expression used for intercepting certain error messag...
void pop()
Pops the top of the internal stack.
Location(const QString &filePath)
Constructs a location with (fileName, 1, 1) on its file position stack.
#define CONFIG_WARNINGLIMIT