Warning: That file was not part of the compilation database. It may have many parsing errors.

1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the tools applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtDebug>
43#include "config.h"
44#include "location.h"
45
46#include <qregexp.h>
47#include <qtranslator.h>
48#include <stdlib.h>
49#include <limits.h>
50
51#include <stdio.h>
52
53QT_BEGIN_NAMESPACE
54
55QT_STATIC_CONST_IMPL Location Location::null;
56
57int Location::tabSize;
58QString Location::programName;
59QRegExp *Location::spuriousRegExp = 0;
60
61/*!
62 \class Location
63
64 \brief The Location class keeps track of where we are in a file.
65
66 It maintains a stack of file positions. A file position
67 consists of the file path, line number, and column number.
68 The location is used for printing error messages that are
69 tied to a location in a file.
70 */
71
72/*!
73 Constructs an empty location.
74 */
75Location::Location()
76 : stk(0), stkTop(&stkBottom), stkDepth(0), etcetera(false)
77{
78 // nothing.
79}
80
81/*!
82 Constructs a location with (fileName, 1, 1) on its file
83 position stack.
84 */
85Location::Location(const QString& fileName)
86 : stk(0), stkTop(&stkBottom), stkDepth(0), etcetera(false)
87{
88 push(fileName);
89}
90
91/*!
92 The copy constructor copies the contents of \a other into
93 this Location using the assignment operator.
94 */
95Location::Location(const Location& other)
96 : stk(0), stkTop(&stkBottom), stkDepth(0), etcetera(false)
97{
98 *this = other;
99}
100
101/*!
102 The assignment operator does a deep copy of the entire
103 state of \a other into this Location.
104 */
105Location& Location::operator=(const Location& other)
106{
107 QStack<StackEntry> *oldStk = stk;
108
109 stkBottom = other.stkBottom;
110 if (other.stk == 0) {
111 stk = 0;
112 stkTop = &stkBottom;
113 }
114 else {
115 stk = new QStack<StackEntry>(*other.stk);
116 stkTop = &stk->top();
117 }
118 stkDepth = other.stkDepth;
119 etcetera = other.etcetera;
120 delete oldStk;
121 return *this;
122}
123
124/*!
125 If the file position on top of the stack has a line number
126 less than 1, set its line number to 1 and its column number
127 to 1. Otherwise, do nothing.
128 */
129void Location::start()
130{
131 if (stkTop->lineNo < 1) {
132 stkTop->lineNo = 1;
133 stkTop->columnNo = 1;
134 }
135}
136
137/*!
138 Advance the current file position, using \a ch to decide how to do
139 that. If \a ch is a \c{'\\n'}, increment the current line number and
140 set the column number to 1. If \ch is a \c{'\\t'}, increment to the
141 next tab column. Otherwise, increment the column number by 1.
142
143 The current file position is the one on top of the position stack.
144 */
145void Location::advance(QChar ch)
146{
147 if (ch == QLatin1Char('\n')) {
148 stkTop->lineNo++;
149 stkTop->columnNo = 1;
150 }
151 else if (ch == QLatin1Char('\t')) {
152 stkTop->columnNo =
153 1 + tabSize * (stkTop->columnNo + tabSize-1) / tabSize;
154 }
155 else {
156 stkTop->columnNo++;
157 }
158}
159
160/*!
161 Pushes \a filePath onto the file position stack. The current
162 file position becomes (\a filePath, 1, 1).
163
164 \sa pop()
165*/
166void Location::push(const QString& filePath)
167{
168 if (stkDepth++ >= 1) {
169 if (stk == 0)
170 stk = new QStack<StackEntry>;
171 stk->push(StackEntry());
172 stkTop = &stk->top();
173 }
174
175 stkTop->filePath = filePath;
176 stkTop->lineNo = INT_MIN;
177 stkTop->columnNo = 1;
178}
179
180/*!
181 Pops the top of the internal stack. The current file position
182 becomes the next one in the new top of stack.
183
184 \sa push()
185*/
186void Location::pop()
187{
188 if (--stkDepth == 0) {
189 stkBottom = StackEntry();
190 }
191 else {
192 stk->pop();
193 if (stk->isEmpty()) {
194 delete stk;
195 stk = 0;
196 stkTop = &stkBottom;
197 }
198 else {
199 stkTop = &stk->top();
200 }
201 }
202}
203
204/*! \fn bool Location::isEmpty() const
205
206 Returns true if there is no file name set yet; returns false
207 otherwise. The functions filePath(), lineNo() and columnNo()
208 must not be called on an empty Location object.
209 */
210
211/*! \fn const QString& Location::filePath() const
212 Returns the current path and file name.
213 Must not be called on an empty Location object.
214
215 \sa lineNo(), columnNo()
216 */
217
218/*!
219 Returns the file name part of the file path, ie the
220 current file. Must not be called on an empty Location
221 object.
222 */
223QString Location::fileName() const
224{
225 QString fp = filePath();
226 return fp.mid(fp.lastIndexOf('/') + 1);
227}
228
229/*! \fn int Location::lineNo() const
230 Returns the current line number.
231 Must not be called on an empty Location object.
232
233 \sa filePath(), columnNo()
234*/
235
236/*! \fn int Location::columnNo() const
237 Returns the current column number.
238 Must not be called on an empty Location object.
239
240 \sa filePath(), lineNo()
241*/
242
243/*!
244 Writes \a message and \a detals to stderr as a formatted
245 warning message.
246 */
247void Location::warning(const QString& message, const QString& details) const
248{
249 emitMessage(Warning, message, details);
250}
251
252/*!
253 Writes \a message and \a detals to stderr as a formatted
254 error message.
255 */
256void Location::error(const QString& message, const QString& details) const
257{
258 emitMessage(Error, message, details);
259}
260
261/*!
262 Writes \a message and \a detals to stderr as a formatted
263 error message and then exits the program.
264 */
265void Location::fatal(const QString& message, const QString& details) const
266{
267 emitMessage(Error, message, details);
268 information(message);
269 information(details);
270 information("Aborting");
271 exit(EXIT_FAILURE);
272}
273
274/*!
275 Gets several parameters from the \a config, including
276 tab size, program name, and a regular expression that
277 appears to be used for matching certain error messages
278 so that emitMessage() can avoid printing them.
279 */
280void Location::initialize(const Config& config)
281{
282 tabSize = config.getInt(CONFIG_TABSIZE);
283 programName = config.programName();
284
285 QRegExp regExp = config.getRegExp(CONFIG_SPURIOUS);
286 if (regExp.isValid()) {
287 spuriousRegExp = new QRegExp(regExp);
288 }
289 else {
290 config.lastLocation().warning(tr("Invalid regular expression '%1'")
291 .arg(regExp.pattern()));
292 }
293}
294
295/*!
296 Apparently, all this does is delete the regular expression
297 used for intercepting certain error messages that should
298 not be emitted by emitMessage().
299 */
300void Location::terminate()
301{
302 delete spuriousRegExp;
303 spuriousRegExp = 0;
304}
305
306/*!
307 Prints \a message to \c stdout followed by a \c{'\n'}.
308 */
309void Location::information(const QString& message)
310{
311 printf("%s\n", message.toLatin1().data());
312 fflush(stdout);
313}
314
315/*!
316 Report a program bug, including the \a hint.
317 */
318void Location::internalError(const QString& hint)
319{
320 Location::null.fatal(tr("Internal error (%1)").arg(hint),
321 tr("There is a bug in %1. Seek advice from your local"
322 " %2 guru.")
323 .arg(programName).arg(programName));
324}
325
326/*!
327 Formats \a message and \a details into a single string
328 and outputs that string to \c stderr. \a type specifies
329 whether the \a message is an error or a warning.
330 */
331void Location::emitMessage(MessageType type,
332 const QString& message,
333 const QString& details) const
334{
335 if (type == Warning &&
336 spuriousRegExp != 0 &&
337 spuriousRegExp->exactMatch(message))
338 return;
339
340 QString result = message;
341 if (!details.isEmpty())
342 result += "\n[" + details + "]";
343 result.replace("\n", "\n ");
344 if (type == Error)
345 result.prepend(tr("error: "));
346 result.prepend(toString());
347 fprintf(stderr, "%s\n", result.toLatin1().data());
348 fflush(stderr);
349}
350
351/*!
352 Converts the location to a string to be prepended to error
353 messages.
354 */
355QString Location::toString() const
356{
357 QString str;
358
359 if (isEmpty()) {
360 str = programName;
361 }
362 else {
363 Location loc2 = *this;
364 loc2.setEtc(false);
365 loc2.pop();
366 if (!loc2.isEmpty()) {
367 QString blah = tr("In file included from ");
368 for (;;) {
369 str += blah;
370 str += loc2.top();
371 loc2.pop();
372 if (loc2.isEmpty())
373 break;
374 str += tr(",");
375 str += QLatin1Char('\n');
376 blah.fill(' ');
377 }
378 str += tr(":");
379 str += QLatin1Char('\n');
380 }
381 str += top();
382 }
383 str += QLatin1String(": ");
384 return str;
385}
386
387QString Location::top() const
388{
389 QString str = filePath();
390 if (lineNo() >= 1) {
391 str += QLatin1Char(':');
392 str += QString::number(lineNo());
393 }
394 if (etc())
395 str += QLatin1String(" (etc.)");
396 return str;
397}
398
399QT_END_NAMESPACE
400

Warning: That file was not part of the compilation database. It may have many parsing errors.