annotate generator/parser/rpp/pp-engine-bits.h @ 382:1d56b2a2e10c

Fixes to debugging stuff. Added size_t as primitive type to workaround Qwt build failure in debug
author Max Samukha <maxter@spambox.com>
date Mon, 12 Jul 2010 20:36:07 +0300
parents 09a0f1d048f2
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
e78566595089 initial import
mandel
parents:
diff changeset
1 /****************************************************************************
e78566595089 initial import
mandel
parents:
diff changeset
2 **
52
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
3 ** Copyright (C) 1992-2009 Nokia. All rights reserved.
1
e78566595089 initial import
mandel
parents:
diff changeset
4 ** Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
e78566595089 initial import
mandel
parents:
diff changeset
5 **
e78566595089 initial import
mandel
parents:
diff changeset
6 ** This file is part of Qt Jambi.
e78566595089 initial import
mandel
parents:
diff changeset
7 **
52
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
8 ** Commercial Usage
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
9 Licensees holding valid Qt Commercial licenses may use this file in
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
10 accordance with the Qt Commercial License Agreement provided with the
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
11 Software or, alternatively, in accordance with the terms contained in
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
12 a written agreement between you and Nokia.
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
13
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
14 GNU Lesser General Public License Usage
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
15 Alternatively, this file may be used under the terms of the GNU Lesser
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
16 General Public License version 2.1 as published by the Free Software
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
17 Foundation and appearing in the file LICENSE.LGPL included in the
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
18 packaging of this file. Please review the following information to
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
19 ensure the GNU Lesser General Public License version 2.1 requirements
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
20 will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
21
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
22 In addition, as a special exception, Nokia gives you certain
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
23 additional rights. These rights are described in the Nokia Qt LGPL
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
24 Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
25 package.
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
26
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
27 GNU General Public License Usage
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
28 Alternatively, this file may be used under the terms of the GNU
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
29 General Public License version 3.0 as published by the Free Software
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
30 Foundation and appearing in the file LICENSE.GPL included in the
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
31 packaging of this file. Please review the following information to
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
32 ensure the GNU General Public License version 3.0 requirements will be
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
33 met: http://www.gnu.org/copyleft/gpl.html.
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
34
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
35 If you are unsure which license is appropriate for your use, please
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
36 contact the sales department at qt-sales@nokia.com.
1
e78566595089 initial import
mandel
parents:
diff changeset
37
e78566595089 initial import
mandel
parents:
diff changeset
38 **
e78566595089 initial import
mandel
parents:
diff changeset
39 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
e78566595089 initial import
mandel
parents:
diff changeset
40 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
e78566595089 initial import
mandel
parents:
diff changeset
41 **
e78566595089 initial import
mandel
parents:
diff changeset
42 ****************************************************************************/
e78566595089 initial import
mandel
parents:
diff changeset
43
e78566595089 initial import
mandel
parents:
diff changeset
44 #ifndef PP_ENGINE_BITS_H
e78566595089 initial import
mandel
parents:
diff changeset
45 #define PP_ENGINE_BITS_H
e78566595089 initial import
mandel
parents:
diff changeset
46
52
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
47 #include <cstdio>
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
48
1
e78566595089 initial import
mandel
parents:
diff changeset
49 namespace rpp {
e78566595089 initial import
mandel
parents:
diff changeset
50
e78566595089 initial import
mandel
parents:
diff changeset
51 inline std::string pp::fix_file_path(std::string const &filename) const
e78566595089 initial import
mandel
parents:
diff changeset
52 {
e78566595089 initial import
mandel
parents:
diff changeset
53 #if defined (PP_OS_WIN)
e78566595089 initial import
mandel
parents:
diff changeset
54 std::string s = filename;
e78566595089 initial import
mandel
parents:
diff changeset
55 for (std::string::iterator it = s.begin(); it != s.end(); ++it)
e78566595089 initial import
mandel
parents:
diff changeset
56 {
e78566595089 initial import
mandel
parents:
diff changeset
57 if (*it == '/')
e78566595089 initial import
mandel
parents:
diff changeset
58 *it = '\\';
e78566595089 initial import
mandel
parents:
diff changeset
59 }
e78566595089 initial import
mandel
parents:
diff changeset
60 return s;
e78566595089 initial import
mandel
parents:
diff changeset
61 #else
e78566595089 initial import
mandel
parents:
diff changeset
62 return filename;
e78566595089 initial import
mandel
parents:
diff changeset
63 #endif
e78566595089 initial import
mandel
parents:
diff changeset
64 }
e78566595089 initial import
mandel
parents:
diff changeset
65
e78566595089 initial import
mandel
parents:
diff changeset
66 inline bool pp::is_absolute(std::string const &filename) const
e78566595089 initial import
mandel
parents:
diff changeset
67 {
e78566595089 initial import
mandel
parents:
diff changeset
68 #if defined(PP_OS_WIN)
e78566595089 initial import
mandel
parents:
diff changeset
69 return filename.length() >= 3
e78566595089 initial import
mandel
parents:
diff changeset
70 && filename.at(1) == ':'
e78566595089 initial import
mandel
parents:
diff changeset
71 && (filename.at(2) == '\\' || filename.at(2) == '/');
e78566595089 initial import
mandel
parents:
diff changeset
72 #else
e78566595089 initial import
mandel
parents:
diff changeset
73 return filename.length() >= 1
e78566595089 initial import
mandel
parents:
diff changeset
74 && filename.at(0) == '/';
e78566595089 initial import
mandel
parents:
diff changeset
75 #endif
e78566595089 initial import
mandel
parents:
diff changeset
76 }
e78566595089 initial import
mandel
parents:
diff changeset
77
e78566595089 initial import
mandel
parents:
diff changeset
78 template <typename _OutputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
79 void pp::file (std::string const &filename, _OutputIterator __result)
e78566595089 initial import
mandel
parents:
diff changeset
80 {
e78566595089 initial import
mandel
parents:
diff changeset
81 FILE *fp = fopen (filename.c_str(), "rb");
e78566595089 initial import
mandel
parents:
diff changeset
82 if (fp != 0)
e78566595089 initial import
mandel
parents:
diff changeset
83 {
e78566595089 initial import
mandel
parents:
diff changeset
84 std::string was = env.current_file;
e78566595089 initial import
mandel
parents:
diff changeset
85 env.current_file = filename;
e78566595089 initial import
mandel
parents:
diff changeset
86 file (fp, __result);
e78566595089 initial import
mandel
parents:
diff changeset
87 env.current_file = was;
e78566595089 initial import
mandel
parents:
diff changeset
88 }
e78566595089 initial import
mandel
parents:
diff changeset
89 //else
e78566595089 initial import
mandel
parents:
diff changeset
90 //std::cerr << "** WARNING file ``" << filename << " not found!" << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
91 }
e78566595089 initial import
mandel
parents:
diff changeset
92
e78566595089 initial import
mandel
parents:
diff changeset
93 template <typename _OutputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
94 void pp::file (FILE *fp, _OutputIterator __result)
e78566595089 initial import
mandel
parents:
diff changeset
95 {
e78566595089 initial import
mandel
parents:
diff changeset
96 assert (fp != 0);
e78566595089 initial import
mandel
parents:
diff changeset
97
e78566595089 initial import
mandel
parents:
diff changeset
98 #if defined (HAVE_MMAP)
e78566595089 initial import
mandel
parents:
diff changeset
99 struct stat st;
e78566595089 initial import
mandel
parents:
diff changeset
100 fstat(FILENO (fp), &st);
e78566595089 initial import
mandel
parents:
diff changeset
101 std::size_t size = st.st_size;
e78566595089 initial import
mandel
parents:
diff changeset
102 char *buffer = 0;
e78566595089 initial import
mandel
parents:
diff changeset
103 buffer = (char *) ::mmap(0, size, PROT_READ, MAP_SHARED, FILENO (fp), 0);
e78566595089 initial import
mandel
parents:
diff changeset
104 fclose (fp);
e78566595089 initial import
mandel
parents:
diff changeset
105 if (!buffer || buffer == (char*) -1)
e78566595089 initial import
mandel
parents:
diff changeset
106 return;
e78566595089 initial import
mandel
parents:
diff changeset
107 this->operator () (buffer, buffer + size, __result);
e78566595089 initial import
mandel
parents:
diff changeset
108 ::munmap(buffer, size);
e78566595089 initial import
mandel
parents:
diff changeset
109 #else
e78566595089 initial import
mandel
parents:
diff changeset
110 std::string buffer;
e78566595089 initial import
mandel
parents:
diff changeset
111 while (!feof(fp)) {
e78566595089 initial import
mandel
parents:
diff changeset
112 char tmp[1024];
e78566595089 initial import
mandel
parents:
diff changeset
113 int read = (int) fread (tmp, sizeof(char), 1023, fp);
e78566595089 initial import
mandel
parents:
diff changeset
114 tmp[read] = '\0';
e78566595089 initial import
mandel
parents:
diff changeset
115 buffer += tmp;
e78566595089 initial import
mandel
parents:
diff changeset
116 }
e78566595089 initial import
mandel
parents:
diff changeset
117 fclose (fp);
e78566595089 initial import
mandel
parents:
diff changeset
118 this->operator () (buffer.c_str(), buffer.c_str() + buffer.size(), __result);
e78566595089 initial import
mandel
parents:
diff changeset
119 #endif
e78566595089 initial import
mandel
parents:
diff changeset
120 }
e78566595089 initial import
mandel
parents:
diff changeset
121
e78566595089 initial import
mandel
parents:
diff changeset
122 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
123 bool pp::find_header_protection (_InputIterator __first, _InputIterator __last, std::string *__prot)
e78566595089 initial import
mandel
parents:
diff changeset
124 {
e78566595089 initial import
mandel
parents:
diff changeset
125 int was = env.current_line;
e78566595089 initial import
mandel
parents:
diff changeset
126
e78566595089 initial import
mandel
parents:
diff changeset
127 while (__first != __last)
e78566595089 initial import
mandel
parents:
diff changeset
128 {
e78566595089 initial import
mandel
parents:
diff changeset
129 if (pp_isspace (*__first))
e78566595089 initial import
mandel
parents:
diff changeset
130 {
e78566595089 initial import
mandel
parents:
diff changeset
131 if (*__first == '\n')
e78566595089 initial import
mandel
parents:
diff changeset
132 ++env.current_line;
e78566595089 initial import
mandel
parents:
diff changeset
133
e78566595089 initial import
mandel
parents:
diff changeset
134 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
135 }
e78566595089 initial import
mandel
parents:
diff changeset
136 else if (_PP_internal::comment_p (__first, __last))
e78566595089 initial import
mandel
parents:
diff changeset
137 {
e78566595089 initial import
mandel
parents:
diff changeset
138 __first = skip_comment_or_divop (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
139 env.current_line += skip_comment_or_divop.lines;
e78566595089 initial import
mandel
parents:
diff changeset
140 }
e78566595089 initial import
mandel
parents:
diff changeset
141 else if (*__first == '#')
e78566595089 initial import
mandel
parents:
diff changeset
142 {
e78566595089 initial import
mandel
parents:
diff changeset
143 __first = skip_blanks (++__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
144 env.current_line += skip_blanks.lines;
e78566595089 initial import
mandel
parents:
diff changeset
145
e78566595089 initial import
mandel
parents:
diff changeset
146 if (__first != __last && *__first == 'i')
e78566595089 initial import
mandel
parents:
diff changeset
147 {
e78566595089 initial import
mandel
parents:
diff changeset
148 _InputIterator __begin = __first;
e78566595089 initial import
mandel
parents:
diff changeset
149 __first = skip_identifier (__begin, __last);
e78566595089 initial import
mandel
parents:
diff changeset
150 env.current_line += skip_identifier.lines;
e78566595089 initial import
mandel
parents:
diff changeset
151
e78566595089 initial import
mandel
parents:
diff changeset
152 std::string __directive (__begin, __first);
e78566595089 initial import
mandel
parents:
diff changeset
153
e78566595089 initial import
mandel
parents:
diff changeset
154 if (__directive == "ifndef")
e78566595089 initial import
mandel
parents:
diff changeset
155 {
e78566595089 initial import
mandel
parents:
diff changeset
156 __first = skip_blanks (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
157 env.current_line += skip_blanks.lines;
e78566595089 initial import
mandel
parents:
diff changeset
158
e78566595089 initial import
mandel
parents:
diff changeset
159 __begin = __first;
e78566595089 initial import
mandel
parents:
diff changeset
160 __first = skip_identifier (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
161 env.current_line += skip_identifier.lines;
e78566595089 initial import
mandel
parents:
diff changeset
162
e78566595089 initial import
mandel
parents:
diff changeset
163 if (__begin != __first && __first != __last)
e78566595089 initial import
mandel
parents:
diff changeset
164 {
e78566595089 initial import
mandel
parents:
diff changeset
165 __prot->assign (__begin, __first);
e78566595089 initial import
mandel
parents:
diff changeset
166 return true;
e78566595089 initial import
mandel
parents:
diff changeset
167 }
e78566595089 initial import
mandel
parents:
diff changeset
168 }
e78566595089 initial import
mandel
parents:
diff changeset
169 }
e78566595089 initial import
mandel
parents:
diff changeset
170 break;
e78566595089 initial import
mandel
parents:
diff changeset
171 }
e78566595089 initial import
mandel
parents:
diff changeset
172 else
e78566595089 initial import
mandel
parents:
diff changeset
173 break;
e78566595089 initial import
mandel
parents:
diff changeset
174 }
e78566595089 initial import
mandel
parents:
diff changeset
175
e78566595089 initial import
mandel
parents:
diff changeset
176 env.current_line = was;
e78566595089 initial import
mandel
parents:
diff changeset
177 return false;
e78566595089 initial import
mandel
parents:
diff changeset
178 }
e78566595089 initial import
mandel
parents:
diff changeset
179
e78566595089 initial import
mandel
parents:
diff changeset
180 inline pp::PP_DIRECTIVE_TYPE pp::find_directive (char const *__directive, std::size_t __size) const
e78566595089 initial import
mandel
parents:
diff changeset
181 {
e78566595089 initial import
mandel
parents:
diff changeset
182 switch (__size)
e78566595089 initial import
mandel
parents:
diff changeset
183 {
e78566595089 initial import
mandel
parents:
diff changeset
184 case 2:
e78566595089 initial import
mandel
parents:
diff changeset
185 if (__directive[0] == 'i'
e78566595089 initial import
mandel
parents:
diff changeset
186 && __directive[1] == 'f')
e78566595089 initial import
mandel
parents:
diff changeset
187 return PP_IF;
e78566595089 initial import
mandel
parents:
diff changeset
188 break;
e78566595089 initial import
mandel
parents:
diff changeset
189
e78566595089 initial import
mandel
parents:
diff changeset
190 case 4:
e78566595089 initial import
mandel
parents:
diff changeset
191 if (__directive[0] == 'e' && !strcmp (__directive, "elif"))
e78566595089 initial import
mandel
parents:
diff changeset
192 return PP_ELIF;
e78566595089 initial import
mandel
parents:
diff changeset
193 else if (__directive[0] == 'e' && !strcmp (__directive, "else"))
e78566595089 initial import
mandel
parents:
diff changeset
194 return PP_ELSE;
e78566595089 initial import
mandel
parents:
diff changeset
195 break;
e78566595089 initial import
mandel
parents:
diff changeset
196
e78566595089 initial import
mandel
parents:
diff changeset
197 case 5:
e78566595089 initial import
mandel
parents:
diff changeset
198 if (__directive[0] == 'i' && !strcmp (__directive, "ifdef"))
e78566595089 initial import
mandel
parents:
diff changeset
199 return PP_IFDEF;
e78566595089 initial import
mandel
parents:
diff changeset
200 else if (__directive[0] == 'u' && !strcmp (__directive, "undef"))
e78566595089 initial import
mandel
parents:
diff changeset
201 return PP_UNDEF;
e78566595089 initial import
mandel
parents:
diff changeset
202 else if (__directive[0] == 'e') {
e78566595089 initial import
mandel
parents:
diff changeset
203 if (!strcmp (__directive, "endif"))
e78566595089 initial import
mandel
parents:
diff changeset
204 return PP_ENDIF;
e78566595089 initial import
mandel
parents:
diff changeset
205 else if (!strcmp (__directive, "error"))
e78566595089 initial import
mandel
parents:
diff changeset
206 return PP_ERROR;
e78566595089 initial import
mandel
parents:
diff changeset
207 }
e78566595089 initial import
mandel
parents:
diff changeset
208 break;
e78566595089 initial import
mandel
parents:
diff changeset
209
e78566595089 initial import
mandel
parents:
diff changeset
210 case 6:
e78566595089 initial import
mandel
parents:
diff changeset
211 if (__directive[0] == 'i' && !strcmp (__directive, "ifndef"))
e78566595089 initial import
mandel
parents:
diff changeset
212 return PP_IFNDEF;
e78566595089 initial import
mandel
parents:
diff changeset
213 else if (__directive[0] == 'd' && !strcmp (__directive, "define"))
e78566595089 initial import
mandel
parents:
diff changeset
214 return PP_DEFINE;
e78566595089 initial import
mandel
parents:
diff changeset
215 else if (__directive[0] == 'p' && !strcmp (__directive, "pragma"))
e78566595089 initial import
mandel
parents:
diff changeset
216 return PP_PRAGMA;
e78566595089 initial import
mandel
parents:
diff changeset
217 break;
e78566595089 initial import
mandel
parents:
diff changeset
218
e78566595089 initial import
mandel
parents:
diff changeset
219 case 7:
e78566595089 initial import
mandel
parents:
diff changeset
220 if (__directive[0] == 'i' && !strcmp (__directive, "include"))
52
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
221 return PP_INCLUDE;
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
222 else if (__directive[0] == 'w' && !strcmp(__directive, "warning"))
09a0f1d048f2 update parser to that from jambi 4.5, attemt to fix building with gcc 4.4
eldar
parents: 1
diff changeset
223 return PP_WARNING;
1
e78566595089 initial import
mandel
parents:
diff changeset
224 break;
e78566595089 initial import
mandel
parents:
diff changeset
225
e78566595089 initial import
mandel
parents:
diff changeset
226 case 12:
e78566595089 initial import
mandel
parents:
diff changeset
227 if (__directive[0] == 'i' && !strcmp (__directive, "include_next"))
e78566595089 initial import
mandel
parents:
diff changeset
228 return PP_INCLUDE_NEXT;
e78566595089 initial import
mandel
parents:
diff changeset
229 break;
e78566595089 initial import
mandel
parents:
diff changeset
230
e78566595089 initial import
mandel
parents:
diff changeset
231 default:
e78566595089 initial import
mandel
parents:
diff changeset
232 break;
e78566595089 initial import
mandel
parents:
diff changeset
233 }
e78566595089 initial import
mandel
parents:
diff changeset
234 std::cerr << "** WARNING unknown directive '#" << __directive << "' at " << env.current_file << ":" << env.current_line << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
235 return PP_UNKNOWN_DIRECTIVE;
e78566595089 initial import
mandel
parents:
diff changeset
236 }
e78566595089 initial import
mandel
parents:
diff changeset
237
e78566595089 initial import
mandel
parents:
diff changeset
238 inline bool pp::file_isdir (std::string const &__filename) const
e78566595089 initial import
mandel
parents:
diff changeset
239 {
e78566595089 initial import
mandel
parents:
diff changeset
240 struct stat __st;
e78566595089 initial import
mandel
parents:
diff changeset
241 #if defined(PP_OS_WIN)
e78566595089 initial import
mandel
parents:
diff changeset
242 if (stat(__filename.c_str (), &__st) == 0)
e78566595089 initial import
mandel
parents:
diff changeset
243 return (__st.st_mode & _S_IFDIR) == _S_IFDIR;
e78566595089 initial import
mandel
parents:
diff changeset
244 else
e78566595089 initial import
mandel
parents:
diff changeset
245 return false;
e78566595089 initial import
mandel
parents:
diff changeset
246 #else
e78566595089 initial import
mandel
parents:
diff changeset
247 if (lstat (__filename.c_str (), &__st) == 0)
e78566595089 initial import
mandel
parents:
diff changeset
248 return (__st.st_mode & S_IFDIR) == S_IFDIR;
e78566595089 initial import
mandel
parents:
diff changeset
249 else
e78566595089 initial import
mandel
parents:
diff changeset
250 return false;
e78566595089 initial import
mandel
parents:
diff changeset
251 #endif
e78566595089 initial import
mandel
parents:
diff changeset
252 }
e78566595089 initial import
mandel
parents:
diff changeset
253
e78566595089 initial import
mandel
parents:
diff changeset
254 inline bool pp::file_exists (std::string const &__filename) const
e78566595089 initial import
mandel
parents:
diff changeset
255 {
e78566595089 initial import
mandel
parents:
diff changeset
256 struct stat __st;
e78566595089 initial import
mandel
parents:
diff changeset
257 #if defined(PP_OS_WIN)
e78566595089 initial import
mandel
parents:
diff changeset
258 return stat(__filename.c_str (), &__st) == 0;
e78566595089 initial import
mandel
parents:
diff changeset
259 #else
e78566595089 initial import
mandel
parents:
diff changeset
260 return lstat (__filename.c_str (), &__st) == 0;
e78566595089 initial import
mandel
parents:
diff changeset
261 #endif
e78566595089 initial import
mandel
parents:
diff changeset
262 }
e78566595089 initial import
mandel
parents:
diff changeset
263
e78566595089 initial import
mandel
parents:
diff changeset
264 inline FILE *pp::find_include_file(std::string const &__input_filename, std::string *__filepath,
e78566595089 initial import
mandel
parents:
diff changeset
265 INCLUDE_POLICY __include_policy, bool __skip_current_path) const
e78566595089 initial import
mandel
parents:
diff changeset
266 {
e78566595089 initial import
mandel
parents:
diff changeset
267 assert (__filepath != 0);
e78566595089 initial import
mandel
parents:
diff changeset
268 assert (! __input_filename.empty());
e78566595089 initial import
mandel
parents:
diff changeset
269
e78566595089 initial import
mandel
parents:
diff changeset
270 __filepath->assign (__input_filename);
e78566595089 initial import
mandel
parents:
diff changeset
271
e78566595089 initial import
mandel
parents:
diff changeset
272 if (is_absolute (*__filepath))
e78566595089 initial import
mandel
parents:
diff changeset
273 return fopen (__filepath->c_str(), "r");
e78566595089 initial import
mandel
parents:
diff changeset
274
e78566595089 initial import
mandel
parents:
diff changeset
275 if (! env.current_file.empty ())
e78566595089 initial import
mandel
parents:
diff changeset
276 _PP_internal::extract_file_path (env.current_file, __filepath);
e78566595089 initial import
mandel
parents:
diff changeset
277
e78566595089 initial import
mandel
parents:
diff changeset
278 if (__include_policy == INCLUDE_LOCAL && ! __skip_current_path)
e78566595089 initial import
mandel
parents:
diff changeset
279 {
e78566595089 initial import
mandel
parents:
diff changeset
280 std::string __tmp (*__filepath);
e78566595089 initial import
mandel
parents:
diff changeset
281 __tmp += __input_filename;
e78566595089 initial import
mandel
parents:
diff changeset
282
e78566595089 initial import
mandel
parents:
diff changeset
283 if (file_exists (__tmp) && !file_isdir(__tmp))
e78566595089 initial import
mandel
parents:
diff changeset
284 {
e78566595089 initial import
mandel
parents:
diff changeset
285 __filepath->append (__input_filename);
e78566595089 initial import
mandel
parents:
diff changeset
286 return fopen (__filepath->c_str (), "r");
e78566595089 initial import
mandel
parents:
diff changeset
287 }
e78566595089 initial import
mandel
parents:
diff changeset
288 }
e78566595089 initial import
mandel
parents:
diff changeset
289
e78566595089 initial import
mandel
parents:
diff changeset
290 std::vector<std::string>::const_iterator it = include_paths.begin ();
e78566595089 initial import
mandel
parents:
diff changeset
291
e78566595089 initial import
mandel
parents:
diff changeset
292 if (__skip_current_path)
e78566595089 initial import
mandel
parents:
diff changeset
293 {
e78566595089 initial import
mandel
parents:
diff changeset
294 it = std::find (include_paths.begin (), include_paths.end (), *__filepath);
e78566595089 initial import
mandel
parents:
diff changeset
295
e78566595089 initial import
mandel
parents:
diff changeset
296 if (it != include_paths.end ())
e78566595089 initial import
mandel
parents:
diff changeset
297 ++it;
e78566595089 initial import
mandel
parents:
diff changeset
298
e78566595089 initial import
mandel
parents:
diff changeset
299 else
e78566595089 initial import
mandel
parents:
diff changeset
300 it = include_paths.begin ();
e78566595089 initial import
mandel
parents:
diff changeset
301 }
e78566595089 initial import
mandel
parents:
diff changeset
302
e78566595089 initial import
mandel
parents:
diff changeset
303 for (; it != include_paths.end (); ++it)
e78566595089 initial import
mandel
parents:
diff changeset
304 {
e78566595089 initial import
mandel
parents:
diff changeset
305 if (__skip_current_path && it == include_paths.begin())
e78566595089 initial import
mandel
parents:
diff changeset
306 continue;
e78566595089 initial import
mandel
parents:
diff changeset
307
e78566595089 initial import
mandel
parents:
diff changeset
308 __filepath->assign (*it);
e78566595089 initial import
mandel
parents:
diff changeset
309 __filepath->append (__input_filename);
e78566595089 initial import
mandel
parents:
diff changeset
310
e78566595089 initial import
mandel
parents:
diff changeset
311 if (file_exists (*__filepath) && !file_isdir(*__filepath))
e78566595089 initial import
mandel
parents:
diff changeset
312 return fopen (__filepath->c_str(), "r");
e78566595089 initial import
mandel
parents:
diff changeset
313 }
e78566595089 initial import
mandel
parents:
diff changeset
314
e78566595089 initial import
mandel
parents:
diff changeset
315 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
316 }
e78566595089 initial import
mandel
parents:
diff changeset
317
e78566595089 initial import
mandel
parents:
diff changeset
318 template <typename _InputIterator, typename _OutputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
319 _InputIterator pp::handle_directive(char const *__directive, std::size_t __size,
e78566595089 initial import
mandel
parents:
diff changeset
320 _InputIterator __first, _InputIterator __last, _OutputIterator __result)
e78566595089 initial import
mandel
parents:
diff changeset
321 {
e78566595089 initial import
mandel
parents:
diff changeset
322 __first = skip_blanks (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
323
e78566595089 initial import
mandel
parents:
diff changeset
324 PP_DIRECTIVE_TYPE d = find_directive (__directive, __size);
e78566595089 initial import
mandel
parents:
diff changeset
325 switch (d)
e78566595089 initial import
mandel
parents:
diff changeset
326 {
e78566595089 initial import
mandel
parents:
diff changeset
327 case PP_DEFINE:
e78566595089 initial import
mandel
parents:
diff changeset
328 if (! skipping ())
e78566595089 initial import
mandel
parents:
diff changeset
329 return handle_define (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
330 break;
e78566595089 initial import
mandel
parents:
diff changeset
331
e78566595089 initial import
mandel
parents:
diff changeset
332 case PP_INCLUDE:
e78566595089 initial import
mandel
parents:
diff changeset
333 case PP_INCLUDE_NEXT:
e78566595089 initial import
mandel
parents:
diff changeset
334 if (! skipping ())
e78566595089 initial import
mandel
parents:
diff changeset
335 return handle_include (d == PP_INCLUDE_NEXT, __first, __last, __result);
e78566595089 initial import
mandel
parents:
diff changeset
336 break;
e78566595089 initial import
mandel
parents:
diff changeset
337
e78566595089 initial import
mandel
parents:
diff changeset
338 case PP_UNDEF:
e78566595089 initial import
mandel
parents:
diff changeset
339 if (! skipping ())
e78566595089 initial import
mandel
parents:
diff changeset
340 return handle_undef(__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
341 break;
e78566595089 initial import
mandel
parents:
diff changeset
342
e78566595089 initial import
mandel
parents:
diff changeset
343 case PP_ELIF:
e78566595089 initial import
mandel
parents:
diff changeset
344 return handle_elif (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
345
e78566595089 initial import
mandel
parents:
diff changeset
346 case PP_ELSE:
e78566595089 initial import
mandel
parents:
diff changeset
347 return handle_else (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
348
e78566595089 initial import
mandel
parents:
diff changeset
349 case PP_ENDIF:
e78566595089 initial import
mandel
parents:
diff changeset
350 return handle_endif (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
351
e78566595089 initial import
mandel
parents:
diff changeset
352 case PP_IF:
e78566595089 initial import
mandel
parents:
diff changeset
353 return handle_if (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
354
e78566595089 initial import
mandel
parents:
diff changeset
355 case PP_IFDEF:
e78566595089 initial import
mandel
parents:
diff changeset
356 return handle_ifdef (false, __first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
357
e78566595089 initial import
mandel
parents:
diff changeset
358 case PP_IFNDEF:
e78566595089 initial import
mandel
parents:
diff changeset
359 return handle_ifdef (true, __first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
360
e78566595089 initial import
mandel
parents:
diff changeset
361 default:
e78566595089 initial import
mandel
parents:
diff changeset
362 break;
e78566595089 initial import
mandel
parents:
diff changeset
363 }
e78566595089 initial import
mandel
parents:
diff changeset
364
e78566595089 initial import
mandel
parents:
diff changeset
365 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
366 }
e78566595089 initial import
mandel
parents:
diff changeset
367
e78566595089 initial import
mandel
parents:
diff changeset
368 template <typename _InputIterator, typename _OutputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
369 _InputIterator pp::handle_include (bool __skip_current_path, _InputIterator __first, _InputIterator __last,
e78566595089 initial import
mandel
parents:
diff changeset
370 _OutputIterator __result)
e78566595089 initial import
mandel
parents:
diff changeset
371 {
e78566595089 initial import
mandel
parents:
diff changeset
372 if (pp_isalpha (*__first) || *__first == '_')
e78566595089 initial import
mandel
parents:
diff changeset
373 {
e78566595089 initial import
mandel
parents:
diff changeset
374 pp_macro_expander expand_include (env);
e78566595089 initial import
mandel
parents:
diff changeset
375 std::string name;
e78566595089 initial import
mandel
parents:
diff changeset
376 name.reserve (255);
e78566595089 initial import
mandel
parents:
diff changeset
377 expand_include (__first, __last, std::back_inserter (name));
e78566595089 initial import
mandel
parents:
diff changeset
378 std::string::iterator it = skip_blanks (name.begin (), name.end ());
e78566595089 initial import
mandel
parents:
diff changeset
379 assert (it != name.end () && (*it == '<' || *it == '"'));
e78566595089 initial import
mandel
parents:
diff changeset
380 handle_include (__skip_current_path, it, name.end (), __result);
e78566595089 initial import
mandel
parents:
diff changeset
381 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
382 }
e78566595089 initial import
mandel
parents:
diff changeset
383
e78566595089 initial import
mandel
parents:
diff changeset
384 assert (*__first == '<' || *__first == '"');
e78566595089 initial import
mandel
parents:
diff changeset
385 int quote = (*__first == '"') ? '"' : '>';
e78566595089 initial import
mandel
parents:
diff changeset
386 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
387
e78566595089 initial import
mandel
parents:
diff changeset
388 _InputIterator end_name = __first;
e78566595089 initial import
mandel
parents:
diff changeset
389 for (; end_name != __last; ++end_name)
e78566595089 initial import
mandel
parents:
diff changeset
390 {
e78566595089 initial import
mandel
parents:
diff changeset
391 assert (*end_name != '\n');
e78566595089 initial import
mandel
parents:
diff changeset
392
e78566595089 initial import
mandel
parents:
diff changeset
393 if (*end_name == quote)
e78566595089 initial import
mandel
parents:
diff changeset
394 break;
e78566595089 initial import
mandel
parents:
diff changeset
395 }
e78566595089 initial import
mandel
parents:
diff changeset
396
e78566595089 initial import
mandel
parents:
diff changeset
397 std::string filename (__first, end_name);
e78566595089 initial import
mandel
parents:
diff changeset
398
e78566595089 initial import
mandel
parents:
diff changeset
399 #ifdef PP_OS_WIN
e78566595089 initial import
mandel
parents:
diff changeset
400 std::replace(filename.begin(), filename.end(), '/', '\\');
e78566595089 initial import
mandel
parents:
diff changeset
401 #endif
e78566595089 initial import
mandel
parents:
diff changeset
402
e78566595089 initial import
mandel
parents:
diff changeset
403 std::string filepath;
e78566595089 initial import
mandel
parents:
diff changeset
404 FILE *fp = find_include_file (filename, &filepath, quote == '>' ? INCLUDE_GLOBAL : INCLUDE_LOCAL, __skip_current_path);
e78566595089 initial import
mandel
parents:
diff changeset
405
e78566595089 initial import
mandel
parents:
diff changeset
406 #if defined (PP_HOOK_ON_FILE_INCLUDED)
e78566595089 initial import
mandel
parents:
diff changeset
407 PP_HOOK_ON_FILE_INCLUDED (env.current_file, fp ? filepath : filename, fp);
e78566595089 initial import
mandel
parents:
diff changeset
408 #endif
e78566595089 initial import
mandel
parents:
diff changeset
409
e78566595089 initial import
mandel
parents:
diff changeset
410 if (fp != 0)
e78566595089 initial import
mandel
parents:
diff changeset
411 {
e78566595089 initial import
mandel
parents:
diff changeset
412 std::string old_file = env.current_file;
e78566595089 initial import
mandel
parents:
diff changeset
413 env.current_file = filepath;
e78566595089 initial import
mandel
parents:
diff changeset
414 int __saved_lines = env.current_line;
e78566595089 initial import
mandel
parents:
diff changeset
415
e78566595089 initial import
mandel
parents:
diff changeset
416 env.current_line = 1;
e78566595089 initial import
mandel
parents:
diff changeset
417 //output_line (env.current_file, 1, __result);
e78566595089 initial import
mandel
parents:
diff changeset
418
e78566595089 initial import
mandel
parents:
diff changeset
419 file (fp, __result);
e78566595089 initial import
mandel
parents:
diff changeset
420
e78566595089 initial import
mandel
parents:
diff changeset
421 // restore the file name and the line position
e78566595089 initial import
mandel
parents:
diff changeset
422 env.current_file = old_file;
e78566595089 initial import
mandel
parents:
diff changeset
423 env.current_line = __saved_lines;
e78566595089 initial import
mandel
parents:
diff changeset
424
e78566595089 initial import
mandel
parents:
diff changeset
425 // sync the buffer
e78566595089 initial import
mandel
parents:
diff changeset
426 _PP_internal::output_line (env.current_file, env.current_line, __result);
e78566595089 initial import
mandel
parents:
diff changeset
427 }
e78566595089 initial import
mandel
parents:
diff changeset
428 #ifndef RPP_JAMBI
e78566595089 initial import
mandel
parents:
diff changeset
429 // else
e78566595089 initial import
mandel
parents:
diff changeset
430 // std::cerr << "*** WARNING " << filename << ": No such file or directory" << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
431 #endif
e78566595089 initial import
mandel
parents:
diff changeset
432
e78566595089 initial import
mandel
parents:
diff changeset
433 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
434 }
e78566595089 initial import
mandel
parents:
diff changeset
435
e78566595089 initial import
mandel
parents:
diff changeset
436 template <typename _InputIterator, typename _OutputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
437 void pp::operator () (_InputIterator __first, _InputIterator __last, _OutputIterator __result)
e78566595089 initial import
mandel
parents:
diff changeset
438 {
e78566595089 initial import
mandel
parents:
diff changeset
439 #ifndef PP_NO_SMART_HEADER_PROTECTION
e78566595089 initial import
mandel
parents:
diff changeset
440 std::string __prot;
e78566595089 initial import
mandel
parents:
diff changeset
441 __prot.reserve (255);
e78566595089 initial import
mandel
parents:
diff changeset
442 pp_fast_string __tmp (__prot.c_str (), __prot.size ());
e78566595089 initial import
mandel
parents:
diff changeset
443
e78566595089 initial import
mandel
parents:
diff changeset
444 if (find_header_protection (__first, __last, &__prot)
e78566595089 initial import
mandel
parents:
diff changeset
445 && env.resolve (&__tmp) != 0)
e78566595089 initial import
mandel
parents:
diff changeset
446 {
e78566595089 initial import
mandel
parents:
diff changeset
447 // std::cerr << "** DEBUG found header protection:" << __prot << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
448 return;
e78566595089 initial import
mandel
parents:
diff changeset
449 }
e78566595089 initial import
mandel
parents:
diff changeset
450 #endif
e78566595089 initial import
mandel
parents:
diff changeset
451
e78566595089 initial import
mandel
parents:
diff changeset
452 env.current_line = 1;
e78566595089 initial import
mandel
parents:
diff changeset
453 char __buffer[512];
e78566595089 initial import
mandel
parents:
diff changeset
454
e78566595089 initial import
mandel
parents:
diff changeset
455 while (true)
e78566595089 initial import
mandel
parents:
diff changeset
456 {
e78566595089 initial import
mandel
parents:
diff changeset
457 __first = skip_blanks (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
458 env.current_line += skip_blanks.lines;
e78566595089 initial import
mandel
parents:
diff changeset
459
e78566595089 initial import
mandel
parents:
diff changeset
460 if (__first == __last)
e78566595089 initial import
mandel
parents:
diff changeset
461 break;
e78566595089 initial import
mandel
parents:
diff changeset
462 else if (*__first == '#')
e78566595089 initial import
mandel
parents:
diff changeset
463 {
e78566595089 initial import
mandel
parents:
diff changeset
464 assert (*__first == '#');
e78566595089 initial import
mandel
parents:
diff changeset
465 __first = skip_blanks (++__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
466 env.current_line += skip_blanks.lines;
e78566595089 initial import
mandel
parents:
diff changeset
467
e78566595089 initial import
mandel
parents:
diff changeset
468 _InputIterator end_id = skip_identifier (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
469 env.current_line += skip_identifier.lines;
e78566595089 initial import
mandel
parents:
diff changeset
470 std::size_t __size = end_id - __first;
e78566595089 initial import
mandel
parents:
diff changeset
471
e78566595089 initial import
mandel
parents:
diff changeset
472 assert (__size < 512);
e78566595089 initial import
mandel
parents:
diff changeset
473 char *__cp = __buffer;
e78566595089 initial import
mandel
parents:
diff changeset
474 std::copy (__first, end_id, __cp);
e78566595089 initial import
mandel
parents:
diff changeset
475 __cp[__size] = '\0';
e78566595089 initial import
mandel
parents:
diff changeset
476
e78566595089 initial import
mandel
parents:
diff changeset
477 end_id = skip_blanks (end_id, __last);
e78566595089 initial import
mandel
parents:
diff changeset
478 __first = skip (end_id, __last);
e78566595089 initial import
mandel
parents:
diff changeset
479
e78566595089 initial import
mandel
parents:
diff changeset
480 int was = env.current_line;
e78566595089 initial import
mandel
parents:
diff changeset
481 (void) handle_directive (__buffer, __size, end_id, __first, __result);
e78566595089 initial import
mandel
parents:
diff changeset
482
e78566595089 initial import
mandel
parents:
diff changeset
483 if (env.current_line != was)
e78566595089 initial import
mandel
parents:
diff changeset
484 {
e78566595089 initial import
mandel
parents:
diff changeset
485 env.current_line = was;
e78566595089 initial import
mandel
parents:
diff changeset
486 _PP_internal::output_line (env.current_file, env.current_line, __result);
e78566595089 initial import
mandel
parents:
diff changeset
487 }
e78566595089 initial import
mandel
parents:
diff changeset
488 }
e78566595089 initial import
mandel
parents:
diff changeset
489 else if (*__first == '\n')
e78566595089 initial import
mandel
parents:
diff changeset
490 {
e78566595089 initial import
mandel
parents:
diff changeset
491 // ### compress the line
e78566595089 initial import
mandel
parents:
diff changeset
492 *__result++ = *__first++;
e78566595089 initial import
mandel
parents:
diff changeset
493 ++env.current_line;
e78566595089 initial import
mandel
parents:
diff changeset
494 }
e78566595089 initial import
mandel
parents:
diff changeset
495 else if (skipping ())
e78566595089 initial import
mandel
parents:
diff changeset
496 __first = skip (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
497 else
e78566595089 initial import
mandel
parents:
diff changeset
498 {
e78566595089 initial import
mandel
parents:
diff changeset
499 _PP_internal::output_line (env.current_file, env.current_line, __result);
e78566595089 initial import
mandel
parents:
diff changeset
500 __first = expand (__first, __last, __result);
e78566595089 initial import
mandel
parents:
diff changeset
501 env.current_line += expand.lines;
e78566595089 initial import
mandel
parents:
diff changeset
502
e78566595089 initial import
mandel
parents:
diff changeset
503 if (expand.generated_lines)
e78566595089 initial import
mandel
parents:
diff changeset
504 _PP_internal::output_line (env.current_file, env.current_line, __result);
e78566595089 initial import
mandel
parents:
diff changeset
505 }
e78566595089 initial import
mandel
parents:
diff changeset
506 }
e78566595089 initial import
mandel
parents:
diff changeset
507 }
e78566595089 initial import
mandel
parents:
diff changeset
508
e78566595089 initial import
mandel
parents:
diff changeset
509 inline pp::pp (pp_environment &__env):
e78566595089 initial import
mandel
parents:
diff changeset
510 env (__env), expand (env)
e78566595089 initial import
mandel
parents:
diff changeset
511 {
e78566595089 initial import
mandel
parents:
diff changeset
512 iflevel = 0;
e78566595089 initial import
mandel
parents:
diff changeset
513 _M_skipping[iflevel] = 0;
e78566595089 initial import
mandel
parents:
diff changeset
514 _M_true_test[iflevel] = 0;
e78566595089 initial import
mandel
parents:
diff changeset
515 }
e78566595089 initial import
mandel
parents:
diff changeset
516
e78566595089 initial import
mandel
parents:
diff changeset
517 inline std::back_insert_iterator<std::vector<std::string> > pp::include_paths_inserter ()
e78566595089 initial import
mandel
parents:
diff changeset
518 { return std::back_inserter (include_paths); }
e78566595089 initial import
mandel
parents:
diff changeset
519
e78566595089 initial import
mandel
parents:
diff changeset
520 inline std::vector<std::string>::iterator pp::include_paths_begin ()
e78566595089 initial import
mandel
parents:
diff changeset
521 { return include_paths.begin (); }
e78566595089 initial import
mandel
parents:
diff changeset
522
e78566595089 initial import
mandel
parents:
diff changeset
523 inline std::vector<std::string>::iterator pp::include_paths_end ()
e78566595089 initial import
mandel
parents:
diff changeset
524 { return include_paths.end (); }
e78566595089 initial import
mandel
parents:
diff changeset
525
e78566595089 initial import
mandel
parents:
diff changeset
526 inline std::vector<std::string>::const_iterator pp::include_paths_begin () const
e78566595089 initial import
mandel
parents:
diff changeset
527 { return include_paths.begin (); }
e78566595089 initial import
mandel
parents:
diff changeset
528
e78566595089 initial import
mandel
parents:
diff changeset
529 inline std::vector<std::string>::const_iterator pp::include_paths_end () const
e78566595089 initial import
mandel
parents:
diff changeset
530 { return include_paths.end (); }
e78566595089 initial import
mandel
parents:
diff changeset
531
e78566595089 initial import
mandel
parents:
diff changeset
532 inline void pp::push_include_path (std::string const &__path)
e78566595089 initial import
mandel
parents:
diff changeset
533 {
e78566595089 initial import
mandel
parents:
diff changeset
534 if (__path.empty () || __path [__path.size () - 1] != PATH_SEPARATOR)
e78566595089 initial import
mandel
parents:
diff changeset
535 {
e78566595089 initial import
mandel
parents:
diff changeset
536 std::string __tmp (__path);
e78566595089 initial import
mandel
parents:
diff changeset
537 __tmp += PATH_SEPARATOR;
e78566595089 initial import
mandel
parents:
diff changeset
538 include_paths.push_back (__tmp);
e78566595089 initial import
mandel
parents:
diff changeset
539 }
e78566595089 initial import
mandel
parents:
diff changeset
540
e78566595089 initial import
mandel
parents:
diff changeset
541 else
e78566595089 initial import
mandel
parents:
diff changeset
542 include_paths.push_back (__path);
e78566595089 initial import
mandel
parents:
diff changeset
543 }
e78566595089 initial import
mandel
parents:
diff changeset
544
e78566595089 initial import
mandel
parents:
diff changeset
545 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
546 _InputIterator pp::handle_define (_InputIterator __first, _InputIterator __last)
e78566595089 initial import
mandel
parents:
diff changeset
547 {
e78566595089 initial import
mandel
parents:
diff changeset
548 pp_macro macro;
e78566595089 initial import
mandel
parents:
diff changeset
549 #if defined (PP_WITH_MACRO_POSITION)
e78566595089 initial import
mandel
parents:
diff changeset
550 macro.file = pp_symbol::get (env.current_file);
e78566595089 initial import
mandel
parents:
diff changeset
551 #endif
e78566595089 initial import
mandel
parents:
diff changeset
552 std::string definition;
e78566595089 initial import
mandel
parents:
diff changeset
553
e78566595089 initial import
mandel
parents:
diff changeset
554 __first = skip_blanks (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
555 _InputIterator end_macro_name = skip_identifier (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
556 pp_fast_string const *macro_name = pp_symbol::get (__first, end_macro_name);
e78566595089 initial import
mandel
parents:
diff changeset
557 __first = end_macro_name;
e78566595089 initial import
mandel
parents:
diff changeset
558
e78566595089 initial import
mandel
parents:
diff changeset
559 if (__first != __last && *__first == '(')
e78566595089 initial import
mandel
parents:
diff changeset
560 {
e78566595089 initial import
mandel
parents:
diff changeset
561 macro.function_like = true;
e78566595089 initial import
mandel
parents:
diff changeset
562 macro.formals.reserve (5);
e78566595089 initial import
mandel
parents:
diff changeset
563
e78566595089 initial import
mandel
parents:
diff changeset
564 __first = skip_blanks (++__first, __last); // skip '('
e78566595089 initial import
mandel
parents:
diff changeset
565 _InputIterator arg_end = skip_identifier (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
566 if (__first != arg_end)
e78566595089 initial import
mandel
parents:
diff changeset
567 macro.formals.push_back (pp_symbol::get (__first, arg_end));
e78566595089 initial import
mandel
parents:
diff changeset
568
e78566595089 initial import
mandel
parents:
diff changeset
569 __first = skip_blanks (arg_end, __last);
e78566595089 initial import
mandel
parents:
diff changeset
570
e78566595089 initial import
mandel
parents:
diff changeset
571 if (*__first == '.')
e78566595089 initial import
mandel
parents:
diff changeset
572 {
e78566595089 initial import
mandel
parents:
diff changeset
573 macro.variadics = true;
e78566595089 initial import
mandel
parents:
diff changeset
574 while (*__first == '.')
e78566595089 initial import
mandel
parents:
diff changeset
575 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
576 }
e78566595089 initial import
mandel
parents:
diff changeset
577
e78566595089 initial import
mandel
parents:
diff changeset
578 while (__first != __last && *__first == ',')
e78566595089 initial import
mandel
parents:
diff changeset
579 {
e78566595089 initial import
mandel
parents:
diff changeset
580 __first = skip_blanks (++__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
581
e78566595089 initial import
mandel
parents:
diff changeset
582 arg_end = skip_identifier (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
583 if (__first != arg_end)
e78566595089 initial import
mandel
parents:
diff changeset
584 macro.formals.push_back (pp_symbol::get (__first, arg_end));
e78566595089 initial import
mandel
parents:
diff changeset
585
e78566595089 initial import
mandel
parents:
diff changeset
586 __first = skip_blanks (arg_end, __last);
e78566595089 initial import
mandel
parents:
diff changeset
587
e78566595089 initial import
mandel
parents:
diff changeset
588 if (*__first == '.')
e78566595089 initial import
mandel
parents:
diff changeset
589 {
e78566595089 initial import
mandel
parents:
diff changeset
590 macro.variadics = true;
e78566595089 initial import
mandel
parents:
diff changeset
591 while (*__first == '.')
e78566595089 initial import
mandel
parents:
diff changeset
592 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
593 }
e78566595089 initial import
mandel
parents:
diff changeset
594 }
e78566595089 initial import
mandel
parents:
diff changeset
595
e78566595089 initial import
mandel
parents:
diff changeset
596 assert (*__first == ')');
e78566595089 initial import
mandel
parents:
diff changeset
597 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
598 }
e78566595089 initial import
mandel
parents:
diff changeset
599
e78566595089 initial import
mandel
parents:
diff changeset
600 __first = skip_blanks (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
601
e78566595089 initial import
mandel
parents:
diff changeset
602 while (__first != __last && *__first != '\n')
e78566595089 initial import
mandel
parents:
diff changeset
603 {
e78566595089 initial import
mandel
parents:
diff changeset
604 if (*__first == '/') {
e78566595089 initial import
mandel
parents:
diff changeset
605 __first = skip_comment_or_divop(__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
606 env.current_line += skip_comment_or_divop.lines;
e78566595089 initial import
mandel
parents:
diff changeset
607 }
e78566595089 initial import
mandel
parents:
diff changeset
608
e78566595089 initial import
mandel
parents:
diff changeset
609 if (*__first == '\\')
e78566595089 initial import
mandel
parents:
diff changeset
610 {
e78566595089 initial import
mandel
parents:
diff changeset
611 _InputIterator __begin = __first;
e78566595089 initial import
mandel
parents:
diff changeset
612 __begin = skip_blanks (++__begin, __last);
e78566595089 initial import
mandel
parents:
diff changeset
613
e78566595089 initial import
mandel
parents:
diff changeset
614 if (__begin != __last && *__begin == '\n')
e78566595089 initial import
mandel
parents:
diff changeset
615 {
e78566595089 initial import
mandel
parents:
diff changeset
616 ++macro.lines;
e78566595089 initial import
mandel
parents:
diff changeset
617 __first = skip_blanks (++__begin, __last);
e78566595089 initial import
mandel
parents:
diff changeset
618 definition += ' ';
e78566595089 initial import
mandel
parents:
diff changeset
619 continue;
e78566595089 initial import
mandel
parents:
diff changeset
620 }
e78566595089 initial import
mandel
parents:
diff changeset
621 }
e78566595089 initial import
mandel
parents:
diff changeset
622
e78566595089 initial import
mandel
parents:
diff changeset
623 definition += *__first++;
e78566595089 initial import
mandel
parents:
diff changeset
624 }
e78566595089 initial import
mandel
parents:
diff changeset
625
e78566595089 initial import
mandel
parents:
diff changeset
626 macro.definition = pp_symbol::get (definition);
e78566595089 initial import
mandel
parents:
diff changeset
627 env.bind (macro_name, macro);
e78566595089 initial import
mandel
parents:
diff changeset
628
e78566595089 initial import
mandel
parents:
diff changeset
629 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
630 }
e78566595089 initial import
mandel
parents:
diff changeset
631
e78566595089 initial import
mandel
parents:
diff changeset
632 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
633 _InputIterator pp::skip (_InputIterator __first, _InputIterator __last)
e78566595089 initial import
mandel
parents:
diff changeset
634 {
e78566595089 initial import
mandel
parents:
diff changeset
635 pp_skip_string_literal skip_string_literal;
e78566595089 initial import
mandel
parents:
diff changeset
636 pp_skip_char_literal skip_char_literal;
e78566595089 initial import
mandel
parents:
diff changeset
637
e78566595089 initial import
mandel
parents:
diff changeset
638 while (__first != __last && *__first != '\n')
e78566595089 initial import
mandel
parents:
diff changeset
639 {
e78566595089 initial import
mandel
parents:
diff changeset
640 if (*__first == '/')
e78566595089 initial import
mandel
parents:
diff changeset
641 {
e78566595089 initial import
mandel
parents:
diff changeset
642 __first = skip_comment_or_divop (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
643 env.current_line += skip_comment_or_divop.lines;
e78566595089 initial import
mandel
parents:
diff changeset
644 }
e78566595089 initial import
mandel
parents:
diff changeset
645 else if (*__first == '"')
e78566595089 initial import
mandel
parents:
diff changeset
646 {
e78566595089 initial import
mandel
parents:
diff changeset
647 __first = skip_string_literal (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
648 env.current_line += skip_string_literal.lines;
e78566595089 initial import
mandel
parents:
diff changeset
649 }
e78566595089 initial import
mandel
parents:
diff changeset
650 else if (*__first == '\'')
e78566595089 initial import
mandel
parents:
diff changeset
651 {
e78566595089 initial import
mandel
parents:
diff changeset
652 __first = skip_char_literal (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
653 env.current_line += skip_char_literal.lines;
e78566595089 initial import
mandel
parents:
diff changeset
654 }
e78566595089 initial import
mandel
parents:
diff changeset
655 else if (*__first == '\\')
e78566595089 initial import
mandel
parents:
diff changeset
656 {
e78566595089 initial import
mandel
parents:
diff changeset
657 __first = skip_blanks (++__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
658 env.current_line += skip_blanks.lines;
e78566595089 initial import
mandel
parents:
diff changeset
659
e78566595089 initial import
mandel
parents:
diff changeset
660 if (__first != __last && *__first == '\n')
e78566595089 initial import
mandel
parents:
diff changeset
661 {
e78566595089 initial import
mandel
parents:
diff changeset
662 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
663 ++env.current_line;
e78566595089 initial import
mandel
parents:
diff changeset
664 }
e78566595089 initial import
mandel
parents:
diff changeset
665 }
e78566595089 initial import
mandel
parents:
diff changeset
666 else
e78566595089 initial import
mandel
parents:
diff changeset
667 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
668 }
e78566595089 initial import
mandel
parents:
diff changeset
669
e78566595089 initial import
mandel
parents:
diff changeset
670 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
671 }
e78566595089 initial import
mandel
parents:
diff changeset
672
e78566595089 initial import
mandel
parents:
diff changeset
673 inline bool pp::test_if_level()
e78566595089 initial import
mandel
parents:
diff changeset
674 {
e78566595089 initial import
mandel
parents:
diff changeset
675 bool result = !_M_skipping[iflevel++];
e78566595089 initial import
mandel
parents:
diff changeset
676 _M_skipping[iflevel] = _M_skipping[iflevel - 1];
e78566595089 initial import
mandel
parents:
diff changeset
677 _M_true_test[iflevel] = false;
e78566595089 initial import
mandel
parents:
diff changeset
678 return result;
e78566595089 initial import
mandel
parents:
diff changeset
679 }
e78566595089 initial import
mandel
parents:
diff changeset
680
e78566595089 initial import
mandel
parents:
diff changeset
681 inline int pp::skipping() const
e78566595089 initial import
mandel
parents:
diff changeset
682 { return _M_skipping[iflevel]; }
e78566595089 initial import
mandel
parents:
diff changeset
683
e78566595089 initial import
mandel
parents:
diff changeset
684 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
685 _InputIterator pp::eval_primary(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
686 {
e78566595089 initial import
mandel
parents:
diff changeset
687 bool expect_paren = false;
e78566595089 initial import
mandel
parents:
diff changeset
688 int token;
e78566595089 initial import
mandel
parents:
diff changeset
689 __first = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
690
e78566595089 initial import
mandel
parents:
diff changeset
691 switch (token)
e78566595089 initial import
mandel
parents:
diff changeset
692 {
e78566595089 initial import
mandel
parents:
diff changeset
693 case TOKEN_NUMBER:
e78566595089 initial import
mandel
parents:
diff changeset
694 result->set_long (token_value);
e78566595089 initial import
mandel
parents:
diff changeset
695 break;
e78566595089 initial import
mandel
parents:
diff changeset
696
e78566595089 initial import
mandel
parents:
diff changeset
697 case TOKEN_UNUMBER:
e78566595089 initial import
mandel
parents:
diff changeset
698 result->set_ulong (token_uvalue);
e78566595089 initial import
mandel
parents:
diff changeset
699 break;
e78566595089 initial import
mandel
parents:
diff changeset
700
e78566595089 initial import
mandel
parents:
diff changeset
701 case TOKEN_DEFINED:
e78566595089 initial import
mandel
parents:
diff changeset
702 __first = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
703
e78566595089 initial import
mandel
parents:
diff changeset
704 if (token == '(')
e78566595089 initial import
mandel
parents:
diff changeset
705 {
e78566595089 initial import
mandel
parents:
diff changeset
706 expect_paren = true;
e78566595089 initial import
mandel
parents:
diff changeset
707 __first = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
708 }
e78566595089 initial import
mandel
parents:
diff changeset
709
e78566595089 initial import
mandel
parents:
diff changeset
710 if (token != TOKEN_IDENTIFIER)
e78566595089 initial import
mandel
parents:
diff changeset
711 {
e78566595089 initial import
mandel
parents:
diff changeset
712 std::cerr << "** WARNING expected ``identifier'' found:" << char(token) << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
713 result->set_long (0);
e78566595089 initial import
mandel
parents:
diff changeset
714 break;
e78566595089 initial import
mandel
parents:
diff changeset
715 }
e78566595089 initial import
mandel
parents:
diff changeset
716
e78566595089 initial import
mandel
parents:
diff changeset
717 result->set_long (env.resolve (token_text->c_str (), token_text->size ()) != 0);
e78566595089 initial import
mandel
parents:
diff changeset
718
e78566595089 initial import
mandel
parents:
diff changeset
719 next_token (__first, __last, &token); // skip '('
e78566595089 initial import
mandel
parents:
diff changeset
720
e78566595089 initial import
mandel
parents:
diff changeset
721 if (expect_paren)
e78566595089 initial import
mandel
parents:
diff changeset
722 {
e78566595089 initial import
mandel
parents:
diff changeset
723 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
724 if (token != ')')
e78566595089 initial import
mandel
parents:
diff changeset
725 std::cerr << "** WARNING expected ``)''" << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
726 else
e78566595089 initial import
mandel
parents:
diff changeset
727 __first = next;
e78566595089 initial import
mandel
parents:
diff changeset
728 }
e78566595089 initial import
mandel
parents:
diff changeset
729 break;
e78566595089 initial import
mandel
parents:
diff changeset
730
e78566595089 initial import
mandel
parents:
diff changeset
731 case TOKEN_IDENTIFIER:
e78566595089 initial import
mandel
parents:
diff changeset
732 result->set_long (0);
e78566595089 initial import
mandel
parents:
diff changeset
733 break;
e78566595089 initial import
mandel
parents:
diff changeset
734
e78566595089 initial import
mandel
parents:
diff changeset
735 case '-':
e78566595089 initial import
mandel
parents:
diff changeset
736 __first = eval_primary (__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
737 result->set_long (- result->l);
e78566595089 initial import
mandel
parents:
diff changeset
738 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
739
e78566595089 initial import
mandel
parents:
diff changeset
740 case '+':
e78566595089 initial import
mandel
parents:
diff changeset
741 __first = eval_primary (__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
742 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
743
e78566595089 initial import
mandel
parents:
diff changeset
744 case '!':
e78566595089 initial import
mandel
parents:
diff changeset
745 __first = eval_primary (__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
746 result->set_long (result->is_zero ());
e78566595089 initial import
mandel
parents:
diff changeset
747 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
748
e78566595089 initial import
mandel
parents:
diff changeset
749 case '(':
e78566595089 initial import
mandel
parents:
diff changeset
750 __first = eval_constant_expression(__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
751 next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
752
e78566595089 initial import
mandel
parents:
diff changeset
753 if (token != ')')
e78566595089 initial import
mandel
parents:
diff changeset
754 std::cerr << "** WARNING expected ``)'' = " << token << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
755 else
e78566595089 initial import
mandel
parents:
diff changeset
756 __first = next_token(__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
757 break;
e78566595089 initial import
mandel
parents:
diff changeset
758
e78566595089 initial import
mandel
parents:
diff changeset
759 default:
e78566595089 initial import
mandel
parents:
diff changeset
760 result->set_long (0);
e78566595089 initial import
mandel
parents:
diff changeset
761 }
e78566595089 initial import
mandel
parents:
diff changeset
762
e78566595089 initial import
mandel
parents:
diff changeset
763 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
764 }
e78566595089 initial import
mandel
parents:
diff changeset
765
e78566595089 initial import
mandel
parents:
diff changeset
766 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
767 _InputIterator pp::eval_multiplicative(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
768 {
e78566595089 initial import
mandel
parents:
diff changeset
769 __first = eval_primary(__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
770
e78566595089 initial import
mandel
parents:
diff changeset
771 int token;
e78566595089 initial import
mandel
parents:
diff changeset
772 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
773
e78566595089 initial import
mandel
parents:
diff changeset
774 while (token == '*' || token == '/' || token == '%')
e78566595089 initial import
mandel
parents:
diff changeset
775 {
e78566595089 initial import
mandel
parents:
diff changeset
776 Value value;
e78566595089 initial import
mandel
parents:
diff changeset
777 __first = eval_primary(next, __last, &value);
e78566595089 initial import
mandel
parents:
diff changeset
778
e78566595089 initial import
mandel
parents:
diff changeset
779 if (token == '*')
e78566595089 initial import
mandel
parents:
diff changeset
780 result->op_mult (value);
e78566595089 initial import
mandel
parents:
diff changeset
781 else if (token == '/')
e78566595089 initial import
mandel
parents:
diff changeset
782 {
e78566595089 initial import
mandel
parents:
diff changeset
783 if (value.is_zero ())
e78566595089 initial import
mandel
parents:
diff changeset
784 {
e78566595089 initial import
mandel
parents:
diff changeset
785 std::cerr << "** WARNING division by zero" << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
786 result->set_long (0);
e78566595089 initial import
mandel
parents:
diff changeset
787 }
e78566595089 initial import
mandel
parents:
diff changeset
788 else
e78566595089 initial import
mandel
parents:
diff changeset
789 result->op_div (value);
e78566595089 initial import
mandel
parents:
diff changeset
790 }
e78566595089 initial import
mandel
parents:
diff changeset
791 else
e78566595089 initial import
mandel
parents:
diff changeset
792 {
e78566595089 initial import
mandel
parents:
diff changeset
793 if (value.is_zero ())
e78566595089 initial import
mandel
parents:
diff changeset
794 {
e78566595089 initial import
mandel
parents:
diff changeset
795 std::cerr << "** WARNING division by zero" << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
796 result->set_long (0);
e78566595089 initial import
mandel
parents:
diff changeset
797 }
e78566595089 initial import
mandel
parents:
diff changeset
798 else
e78566595089 initial import
mandel
parents:
diff changeset
799 result->op_mod (value);
e78566595089 initial import
mandel
parents:
diff changeset
800 }
e78566595089 initial import
mandel
parents:
diff changeset
801 next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
802 }
e78566595089 initial import
mandel
parents:
diff changeset
803
e78566595089 initial import
mandel
parents:
diff changeset
804 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
805 }
e78566595089 initial import
mandel
parents:
diff changeset
806
e78566595089 initial import
mandel
parents:
diff changeset
807 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
808 _InputIterator pp::eval_additive(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
809 {
e78566595089 initial import
mandel
parents:
diff changeset
810 __first = eval_multiplicative(__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
811
e78566595089 initial import
mandel
parents:
diff changeset
812 int token;
e78566595089 initial import
mandel
parents:
diff changeset
813 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
814
e78566595089 initial import
mandel
parents:
diff changeset
815 while (token == '+' || token == '-')
e78566595089 initial import
mandel
parents:
diff changeset
816 {
e78566595089 initial import
mandel
parents:
diff changeset
817 Value value;
e78566595089 initial import
mandel
parents:
diff changeset
818 __first = eval_multiplicative(next, __last, &value);
e78566595089 initial import
mandel
parents:
diff changeset
819
e78566595089 initial import
mandel
parents:
diff changeset
820 if (token == '+')
e78566595089 initial import
mandel
parents:
diff changeset
821 result->op_add (value);
e78566595089 initial import
mandel
parents:
diff changeset
822 else
e78566595089 initial import
mandel
parents:
diff changeset
823 result->op_sub (value);
e78566595089 initial import
mandel
parents:
diff changeset
824 next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
825 }
e78566595089 initial import
mandel
parents:
diff changeset
826
e78566595089 initial import
mandel
parents:
diff changeset
827 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
828 }
e78566595089 initial import
mandel
parents:
diff changeset
829
e78566595089 initial import
mandel
parents:
diff changeset
830 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
831 _InputIterator pp::eval_shift(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
832 {
e78566595089 initial import
mandel
parents:
diff changeset
833 __first = eval_additive(__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
834
e78566595089 initial import
mandel
parents:
diff changeset
835 int token;
e78566595089 initial import
mandel
parents:
diff changeset
836 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
837
e78566595089 initial import
mandel
parents:
diff changeset
838 while (token == TOKEN_LT_LT || token == TOKEN_GT_GT)
e78566595089 initial import
mandel
parents:
diff changeset
839 {
e78566595089 initial import
mandel
parents:
diff changeset
840 Value value;
e78566595089 initial import
mandel
parents:
diff changeset
841 __first = eval_additive (next, __last, &value);
e78566595089 initial import
mandel
parents:
diff changeset
842
e78566595089 initial import
mandel
parents:
diff changeset
843 if (token == TOKEN_LT_LT)
e78566595089 initial import
mandel
parents:
diff changeset
844 result->op_lhs (value);
e78566595089 initial import
mandel
parents:
diff changeset
845 else
e78566595089 initial import
mandel
parents:
diff changeset
846 result->op_rhs (value);
e78566595089 initial import
mandel
parents:
diff changeset
847 next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
848 }
e78566595089 initial import
mandel
parents:
diff changeset
849
e78566595089 initial import
mandel
parents:
diff changeset
850 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
851 }
e78566595089 initial import
mandel
parents:
diff changeset
852
e78566595089 initial import
mandel
parents:
diff changeset
853 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
854 _InputIterator pp::eval_relational(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
855 {
e78566595089 initial import
mandel
parents:
diff changeset
856 __first = eval_shift(__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
857
e78566595089 initial import
mandel
parents:
diff changeset
858 int token;
e78566595089 initial import
mandel
parents:
diff changeset
859 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
860
e78566595089 initial import
mandel
parents:
diff changeset
861 while (token == '<'
e78566595089 initial import
mandel
parents:
diff changeset
862 || token == '>'
e78566595089 initial import
mandel
parents:
diff changeset
863 || token == TOKEN_LT_EQ
e78566595089 initial import
mandel
parents:
diff changeset
864 || token == TOKEN_GT_EQ)
e78566595089 initial import
mandel
parents:
diff changeset
865 {
e78566595089 initial import
mandel
parents:
diff changeset
866 Value value;
e78566595089 initial import
mandel
parents:
diff changeset
867 __first = eval_shift(next, __last, &value);
e78566595089 initial import
mandel
parents:
diff changeset
868
e78566595089 initial import
mandel
parents:
diff changeset
869 switch (token)
e78566595089 initial import
mandel
parents:
diff changeset
870 {
e78566595089 initial import
mandel
parents:
diff changeset
871 default:
e78566595089 initial import
mandel
parents:
diff changeset
872 assert (0);
e78566595089 initial import
mandel
parents:
diff changeset
873 break;
e78566595089 initial import
mandel
parents:
diff changeset
874
e78566595089 initial import
mandel
parents:
diff changeset
875 case '<':
e78566595089 initial import
mandel
parents:
diff changeset
876 result->op_lt (value);
e78566595089 initial import
mandel
parents:
diff changeset
877 break;
e78566595089 initial import
mandel
parents:
diff changeset
878
e78566595089 initial import
mandel
parents:
diff changeset
879 case '>':
e78566595089 initial import
mandel
parents:
diff changeset
880 result->op_gt (value);
e78566595089 initial import
mandel
parents:
diff changeset
881 break;
e78566595089 initial import
mandel
parents:
diff changeset
882
e78566595089 initial import
mandel
parents:
diff changeset
883 case TOKEN_LT_EQ:
e78566595089 initial import
mandel
parents:
diff changeset
884 result->op_le (value);
e78566595089 initial import
mandel
parents:
diff changeset
885 break;
e78566595089 initial import
mandel
parents:
diff changeset
886
e78566595089 initial import
mandel
parents:
diff changeset
887 case TOKEN_GT_EQ:
e78566595089 initial import
mandel
parents:
diff changeset
888 result->op_ge (value);
e78566595089 initial import
mandel
parents:
diff changeset
889 break;
e78566595089 initial import
mandel
parents:
diff changeset
890 }
e78566595089 initial import
mandel
parents:
diff changeset
891 next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
892 }
e78566595089 initial import
mandel
parents:
diff changeset
893
e78566595089 initial import
mandel
parents:
diff changeset
894 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
895 }
e78566595089 initial import
mandel
parents:
diff changeset
896
e78566595089 initial import
mandel
parents:
diff changeset
897 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
898 _InputIterator pp::eval_equality(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
899 {
e78566595089 initial import
mandel
parents:
diff changeset
900 __first = eval_relational(__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
901
e78566595089 initial import
mandel
parents:
diff changeset
902 int token;
e78566595089 initial import
mandel
parents:
diff changeset
903 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
904
e78566595089 initial import
mandel
parents:
diff changeset
905 while (token == TOKEN_EQ_EQ || token == TOKEN_NOT_EQ)
e78566595089 initial import
mandel
parents:
diff changeset
906 {
e78566595089 initial import
mandel
parents:
diff changeset
907 Value value;
e78566595089 initial import
mandel
parents:
diff changeset
908 __first = eval_relational(next, __last, &value);
e78566595089 initial import
mandel
parents:
diff changeset
909
e78566595089 initial import
mandel
parents:
diff changeset
910 if (token == TOKEN_EQ_EQ)
e78566595089 initial import
mandel
parents:
diff changeset
911 result->op_eq (value);
e78566595089 initial import
mandel
parents:
diff changeset
912 else
e78566595089 initial import
mandel
parents:
diff changeset
913 result->op_ne (value);
e78566595089 initial import
mandel
parents:
diff changeset
914 next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
915 }
e78566595089 initial import
mandel
parents:
diff changeset
916
e78566595089 initial import
mandel
parents:
diff changeset
917 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
918 }
e78566595089 initial import
mandel
parents:
diff changeset
919
e78566595089 initial import
mandel
parents:
diff changeset
920 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
921 _InputIterator pp::eval_and(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
922 {
e78566595089 initial import
mandel
parents:
diff changeset
923 __first = eval_equality(__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
924
e78566595089 initial import
mandel
parents:
diff changeset
925 int token;
e78566595089 initial import
mandel
parents:
diff changeset
926 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
927
e78566595089 initial import
mandel
parents:
diff changeset
928 while (token == '&')
e78566595089 initial import
mandel
parents:
diff changeset
929 {
e78566595089 initial import
mandel
parents:
diff changeset
930 Value value;
e78566595089 initial import
mandel
parents:
diff changeset
931 __first = eval_equality(next, __last, &value);
e78566595089 initial import
mandel
parents:
diff changeset
932 result->op_bit_and (value);
e78566595089 initial import
mandel
parents:
diff changeset
933 next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
934 }
e78566595089 initial import
mandel
parents:
diff changeset
935
e78566595089 initial import
mandel
parents:
diff changeset
936 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
937 }
e78566595089 initial import
mandel
parents:
diff changeset
938
e78566595089 initial import
mandel
parents:
diff changeset
939 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
940 _InputIterator pp::eval_xor(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
941 {
e78566595089 initial import
mandel
parents:
diff changeset
942 __first = eval_and(__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
943
e78566595089 initial import
mandel
parents:
diff changeset
944 int token;
e78566595089 initial import
mandel
parents:
diff changeset
945 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
946
e78566595089 initial import
mandel
parents:
diff changeset
947 while (token == '^')
e78566595089 initial import
mandel
parents:
diff changeset
948 {
e78566595089 initial import
mandel
parents:
diff changeset
949 Value value;
e78566595089 initial import
mandel
parents:
diff changeset
950 __first = eval_and(next, __last, &value);
e78566595089 initial import
mandel
parents:
diff changeset
951 result->op_bit_xor (value);
e78566595089 initial import
mandel
parents:
diff changeset
952 next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
953 }
e78566595089 initial import
mandel
parents:
diff changeset
954
e78566595089 initial import
mandel
parents:
diff changeset
955 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
956 }
e78566595089 initial import
mandel
parents:
diff changeset
957
e78566595089 initial import
mandel
parents:
diff changeset
958 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
959 _InputIterator pp::eval_or(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
960 {
e78566595089 initial import
mandel
parents:
diff changeset
961 __first = eval_xor(__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
962
e78566595089 initial import
mandel
parents:
diff changeset
963 int token;
e78566595089 initial import
mandel
parents:
diff changeset
964 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
965
e78566595089 initial import
mandel
parents:
diff changeset
966 while (token == '|')
e78566595089 initial import
mandel
parents:
diff changeset
967 {
e78566595089 initial import
mandel
parents:
diff changeset
968 Value value;
e78566595089 initial import
mandel
parents:
diff changeset
969 __first = eval_xor(next, __last, &value);
e78566595089 initial import
mandel
parents:
diff changeset
970 result->op_bit_or (value);
e78566595089 initial import
mandel
parents:
diff changeset
971 next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
972 }
e78566595089 initial import
mandel
parents:
diff changeset
973
e78566595089 initial import
mandel
parents:
diff changeset
974 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
975 }
e78566595089 initial import
mandel
parents:
diff changeset
976
e78566595089 initial import
mandel
parents:
diff changeset
977 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
978 _InputIterator pp::eval_logical_and(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
979 {
e78566595089 initial import
mandel
parents:
diff changeset
980 __first = eval_or(__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
981
e78566595089 initial import
mandel
parents:
diff changeset
982 int token;
e78566595089 initial import
mandel
parents:
diff changeset
983 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
984
e78566595089 initial import
mandel
parents:
diff changeset
985 while (token == TOKEN_AND_AND)
e78566595089 initial import
mandel
parents:
diff changeset
986 {
e78566595089 initial import
mandel
parents:
diff changeset
987 Value value;
e78566595089 initial import
mandel
parents:
diff changeset
988 __first = eval_or(next, __last, &value);
e78566595089 initial import
mandel
parents:
diff changeset
989 result->op_and (value);
e78566595089 initial import
mandel
parents:
diff changeset
990 next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
991 }
e78566595089 initial import
mandel
parents:
diff changeset
992
e78566595089 initial import
mandel
parents:
diff changeset
993 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
994 }
e78566595089 initial import
mandel
parents:
diff changeset
995
e78566595089 initial import
mandel
parents:
diff changeset
996 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
997 _InputIterator pp::eval_logical_or(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
998 {
e78566595089 initial import
mandel
parents:
diff changeset
999 __first = eval_logical_and (__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
1000
e78566595089 initial import
mandel
parents:
diff changeset
1001 int token;
e78566595089 initial import
mandel
parents:
diff changeset
1002 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
1003
e78566595089 initial import
mandel
parents:
diff changeset
1004 while (token == TOKEN_OR_OR)
e78566595089 initial import
mandel
parents:
diff changeset
1005 {
e78566595089 initial import
mandel
parents:
diff changeset
1006 Value value;
e78566595089 initial import
mandel
parents:
diff changeset
1007 __first = eval_logical_and(next, __last, &value);
e78566595089 initial import
mandel
parents:
diff changeset
1008 result->op_or (value);
e78566595089 initial import
mandel
parents:
diff changeset
1009 next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
1010 }
e78566595089 initial import
mandel
parents:
diff changeset
1011
e78566595089 initial import
mandel
parents:
diff changeset
1012 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1013 }
e78566595089 initial import
mandel
parents:
diff changeset
1014
e78566595089 initial import
mandel
parents:
diff changeset
1015 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
1016 _InputIterator pp::eval_constant_expression(_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
1017 {
e78566595089 initial import
mandel
parents:
diff changeset
1018 __first = eval_logical_or(__first, __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
1019
e78566595089 initial import
mandel
parents:
diff changeset
1020 int token;
e78566595089 initial import
mandel
parents:
diff changeset
1021 _InputIterator next = next_token (__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
1022
e78566595089 initial import
mandel
parents:
diff changeset
1023 if (token == '?')
e78566595089 initial import
mandel
parents:
diff changeset
1024 {
e78566595089 initial import
mandel
parents:
diff changeset
1025 Value left_value;
e78566595089 initial import
mandel
parents:
diff changeset
1026 __first = eval_constant_expression(next, __last, &left_value);
e78566595089 initial import
mandel
parents:
diff changeset
1027 __first = skip_blanks (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
1028
e78566595089 initial import
mandel
parents:
diff changeset
1029 __first = next_token(__first, __last, &token);
e78566595089 initial import
mandel
parents:
diff changeset
1030 if (token == ':')
e78566595089 initial import
mandel
parents:
diff changeset
1031 {
e78566595089 initial import
mandel
parents:
diff changeset
1032 Value right_value;
e78566595089 initial import
mandel
parents:
diff changeset
1033 __first = eval_constant_expression(__first, __last, &right_value);
e78566595089 initial import
mandel
parents:
diff changeset
1034
e78566595089 initial import
mandel
parents:
diff changeset
1035 *result = !result->is_zero () ? left_value : right_value;
e78566595089 initial import
mandel
parents:
diff changeset
1036 }
e78566595089 initial import
mandel
parents:
diff changeset
1037 else
e78566595089 initial import
mandel
parents:
diff changeset
1038 {
e78566595089 initial import
mandel
parents:
diff changeset
1039 std::cerr << "** WARNING expected ``:'' = " << int (token) << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
1040 *result = left_value;
e78566595089 initial import
mandel
parents:
diff changeset
1041 }
e78566595089 initial import
mandel
parents:
diff changeset
1042 }
e78566595089 initial import
mandel
parents:
diff changeset
1043
e78566595089 initial import
mandel
parents:
diff changeset
1044 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1045 }
e78566595089 initial import
mandel
parents:
diff changeset
1046
e78566595089 initial import
mandel
parents:
diff changeset
1047 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
1048 _InputIterator pp::eval_expression (_InputIterator __first, _InputIterator __last, Value *result)
e78566595089 initial import
mandel
parents:
diff changeset
1049 {
e78566595089 initial import
mandel
parents:
diff changeset
1050 return __first = eval_constant_expression (skip_blanks (__first, __last), __last, result);
e78566595089 initial import
mandel
parents:
diff changeset
1051 }
e78566595089 initial import
mandel
parents:
diff changeset
1052
e78566595089 initial import
mandel
parents:
diff changeset
1053 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
1054 _InputIterator pp::handle_if (_InputIterator __first, _InputIterator __last)
e78566595089 initial import
mandel
parents:
diff changeset
1055 {
e78566595089 initial import
mandel
parents:
diff changeset
1056 if (test_if_level())
e78566595089 initial import
mandel
parents:
diff changeset
1057 {
e78566595089 initial import
mandel
parents:
diff changeset
1058 pp_macro_expander expand_condition (env);
e78566595089 initial import
mandel
parents:
diff changeset
1059 std::string condition;
e78566595089 initial import
mandel
parents:
diff changeset
1060 condition.reserve (255);
e78566595089 initial import
mandel
parents:
diff changeset
1061 expand_condition (skip_blanks (__first, __last), __last, std::back_inserter (condition));
e78566595089 initial import
mandel
parents:
diff changeset
1062
e78566595089 initial import
mandel
parents:
diff changeset
1063 Value result;
e78566595089 initial import
mandel
parents:
diff changeset
1064 result.set_long (0);
e78566595089 initial import
mandel
parents:
diff changeset
1065 eval_expression(condition.c_str (), condition.c_str () + condition.size (), &result);
e78566595089 initial import
mandel
parents:
diff changeset
1066
e78566595089 initial import
mandel
parents:
diff changeset
1067 _M_true_test[iflevel] = !result.is_zero ();
e78566595089 initial import
mandel
parents:
diff changeset
1068 _M_skipping[iflevel] = result.is_zero ();
e78566595089 initial import
mandel
parents:
diff changeset
1069 }
e78566595089 initial import
mandel
parents:
diff changeset
1070
e78566595089 initial import
mandel
parents:
diff changeset
1071 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1072 }
e78566595089 initial import
mandel
parents:
diff changeset
1073
e78566595089 initial import
mandel
parents:
diff changeset
1074 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
1075 _InputIterator pp::handle_else (_InputIterator __first, _InputIterator /*__last*/)
e78566595089 initial import
mandel
parents:
diff changeset
1076 {
e78566595089 initial import
mandel
parents:
diff changeset
1077 if (iflevel == 0 && !skipping ())
e78566595089 initial import
mandel
parents:
diff changeset
1078 {
e78566595089 initial import
mandel
parents:
diff changeset
1079 std::cerr << "** WARNING #else without #if" << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
1080 }
e78566595089 initial import
mandel
parents:
diff changeset
1081 else if (iflevel > 0 && _M_skipping[iflevel - 1])
e78566595089 initial import
mandel
parents:
diff changeset
1082 {
e78566595089 initial import
mandel
parents:
diff changeset
1083 _M_skipping[iflevel] = true;
e78566595089 initial import
mandel
parents:
diff changeset
1084 }
e78566595089 initial import
mandel
parents:
diff changeset
1085 else
e78566595089 initial import
mandel
parents:
diff changeset
1086 {
e78566595089 initial import
mandel
parents:
diff changeset
1087 _M_skipping[iflevel] = _M_true_test[iflevel];
e78566595089 initial import
mandel
parents:
diff changeset
1088 }
e78566595089 initial import
mandel
parents:
diff changeset
1089
e78566595089 initial import
mandel
parents:
diff changeset
1090 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1091 }
e78566595089 initial import
mandel
parents:
diff changeset
1092
e78566595089 initial import
mandel
parents:
diff changeset
1093 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
1094 _InputIterator pp::handle_elif (_InputIterator __first, _InputIterator __last)
e78566595089 initial import
mandel
parents:
diff changeset
1095 {
e78566595089 initial import
mandel
parents:
diff changeset
1096 assert(iflevel > 0);
e78566595089 initial import
mandel
parents:
diff changeset
1097
e78566595089 initial import
mandel
parents:
diff changeset
1098 if (iflevel == 0 && !skipping())
e78566595089 initial import
mandel
parents:
diff changeset
1099 {
e78566595089 initial import
mandel
parents:
diff changeset
1100 std::cerr << "** WARNING #else without #if" << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
1101 }
e78566595089 initial import
mandel
parents:
diff changeset
1102 else if (!_M_true_test[iflevel] && !_M_skipping[iflevel - 1])
e78566595089 initial import
mandel
parents:
diff changeset
1103 {
e78566595089 initial import
mandel
parents:
diff changeset
1104 Value result;
e78566595089 initial import
mandel
parents:
diff changeset
1105 __first = eval_expression(__first, __last, &result);
e78566595089 initial import
mandel
parents:
diff changeset
1106 _M_true_test[iflevel] = !result.is_zero ();
e78566595089 initial import
mandel
parents:
diff changeset
1107 _M_skipping[iflevel] = result.is_zero ();
e78566595089 initial import
mandel
parents:
diff changeset
1108 }
e78566595089 initial import
mandel
parents:
diff changeset
1109 else
e78566595089 initial import
mandel
parents:
diff changeset
1110 {
e78566595089 initial import
mandel
parents:
diff changeset
1111 _M_skipping[iflevel] = true;
e78566595089 initial import
mandel
parents:
diff changeset
1112 }
e78566595089 initial import
mandel
parents:
diff changeset
1113
e78566595089 initial import
mandel
parents:
diff changeset
1114 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1115 }
e78566595089 initial import
mandel
parents:
diff changeset
1116
e78566595089 initial import
mandel
parents:
diff changeset
1117 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
1118 _InputIterator pp::handle_endif (_InputIterator __first, _InputIterator /*__last*/)
e78566595089 initial import
mandel
parents:
diff changeset
1119 {
e78566595089 initial import
mandel
parents:
diff changeset
1120 if (iflevel == 0 && !skipping())
e78566595089 initial import
mandel
parents:
diff changeset
1121 {
e78566595089 initial import
mandel
parents:
diff changeset
1122 std::cerr << "** WARNING #endif without #if" << std::endl;
e78566595089 initial import
mandel
parents:
diff changeset
1123 }
e78566595089 initial import
mandel
parents:
diff changeset
1124 else
e78566595089 initial import
mandel
parents:
diff changeset
1125 {
e78566595089 initial import
mandel
parents:
diff changeset
1126 _M_skipping[iflevel] = 0;
e78566595089 initial import
mandel
parents:
diff changeset
1127 _M_true_test[iflevel] = 0;
e78566595089 initial import
mandel
parents:
diff changeset
1128
e78566595089 initial import
mandel
parents:
diff changeset
1129 --iflevel;
e78566595089 initial import
mandel
parents:
diff changeset
1130 }
e78566595089 initial import
mandel
parents:
diff changeset
1131
e78566595089 initial import
mandel
parents:
diff changeset
1132 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1133 }
e78566595089 initial import
mandel
parents:
diff changeset
1134
e78566595089 initial import
mandel
parents:
diff changeset
1135 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
1136 _InputIterator pp::handle_ifdef (bool check_undefined, _InputIterator __first, _InputIterator __last)
e78566595089 initial import
mandel
parents:
diff changeset
1137 {
e78566595089 initial import
mandel
parents:
diff changeset
1138 if (test_if_level())
e78566595089 initial import
mandel
parents:
diff changeset
1139 {
e78566595089 initial import
mandel
parents:
diff changeset
1140 _InputIterator end_macro_name = skip_identifier (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
1141
e78566595089 initial import
mandel
parents:
diff changeset
1142 std::size_t __size;
e78566595089 initial import
mandel
parents:
diff changeset
1143 #if defined(__SUNPRO_CC)
e78566595089 initial import
mandel
parents:
diff changeset
1144 std::distance (__first, end_macro_name, __size);
e78566595089 initial import
mandel
parents:
diff changeset
1145 #else
e78566595089 initial import
mandel
parents:
diff changeset
1146 __size = std::distance (__first, end_macro_name);
e78566595089 initial import
mandel
parents:
diff changeset
1147 #endif
e78566595089 initial import
mandel
parents:
diff changeset
1148 assert (__size < 256);
e78566595089 initial import
mandel
parents:
diff changeset
1149
e78566595089 initial import
mandel
parents:
diff changeset
1150 char __buffer [256];
e78566595089 initial import
mandel
parents:
diff changeset
1151 std::copy (__first, end_macro_name, __buffer);
e78566595089 initial import
mandel
parents:
diff changeset
1152
e78566595089 initial import
mandel
parents:
diff changeset
1153 bool value = env.resolve (__buffer, __size) != 0;
e78566595089 initial import
mandel
parents:
diff changeset
1154
e78566595089 initial import
mandel
parents:
diff changeset
1155 __first = end_macro_name;
e78566595089 initial import
mandel
parents:
diff changeset
1156
e78566595089 initial import
mandel
parents:
diff changeset
1157 if (check_undefined)
e78566595089 initial import
mandel
parents:
diff changeset
1158 value = !value;
e78566595089 initial import
mandel
parents:
diff changeset
1159
e78566595089 initial import
mandel
parents:
diff changeset
1160 _M_true_test[iflevel] = value;
e78566595089 initial import
mandel
parents:
diff changeset
1161 _M_skipping[iflevel] = !value;
e78566595089 initial import
mandel
parents:
diff changeset
1162 }
e78566595089 initial import
mandel
parents:
diff changeset
1163
e78566595089 initial import
mandel
parents:
diff changeset
1164 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1165 }
e78566595089 initial import
mandel
parents:
diff changeset
1166
e78566595089 initial import
mandel
parents:
diff changeset
1167 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
1168 _InputIterator pp::handle_undef(_InputIterator __first, _InputIterator __last)
e78566595089 initial import
mandel
parents:
diff changeset
1169 {
e78566595089 initial import
mandel
parents:
diff changeset
1170 __first = skip_blanks (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
1171 _InputIterator end_macro_name = skip_identifier (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
1172 assert (end_macro_name != __first);
e78566595089 initial import
mandel
parents:
diff changeset
1173
e78566595089 initial import
mandel
parents:
diff changeset
1174 std::size_t __size;
e78566595089 initial import
mandel
parents:
diff changeset
1175 #if defined(__SUNPRO_CC)
e78566595089 initial import
mandel
parents:
diff changeset
1176 std::distance (__first, end_macro_name, __size);
e78566595089 initial import
mandel
parents:
diff changeset
1177 #else
e78566595089 initial import
mandel
parents:
diff changeset
1178 __size = std::distance (__first, end_macro_name);
e78566595089 initial import
mandel
parents:
diff changeset
1179 #endif
e78566595089 initial import
mandel
parents:
diff changeset
1180
e78566595089 initial import
mandel
parents:
diff changeset
1181 assert (__size < 256);
e78566595089 initial import
mandel
parents:
diff changeset
1182
e78566595089 initial import
mandel
parents:
diff changeset
1183 char __buffer [256];
e78566595089 initial import
mandel
parents:
diff changeset
1184 std::copy (__first, end_macro_name, __buffer);
e78566595089 initial import
mandel
parents:
diff changeset
1185
e78566595089 initial import
mandel
parents:
diff changeset
1186 pp_fast_string const __tmp (__buffer, __size);
e78566595089 initial import
mandel
parents:
diff changeset
1187 env.unbind (&__tmp);
e78566595089 initial import
mandel
parents:
diff changeset
1188
e78566595089 initial import
mandel
parents:
diff changeset
1189 __first = end_macro_name;
e78566595089 initial import
mandel
parents:
diff changeset
1190
e78566595089 initial import
mandel
parents:
diff changeset
1191 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1192 }
e78566595089 initial import
mandel
parents:
diff changeset
1193
e78566595089 initial import
mandel
parents:
diff changeset
1194 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
1195 char pp::peek_char (_InputIterator __first, _InputIterator __last)
e78566595089 initial import
mandel
parents:
diff changeset
1196 {
e78566595089 initial import
mandel
parents:
diff changeset
1197 if (__first == __last)
e78566595089 initial import
mandel
parents:
diff changeset
1198 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1199
e78566595089 initial import
mandel
parents:
diff changeset
1200 return *++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1201 }
e78566595089 initial import
mandel
parents:
diff changeset
1202
e78566595089 initial import
mandel
parents:
diff changeset
1203 template <typename _InputIterator>
e78566595089 initial import
mandel
parents:
diff changeset
1204 _InputIterator pp::next_token (_InputIterator __first, _InputIterator __last, int *kind)
e78566595089 initial import
mandel
parents:
diff changeset
1205 {
e78566595089 initial import
mandel
parents:
diff changeset
1206 __first = skip_blanks (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
1207
e78566595089 initial import
mandel
parents:
diff changeset
1208 if (__first == __last)
e78566595089 initial import
mandel
parents:
diff changeset
1209 {
e78566595089 initial import
mandel
parents:
diff changeset
1210 *kind = 0;
e78566595089 initial import
mandel
parents:
diff changeset
1211 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1212 }
e78566595089 initial import
mandel
parents:
diff changeset
1213
e78566595089 initial import
mandel
parents:
diff changeset
1214 char ch = *__first;
e78566595089 initial import
mandel
parents:
diff changeset
1215 char ch2 = peek_char (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
1216
e78566595089 initial import
mandel
parents:
diff changeset
1217 switch (ch)
e78566595089 initial import
mandel
parents:
diff changeset
1218 {
e78566595089 initial import
mandel
parents:
diff changeset
1219 case '/':
e78566595089 initial import
mandel
parents:
diff changeset
1220 if (ch2 == '/' || ch2 == '*')
e78566595089 initial import
mandel
parents:
diff changeset
1221 {
e78566595089 initial import
mandel
parents:
diff changeset
1222 __first = skip_comment_or_divop (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
1223 return next_token (__first, __last, kind);
e78566595089 initial import
mandel
parents:
diff changeset
1224 }
e78566595089 initial import
mandel
parents:
diff changeset
1225 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1226 *kind = '/';
e78566595089 initial import
mandel
parents:
diff changeset
1227 break;
e78566595089 initial import
mandel
parents:
diff changeset
1228
e78566595089 initial import
mandel
parents:
diff changeset
1229 case '<':
e78566595089 initial import
mandel
parents:
diff changeset
1230 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1231 if (ch2 == '<')
e78566595089 initial import
mandel
parents:
diff changeset
1232 {
e78566595089 initial import
mandel
parents:
diff changeset
1233 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1234 *kind = TOKEN_LT_LT;
e78566595089 initial import
mandel
parents:
diff changeset
1235 }
e78566595089 initial import
mandel
parents:
diff changeset
1236 else if (ch2 == '=')
e78566595089 initial import
mandel
parents:
diff changeset
1237 {
e78566595089 initial import
mandel
parents:
diff changeset
1238 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1239 *kind = TOKEN_LT_EQ;
e78566595089 initial import
mandel
parents:
diff changeset
1240 }
e78566595089 initial import
mandel
parents:
diff changeset
1241 else
e78566595089 initial import
mandel
parents:
diff changeset
1242 *kind = '<';
e78566595089 initial import
mandel
parents:
diff changeset
1243
e78566595089 initial import
mandel
parents:
diff changeset
1244 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1245
e78566595089 initial import
mandel
parents:
diff changeset
1246 case '>':
e78566595089 initial import
mandel
parents:
diff changeset
1247 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1248 if (ch2 == '>')
e78566595089 initial import
mandel
parents:
diff changeset
1249 {
e78566595089 initial import
mandel
parents:
diff changeset
1250 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1251 *kind = TOKEN_GT_GT;
e78566595089 initial import
mandel
parents:
diff changeset
1252 }
e78566595089 initial import
mandel
parents:
diff changeset
1253 else if (ch2 == '=')
e78566595089 initial import
mandel
parents:
diff changeset
1254 {
e78566595089 initial import
mandel
parents:
diff changeset
1255 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1256 *kind = TOKEN_GT_EQ;
e78566595089 initial import
mandel
parents:
diff changeset
1257 }
e78566595089 initial import
mandel
parents:
diff changeset
1258 else
e78566595089 initial import
mandel
parents:
diff changeset
1259 *kind = '>';
e78566595089 initial import
mandel
parents:
diff changeset
1260
e78566595089 initial import
mandel
parents:
diff changeset
1261 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1262
e78566595089 initial import
mandel
parents:
diff changeset
1263 case '!':
e78566595089 initial import
mandel
parents:
diff changeset
1264 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1265 if (ch2 == '=')
e78566595089 initial import
mandel
parents:
diff changeset
1266 {
e78566595089 initial import
mandel
parents:
diff changeset
1267 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1268 *kind = TOKEN_NOT_EQ;
e78566595089 initial import
mandel
parents:
diff changeset
1269 }
e78566595089 initial import
mandel
parents:
diff changeset
1270 else
e78566595089 initial import
mandel
parents:
diff changeset
1271 *kind = '!';
e78566595089 initial import
mandel
parents:
diff changeset
1272
e78566595089 initial import
mandel
parents:
diff changeset
1273 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1274
e78566595089 initial import
mandel
parents:
diff changeset
1275 case '=':
e78566595089 initial import
mandel
parents:
diff changeset
1276 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1277 if (ch2 == '=')
e78566595089 initial import
mandel
parents:
diff changeset
1278 {
e78566595089 initial import
mandel
parents:
diff changeset
1279 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1280 *kind = TOKEN_EQ_EQ;
e78566595089 initial import
mandel
parents:
diff changeset
1281 }
e78566595089 initial import
mandel
parents:
diff changeset
1282 else
e78566595089 initial import
mandel
parents:
diff changeset
1283 *kind = '=';
e78566595089 initial import
mandel
parents:
diff changeset
1284
e78566595089 initial import
mandel
parents:
diff changeset
1285 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1286
e78566595089 initial import
mandel
parents:
diff changeset
1287 case '|':
e78566595089 initial import
mandel
parents:
diff changeset
1288 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1289 if (ch2 == '|')
e78566595089 initial import
mandel
parents:
diff changeset
1290 {
e78566595089 initial import
mandel
parents:
diff changeset
1291 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1292 *kind = TOKEN_OR_OR;
e78566595089 initial import
mandel
parents:
diff changeset
1293 }
e78566595089 initial import
mandel
parents:
diff changeset
1294 else
e78566595089 initial import
mandel
parents:
diff changeset
1295 *kind = '|';
e78566595089 initial import
mandel
parents:
diff changeset
1296
e78566595089 initial import
mandel
parents:
diff changeset
1297 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1298
e78566595089 initial import
mandel
parents:
diff changeset
1299 case '&':
e78566595089 initial import
mandel
parents:
diff changeset
1300 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1301 if (ch2 == '&')
e78566595089 initial import
mandel
parents:
diff changeset
1302 {
e78566595089 initial import
mandel
parents:
diff changeset
1303 ++__first;
e78566595089 initial import
mandel
parents:
diff changeset
1304 *kind = TOKEN_AND_AND;
e78566595089 initial import
mandel
parents:
diff changeset
1305 }
e78566595089 initial import
mandel
parents:
diff changeset
1306 else
e78566595089 initial import
mandel
parents:
diff changeset
1307 *kind = '&';
e78566595089 initial import
mandel
parents:
diff changeset
1308
e78566595089 initial import
mandel
parents:
diff changeset
1309 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1310
e78566595089 initial import
mandel
parents:
diff changeset
1311 default:
e78566595089 initial import
mandel
parents:
diff changeset
1312 if (pp_isalpha (ch) || ch == '_')
e78566595089 initial import
mandel
parents:
diff changeset
1313 {
e78566595089 initial import
mandel
parents:
diff changeset
1314 _InputIterator end = skip_identifier (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
1315 _M_current_text.assign (__first, end);
e78566595089 initial import
mandel
parents:
diff changeset
1316
e78566595089 initial import
mandel
parents:
diff changeset
1317 token_text = &_M_current_text;
e78566595089 initial import
mandel
parents:
diff changeset
1318 __first = end;
e78566595089 initial import
mandel
parents:
diff changeset
1319
e78566595089 initial import
mandel
parents:
diff changeset
1320 if (*token_text == "defined")
e78566595089 initial import
mandel
parents:
diff changeset
1321 *kind = TOKEN_DEFINED;
e78566595089 initial import
mandel
parents:
diff changeset
1322 else
e78566595089 initial import
mandel
parents:
diff changeset
1323 *kind = TOKEN_IDENTIFIER;
e78566595089 initial import
mandel
parents:
diff changeset
1324 }
e78566595089 initial import
mandel
parents:
diff changeset
1325 else if (pp_isdigit (ch))
e78566595089 initial import
mandel
parents:
diff changeset
1326 {
e78566595089 initial import
mandel
parents:
diff changeset
1327 _InputIterator end = skip_number (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
1328 std::string __str (__first, __last);
e78566595089 initial import
mandel
parents:
diff changeset
1329 char ch = __str [__str.size () - 1];
e78566595089 initial import
mandel
parents:
diff changeset
1330 if (ch == 'u' || ch == 'U')
e78566595089 initial import
mandel
parents:
diff changeset
1331 {
e78566595089 initial import
mandel
parents:
diff changeset
1332 token_uvalue = strtoul (__str.c_str (), 0, 0);
e78566595089 initial import
mandel
parents:
diff changeset
1333 *kind = TOKEN_UNUMBER;
e78566595089 initial import
mandel
parents:
diff changeset
1334 }
e78566595089 initial import
mandel
parents:
diff changeset
1335 else
e78566595089 initial import
mandel
parents:
diff changeset
1336 {
e78566595089 initial import
mandel
parents:
diff changeset
1337 token_value = strtol (__str.c_str (), 0, 0);
e78566595089 initial import
mandel
parents:
diff changeset
1338 *kind = TOKEN_NUMBER;
e78566595089 initial import
mandel
parents:
diff changeset
1339 }
e78566595089 initial import
mandel
parents:
diff changeset
1340 __first = end;
e78566595089 initial import
mandel
parents:
diff changeset
1341 }
e78566595089 initial import
mandel
parents:
diff changeset
1342 else
e78566595089 initial import
mandel
parents:
diff changeset
1343 *kind = *__first++;
e78566595089 initial import
mandel
parents:
diff changeset
1344 }
e78566595089 initial import
mandel
parents:
diff changeset
1345
e78566595089 initial import
mandel
parents:
diff changeset
1346 return __first;
e78566595089 initial import
mandel
parents:
diff changeset
1347 }
e78566595089 initial import
mandel
parents:
diff changeset
1348
e78566595089 initial import
mandel
parents:
diff changeset
1349 } // namespace rpp
e78566595089 initial import
mandel
parents:
diff changeset
1350
e78566595089 initial import
mandel
parents:
diff changeset
1351 #endif // PP_ENGINE_BITS_H
e78566595089 initial import
mandel
parents:
diff changeset
1352
e78566595089 initial import
mandel
parents:
diff changeset
1353 // kate: space-indent on; indent-width 2; replace-tabs on;