OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / libs / cplusplus / pp-scanner.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32 /*
33   Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
34
35   Permission to use, copy, modify, distribute, and sell this software and its
36   documentation for any purpose is hereby granted without fee, provided that
37   the above copyright notice appear in all copies and that both that
38   copyright notice and this permission notice appear in supporting
39   documentation.
40
41   The above copyright notice and this permission notice shall be included in
42   all copies or substantial portions of the Software.
43
44   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
47   KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
48   AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
49   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
50 */
51
52 #include "pp-scanner.h"
53 #include "pp-cctype.h"
54
55 using namespace CPlusPlus;
56
57 const char *pp_skip_blanks::operator () (const char *__first, const char *__last)
58 {
59     lines = 0;
60
61     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
62         if (*__first == '\\') {
63             const char *__begin = __first;
64             ++__begin;
65
66             if (__begin != __last && *__begin == '\n')
67                 ++__first;
68             else
69                 break;
70         } else if (*__first == '\n' || !pp_isspace (*__first))
71             break;
72     }
73
74     return __first;
75 }
76
77 const char *pp_skip_whitespaces::operator () (const char *__first, const char *__last)
78 {
79     lines = 0;
80
81     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
82         if (! pp_isspace (*__first))
83             break;
84     }
85
86     return __first;
87 }
88
89 const char *pp_skip_comment_or_divop::operator () (const char *__first, const char *__last)
90 {
91     enum {
92         MAYBE_BEGIN,
93         BEGIN,
94         MAYBE_END,
95         END,
96         IN_COMMENT,
97         IN_CXX_COMMENT
98     } state (MAYBE_BEGIN);
99
100     lines = 0;
101
102     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
103         switch (state) {
104         default:
105             break;
106
107         case MAYBE_BEGIN:
108             if (*__first != '/')
109                 return __first;
110
111             state = BEGIN;
112             break;
113
114         case BEGIN:
115             if (*__first == '*')
116                 state = IN_COMMENT;
117             else if (*__first == '/')
118                 state = IN_CXX_COMMENT;
119             else
120                 return __first;
121             break;
122
123         case IN_COMMENT:
124             if (*__first == '*')
125                 state = MAYBE_END;
126             break;
127
128         case IN_CXX_COMMENT:
129             if (*__first == '\n')
130                 return __first;
131             break;
132
133         case MAYBE_END:
134             if (*__first == '/')
135                 state = END;
136             else if (*__first != '*')
137                 state = IN_COMMENT;
138             break;
139
140         case END:
141             return __first;
142         }
143     }
144
145     return __first;
146 }
147
148 const char *pp_skip_identifier::operator () (const char *__first, const char *__last)
149 {
150     lines = 0;
151
152     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
153         if (! pp_isalnum (*__first) && *__first != '_')
154             break;
155     }
156
157     return __first;
158 }
159
160 const char *pp_skip_number::operator () (const char *__first, const char *__last)
161 {
162     lines = 0;
163
164     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
165         if (! pp_isalnum (*__first) && *__first != '.')
166             break;
167     }
168
169     return __first;
170 }
171
172 const char *pp_skip_string_literal::operator () (const char *__first, const char *__last)
173 {
174     enum {
175         BEGIN,
176         IN_STRING,
177         QUOTE,
178         END
179     } state (BEGIN);
180
181     lines = 0;
182
183     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
184         switch (state)
185         {
186         default:
187             break;
188
189         case BEGIN:
190             if (*__first != '\"')
191                 return __first;
192             state = IN_STRING;
193             break;
194
195         case IN_STRING:
196             if (! (*__first != '\n'))
197                 return __last;
198
199             if (*__first == '\"')
200                 state = END;
201             else if (*__first == '\\')
202                 state = QUOTE;
203             break;
204
205         case QUOTE:
206             state = IN_STRING;
207             break;
208
209         case END:
210             return __first;
211         }
212     }
213
214     return __first;
215 }
216
217 const char *pp_skip_char_literal::operator () (const char *__first, const char *__last)
218 {
219     enum {
220         BEGIN,
221         IN_STRING,
222         QUOTE,
223         END
224     } state (BEGIN);
225
226     lines = 0;
227
228     for (; state != END && __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
229         switch (state)
230         {
231         default:
232             break;
233
234         case BEGIN:
235             if (*__first != '\'')
236                 return __first;
237             state = IN_STRING;
238             break;
239
240         case IN_STRING:
241             if (! (*__first != '\n'))
242                 return __last;
243
244             if (*__first == '\'')
245                 state = END;
246             else if (*__first == '\\')
247                 state = QUOTE;
248             break;
249
250         case QUOTE:
251             state = IN_STRING;
252             break;
253         }
254     }
255
256     return __first;
257 }
258
259 const char *pp_skip_argument::operator () (const char *__first, const char *__last)
260 {
261     int depth = 0;
262     lines = 0;
263
264     while (__first != __last) {
265         if (!depth && (*__first == ')' || *__first == ','))
266             break;
267         else if (*__first == '(')
268             ++depth, ++__first;
269         else if (*__first == ')')
270             --depth, ++__first;
271         else if (*__first == '\"') {
272             __first = skip_string_literal (__first, __last);
273             lines += skip_string_literal.lines;
274         } else if (*__first == '\'') {
275             __first = skip_char_literal (__first, __last);
276             lines += skip_char_literal.lines;
277         } else if (*__first == '/') {
278             __first = skip_comment_or_divop (__first, __last);
279             lines += skip_comment_or_divop.lines;
280         } else if (pp_isalpha (*__first) || *__first == '_') {
281             __first = skip_identifier (__first, __last);
282             lines += skip_identifier.lines;
283         } else if (pp_isdigit (*__first)) {
284             __first = skip_number (__first, __last);
285             lines += skip_number.lines;
286         } else if (*__first == '\n') {
287             ++__first;
288             ++lines;
289         } else
290             ++__first;
291     }
292
293     return __first;
294 }
295