2
Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
3
Copyright 2006 Hamish Rodda <rodda@kde.org>
5
Permission to use, copy, modify, distribute, and sell this software and its
6
documentation for any purpose is hereby granted without fee, provided that
7
the above copyright notice appear in all copies and that both that
8
copyright notice and this permission notice appear in supporting
11
The above copyright notice and this permission notice shall be included in
12
all copies or substantial portions of the Software.
14
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
#include "pp-scanner.h"
23
#include "chartools.h"
24
#include <language/duchain/indexedstring.h>
25
#include <util/kdevvarlengtharray.h>
29
void pp_skip_blanks::operator()(Stream& input, Stream& output)
31
while (!input.atEnd()) {
44
if (input == '\n' || !isSpace(input.current()))
52
void pp_skip_whitespaces::operator()(Stream& input, Stream& output)
54
while (!input.atEnd()) {
55
if (!isSpace(input.current()))
63
void pp_skip_comment_or_divop::operator()(Stream& input, Stream& output, bool outputText)
72
} state (MAYBE_BEGIN);
74
while (!input.atEnd()) {
86
else if (input == '/')
87
state = IN_CXX_COMMENT;
105
else if (input != '*')
117
} else if (input == '\n') {
120
output.mark(input.inputPosition());
129
uint pp_skip_identifier::operator()(Stream& input)
131
KDevVarLengthArray<char, 100> identifier;
133
KDevelop::IndexedString::RunningHash hash;
135
while (!input.atEnd()) {
136
if(!isCharacter(input.current())) {
137
//Do a more complex merge, where also tokenized identifiers can be merged
138
KDevelop::IndexedString ret;
139
if(!identifier.isEmpty())
140
ret = KDevelop::IndexedString(identifier.constData(), identifier.size(), hash.hash);
142
while (!input.atEnd()) {
143
uint current = input.current();
145
if (!isLetterOrNumber(current) && input != '_' && isCharacter(current))
149
ret = KDevelop::IndexedString::fromIndex(current); //The most common fast path
150
else ///@todo Be better to build up a complete buffer and then append it all, so we don't get he intermediate strings into the repository
151
ret = KDevelop::IndexedString(ret.byteArray() + KDevelop::IndexedString::fromIndex(input.current()).byteArray());
157
//Collect characters and connect them to an IndexedString
159
if (!isLetterOrNumber(input.current()) && input != '_')
162
char c = characterFromIndex(input);
164
identifier.append(c);
168
return KDevelop::IndexedString(identifier.constData(), identifier.size(), hash.hash).index();
171
void pp_skip_number::operator()(Stream& input, Stream& output)
173
while (!input.atEnd()) {
174
if (!isLetterOrNumber(input.current()) && input != '_')
182
void pp_skip_string_literal::operator()(Stream& input, Stream& output)
191
while (!input.atEnd()) {
200
// Q_ASSERT(input != '\n');
204
else if (input == '\\')
221
void pp_skip_char_literal::operator()(Stream& input, Stream& output)
231
while (!input.atEnd()) {
243
if(input == '\n' || inner_count > 3)
244
return; //Probably this isn't a string literal. Example: "#warning What's up"
248
else if (input == '\\')
266
///@todo Can this deal with comments? like /*(*/
267
void pp_skip_argument::operator()(Stream& input, Stream& output)
271
while (!input.atEnd()) {
272
if (!depth && (input == ')' || input == ',')) {
275
} else if (input == '(') {
278
} else if (input == ')') {
281
} else if (input == '\"') {
282
skip_string_literal(input, output);
285
} else if (input == '\'') {
286
skip_char_literal (input, output);
289
} else if (input == '/') {
290
skip_comment_or_divop (input, output, true);
293
} else if (isLetter(input.current()) || input == '_') {
294
Anchor inputPosition = input.inputPosition();
295
output.appendString(inputPosition, KDevelop::IndexedString::fromIndex(skip_identifier(input)));
298
} else if (isNumber(input.current())) {
299
output.mark(input.inputPosition());
300
skip_number(input, output);