1 | /*
|
---|
2 | * TOPPERS/JSP Kernel
|
---|
3 | * Toyohashi Open Platform for Embedded Real-Time Systems/
|
---|
4 | * Just Standard Profile Kernel
|
---|
5 | *
|
---|
6 | * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
|
---|
7 | * Toyohashi Univ. of Technology, JAPAN
|
---|
8 | *
|
---|
9 | * ä¸è¨è使¨©è
|
---|
10 | ã¯ï¼ä»¥ä¸ã® (1)ã(4) ã®æ¡ä»¶ãï¼Free Software Foundation
|
---|
11 | * ã«ãã£ã¦å
|
---|
12 | ¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
|
---|
13 | * è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
|
---|
14 | * ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ã使ç¨ã»è¤è£½ã»æ¹å¤ã»åé
|
---|
15 | å¸ï¼ä»¥ä¸ï¼
|
---|
16 | * å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
|
---|
17 | * (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
|
---|
18 | * 権表示ï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
|
---|
19 | * ã¹ã³ã¼ãä¸ã«å«ã¾ãã¦ãããã¨ï¼
|
---|
20 | * (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
|
---|
21 | * ç¨ã§ããå½¢ã§åé
|
---|
22 | å¸ããå ´åã«ã¯ï¼åé
|
---|
23 | å¸ã«ä¼´ãããã¥ã¡ã³ãï¼å©ç¨
|
---|
24 | * è
|
---|
25 | ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è使¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
|
---|
26 | * ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
|
---|
27 | * (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
|
---|
28 | * ç¨ã§ããªãå½¢ã§åé
|
---|
29 | å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
|
---|
30 | * ã¨ï¼
|
---|
31 | * (a) åé
|
---|
32 | å¸ã«ä¼´ãããã¥ã¡ã³ãï¼å©ç¨è
|
---|
33 | ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
|
---|
34 | * 使¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
|
---|
35 | * (b) åé
|
---|
36 | å¸ã®å½¢æ
|
---|
37 | ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSããã¸ã§ã¯ãã«
|
---|
38 | * å ±åãããã¨ï¼
|
---|
39 | * (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
|
---|
40 | * 害ãããï¼ä¸è¨è使¨©è
|
---|
41 | ããã³TOPPERSããã¸ã§ã¯ããå
|
---|
42 | 責ãããã¨ï¼
|
---|
43 | *
|
---|
44 | * æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨è使¨©è
|
---|
45 | ã
|
---|
46 | * ãã³TOPPERSããã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
|
---|
47 | * å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
|
---|
48 | * æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
|
---|
49 | *
|
---|
50 | * @(#) $Id: parser.cpp,v 1.18 2003/12/15 07:32:14 takayuki Exp $
|
---|
51 | */
|
---|
52 |
|
---|
53 |
|
---|
54 |
|
---|
55 | // $Header: /home/CVS/configurator/base/parser.cpp,v 1.18 2003/12/15 07:32:14 takayuki Exp $
|
---|
56 |
|
---|
57 | #include "base/defs.h"
|
---|
58 | #include "base/parser.h"
|
---|
59 | #include <sstream>
|
---|
60 | #include <set>
|
---|
61 | #include <map>
|
---|
62 | #include <iomanip>
|
---|
63 |
|
---|
64 | using namespace std;
|
---|
65 |
|
---|
66 | /*
|
---|
67 | * å
|
---|
68 | é ã¨æ«å°¾ã«ããç©ºç½æåãåãé¤ã
|
---|
69 | */
|
---|
70 | Token & Token::trim(void)
|
---|
71 | {
|
---|
72 | string::iterator scope;
|
---|
73 |
|
---|
74 | /* ããã¾ */
|
---|
75 | scope = begin();
|
---|
76 | while(*scope == ' ' || *scope == '\t' || *scope == '\r' || *scope == '\n')
|
---|
77 | ++ scope;
|
---|
78 | erase(begin(), scope);
|
---|
79 |
|
---|
80 | if(!empty())
|
---|
81 | {
|
---|
82 | /* ããã */
|
---|
83 | scope = end();
|
---|
84 | do {
|
---|
85 | -- scope;
|
---|
86 | } while(*scope == ' ' || *scope == '\t' || *scope == '\r' || *scope == '\n');
|
---|
87 | ++ scope;
|
---|
88 | erase(scope, end());
|
---|
89 | }
|
---|
90 | return *this;
|
---|
91 | }
|
---|
92 |
|
---|
93 |
|
---|
94 | /*
|
---|
95 | * æååãªãã©ã«ã®å±é (ããã«ã¯ã©ã¼ãã®åãé¤ã + ã¨ã¹ã±ã¼ãã·ã¼ã±ã³ã¹ã®å±é)
|
---|
96 | */
|
---|
97 | Token & Token::chopLiteral(void)
|
---|
98 | {
|
---|
99 | if(type != STRINGLITERAL)
|
---|
100 | return *this;
|
---|
101 |
|
---|
102 | string::iterator scope;
|
---|
103 |
|
---|
104 | //ã¨ã©ã¼å¦çã®ããã«éç ´å£å¦çããã
|
---|
105 | string src(*this);
|
---|
106 | string work;
|
---|
107 |
|
---|
108 | if(src[0] != '"' || src[src.length()-1] != '"')
|
---|
109 | return *this;
|
---|
110 |
|
---|
111 | src = src.substr(1, src.length()-2);
|
---|
112 |
|
---|
113 | scope = src.begin();
|
---|
114 | while(scope != src.end())
|
---|
115 | {
|
---|
116 | if(*scope == '\\')
|
---|
117 | {
|
---|
118 | //ãªãã©ã«ã®æ«å°¾ã\ã§çµãããã¨ã¯ãªãã®ã§ãã§ãã¯ããªã
|
---|
119 | ++ scope;
|
---|
120 | switch(*scope)
|
---|
121 | {
|
---|
122 | case '"': work += '"'; break;
|
---|
123 | case 't': work += '\t'; break;
|
---|
124 | case 'r': work += '\r'; break;
|
---|
125 | case 'n': work += '\n'; break;
|
---|
126 | case 'b': work += '\b'; break;
|
---|
127 | case '\\': work += '\\'; break;
|
---|
128 | default:
|
---|
129 | ExceptionMessage("Illegal escape sequence [\\%]","ã¨ã¹ã±ã¼ãã·ã¼ã±ã³ã¹[\\%]ã¯ä¸æ£ã§ã") << *scope << throwException;
|
---|
130 | }
|
---|
131 | }else
|
---|
132 | work += *scope;
|
---|
133 |
|
---|
134 | ++ scope;
|
---|
135 | }
|
---|
136 |
|
---|
137 | type = STRING;
|
---|
138 | assign(work);
|
---|
139 | value = this->length();
|
---|
140 |
|
---|
141 | return *this;
|
---|
142 | }
|
---|
143 |
|
---|
144 | /* åºåãæå (䏿åã ãã§æå³ãæãæå) */
|
---|
145 | const char * Parser::Punctuator =
|
---|
146 | ",;(){}";
|
---|
147 |
|
---|
148 | /* æ¼ç®å (ç¹æ®æåãããªãæå) */
|
---|
149 | const char * Parser::Operator =
|
---|
150 | "+-*/&|%^~!?[]=:.#";
|
---|
151 |
|
---|
152 | Token Parser::lastErrorToken;
|
---|
153 |
|
---|
154 |
|
---|
155 | /*
|
---|
156 | * ã¹ããªã¼ã ãã䏿åã ãåãåºã
|
---|
157 | */
|
---|
158 | inline int Parser::getChar(void)
|
---|
159 | {
|
---|
160 | int work = current->stream->get();
|
---|
161 |
|
---|
162 | /* è¡çªå·ã®å¦ç */
|
---|
163 | if(work == '\n')
|
---|
164 | current->line ++;
|
---|
165 |
|
---|
166 | /* ã¹ããªã¼ã ãã°ã®ããã®å¦ç */
|
---|
167 | if(PutBackCount == 0)
|
---|
168 | {
|
---|
169 | if(LogBuffer != 0 && isenabled(LOGGING))
|
---|
170 | *LogBuffer += static_cast<char>(work);
|
---|
171 | }else
|
---|
172 | PutBackCount --; //ãã§ã«èªã¿è¾¼ãã§ãã
|
---|
173 |
|
---|
174 | return work;
|
---|
175 | }
|
---|
176 |
|
---|
177 | /*
|
---|
178 | * åãåºããããæåãã¹ããªã¼ã ã«è¿ã
|
---|
179 | */
|
---|
180 | inline void Parser::putBack(int ch)
|
---|
181 | {
|
---|
182 | /* è¡çªå·ã®ããã®å¦ç */
|
---|
183 | if(ch == '\n')
|
---|
184 | current->line --;
|
---|
185 |
|
---|
186 | /* ã¹ããªã¼ã ãã°ã®ããã®å¦ç */
|
---|
187 | PutBackCount ++;
|
---|
188 |
|
---|
189 | current->stream->putback(ch);
|
---|
190 | }
|
---|
191 |
|
---|
192 | /*
|
---|
193 | * Parserã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿
|
---|
194 | */
|
---|
195 | Parser::~Parser(void)
|
---|
196 | {
|
---|
197 | list<tagFile *>::iterator scope;
|
---|
198 |
|
---|
199 | /* æå¾ã¾ã§ãã¼ã¹ãã¦ãªããªããã¨ããããã¹ã¿ãã¯ã«å
|
---|
200 | ¥ãã¦ãã */
|
---|
201 | if(current != 0)
|
---|
202 | fileStack.push_front(current);
|
---|
203 |
|
---|
204 | /* ã¹ã¿ãã¯ã®ä¸èº«å
|
---|
205 | ¨é¨ãç ´æ£ */
|
---|
206 | scope = fileStack.begin();
|
---|
207 | while(scope != fileStack.end())
|
---|
208 | {
|
---|
209 | if((*scope)->stream != 0 && (*scope)->stream != &cin)
|
---|
210 | delete (*scope)->stream; //ã¹ããªã¼ã ã®ç ´æ£
|
---|
211 | delete (*scope); //æ§é ä½ã®ãã¼ã¿é åã®ç ´æ£
|
---|
212 |
|
---|
213 | ++ scope;
|
---|
214 | }
|
---|
215 |
|
---|
216 | /* 念ã®ãã */
|
---|
217 | fileStack.clear();
|
---|
218 | TokenStack.clear();
|
---|
219 | }
|
---|
220 |
|
---|
221 |
|
---|
222 | /*
|
---|
223 | * èå¥åã®ååºã (èå¥å = [a-zA-Z_][0-9a-zA-Z_]*)
|
---|
224 | */
|
---|
225 | bool Parser::getIdentifier(Token & token,int ch)
|
---|
226 | {
|
---|
227 | token.value = 0;
|
---|
228 |
|
---|
229 | do {
|
---|
230 | token.value ++;
|
---|
231 | token += static_cast<char>(ch);
|
---|
232 | ch = getChar();
|
---|
233 | } while( (ch >='a' && ch <= 'z') || (ch >='A' && ch <= 'Z') || (ch == '_') || (ch >= '0' && ch <= '9') );
|
---|
234 |
|
---|
235 | if(ch != -1)
|
---|
236 | putBack(static_cast<char>(ch));
|
---|
237 |
|
---|
238 | token.type = Token::IDENTIFIER;
|
---|
239 | return true;
|
---|
240 | }
|
---|
241 |
|
---|
242 |
|
---|
243 | /*
|
---|
244 | * ãã£ã¬ã¯ãã£ãã®ååºãã¨å¦ç
|
---|
245 | */
|
---|
246 | bool Parser::parseDirectives(Token & token, int ch, bool allow_space)
|
---|
247 | {
|
---|
248 | Token directive;
|
---|
249 | map<string, ParseUnit *>::iterator scope;
|
---|
250 |
|
---|
251 | //空ç½èªã¿é£ã°ã
|
---|
252 | do {
|
---|
253 | token += static_cast<char>(ch);
|
---|
254 | ch = getChar();
|
---|
255 | } while(ch == ' ' || ch == '\t');
|
---|
256 |
|
---|
257 | if(ch >= '0' && ch <= '9')
|
---|
258 | {
|
---|
259 | //GNU-cpp lineãã£ã¬ã¯ãã£ã 対ç
|
---|
260 | directive.assign("line");
|
---|
261 | this->putBack(ch);
|
---|
262 | }else
|
---|
263 | {
|
---|
264 | //ãã£ã¬ã¯ãã£ãã®èªã¿åºã
|
---|
265 | putBack(ch);
|
---|
266 | getToken(directive);
|
---|
267 | token += directive;
|
---|
268 | }
|
---|
269 |
|
---|
270 | //lineãã£ã¬ã¯ãã£ãã®è§£æ
|
---|
271 | if(directive.compare("line") == 0)
|
---|
272 | {
|
---|
273 | Token token;
|
---|
274 |
|
---|
275 | getToken(token, Token::INTEGER);
|
---|
276 | setCurrentLine(token.value -1);
|
---|
277 |
|
---|
278 | getToken(token, Token::STRINGLITERAL);
|
---|
279 | try {
|
---|
280 | token.chopLiteral();
|
---|
281 | }
|
---|
282 | catch(Exception &) {
|
---|
283 | token.assign("Unknown");
|
---|
284 | }
|
---|
285 | setStreamIdentifier(token);
|
---|
286 |
|
---|
287 | return true;
|
---|
288 | }
|
---|
289 |
|
---|
290 | //pragmaãã£ã¬ã¯ãã£ãã®è§£æ
|
---|
291 | if(directive.compare("pragma") == 0)
|
---|
292 | {
|
---|
293 | getToken(directive);
|
---|
294 | token += " ";
|
---|
295 | token += directive;
|
---|
296 |
|
---|
297 | if((scope = Directive::container().find(directive)) != Directive::container().end())
|
---|
298 | {
|
---|
299 | (*scope).second->body(directive, *Container, *this, string(""));
|
---|
300 |
|
---|
301 | //ä½åãªãã¼ã¯ã³ã®èªã¿é£ã°ã
|
---|
302 | if(!TokenStack.empty())
|
---|
303 | {
|
---|
304 | do {
|
---|
305 | token = TokenStack.front();
|
---|
306 | TokenStack.pop_front();
|
---|
307 | } while(!TokenStack.empty() && !allow_space && token.type == Token::SPACE);
|
---|
308 |
|
---|
309 | return true;
|
---|
310 | }
|
---|
311 | }
|
---|
312 | }
|
---|
313 |
|
---|
314 | //includeãã£ã¬ã¯ãã£ãã®è§£æ
|
---|
315 | if(directive.compare("include") == 0)
|
---|
316 | {
|
---|
317 | cerr << getStreamLocation() << Message(": Configurator found 'include' directive\nKernel configuration file must be preprocessed.\n",": #includeãã£ã¬ã¯ãã£ããçºè¦ãã¾ãã\n ã«ã¼ãã«æ§æãã¡ã¤ã«ã¯Cããªããã»ããµãééãããå¿
|
---|
318 | è¦ãããã¾ã\n");
|
---|
319 | ExceptionMessage("Illegal kernel configuration file","䏿£ãªã«ã¼ãã«æ§æãã¡ã¤ã«").throwException();
|
---|
320 | }
|
---|
321 |
|
---|
322 | putBack(directive);
|
---|
323 | return false;
|
---|
324 | }
|
---|
325 |
|
---|
326 |
|
---|
327 | /*
|
---|
328 | * ç©ºç½æåã®ååºã
|
---|
329 | * ã»ã¹ãã¼ã¹, ã¿ã ã»#ã§å§ã¾ã£ã¦æ¹è¡ã¾ã§ ã»Cè¨èªã®ã³ã¡ã³ããããã¯
|
---|
330 | * ã»2é£ã®ã¹ã©ãã·ã¥(//)ããæ¹è¡ã¾ã§
|
---|
331 | * ã»ä¸ã®4ã¤ãçµã¿åããããã®
|
---|
332 | */
|
---|
333 | bool Parser::getWhitespace(Token & token, int ch, bool allow_space)
|
---|
334 | {
|
---|
335 | int prev;
|
---|
336 |
|
---|
337 | token.type = Token::SPACE;
|
---|
338 | switch(ch)
|
---|
339 | {
|
---|
340 | case '/':
|
---|
341 | ch = getChar();
|
---|
342 |
|
---|
343 | switch(ch)
|
---|
344 | {
|
---|
345 | /* ã³ã¡ã³ãããã㯠*/
|
---|
346 | case '*':
|
---|
347 | token += "/*";
|
---|
348 | prev = '\x0';
|
---|
349 | while( ((ch = getChar()) != '/') || (prev!='*'))
|
---|
350 | {
|
---|
351 | token += static_cast<char>(ch);
|
---|
352 | prev = ch;
|
---|
353 | }
|
---|
354 | token += static_cast<char>(ch);
|
---|
355 | break;
|
---|
356 |
|
---|
357 | /* ããã«ã¹ã©ãã·ã¥ */
|
---|
358 | case '/':
|
---|
359 | token += '/';
|
---|
360 | do {
|
---|
361 | token += static_cast<char>(ch);
|
---|
362 | } while( (ch = getChar()) != '\n' );
|
---|
363 | break;
|
---|
364 |
|
---|
365 | /* ãã '/'ã§å§ã¾ã£ãã ãã§ãã */
|
---|
366 | default:
|
---|
367 | putBack(ch);
|
---|
368 | return getOperator(token, '/');;
|
---|
369 | }
|
---|
370 | break;
|
---|
371 |
|
---|
372 | /* # ã§å§ã¾ãè¡ */
|
---|
373 | case '#':
|
---|
374 | /* ãã£ã¬ã¯ãã£ããç¡å¹ or ãããªãã£ã¬ã¯ãã£ãã¯ç¥ããªã */
|
---|
375 | if(! (isenabled(DIRECTIVE) && parseDirectives(token, ch, allow_space)) )
|
---|
376 | {
|
---|
377 | //æ¹è¡ã¾ã§èªã¿é£ã°ã
|
---|
378 | TokenStack.clear();
|
---|
379 | do {
|
---|
380 | token += static_cast<char>(ch);
|
---|
381 | ch = getChar();
|
---|
382 | } while(ch != '\n');
|
---|
383 | putBack(ch);
|
---|
384 | }
|
---|
385 | break;
|
---|
386 |
|
---|
387 | /* ä¿ã«è¨ãç©ºç½æå */
|
---|
388 | case ' ':
|
---|
389 | case '\t':
|
---|
390 | case '\n':
|
---|
391 | case '\r':
|
---|
392 | do {
|
---|
393 | token += static_cast<char>(ch);
|
---|
394 | ch = getChar();
|
---|
395 | } while((ch == ' ') || (ch == '\n') || (ch == '\r') || (ch == '\t'));
|
---|
396 | putBack(static_cast<char>(ch));
|
---|
397 | break;
|
---|
398 | }
|
---|
399 | return true;
|
---|
400 | }
|
---|
401 |
|
---|
402 | /*
|
---|
403 | * æ´æ°å¤ã®ååºã (8/10/16é², æ£æ°/è² æ°)
|
---|
404 | * ã»2é²ã¯ä¸è©ã ã£ãã®ã§ããã¾ãã
|
---|
405 | */
|
---|
406 | bool Parser::getInteger(Token & token, int ch)
|
---|
407 | {
|
---|
408 | bool minus = false;
|
---|
409 |
|
---|
410 | if(ch == '-')
|
---|
411 | {
|
---|
412 | minus = true;
|
---|
413 | ch = getChar();
|
---|
414 | if(ch < '0' || ch >'9')
|
---|
415 | {
|
---|
416 | putBack(static_cast<char>(ch));
|
---|
417 | return false;
|
---|
418 | }
|
---|
419 | token += "-";
|
---|
420 | }
|
---|
421 |
|
---|
422 | token.type = Token::INTEGER;
|
---|
423 | token.value = 0;
|
---|
424 |
|
---|
425 | if(ch == '0')
|
---|
426 | {
|
---|
427 | token += static_cast<char>(ch);
|
---|
428 | ch = getChar();
|
---|
429 | if(ch == 'x' || ch == 'X')
|
---|
430 | {
|
---|
431 | token += static_cast<char>(ch);
|
---|
432 | ch = getChar();
|
---|
433 | while((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'))
|
---|
434 | {
|
---|
435 | token += static_cast<char>(ch);
|
---|
436 | if((ch -= '0') >= 10)
|
---|
437 | {
|
---|
438 | ch = ch + '0' - 'A' + 10;
|
---|
439 | if(ch >= 16)
|
---|
440 | ch = ch - ('a' - 'A');
|
---|
441 | }
|
---|
442 | token.value = token.value * 16 + ch;
|
---|
443 | ch = getChar();
|
---|
444 | }
|
---|
445 | }else
|
---|
446 | {
|
---|
447 | while(ch >= '0' && ch <= '7')
|
---|
448 | {
|
---|
449 | token += static_cast<char>(ch);
|
---|
450 | token.value = token.value * 8 + ch - '0';
|
---|
451 | ch = getChar();
|
---|
452 | }
|
---|
453 | }
|
---|
454 | }else
|
---|
455 | {
|
---|
456 | do {
|
---|
457 | token += static_cast<char>(ch);
|
---|
458 | token.value = token.value * 10 + ch - '0';
|
---|
459 | ch = getChar();
|
---|
460 | } while(ch >= '0' && ch <= '9');
|
---|
461 | }
|
---|
462 |
|
---|
463 | /* integer-suffix */
|
---|
464 | if(ch != -1)
|
---|
465 | {
|
---|
466 | bool unsigned_suffix = false;
|
---|
467 | bool long_suffix = false;
|
---|
468 |
|
---|
469 | int first_longsuffix;
|
---|
470 |
|
---|
471 | if(ch == 'u' || ch == 'U')
|
---|
472 | {
|
---|
473 | unsigned_suffix = true;
|
---|
474 | token += static_cast<char>(ch);
|
---|
475 | ch = getChar();
|
---|
476 | }
|
---|
477 |
|
---|
478 | if(ch == 'i' || ch == 'I') //i8, i16, i32, i64
|
---|
479 | {
|
---|
480 | int first, second;
|
---|
481 | bool accept = false;
|
---|
482 | const signed char suffix_list[10] = { -1, '6', -1, '2', -1, -1, '4', -1, 0, -1}; //8, 16, 32, 64ã®ã¿ãåç
|
---|
483 |
|
---|
484 | first = getChar();
|
---|
485 | second = -1;
|
---|
486 | if(first >= '0' && first <= '9')
|
---|
487 | {
|
---|
488 | if(suffix_list[first - '0'] > 0)
|
---|
489 | {
|
---|
490 | second = getChar();
|
---|
491 | if(second == suffix_list[first - '0'])
|
---|
492 | accept = true;
|
---|
493 | }else
|
---|
494 | if(suffix_list[first - '0'] == 0)
|
---|
495 | accept = true;
|
---|
496 | }
|
---|
497 |
|
---|
498 | if(!accept)
|
---|
499 | {
|
---|
500 | if(second != -1)
|
---|
501 | putBack(second);
|
---|
502 | putBack(first);
|
---|
503 | } else
|
---|
504 | {
|
---|
505 | token += static_cast<char>(ch);
|
---|
506 | token += static_cast<char>(first);
|
---|
507 | if(second != -1)
|
---|
508 | token += static_cast<char>(second);
|
---|
509 | ch = getChar();
|
---|
510 | }
|
---|
511 | } else
|
---|
512 | {
|
---|
513 | if(ch == 'l' || ch == 'L')
|
---|
514 | {
|
---|
515 | first_longsuffix = ch;
|
---|
516 | long_suffix = true;
|
---|
517 |
|
---|
518 | token += static_cast<char>(ch);
|
---|
519 | ch = getChar();
|
---|
520 | if(ch == first_longsuffix)
|
---|
521 | {
|
---|
522 | token += static_cast<char>(ch);
|
---|
523 | ch = getChar();
|
---|
524 | }
|
---|
525 | }
|
---|
526 |
|
---|
527 | if(!unsigned_suffix && (ch == 'u' || ch == 'U'))
|
---|
528 | {
|
---|
529 | token += static_cast<char>(ch);
|
---|
530 | ch = getChar();
|
---|
531 | }
|
---|
532 | }
|
---|
533 | }
|
---|
534 |
|
---|
535 | if(minus)
|
---|
536 | token.value = - token.value;
|
---|
537 |
|
---|
538 | if(ch != -1)
|
---|
539 | putBack(static_cast<char>(ch));
|
---|
540 |
|
---|
541 | return true;
|
---|
542 | }
|
---|
543 |
|
---|
544 |
|
---|
545 | /*
|
---|
546 | * ãªãã¬ã¼ã¿(ç¹æ®æåã®çµåããããªããã¼ã¯ã³)ã®ååºã
|
---|
547 | */
|
---|
548 | bool Parser::getOperator(Token & token, int ch)
|
---|
549 | {
|
---|
550 | const char * work;
|
---|
551 |
|
---|
552 | /* chããªãã¬ã¼ã¿æåã§ãããã©ãã確ããã */
|
---|
553 | for(work = Operator;*work != '\x0' && *work != ch;work++);
|
---|
554 | if(*work == '\x0')
|
---|
555 | return false;
|
---|
556 |
|
---|
557 | /* å¾ç¶ããæåããªãã¬ã¼ã¿æåã§ãããã©ãã確ããã */
|
---|
558 | do {
|
---|
559 | token += static_cast<char>(ch);
|
---|
560 | ch = getChar();
|
---|
561 | for(work = Operator;*work != '\x0' && *work != ch;work++);
|
---|
562 | } while(*work != '\x0');
|
---|
563 |
|
---|
564 | putBack(ch);
|
---|
565 | token.type = Token::OPERATOR;
|
---|
566 | return true;
|
---|
567 | }
|
---|
568 |
|
---|
569 |
|
---|
570 | /*
|
---|
571 | * æååãªãã©ã« (ããã«ã¯ã©ã¼ãã§æ¬ãããæå)
|
---|
572 | * ã»ã·ã³ã°ã«ã¯ã©ã¼ãã許ãããã«ãã
|
---|
573 | *
|
---|
574 | * VisualStudio6.0ã§ã³ã³ãã¤ã«ããå ´åãæ¹è¡ãLFã®ãã¡ã¤ã«ã«å¯¾ãã¦tellgå¾ã«
|
---|
575 | * getããã¨EOFãè¿ããããåå¦çãã³ã¡ã³ãã¢ã¦ããã¦ããã
|
---|
576 | */
|
---|
577 | bool Parser::getStringLiteral(Token & token, int delimitor)
|
---|
578 | {
|
---|
579 | int ch;
|
---|
580 | int prev;
|
---|
581 |
|
---|
582 | ch = delimitor;
|
---|
583 |
|
---|
584 | token.value = 1;
|
---|
585 | token.type = Token::STRINGLITERAL;
|
---|
586 | token.assign("");
|
---|
587 | token += static_cast<char>(ch);
|
---|
588 |
|
---|
589 | while(!current->stream->bad() && !current->stream->eof())
|
---|
590 | {
|
---|
591 | prev = ch;
|
---|
592 | ch = getChar();
|
---|
593 | token += static_cast<char>(ch);
|
---|
594 | token.value ++;
|
---|
595 |
|
---|
596 | if(ch == delimitor && prev != '\\')
|
---|
597 | return true;
|
---|
598 | }
|
---|
599 |
|
---|
600 | //ãã£ããéãã¦åãªã¼ãã³ãã¦ããªãã©ã«éå§ã® " ã®æ¬¡ã«ç§»å
|
---|
601 |
|
---|
602 | ExceptionMessage(ExceptionMessage::FATAL, "Unterminated string literal appeared.","éãããã¦ããªãæåãªãã©ã«ãæ¤åºãã¾ãã").throwException();
|
---|
603 | return false;
|
---|
604 | }
|
---|
605 |
|
---|
606 |
|
---|
607 | /*
|
---|
608 | * ãã¼ã¯ã³ã®ååºã
|
---|
609 | */
|
---|
610 | enum Token::tagTokenType Parser::getToken(Token & token, bool allow_space)
|
---|
611 | {
|
---|
612 | int ch;
|
---|
613 | const char * work;
|
---|
614 |
|
---|
615 | do {
|
---|
616 | token.erase();
|
---|
617 | token.type = Token::ERROR;
|
---|
618 | token.value = 0;
|
---|
619 |
|
---|
620 | //ãã¼ã¯ã³ã¹ã¿ãã¯ããåãåºã
|
---|
621 | if(!TokenStack.empty())
|
---|
622 | {
|
---|
623 | do {
|
---|
624 | token = TokenStack.front();
|
---|
625 | TokenStack.pop_front();
|
---|
626 | } while(!TokenStack.empty() && !allow_space && token.type == Token::SPACE);
|
---|
627 |
|
---|
628 | if(!allow_space && token.type != Token::SPACE)
|
---|
629 | return token.type;
|
---|
630 | }
|
---|
631 |
|
---|
632 | //ã¹ããªã¼ã ããåãåºã
|
---|
633 | if(current == NULL || current->stream == NULL || current->stream->bad())
|
---|
634 | {
|
---|
635 | token.assign("<End of stream>");
|
---|
636 | return (token.type = Token::EOS);
|
---|
637 | }
|
---|
638 |
|
---|
639 | //ã«ã¬ã³ãã®ã¹ããªã¼ã ã空ã«ãªã£ã
|
---|
640 | if(current->stream->eof())
|
---|
641 | {
|
---|
642 | //ãã¡ã¤ã«ã¹ã¿ãã¯ããæ¬¡ã®ã¹ããªã¼ã ãåã
|
---|
643 | if(!fileStack.empty())
|
---|
644 | {
|
---|
645 | if(current->stream != &cin)
|
---|
646 | delete current->stream;
|
---|
647 | delete current;
|
---|
648 |
|
---|
649 | current = *fileStack.begin();
|
---|
650 | fileStack.pop_front();
|
---|
651 | }else
|
---|
652 | {
|
---|
653 | token.assign("<End of stream>");
|
---|
654 | return (token.type = Token::EOS);
|
---|
655 | }
|
---|
656 | }
|
---|
657 |
|
---|
658 | ch = getChar();
|
---|
659 |
|
---|
660 | //First(whitespaces) is [ \n\t\r/#]
|
---|
661 | if( (ch == ' ') || (ch == '\t') || (ch == '\n') || (ch == '\r') || (ch == '/') || (isHeadofLine && ch == '#'))
|
---|
662 | {
|
---|
663 | if(ch == '\n')
|
---|
664 | isHeadofLine = true;
|
---|
665 |
|
---|
666 | if(getWhitespace(token, ch, allow_space))
|
---|
667 | if((token == Token::SPACE && allow_space) || !(token == Token::SPACE || token == Token::ERROR))
|
---|
668 | return token.type;
|
---|
669 |
|
---|
670 | continue;
|
---|
671 | }else
|
---|
672 | break;
|
---|
673 | }while(true);
|
---|
674 |
|
---|
675 | isHeadofLine = false;
|
---|
676 |
|
---|
677 | token.line = current->line;
|
---|
678 |
|
---|
679 | //First(identifier) is [a-zA-Z_]
|
---|
680 | if( (ch >='a' && ch <= 'z') || (ch >='A' && ch <= 'Z') || (ch == '_') )
|
---|
681 | if(getIdentifier(token, ch))
|
---|
682 | return Token::IDENTIFIER;
|
---|
683 |
|
---|
684 | //First(integer) is [\-0-9]
|
---|
685 | if( (ch >='0' && ch <='9') || (ch == '-') )
|
---|
686 | if(getInteger(token,ch))
|
---|
687 | return Token::INTEGER;
|
---|
688 |
|
---|
689 | //First(string) is ["']
|
---|
690 | if( ch == '"' || ch == '\'')
|
---|
691 | if(getStringLiteral(token,ch))
|
---|
692 | return Token::STRINGLITERAL;
|
---|
693 |
|
---|
694 | //Operator
|
---|
695 | if(getOperator(token,ch))
|
---|
696 | return Token::OPERATOR;
|
---|
697 |
|
---|
698 | //Punctuator
|
---|
699 | work = Punctuator;
|
---|
700 | while(*work != '\x0')
|
---|
701 | if( *(work++) == ch )
|
---|
702 | {
|
---|
703 | token += static_cast<char>(ch);
|
---|
704 | return (token.type = Token::PUNCTUATOR);
|
---|
705 | }
|
---|
706 |
|
---|
707 | token += static_cast<char>(ch);
|
---|
708 | token.type = Token::UNKNOWN;
|
---|
709 | return Token::UNKNOWN;
|
---|
710 | }
|
---|
711 |
|
---|
712 |
|
---|
713 | /*
|
---|
714 | * ãã¼ã¯ã³ç¨ ã¹ããªã¼ã ãªãã¬ã¼ã¿ (主ã«ãã¹ãç®ç)
|
---|
715 | */
|
---|
716 | ostream & operator << (ostream & out, Token & src)
|
---|
717 | {
|
---|
718 | switch(src.type)
|
---|
719 | {
|
---|
720 | case Token::IDENTIFIER:
|
---|
721 | out << "<IDENTIFIER:["; break;
|
---|
722 | case Token::INTEGER:
|
---|
723 | out << "<INTEGER:["; break;
|
---|
724 | case Token::STRINGLITERAL:
|
---|
725 | out << "<STRINGLITERAL:["; break;
|
---|
726 | case Token::STRING:
|
---|
727 | out << "<STRING:["; break;
|
---|
728 | case Token::OPERATOR:
|
---|
729 | out << "<OPERATOR:["; break;
|
---|
730 | case Token::PUNCTUATOR:
|
---|
731 | out << "<PUNCTUATOR:["; break;
|
---|
732 | case Token::RESERVEDWORD:
|
---|
733 | out << "<RESERVEDWORD:["; break;
|
---|
734 | case Token::SPECIAL:
|
---|
735 | out << "<SPECIAL:["; break;
|
---|
736 | case Token::SPACE:
|
---|
737 | out << "<SPACE:["; break;
|
---|
738 | case Token::UNKNOWN:
|
---|
739 | out << "<UNKNOWN>"; return out;
|
---|
740 | case Token::ERROR:
|
---|
741 | out << "<ERROR>"; return out;
|
---|
742 | default:
|
---|
743 | out << "<???:[";
|
---|
744 | }
|
---|
745 |
|
---|
746 | return out << static_cast<string &>(src) << "]("<<src.value<<")>";
|
---|
747 | }
|
---|
748 |
|
---|
749 | /*
|
---|
750 | * äºç´èªã®ååºã(ã¨ããããã確èª)
|
---|
751 | */
|
---|
752 | void Parser::getToken(const char * term) throw(Exception)
|
---|
753 | {
|
---|
754 | Token token;
|
---|
755 |
|
---|
756 | if(term == NULL)
|
---|
757 | ExceptionMessage("Internal: GetToken received an empty string as reserved word.","å
|
---|
758 | é¨ã¨ã©ã¼: GetTokenã«ç©ºæååãæ¸¡ããã¾ãã").throwException();
|
---|
759 |
|
---|
760 | getToken(token, false);
|
---|
761 | if(token.compare(term) != 0) {
|
---|
762 | lastErrorToken = token;
|
---|
763 | ExceptionMessage("Token [%] should be replaced by [%]","åå¥[%]ã¯[%]ã§ããã¹ãã§ã") << token << term << throwException;
|
---|
764 | }
|
---|
765 | }
|
---|
766 |
|
---|
767 | void Parser::getToken(const char * first, const char * second, const char * third, const char * fourth) throw(Exception)
|
---|
768 | {
|
---|
769 | getToken(first);
|
---|
770 | if(second != NULL)
|
---|
771 | getToken(second);
|
---|
772 | if(third != NULL)
|
---|
773 | getToken(third);
|
---|
774 | if(fourth != NULL)
|
---|
775 | getToken(fourth);
|
---|
776 | }
|
---|
777 |
|
---|
778 | string Parser::getStreamLocation(void)
|
---|
779 | {
|
---|
780 | list<tagFile *>::iterator scope;
|
---|
781 |
|
---|
782 | string location;
|
---|
783 | char buffer[16];
|
---|
784 |
|
---|
785 | if(current == 0)
|
---|
786 | return string("");
|
---|
787 |
|
---|
788 | ::sprintf(buffer, ":%d", current->line);
|
---|
789 | location += current->identifier;
|
---|
790 | location += buffer;
|
---|
791 |
|
---|
792 | if(!fileStack.empty())
|
---|
793 | {
|
---|
794 | location += " (included at ";
|
---|
795 |
|
---|
796 | scope = fileStack.begin();
|
---|
797 | while(scope != fileStack.end())
|
---|
798 | {
|
---|
799 | ::sprintf(buffer, ":%d, ", (*scope)->line);
|
---|
800 | location += (*scope)->identifier;
|
---|
801 | location += buffer;
|
---|
802 |
|
---|
803 | ++ scope;
|
---|
804 |
|
---|
805 | }
|
---|
806 |
|
---|
807 | location.erase(location.size()-2);
|
---|
808 | location += ")";
|
---|
809 | }
|
---|
810 |
|
---|
811 | return location;
|
---|
812 | }
|
---|
813 |
|
---|
814 | void Parser::pushStream(const std::string & filename, std::string strid)
|
---|
815 | {
|
---|
816 | fstream * fin;
|
---|
817 |
|
---|
818 | if(current != 0)
|
---|
819 | fileStack.push_front(current);
|
---|
820 |
|
---|
821 | fin = new fstream(filename.c_str(),ios::in);
|
---|
822 |
|
---|
823 | if(fin->is_open())
|
---|
824 | {
|
---|
825 | if(strid.size() == 0)
|
---|
826 | strid = filename;
|
---|
827 |
|
---|
828 | current = new tagFile;
|
---|
829 | current->stream = fin;
|
---|
830 | current->identifier = strid;
|
---|
831 | current->line = 1;
|
---|
832 | }else
|
---|
833 | {
|
---|
834 | ExceptionMessage("File operation failure : [%]","ãã¡ã¤ã«æä½ã«å¤±æãã¾ãã [%]") << filename << throwException;
|
---|
835 | delete fin;
|
---|
836 | }
|
---|
837 | }
|
---|
838 |
|
---|
839 | void Parser::pushStdStream(std::string strid)
|
---|
840 | {
|
---|
841 | stringstream * work = new stringstream;
|
---|
842 | char buffer[1024];
|
---|
843 | int count;
|
---|
844 |
|
---|
845 | //æ¨æºå
|
---|
846 | ¥åã®æ
|
---|
847 | å ±ããã¹ã¦åãè¾¼ã (ã¨ã©ã¼å¯¾å¦ç¨ã« seekg/tellg ã使ããã)
|
---|
848 | do {
|
---|
849 | cin.read(buffer, 1024);
|
---|
850 | count = cin.gcount();
|
---|
851 | work->write(buffer, count);
|
---|
852 | } while(count != 0);
|
---|
853 |
|
---|
854 | if(current != 0)
|
---|
855 | fileStack.push_front(current);
|
---|
856 |
|
---|
857 | current = new tagFile;
|
---|
858 | current->stream = work;
|
---|
859 | current->identifier = strid;
|
---|
860 | current->line = 1;
|
---|
861 | }
|
---|
862 |
|
---|
863 | string * Parser::setLogBuffer(string * buffer)
|
---|
864 | {
|
---|
865 | string * old = LogBuffer;
|
---|
866 | LogBuffer = buffer;
|
---|
867 | PutBackCount = 0;
|
---|
868 | return old;
|
---|
869 | }
|
---|
870 |
|
---|
871 | streampos Parser::getLogBufferPos(int offset)
|
---|
872 | {
|
---|
873 | streampos pos;
|
---|
874 |
|
---|
875 | pos = 0;
|
---|
876 | if(LogBuffer != 0)
|
---|
877 | pos = LogBuffer->size();
|
---|
878 | pos += static_cast<streampos>(offset - PutBackCount);
|
---|
879 | return pos;
|
---|
880 | }
|
---|
881 |
|
---|
882 | #ifdef CALL_EXTERNAL_PROGRAM
|
---|
883 | void Parser::doPreProcess(const char * cmd)
|
---|
884 | {
|
---|
885 | string tempfilename;
|
---|
886 | char buffer[1024];
|
---|
887 | int count;
|
---|
888 | fstream tempfile;
|
---|
889 | string work;
|
---|
890 | stringstream * stream;
|
---|
891 |
|
---|
892 | if(current == NULL || current->stream == NULL)
|
---|
893 | ExceptionMessage("No stream specified for processing","å¦ç対象ã¨ãªãã¹ããªã¼ã ãè¨å®ããã¦ãã¾ãã").throwException();
|
---|
894 |
|
---|
895 |
|
---|
896 | /* ä»ã®ã¹ããªã¼ã ã®å
|
---|
897 | 容ããã¹ã¦ãã³ãã©ãªã«æ¸ãåºã */
|
---|
898 |
|
---|
899 | strcpy(buffer,"cfgXXXXXX");
|
---|
900 | mktemp(buffer);
|
---|
901 |
|
---|
902 | tempfilename.assign(buffer);
|
---|
903 | tempfile.open(tempfilename.c_str(),ios::out);
|
---|
904 |
|
---|
905 | if(!tempfile.is_open())
|
---|
906 | ExceptionMessage("Failed to open a temporary file","ãã³ãã©ãªãã¡ã¤ã«ã®ä½æã«å¤±æãã¾ãã").throwException();
|
---|
907 |
|
---|
908 | do {
|
---|
909 | current->stream->read(buffer, 1024);
|
---|
910 | count = current->stream->gcount();
|
---|
911 | tempfile.write(buffer, count);
|
---|
912 | } while(count != 0);
|
---|
913 | tempfile.close();
|
---|
914 |
|
---|
915 |
|
---|
916 | /* ã¹ããªã¼ã å·®ãæ¿ã */
|
---|
917 |
|
---|
918 | preprocessname = tempfilename;
|
---|
919 | originalname = current->identifier;
|
---|
920 |
|
---|
921 | if(current->stream != &cin)
|
---|
922 | delete current->stream;
|
---|
923 | stream = new stringstream;
|
---|
924 | current->stream = stream;
|
---|
925 |
|
---|
926 |
|
---|
927 | /* ããªããã»ããµã®èµ·å & åºåã®åã込㿠*/
|
---|
928 |
|
---|
929 | work = string(cmd) + " " + tempfilename;
|
---|
930 | VerboseMessage(" Start the external preprocessor [%]\n"," å¤é¨ããã°ã©ã ãèµ·åãã¾ã [%]\n") << work;
|
---|
931 |
|
---|
932 | FILE * pipe = popen(work.c_str(),"r");
|
---|
933 | while(feof(pipe) == 0)
|
---|
934 | stream->put((char)fgetc(pipe));
|
---|
935 |
|
---|
936 | pclose(pipe);
|
---|
937 | remove(tempfilename.c_str());
|
---|
938 | isHeadofLine = true;
|
---|
939 | }
|
---|
940 | #else
|
---|
941 | void Parser::doPreProcess(const char * cmd)
|
---|
942 | {}
|
---|
943 | #endif /* CALL_EXTERNAL_PROGRAM */
|
---|
944 |
|
---|
945 |
|
---|
946 | ParseUnit::ParseUnit(void * _container, const char * name)
|
---|
947 | {
|
---|
948 | map<string, ParseUnit *> * container;
|
---|
949 | string work(name);
|
---|
950 | string apiname;
|
---|
951 | string::size_type i,j;
|
---|
952 |
|
---|
953 | i = 0;
|
---|
954 | container = reinterpret_cast<map<string, ParseUnit *> *>(_container);
|
---|
955 |
|
---|
956 | do {
|
---|
957 | j = work.find_first_of(',', i);
|
---|
958 | apiname = work.substr(i, j-i);
|
---|
959 |
|
---|
960 | if(container->find(apiname) != container->end())
|
---|
961 | ExceptionMessage("Multiple registration of [%]\n","[%]ãéè¤ãã¦ç»é²ããããã¨ãã¦ãã¾ã") << apiname << throwException;
|
---|
962 | (*container)[apiname] = this;
|
---|
963 | i = j + 1;
|
---|
964 | }while(j != string::npos);
|
---|
965 | }
|
---|
966 |
|
---|
967 | void ParseUnit::printList(void * _container)
|
---|
968 | {
|
---|
969 | int i;
|
---|
970 | map<string, ParseUnit *> * container;
|
---|
971 | map<string, ParseUnit *>::iterator scope;
|
---|
972 |
|
---|
973 | container = reinterpret_cast<map<string, ParseUnit *> *>(_container);
|
---|
974 | if(container->empty())
|
---|
975 | {
|
---|
976 | cerr << " " << Message("None of element registed\n", "ç»é²ããã¦ããè¦ç´ ã¯ããã¾ãã\n");
|
---|
977 | return;
|
---|
978 | }
|
---|
979 |
|
---|
980 | i = 0;
|
---|
981 | scope = container->begin();
|
---|
982 | while(scope != container->end())
|
---|
983 | {
|
---|
984 | cerr << '[' << (*scope).first << "] ";
|
---|
985 |
|
---|
986 | if(i++ >= 6)
|
---|
987 | {
|
---|
988 | i = 0;
|
---|
989 | cerr << '\n';
|
---|
990 | }
|
---|
991 |
|
---|
992 | ++ scope;
|
---|
993 | }
|
---|
994 |
|
---|
995 | if(i != 0)
|
---|
996 | cerr << '\n';
|
---|
997 | }
|
---|
998 |
|
---|
999 | Token & ParseUnit::parseParameter(Parser & p)
|
---|
1000 | {
|
---|
1001 | static Token result;
|
---|
1002 | Token token;
|
---|
1003 | int nest = 0;
|
---|
1004 |
|
---|
1005 | result.type = Token::ERROR;
|
---|
1006 | result.value = 0;
|
---|
1007 | result.assign("");
|
---|
1008 |
|
---|
1009 | do
|
---|
1010 | {
|
---|
1011 | p.getToken(token);
|
---|
1012 | if(token == Token::PUNCTUATOR)
|
---|
1013 | {
|
---|
1014 | if(token.compare("(") == 0)
|
---|
1015 | nest ++;
|
---|
1016 | else if(token.compare(")") == 0)
|
---|
1017 | nest --;
|
---|
1018 | else if(nest == 0)
|
---|
1019 | break;
|
---|
1020 | if(nest < 0)
|
---|
1021 | ExceptionMessage("')' appeared before '('.","対å¿ããªãéãæ¬å¼§ãããã¾ã").throwException();
|
---|
1022 | }
|
---|
1023 |
|
---|
1024 | if(result == Token::ERROR)
|
---|
1025 | result = token;
|
---|
1026 | else
|
---|
1027 | {
|
---|
1028 | result.type = Token::STRING;
|
---|
1029 | result += ' ';
|
---|
1030 | result += token;
|
---|
1031 | }
|
---|
1032 |
|
---|
1033 | }while(true);
|
---|
1034 |
|
---|
1035 | p.putBack(token);
|
---|
1036 | result.trim();
|
---|
1037 | return result;
|
---|
1038 | }
|
---|
1039 |
|
---|
1040 | int ParseUnit::parseParameters(Parser & p, Directory * container, int min, int max)
|
---|
1041 | {
|
---|
1042 | Token work;
|
---|
1043 | int count = 0;
|
---|
1044 |
|
---|
1045 | if(max == 0)
|
---|
1046 | max = min;
|
---|
1047 |
|
---|
1048 | do
|
---|
1049 | {
|
---|
1050 | Token & token = parseParameter(p);
|
---|
1051 | if(token.type == Token::ERROR)
|
---|
1052 | break;
|
---|
1053 |
|
---|
1054 | if(token == Token::INTEGER)
|
---|
1055 | container->addChild(new Directory(token.value));
|
---|
1056 | else
|
---|
1057 | container->addChild(new Directory((string &)token));
|
---|
1058 |
|
---|
1059 | count ++;
|
---|
1060 | p.getToken(work);
|
---|
1061 | }while(work.compare(",")==0 && count < max);
|
---|
1062 |
|
---|
1063 | if(count < min)
|
---|
1064 | ExceptionMessage("Too few parameters [%/%]","ãã©ã¡ã¼ã¿ã®æ°ãå°ãªããã¾ã [%/%]") << count << min << throwException;
|
---|
1065 |
|
---|
1066 | p.putBack(work);
|
---|
1067 | return count;
|
---|
1068 | }
|
---|
1069 |
|
---|
1070 | int ParseUnit::parseParameters(Parser & p, Directory * container, const char * paramlist)
|
---|
1071 | {
|
---|
1072 | Token work;
|
---|
1073 | int count;
|
---|
1074 | string list;
|
---|
1075 | string key;
|
---|
1076 | string::size_type head,tail;
|
---|
1077 |
|
---|
1078 | list.assign(paramlist);
|
---|
1079 |
|
---|
1080 | count = 0;
|
---|
1081 | head = 0;
|
---|
1082 | tail = list.find_first_of(',');
|
---|
1083 | key = list.substr(head,tail-head);
|
---|
1084 |
|
---|
1085 | do
|
---|
1086 | {
|
---|
1087 | if(head == string::npos)
|
---|
1088 | ExceptionMessage("Too many parameters","ãã©ã¡ã¼ã¿ã®æ°ãå¤ããã¾ã").throwException();
|
---|
1089 |
|
---|
1090 | Token & token = parseParameter(p);
|
---|
1091 | if(token.type == Token::ERROR)
|
---|
1092 | break;
|
---|
1093 |
|
---|
1094 | if(token == Token::INTEGER)
|
---|
1095 | container->addChild(key,new Directory(token.value));
|
---|
1096 | else
|
---|
1097 | container->addChild(key,new Directory((string &)token));
|
---|
1098 |
|
---|
1099 | if(tail != string::npos)
|
---|
1100 | {
|
---|
1101 | head = tail + 1;
|
---|
1102 | tail = list.find_first_of(',',head);
|
---|
1103 | key = list.substr(head,tail != string::npos ? tail-head : string::npos);
|
---|
1104 | count ++;
|
---|
1105 | p.getToken(work);
|
---|
1106 | }else
|
---|
1107 | break;
|
---|
1108 | }while(work.compare(",")==0);
|
---|
1109 |
|
---|
1110 | if(tail != string::npos)
|
---|
1111 | ExceptionMessage("Too few parameters","ãã©ã¡ã¼ã¿ã®æ°ãå°ãªããã¾ã").throwException();
|
---|
1112 |
|
---|
1113 | return count;
|
---|
1114 | }
|
---|
1115 |
|
---|
1116 | //------
|
---|
1117 |
|
---|
1118 | Directory * StaticAPI::last = NULL;
|
---|
1119 |
|
---|
1120 | map<std::string, class ParseUnit *> & StaticAPI::container(void)
|
---|
1121 | {
|
---|
1122 | static map<std::string, class ParseUnit *> _container;
|
---|
1123 | return _container;
|
---|
1124 | }
|
---|
1125 |
|
---|
1126 | Directory * StaticAPI::allocate(Directory & container, const Token & token, const char * id, bool regist)
|
---|
1127 | {
|
---|
1128 | static unsigned int assignment_count = 0;
|
---|
1129 | Directory * node;
|
---|
1130 |
|
---|
1131 | if(!(token == Token::IDENTIFIER || token == Token::INTEGER))
|
---|
1132 | ExceptionMessage("Given token(%) is not suitable for an object identifier.","ãªãã¸ã§ã¯ãã®èå¥åã¨ãã¦å©ç¨ã§ããªãåå¥(%)ãæå®ããã¾ãã") << token << throwException;
|
---|
1133 |
|
---|
1134 | if(regist && (token == Token::INTEGER && token.value <= 0))
|
---|
1135 | ExceptionMessage("Cannot assign an ID number less or equal to 0.","0以ä¸ã®IDçªå·ãè¨å®ãããã¨ã¯ã§ãã¾ãã").throwException();
|
---|
1136 |
|
---|
1137 |
|
---|
1138 | node = container.findChild(id);
|
---|
1139 | if(node != 0)
|
---|
1140 | {
|
---|
1141 | Directory::iterator scope;
|
---|
1142 |
|
---|
1143 | scope = node->begin();
|
---|
1144 | while(scope != node->end())
|
---|
1145 | {
|
---|
1146 | if((*scope).first.compare(token) == 0)
|
---|
1147 | ExceptionMessage("Identifier % is already used.","èå¥å%ã¯ãã§ã«å©ç¨ããã¦ãã¾ã") << token << throwException;
|
---|
1148 | ++ scope;
|
---|
1149 | }
|
---|
1150 | }else
|
---|
1151 | node = container.addChild(id);
|
---|
1152 |
|
---|
1153 | node = node->addChild(token);
|
---|
1154 | (*node)["#order"] = assignment_count++;
|
---|
1155 |
|
---|
1156 | if(token == Token::IDENTIFIER)
|
---|
1157 | {
|
---|
1158 | if(regist)
|
---|
1159 | {
|
---|
1160 | Directory * scope = container.openChild("/","identifier",token.c_str(),NULL);
|
---|
1161 | if(*scope == Directory::INTEGER)
|
---|
1162 | *node = scope->toInteger();
|
---|
1163 | }
|
---|
1164 | }else
|
---|
1165 | *node = token.value;
|
---|
1166 |
|
---|
1167 | last = node;
|
---|
1168 | return node;
|
---|
1169 | }
|
---|
1170 |
|
---|
1171 | //------
|
---|
1172 |
|
---|
1173 | map<std::string, class ParseUnit *> & Directive::container(void)
|
---|
1174 | {
|
---|
1175 | static map<std::string, class ParseUnit *> _container;
|
---|
1176 | return _container;
|
---|
1177 | }
|
---|
1178 |
|
---|
1179 | //------
|
---|
1180 |
|
---|
1181 | ParserComponent::ParserComponent(void) throw() : Component(PARSER)
|
---|
1182 | {}
|
---|
1183 |
|
---|
1184 | ParserComponent::~ParserComponent(void) throw()
|
---|
1185 | {}
|
---|
1186 |
|
---|
1187 | void ParserComponent::parseOption(Directory & container)
|
---|
1188 | {
|
---|
1189 | if(findOption("h", "help"))
|
---|
1190 | {
|
---|
1191 | cerr << Message(
|
---|
1192 | "Static API parser\n"
|
---|
1193 | " -s, --source=filename : Specify the source file\n"
|
---|
1194 | " -idir ,--ignore-directive : Ignore directives\n"
|
---|
1195 | " -iapi ,--ignore-api : Ignore unknown static api\n"
|
---|
1196 | " -t, --through : Get unprocessed APIs through\n"
|
---|
1197 | " --print-api : Show registered static api list\n",
|
---|
1198 | "éçAPIãã¼ãµ\n"
|
---|
1199 | " -s, --source=ãã¡ã¤ã«å : å
|
---|
1200 | ¥åãã¡ã¤ã«åãæå®ãã¾ã\n"
|
---|
1201 | " -idir ,--ignore-directive : ãã£ã¬ã¯ãã£ãã®è§£æãè¡ãã¾ãã\n"
|
---|
1202 | " -iapi, --ignore-api : ç»é²ããã¦ããªãAPIãç¡è¦ãã¾ã\n"
|
---|
1203 | " -t, --through : å¦çããªãã£ãAPIãééããã¾ã\n"
|
---|
1204 | " --print-api : ç»é²ããã¦ããAPIã®ä¸è¦§ã表示ãã¾ã\n");
|
---|
1205 | return;
|
---|
1206 | }
|
---|
1207 |
|
---|
1208 | if(findOption("-print-api"))
|
---|
1209 | {
|
---|
1210 | cerr << Message("List of Registerd Static API\n","éçAPI ä¸è¦§\n");
|
---|
1211 | StaticAPI::printList();
|
---|
1212 | return;
|
---|
1213 | }
|
---|
1214 |
|
---|
1215 | checkOption("idir", "ignore-directive");
|
---|
1216 | checkOption("iapi", "ignore-api");
|
---|
1217 | checkOption("t", "through");
|
---|
1218 |
|
---|
1219 | if(checkOption("s","source") || checkOption(DEFAULT_PARAMETER))
|
---|
1220 | activateComponent();
|
---|
1221 | }
|
---|
1222 |
|
---|
1223 | bool ParserComponent::parseStaticAPI(Parser & p, Directory & container, Token token, const string domain)
|
---|
1224 | {
|
---|
1225 | bool isParseErrorOccured = false;
|
---|
1226 | map<string, ParseUnit *>::iterator api;
|
---|
1227 | Directory * node = NULL;
|
---|
1228 |
|
---|
1229 | if(token.type != Token::IDENTIFIER)
|
---|
1230 | return false;
|
---|
1231 |
|
---|
1232 | StaticAPI::clearLastObject();
|
---|
1233 | node = container[PARSERESULT].addChild();
|
---|
1234 |
|
---|
1235 | try {
|
---|
1236 | node->addChild("api",new Directory(token));
|
---|
1237 | node->addChild("begin",new Directory((long)p.getLogBufferPos(-(int)token.size()-1)));
|
---|
1238 | if(!domain.empty())
|
---|
1239 | node->addChild("domain", new Directory(domain));
|
---|
1240 |
|
---|
1241 | api = StaticAPI::container().find(token);
|
---|
1242 | if(api == StaticAPI::container().end())
|
---|
1243 | {
|
---|
1244 | if(ignoreUnknownAPI)
|
---|
1245 | {
|
---|
1246 | cerr << Message("%: Unknown static api % was ignored. (skipped)\n","%: éç»é²ã®API % ã¯ç¡è¦ããã¾ã\n") << p.getStreamLocation() << token;
|
---|
1247 | do {
|
---|
1248 | p.getToken(token);
|
---|
1249 | }while(token.compare(";") != 0);
|
---|
1250 | node->addChild("end",new Directory((long)p.getLogBufferPos()));
|
---|
1251 | (*node) = (long)0;
|
---|
1252 | return true;
|
---|
1253 | }
|
---|
1254 | ExceptionMessage("Static API [%] is not registered in the configurator", "éçAPI[%]ã¯æªç»é²ã§ã") << token << throwException;
|
---|
1255 | }
|
---|
1256 |
|
---|
1257 | DebugMessage(" StaticAPI [%]\n") << (*api).first;
|
---|
1258 |
|
---|
1259 | p.getToken("(");
|
---|
1260 |
|
---|
1261 | (*api).second->body(token, container, p, domain);
|
---|
1262 |
|
---|
1263 | p.getToken(")");
|
---|
1264 | p.getToken(";");
|
---|
1265 |
|
---|
1266 | node->addChild("end",new Directory((long)p.getLogBufferPos()));
|
---|
1267 | (*node) = (long)1;
|
---|
1268 | }
|
---|
1269 | catch(Exception & e)
|
---|
1270 | {
|
---|
1271 | int offset;
|
---|
1272 | string work;
|
---|
1273 | work = p.getStreamLocation() + Message(":[Error] ",":[ã¨ã©ã¼] ").str() + e.getDetails();
|
---|
1274 | isParseErrorOccured = true;
|
---|
1275 |
|
---|
1276 | StaticAPI::dropLastObject();
|
---|
1277 | failCount ++;
|
---|
1278 |
|
---|
1279 | offset = 0;
|
---|
1280 | token = p.getLastErrorToken();
|
---|
1281 | while (token != Token::ERROR && token != Token::EOS)
|
---|
1282 | {
|
---|
1283 | if( token == ";" )
|
---|
1284 | break;
|
---|
1285 |
|
---|
1286 | //èªã¿åºãããã¼ã¯ã³ãéçAPIã¨åãååãªã ãã£ã¨ã»ãã³ãã³å¿ã
|
---|
1287 | api = StaticAPI::container().find(token);
|
---|
1288 | if(api != StaticAPI::container().end())
|
---|
1289 | {
|
---|
1290 | cerr << Message("<The following error must be occured by lack of ';' at the end of previous line>\n","<次ã®ã¨ã©ã¼ã¯ç´åè¡ã®';'å¿ãã«ããå¯è½æ§ãé«ãã§ã>\n");
|
---|
1291 | offset = -(int)token.size();
|
---|
1292 | p.putBack(token);
|
---|
1293 | break;
|
---|
1294 | }
|
---|
1295 |
|
---|
1296 | p.getToken(token);
|
---|
1297 | }
|
---|
1298 |
|
---|
1299 | node->addChild("end",new Directory((long)p.getLogBufferPos(offset)));
|
---|
1300 | (*node) = (long)0;
|
---|
1301 |
|
---|
1302 | cerr << work << '\n';
|
---|
1303 |
|
---|
1304 | ExceptionMessage("Fatal error on Static API parsing","éçAPIã®æ§æè§£æã«å¤±æãã¾ãã").throwException();
|
---|
1305 | }
|
---|
1306 |
|
---|
1307 | return true;
|
---|
1308 | }
|
---|
1309 |
|
---|
1310 | /*
|
---|
1311 | * å¦çã§ããªãã£ãAPIãæ¨æºåºåã«åãåºã
|
---|
1312 | */
|
---|
1313 | void ParserComponent::throughConfigurationFile(string & log, Directory & container)
|
---|
1314 | {
|
---|
1315 | Directory * node;
|
---|
1316 | string::size_type pos;
|
---|
1317 | string::size_type begin;
|
---|
1318 | string::size_type end;
|
---|
1319 |
|
---|
1320 | pos = 0;
|
---|
1321 | end = 0;
|
---|
1322 |
|
---|
1323 | node = container[PARSERESULT].getFirstChild();
|
---|
1324 | while(node != NULL)
|
---|
1325 | {
|
---|
1326 | begin = static_cast<string::size_type>((*node)["begin"].toInteger());
|
---|
1327 | end = static_cast<string::size_type>((*node)["end"].toInteger());
|
---|
1328 |
|
---|
1329 | if(pos < begin)
|
---|
1330 | cout << log.substr(pos, begin - pos);
|
---|
1331 |
|
---|
1332 | if(node->toInteger() == 0)
|
---|
1333 | {
|
---|
1334 | cout << log.substr(begin, end - begin);
|
---|
1335 | }else
|
---|
1336 | {
|
---|
1337 | for(pos = begin; pos < end; ++pos)
|
---|
1338 | if( log.at(pos) == '\n' )
|
---|
1339 | cout << '\n';
|
---|
1340 | }
|
---|
1341 | node = node->getNext();
|
---|
1342 | }
|
---|
1343 |
|
---|
1344 | if(end < log.size())
|
---|
1345 | cout << log.substr(end);
|
---|
1346 |
|
---|
1347 | ExceptionMessage("","").throwException();
|
---|
1348 | }
|
---|
1349 |
|
---|
1350 |
|
---|
1351 | void ParserComponent::body(Directory & container)
|
---|
1352 | {
|
---|
1353 | Token token;
|
---|
1354 | Parser p(container);
|
---|
1355 | string logbuffer;
|
---|
1356 | OptionParameter::OptionItem item;
|
---|
1357 | unsigned int itemcount = 0;
|
---|
1358 |
|
---|
1359 | failCount = 0;
|
---|
1360 |
|
---|
1361 | //idirãªãã·ã§ã³ã®å¦ç
|
---|
1362 | if(findOption("idir","ignore-directive"))
|
---|
1363 | p.disable(Parser::DIRECTIVE);
|
---|
1364 |
|
---|
1365 | ignoreUnknownAPI = findOption("iapi", "ignore-api");
|
---|
1366 |
|
---|
1367 | if(findOption("t","through"))
|
---|
1368 | {
|
---|
1369 | p.setLogBuffer(&logbuffer);
|
---|
1370 | ignoreUnknownAPI = true;
|
---|
1371 | }
|
---|
1372 |
|
---|
1373 | //å
|
---|
1374 | ¥åã½ã¼ã¹
|
---|
1375 | item = getOption("s", "source");
|
---|
1376 | item.mergeItem(getOption(DEFAULT_PARAMETER));
|
---|
1377 | if(item.countParameter() == 0)
|
---|
1378 | {
|
---|
1379 | p.pushStdStream(Message("Standard Input","æ¨æºå
|
---|
1380 | ¥å").str());
|
---|
1381 | VerboseMessage("Starting parse with standard input\n","æ¨æºå
|
---|
1382 | ¥åããã®åå¥è§£æãéå§ãã¾ãã\n");
|
---|
1383 | }
|
---|
1384 |
|
---|
1385 | try{
|
---|
1386 | do {
|
---|
1387 | if(item.hasParameter())
|
---|
1388 | {
|
---|
1389 | VerboseMessage("Starting parse with file[%]\n","ãã¡ã¤ã«[%]ã®åå¥è§£æãéå§ãã¾ãã\n") << item[itemcount];
|
---|
1390 | p.pushStream(item[itemcount]);
|
---|
1391 | }
|
---|
1392 |
|
---|
1393 | this->parse(p, container);
|
---|
1394 |
|
---|
1395 | if(p.getToken(token) != Token::EOS)
|
---|
1396 | ExceptionMessage("Buffer has remaining tokens, parsing is not yet finished", "ãã¼ã¹ã䏿ããã¾ãã").throwException();
|
---|
1397 |
|
---|
1398 | if(failCount != 0)
|
---|
1399 | ExceptionMessage("Total % failures found in this configuration.","%åã®é害ãããã¾ã") << failCount << throwException;
|
---|
1400 |
|
---|
1401 | VerboseMessage("Parse finished\n","åå¥è§£æã¯æ£å¸¸ã«çµäºãã¾ãã\n");
|
---|
1402 |
|
---|
1403 | } while(++itemcount < item.countParameter());
|
---|
1404 |
|
---|
1405 | if(findOption("t","through"))
|
---|
1406 | throughConfigurationFile(logbuffer,container);
|
---|
1407 |
|
---|
1408 | container[PARSERESULT].erase();
|
---|
1409 | }
|
---|
1410 | catch(Exception & e)
|
---|
1411 | {
|
---|
1412 | string work;
|
---|
1413 |
|
---|
1414 | work = p.getStreamLocation() + Message(":[Error] ",":[ã¨ã©ã¼] ").str() + e.getDetails();
|
---|
1415 | ExceptionMessage(work.c_str()).throwException();
|
---|
1416 | }
|
---|
1417 | }
|
---|
1418 |
|
---|
1419 | // ãªãã·ã§ã³ãã¼ãããå²ä»æ¹æ³ãåå¾ãã
|
---|
1420 | enum Common::tagAssignmentOrder Common::parseOrder(Directory * node)
|
---|
1421 | {
|
---|
1422 | Directory * scope;
|
---|
1423 | int i;
|
---|
1424 |
|
---|
1425 | //å²å½ãã©ã¡ã¼ã¿è§£æ
|
---|
1426 | i = FCFS;
|
---|
1427 | if(node != 0)
|
---|
1428 | {
|
---|
1429 | scope = node->getFirstChild();
|
---|
1430 | while(scope != 0)
|
---|
1431 | {
|
---|
1432 | string param = scope->toString();
|
---|
1433 | if(param.compare("alphabetic") == 0 || param.compare("ALPHABETIC") == 0)
|
---|
1434 | i = (i & 0xf0) | ALPHABETIC;
|
---|
1435 | else if(param.compare("fcfs") == 0 || param.compare("FCFS") == 0)
|
---|
1436 | i = (i & 0xf0) | FCFS;
|
---|
1437 | else if(param.compare("reverse") == 0 || param.compare("REVERSE") == 0)
|
---|
1438 | i |= REVERSE;
|
---|
1439 |
|
---|
1440 | scope = scope->getNext();
|
---|
1441 | }
|
---|
1442 | }
|
---|
1443 |
|
---|
1444 | return static_cast<enum tagAssignmentOrder>(i);
|
---|
1445 | }
|
---|
1446 |
|
---|
1447 | // ãªãã·ã§ã³ãã¼ãããå²ä»æ¹æ³ãåå¾ãã
|
---|
1448 | enum Common::tagAssignmentOrder Common::parseOrder(OptionParameter::OptionItem item)
|
---|
1449 | {
|
---|
1450 | Directory node;
|
---|
1451 | unsigned int i;
|
---|
1452 |
|
---|
1453 | for(i=0;i<item.countParameter();++i)
|
---|
1454 | node.addChild(item[i]);
|
---|
1455 |
|
---|
1456 | return parseOrder(&node);
|
---|
1457 | }
|
---|
1458 |
|
---|
1459 | //IDå¤ã®ã¢ãµã¤ã³ã¡ã³ã
|
---|
1460 | // (ä»ã®å ´æããã使ãã®ã§ããã«ç§»å)
|
---|
1461 | int Common::assignID(Directory & container, const char * category, const char * top, enum tagAssignmentOrder order)
|
---|
1462 | {
|
---|
1463 | Directory * node = 0;
|
---|
1464 | Directory * scope = 0;
|
---|
1465 | Directory * work = 0;
|
---|
1466 | set<int> idpool;
|
---|
1467 | map<int, Directory *> sorter;
|
---|
1468 | map<int, Directory *>::iterator p_sorter;
|
---|
1469 | int i;
|
---|
1470 |
|
---|
1471 | //䏿ºå
|
---|
1472 | node = container.findChild(top,category,NULL);
|
---|
1473 | if(node == 0)
|
---|
1474 | return 0;
|
---|
1475 |
|
---|
1476 | for(i=1;i< (signed int) node->size() + 32; i++)
|
---|
1477 | idpool.insert(i);
|
---|
1478 |
|
---|
1479 | //å²ä»é ã®æ±ºå®ã¨ï¼å²å½æ¸ã¿IDã®åé¤
|
---|
1480 | i = 0;
|
---|
1481 | scope = node->getFirstChild();
|
---|
1482 | while(scope != 0)
|
---|
1483 | {
|
---|
1484 | if( *scope == Directory::INTEGER )
|
---|
1485 | idpool.erase(*scope);
|
---|
1486 | else
|
---|
1487 | {
|
---|
1488 | //éè¤åç§°ã®åå¨ãã§ãã¯
|
---|
1489 | work = container.openChild("/","identifier",scope->getKey().c_str(),NULL);
|
---|
1490 | if( *work == Directory::INTEGER)
|
---|
1491 | {
|
---|
1492 | VerboseMessage("Assigning the same ID (%) since the name (%[%]) is duplicated\n","IDçªå·(%)ãç°ç¨®ååã®ãªãã¸ã§ã¯ã(%[%])ã«å²ãå½ã¦ã¾ãï¼\n") << work->toInteger() << scope->getKey() << category;
|
---|
1493 | idpool.erase(*scope = work->toInteger());
|
---|
1494 | } else
|
---|
1495 | {
|
---|
1496 | //å²å½æ¹æ³ã«å¾ã£ã¦å²å½åè£ã«è¿½å
|
---|
1497 | switch(order)
|
---|
1498 | {
|
---|
1499 | case ALPHABETIC:
|
---|
1500 | sorter[i++] = scope;
|
---|
1501 | break;
|
---|
1502 | case REVERSE_ALPHABETIC:
|
---|
1503 | sorter[i--] = scope;
|
---|
1504 | break;
|
---|
1505 | case FCFS:
|
---|
1506 | default:
|
---|
1507 | sorter[scope->openChild("#order")->toInteger()] = scope;
|
---|
1508 | break;
|
---|
1509 | case REVERSE_FCFS:
|
---|
1510 | sorter[-scope->openChild("#order")->toInteger()] = scope;
|
---|
1511 | break;
|
---|
1512 | }
|
---|
1513 | }
|
---|
1514 | }
|
---|
1515 | scope = scope->getNext();
|
---|
1516 | }
|
---|
1517 |
|
---|
1518 | //IDå²å½
|
---|
1519 | p_sorter = sorter.begin();
|
---|
1520 | while(p_sorter != sorter.end())
|
---|
1521 | {
|
---|
1522 | scope = (*p_sorter).second;
|
---|
1523 | if( !(*scope == Directory::INTEGER) )
|
---|
1524 | {
|
---|
1525 | i = *(idpool.begin());
|
---|
1526 | idpool.erase(idpool.begin());
|
---|
1527 |
|
---|
1528 | work = container.openChild("/","identifier",scope->getKey().c_str(),NULL);
|
---|
1529 | *work = i;
|
---|
1530 | *scope = i;
|
---|
1531 | }
|
---|
1532 | ++ p_sorter;
|
---|
1533 | }
|
---|
1534 |
|
---|
1535 | //å²å½è¡¨ä½æ
|
---|
1536 | if(node->size() != 0 && VerboseMessage::getVerbose())
|
---|
1537 | {
|
---|
1538 | VerboseMessage("Object ID assignment list [%]\n","ãªãã¸ã§ã¯ãIDå²ä»è¡¨ [%]\n") << category;
|
---|
1539 |
|
---|
1540 | sorter.clear();
|
---|
1541 | scope = node->getFirstChild();
|
---|
1542 | while(scope != 0)
|
---|
1543 | {
|
---|
1544 | sorter[scope->toInteger()] = scope;
|
---|
1545 | scope = scope->getNext();
|
---|
1546 | }
|
---|
1547 |
|
---|
1548 | p_sorter = sorter.begin();
|
---|
1549 | while(p_sorter != sorter.end())
|
---|
1550 | {
|
---|
1551 | VerboseMessage(" % : %\n") << setw(3) << (*p_sorter).first << (*p_sorter).second->getKey();
|
---|
1552 | ++ p_sorter;
|
---|
1553 | }
|
---|
1554 | }
|
---|
1555 |
|
---|
1556 | //妥彿§ã®å¤å®
|
---|
1557 | if((signed)node->size()+1 != *(idpool.begin()))
|
---|
1558 | ExceptionMessage("Discontinuous % ID assignment occured","ä¸é£ç¶ãªãªãã¸ã§ã¯ãID(%)") << category << throwException;
|
---|
1559 |
|
---|
1560 | return node->size();
|
---|
1561 | }
|
---|
1562 |
|
---|