source: cfg_itronx+oil_gcc/toppers/itronx/factory.cpp

Last change on this file was 54, checked in by ertl-ishikawa, 12 years ago

cfg+oil対応コンフィギュレータを追加

File size: 26.3 KB
Line 
1/*
2 * TOPPERS Software
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 *
5 * Copyright (C) 2007-2011 by TAKAGI Nobuhisa
6 *
7 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12 * スコード中に含まれていること.
13 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16 * の無保証規定を掲載すること.
17 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19 * と.
20 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
22 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23 * 報告すること.
24 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28 * 免責すること.
29 *
30 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34 * の責任を負わない.
35 *
36 */
37#include <cstring>
38#include <cstdlib>
39#include <fstream>
40#include <boost/lexical_cast.hpp>
41#include "toppers/misc.hpp"
42#include "toppers/global.hpp"
43#include "toppers/csv.hpp"
44#include "toppers/nm_symbol.hpp"
45#include "toppers/s_record.hpp"
46#include "toppers/diagnostics.hpp"
47#include "toppers/macro_processor.hpp"
48#include "toppers/io.hpp"
49#include "toppers/cpp.hpp"
50#include "toppers/itronx/factory.hpp"
51#include "toppers/itronx/cfg1_out.hpp"
52
53namespace toppers
54{
55 namespace itronx
56 {
57 namespace
58 {
59
60 // カーネルオブジェクト生成・定義用静的APIの各パラメータをマクロプロセッサの変数として設定する。
61 void set_object_vars( cfg1_out::static_api_map const& api_map, macro_processor& mproc )
62 {
63 typedef macro_processor::element element;
64 typedef macro_processor::var_t var_t;
65 std::map< std::string, var_t > order_list_map;
66 std::map< std::string, long > id_map;
67
68 for ( cfg1_out::static_api_map::const_iterator m_iter( api_map.begin() ), m_last( api_map.end() );
69 m_iter != m_last;
70 ++m_iter )
71 {
72 int order = 1;
73
74 for ( std::vector< static_api >::const_iterator v_iter( m_iter->second.begin() ), v_last( m_iter->second.end() );
75 v_iter != v_last;
76 ++v_iter )
77 {
78 static_api::info const* info = v_iter->get_info();
79
80 long id = -1;
81 if ( !info->slave )
82 {
83 // 出現順 $OBJ.ORDER$
84 if ( v_iter->id().value )
85 {
86 id = static_cast< long >( v_iter->id().value.get() );
87 }
88 else
89 {
90 id = order;
91 }
92 id_map[ v_iter->id().text ] = id;
93 element e;
94 e.i = order;
95 mproc.set_var( toppers::toupper( ( boost::format( "%s.order" ) % info->type ).str() ), id, var_t( 1, e ) );
96
97 e.i = id;
98 e.s = v_iter->id().text;
99 order_list_map[ info->type ].push_back( e );
100 ++order;
101 }
102 else
103 {
104 std::map< std::string, long >::iterator iter( id_map.find( v_iter->id().text ) );
105 if ( iter == id_map.end() )
106 {
107 error( v_iter->line(), _( "E_NOEXS: `%1%\' is undefined" ), v_iter->id().text );
108 }
109 else
110 {
111 id = iter->second;
112 }
113 }
114
115 // 各パラメータ
116 var_t var;
117 std::string prev_name;
118 for ( static_api::const_iterator api_iter( v_iter->begin() ), api_last( v_iter->end() );
119 api_iter != api_last;
120 ++api_iter )
121 {
122 bool is_param_list = false;
123
124 std::string name( toppers::toupper( ( boost::format( "%s.%s" ) % info->type % ( api_iter->symbol.c_str() + 1 ) ).str() ) );
125 // 末尾の ? を除去
126 if ( *name.rbegin() == '\?' )
127 {
128 name.resize( name.size() - 1 );
129 }
130 // 末尾の ... を除去
131 if ( name.size() > 3 && name.substr( name.size() - 3 ) == "..." )
132 {
133 name.resize( name.size() - 3 );
134 is_param_list = true;
135 }
136
137 if (!var.empty())
138 {
139 if (prev_name != name)
140 {
141 var.clear();
142 }
143 }
144
145 element e;
146 e.s = api_iter->text; // ソースの字面
147 if ( api_iter->symbol[0] != '&' ) // 一般定数式パラメータは値が特定できない
148 {
149 if ( api_iter->symbol[0] == '$' ) // 文字列定数式パラメータ
150 {
151 e.v = api_iter->string; // 展開後の文字列
152 }
153 else
154 {
155 e.i = api_iter->value;
156 }
157 if ( api_iter->symbol[0] == '%' )
158 {
159 continue;
160 }
161 }
162 var.push_back(e);
163 mproc.set_var( name, id, var );
164
165 prev_name = name;
166
167 // 下位互換性のため、symbol + order 名の変数を登録
168 if (is_param_list)
169 {
170 name += boost::lexical_cast< std::string >( api_iter->order );
171 mproc.set_var( name, id, var_t( 1, e ) );
172 }
173 }
174
175 // 静的APIが出現した行番号
176 {
177 element e;
178 e.s = v_iter->line().file;
179 e.i = v_iter->line().line;
180 std::string type( toppers::toupper( info->type ) );
181
182 if ( info->slave )
183 {
184 type = info->api_name;
185 }
186 mproc.set_var( type + ".TEXT_LINE", id, var_t( 1, e ) );
187 }
188 }
189 }
190
191 std::map< std::string, var_t > id_list_map;
192
193 for ( std::map< std::string, var_t >::const_iterator iter( order_list_map.begin() ), last( order_list_map.end() );
194 iter != last;
195 ++iter )
196 {
197 // 出現順リスト $OBJ.ORDER_LIST$ -- ID番号の並び
198 mproc.set_var( toppers::toupper( iter->first + ".order_list" ), iter->second );
199 var_t rorder_list( iter->second );
200
201 // 逆順リスト $OBJ.RORDER_LIST$ -- ID番号の並び
202 std::reverse( rorder_list.begin(), rorder_list.end() );
203 mproc.set_var( toppers::toupper( iter->first + ".rorder_list" ), rorder_list );
204
205 // ID番号リスト $OBJ.ID_LIST$ -- ID番号の並び
206 var_t id_list( iter->second );
207 std::sort( id_list.begin(), id_list.end() );
208 mproc.set_var( toppers::toupper( iter->first + ".id_list" ), id_list );
209 }
210
211 element external_id;
212 external_id.i = get_global< bool >( "external-id" );
213 mproc.set_var( "USE_EXTERNAL_ID", var_t( 1, external_id ) );
214 }
215
216 // カーネルオブジェクト生成・定義用静的APIの各パラメータをマクロプロセッサの変数として設定する。
217 void set_object_vars( std::vector< static_api > const& api_array, macro_processor& mproc )
218 {
219 typedef macro_processor::element element;
220 typedef macro_processor::var_t var_t;
221 long order = 1;
222 var_t order_list;
223
224 for ( std::vector< static_api >::const_iterator v_iter( api_array.begin() ), v_last( api_array.end() );
225 v_iter != v_last;
226 ++v_iter )
227 {
228 static_api::info const* info = v_iter->get_info();
229 var_t params;
230 var_t args;
231
232 // 静的APIが出現した行番号
233 element e;
234 e.s = v_iter->line().file;
235 e.i = v_iter->line().line;
236 mproc.set_var( "API.TEXT_LINE", order, var_t( 1, e ) );
237
238 // 静的API名
239 e.s = info->api_name;
240 e.i = boost::none;
241 mproc.set_var( "API.NAME", order, var_t( 1, e ) );
242
243 // オブジェクトタイプ("TSK", "SEM", ...)
244 e.s = toppers::toupper( info->type );
245 mproc.set_var( "API.TYPE", order, var_t( 1 , e ) );
246
247 // 各パラメータ
248 for ( static_api::const_iterator api_iter( v_iter->begin() ), api_last( v_iter->end() );
249 api_iter != api_last;
250 ++api_iter )
251 {
252 std::string name( toppers::toupper( ( boost::format( "%s.%s" ) % info->type % ( api_iter->symbol.c_str() + 1 ) ).str() ) );
253 // 末尾の ? を除去
254 if ( *name.rbegin() == '\?' )
255 {
256 name.resize( name.size() - 1 );
257 }
258 // 末尾の ... を除去 & order を付加
259 if ( name.size() > 3 && name.substr( name.size() - 3 ) == "..." )
260 {
261 name.resize( name.size() - 3 );
262 name += boost::lexical_cast< std::string >( api_iter->order );
263 }
264
265 element e;
266 e.s = api_iter->text; // ソースの字面
267 if ( api_iter->symbol[0] != '&' ) // 一般定数式パラメータは値が特定できない
268 {
269 if ( api_iter->symbol[0] == '$' ) // 文字列定数式パラメータ
270 {
271 e.v = api_iter->string; // 展開後の文字列
272 }
273 else
274 {
275 e.i = api_iter->value;
276 }
277 }
278 args.push_back( e );
279
280 e.s = name;
281 e.i = boost::none;
282 params.push_back( e );
283
284 if ( api_iter->symbol[0] == '%' )
285 {
286 continue;
287 }
288 }
289 mproc.set_var( "API.ARGS", order, args );
290 mproc.set_var( "API.PARAMS", order, params );
291 e.s.clear();
292 e.i = order;
293 order_list.push_back( e );
294 ++order;
295 }
296 mproc.set_var( "API.ORDER_LIST", order_list );
297
298 element external_id;
299 external_id.i = get_global< bool >( "external-id" );
300 mproc.set_var( "USE_EXTERNAL_ID", var_t( 1, external_id ) );
301 }
302
303 // クラスIDリストをマクロプロセッサの変数として設定する。
304 void set_clsid_vars( std::vector< std::pair< std::string, long > > const& table, cfg1_out const& cfg1out, macro_processor& mproc )
305 {
306 typedef macro_processor::element element;
307 macro_processor::var_t var;
308
309 bool little_endian = cfg1out.is_little_endian();
310 nm_symbol::entry nm_entry = cfg1out.get_syms()->find( "TOPPERS_cfg_sizeof_signed_t" );
311 std::size_t sizeof_signed_t = static_cast< std::size_t >( cfg1out.get_srec()->get_value( nm_entry.address, 4, little_endian ) );
312
313 for ( std::vector< std::pair< std::string, long > >::const_iterator iter( table.begin() ), last( table.end() );
314 iter != last;
315 ++iter )
316 {
317 if ( !iter->first.empty() )
318 {
319 element e;
320 e.s = iter->first;
321
322 std::string symbol = "TOPPERS_cfg_valueof_" + iter->first;
323 nm_symbol::entry nm_entry = cfg1out.get_syms()->find( symbol );
324 if ( nm_entry.type == -1 )
325 {
326 continue;
327 }
328 const std::size_t size = sizeof_signed_t;
329 std::tr1::intmax_t value = cfg1out.get_srec()->get_value( nm_entry.address, size, little_endian );
330
331 e.i = value;
332
333 var.push_back( e );
334 }
335 }
336 // クラスIDの値でソートしていない
337 mproc.set_var( "CLS.ID_LIST", var );
338 }
339
340 // ドメインIDリストをマクロプロセッサの変数として設定する。
341 void set_domid_vars( std::vector< std::pair< std::string, long > > const& table, macro_processor& mproc )
342 {
343 typedef macro_processor::element element;
344 macro_processor::var_t var;
345
346 for ( std::vector< std::pair< std::string, long > >::const_iterator iter( table.begin() ), last( table.end() );
347 iter != last;
348 ++iter )
349 {
350 if ( !iter->first.empty() )
351 {
352 element e;
353 e.s = iter->first;
354 e.i = iter->second;
355 var.push_back( e );
356 }
357 }
358 mproc.set_var( "DOM.ID_LIST", var );
359 }
360
361 // プラットフォーム・コンパイラ依存の値をマクロプロセッサの変数として設定する。
362 void set_platform_vars( cfg1_out const& cfg1out, macro_processor& mproc )
363 {
364 typedef macro_processor::element element;
365 typedef macro_processor::var_t var_t;
366
367 cfg1_out::cfg1_def_table const* def_table = cfg1out.get_def_table();
368 std::size_t sizeof_signed_t;
369 std::size_t sizeof_pointer;
370
371 static cfg1_out::cfg1_def_t const limit_defs[] =
372 {
373 { false, "TOPPERS_cfg_CHAR_BIT", "CHAR_BIT" },
374 { false, "TOPPERS_cfg_CHAR_MAX", "CHAR_MAX" },
375 { true, "TOPPERS_cfg_CHAR_MIN", "CHAR_MIN" },
376 { false, "TOPPERS_cfg_SCHAR_MAX", "SCHAR_MAX" }, // 本来は符号付きだが、負になることはない
377 { false, "TOPPERS_cfg_SHRT_MAX", "SHRT_MAX" }, // 本来は符号付きだが、負になることはない
378 { false, "TOPPERS_cfg_INT_MAX", "INT_MAX" }, // 本来は符号付きだが、負になることはない
379 { false, "TOPPERS_cfg_LONG_MAX", "LONG_MAX" }, // 本来は符号付きだが、負になることはない
380 };
381
382 nm_symbol::entry nm_entry = cfg1out.get_syms()->find( "TOPPERS_cfg_sizeof_signed_t" );
383 sizeof_signed_t = static_cast< std::size_t >( cfg1out.get_srec()->get_value( nm_entry.address, 4, cfg1out.is_little_endian() ) );
384
385 nm_entry = cfg1out.get_syms()->find( "TOPPERS_cfg_sizeof_pointer" );
386 sizeof_pointer = static_cast< std::size_t >( cfg1out.get_srec()->get_value( nm_entry.address, 4, cfg1out.is_little_endian() ) );
387
388 for ( std::size_t i = 0; i < sizeof limit_defs / sizeof limit_defs[ 0 ]; ++i )
389 {
390 element e;
391 e.s = limit_defs[ i ].expression;
392 nm_entry = cfg1out.get_syms()->find( limit_defs[ i ].name );
393 std::tr1::int64_t value = cfg1out.get_srec()->get_value( nm_entry.address, sizeof_signed_t, cfg1out.is_little_endian() );
394 if ( sizeof_signed_t < 8 && limit_defs[ i ].is_signed )
395 {
396 value = cfg1_out::make_signed( static_cast< std::tr1::uint32_t >( value ) );
397 }
398 mproc.set_var( e.s, var_t( 1, e ) );
399 }
400
401 for ( cfg1_out::cfg1_def_table::const_iterator iter( def_table->begin() ), last( def_table->end() );
402 iter != last;
403 ++iter )
404 {
405 element e;
406 std::tr1::int64_t value;
407
408 nm_entry = cfg1out.get_syms()->find( "TOPPERS_cfg_" + iter->name );
409 if ( nm_entry.type >= 0 )
410 {
411 if ( !iter->expression.empty() && iter->expression[ 0 ] == '@' ) // 式が'@'で始まる場合はアドレス定数式
412 {
413 value = cfg1out.get_srec()->get_value( nm_entry.address, sizeof_pointer, cfg1out.is_little_endian() );
414 if ( sizeof_signed_t < 8 && iter->is_signed )
415 {
416 value = cfg1_out::make_signed( static_cast< std::tr1::uint32_t >( value ) );
417 }
418
419 // 先ほど取り出したアドレスを使って間接参照
420 value = cfg1out.get_srec()->get_value( value, 8, cfg1out.is_little_endian() ); // 取り出す値は型に関係なく常に8バイト
421 if ( sizeof_signed_t < 8 && iter->is_signed )
422 {
423 value = cfg1_out::make_signed( static_cast< std::tr1::uint32_t >( value ) );
424 }
425 e.s = iter->expression.c_str() + 1; // 先頭の'@'を除去
426 }
427 else // アドレスではない通常の整数定数式
428 {
429 value = cfg1out.get_srec()->get_value( nm_entry.address, sizeof_signed_t, cfg1out.is_little_endian() );
430 if ( sizeof_signed_t < 8 && iter->is_signed )
431 {
432 value = cfg1_out::make_signed( static_cast< std::tr1::uint32_t >( value ) );
433 }
434 e.s = iter->expression;
435 }
436 e.i = value;
437 mproc.set_var( iter->name, var_t( 1, e ) );
438 }
439 }
440
441 // バイトオーダー
442 {
443 bool little_endian = cfg1out.is_little_endian();
444 element e;
445 e.i = little_endian;
446 mproc.set_var( "LITTLE_ENDIAN", var_t( 1, e ) );
447
448 e.i = !little_endian;
449 mproc.set_var( "BIG_ENDIAN", var_t( 1, e ) );
450 }
451 }
452
453 }
454
455 //! コンストラクタ
456 factory::factory( std::string const& kernel )
457 : kernel_( tolower( kernel ) )
458 {
459 }
460
461 //! デストラクタ
462 factory::~factory()
463 {
464 }
465
466 //! サポートしている静的API情報の取得
467 std::map< std::string, static_api::info > const* factory::get_static_api_info_map() const
468 {
469 // CSVから静的API情報を読み取り、登録するためのローカルクラス
470 struct init_t
471 {
472 init_t()
473 {
474 boost::any t = global( "api-table" );
475 if ( !t.empty() )
476 {
477 std::vector< std::string > api_tables( boost::any_cast< std::vector< std::string >& >( t ) );
478 for ( std::vector< std::string >::const_iterator iter( api_tables.begin() ), last( api_tables.end() );
479 iter != last;
480 ++iter )
481 {
482 std::string buf;
483 std::string api_table_filename = *iter;
484 read( api_table_filename.c_str(), buf );
485 csv data( buf.begin(), buf.end() );
486 for ( csv::const_iterator d_iter( data.begin() ), d_last( data.end() );
487 d_iter != d_last;
488 ++d_iter )
489 {
490 csv::size_type len = d_iter->size();
491 if ( len < 3 ) // type, api_name, params は必須要素
492 {
493 toppers::fatal( _( "too little fields in `%1%\'" ), *iter );
494 }
495 static_api::info api_info = { 0 };
496 try
497 {
498 char* s;
499 s = new char[ ( *d_iter )[ 0 ].size() + 1 ];
500 std::strcpy( s, ( *d_iter )[ 0 ].c_str() );
501 api_info.type = s;
502
503 s = new char[ ( *d_iter )[ 1 ].size() + 1 ];
504 std::strcpy( s, ( *d_iter )[ 1 ].c_str() );
505 api_info.api_name = s;
506
507 s = new char[ ( *d_iter )[ 2 ].size() + 1 ];
508 std::strcpy( s, ( *d_iter )[ 2 ].c_str() );
509 api_info.params = s;
510 if ( len >= 4 && !( *d_iter )[ 3 ].empty() )
511 {
512 api_info.id_pos = std::strtol( ( *d_iter )[ 3 ].c_str(), 0, 0 );
513 }
514 if ( len >= 5 && !( *d_iter )[ 4 ].empty() )
515 {
516 api_info.slave = !!std::strtol( ( *d_iter )[ 4 ].c_str(), 0, 0 );
517 }
518 static_api_table_[ api_info.api_name ] = api_info;
519 }
520 catch ( ... )
521 {
522 delete[] api_info.type;
523 delete[] api_info.api_name;
524 delete[] api_info.params;
525 throw;
526 }
527 }
528 }
529 }
530 }
531
532 ~init_t()
533 {
534 for ( std::map< std::string, static_api::info >::const_iterator iter( static_api_table_.begin() ), last( static_api_table_.end() );
535 iter != last;
536 ++iter )
537 {
538 delete[] iter->second.type;
539 delete[] iter->second.api_name;
540 delete[] iter->second.params;
541 }
542 }
543
544 std::map< std::string, static_api::info > static_api_table_;
545 };
546 static init_t init;
547 std::map< std::string, static_api::info > const* result = &init.static_api_table_;
548 return result;
549 }
550
551 /*!
552 * \brief cfg1_out.c への出力情報テーブルの生成
553 * \return 生成した cfg1_out::cfg1_def_table オブジェクトへのポインタ
554 * \note この関数が返すポインタは delete してはならない
555 *
556 * --cfg1-def-table オプションで指定したファイルから、cfg1_out.c へ出力する情報を読み取り、
557 * cfg1_out::cfg1_def_table オブジェクトを生成する。
558 *
559 * CSV の形式は以下の通り
560 *
561 * シンボル名,式[,s|signed]
562 *
563 * 末尾の s または signed は省略可能。省略時は符号無し整数とみなす。s または signed 指定時は
564 * 符号付き整数とみなす。\n
565 * 「式」の最初に # があれば前処理式とみなす。
566 */
567 cfg1_out::cfg1_def_table const* factory::get_cfg1_def_table() const
568 {
569 struct init_t
570 {
571 init_t()
572 {
573 boost::any t = global( "cfg1-def-table" );
574 if ( !t.empty() )
575 {
576 std::vector< std::string > cfg1_def_table = boost::any_cast< std::vector< std::string >& >( t );
577 for ( std::vector< std::string >::const_iterator iter( cfg1_def_table.begin() ), last( cfg1_def_table.end() );
578 iter != last;
579 ++iter )
580 {
581 std::string buf;
582 read( iter->c_str(), buf );
583 csv data( buf.begin(), buf.end() );
584 for ( csv::const_iterator d_iter( data.begin() ), d_last( data.end() );
585 d_iter != d_last;
586 ++d_iter )
587 {
588 csv::size_type len = d_iter->size();
589 if ( len < 2 )
590 {
591 toppers::fatal( _( "too little fields in `%1%\'" ), *iter );
592 }
593 cfg1_out::cfg1_def_t def = { 0 };
594 def.name = ( *d_iter )[ 0 ];
595 def.expression = ( *d_iter )[ 1 ];
596 if ( len >= 3 )
597 {
598 std::string is_signed( ( *d_iter )[ 2 ] );
599 def.is_signed = ( is_signed == "s" || is_signed == "signed" );
600 }
601 if ( len >= 4)
602 {
603 def.value1 = ( *d_iter )[ 3 ];
604 }
605 if ( len >= 5)
606 {
607 def.value2 = ( *d_iter )[ 4 ];
608 }
609 cfg1_def_table_.push_back( def );
610 }
611 }
612 }
613 }
614 cfg1_out::cfg1_def_table cfg1_def_table_;
615 };
616 static init_t init;
617 cfg1_out::cfg1_def_table const* result = &init.cfg1_def_table_;
618 return result;
619 }
620
621 //! オブジェクトの交換
622 void factory::do_swap( factory& other )
623 {
624 kernel_.swap( other.kernel_ );
625 }
626
627 /*!
628 * \brief マクロプロセッサの生成
629 * \param[in] cfg1out cfg1_out オブジェクト
630 * \param[in] api_map .cfg ファイルに記述された静的API情報
631 * \return マクロプロセッサへのポインタ
632 * \note このメンバ関数は従来仕様(ソフトウェア部品非対応版)の温存のためにそのまま残す。
633 */
634 std::auto_ptr< macro_processor > factory::do_create_macro_processor( cfg1_out const& cfg1out, cfg1_out::static_api_map const& api_map ) const
635 {
636 typedef macro_processor::element element;
637 typedef macro_processor::var_t var_t;
638 std::auto_ptr< macro_processor > mproc( new macro_processor );
639 element e;
640
641 e.s = " "; mproc->set_var( "SPC", var_t( 1, e ) ); // $SPC$
642 e.s = "\t"; mproc->set_var( "TAB", var_t( 1, e ) ); // $TAB$
643 e.s = "\n"; mproc->set_var( "NL", var_t( 1, e ) ); // $NL$
644
645 // バージョン情報
646 e.s = toppers::get_global< std::string >( "version" );
647 e.i = toppers::get_global< std::tr1::int64_t >( "timestamp" );
648 mproc->set_var( "CFG_VERSION", var_t( 1, e ) ); // $CFG_VERSION$
649
650 // その他の組み込み変数の設定
651 set_object_vars( api_map, *mproc );
652 set_object_vars( cfg1out.get_static_api_array(), *mproc );
653 set_clsid_vars( cfg1out.get_clsid_table(), cfg1out, *mproc );
654 set_domid_vars( cfg1out.get_domid_table(), *mproc );
655 set_platform_vars( cfg1out, *mproc );
656 e.s = cfg1out.get_includes();
657 mproc->set_var( "INCLUDES", var_t( 1, e ) );
658
659 // パス情報
660 e.s = boost::lexical_cast< std::string >(toppers::get_global< int >( "pass" ));
661 e.i = toppers::get_global< int >( "pass" );
662 mproc->set_var( "CFG_PASS", var_t( 1, e ) );
663
664 return mproc;
665 }
666
667 /*!
668 * \brief マクロプロセッサの生成
669 * \param[in] cfg1out cfg1_out オブジェクト
670 * \param[in] api_array .cfg ファイルに記述された静的API情報
671 * \return マクロプロセッサへのポインタ
672 */
673 std::auto_ptr< macro_processor > factory::do_create_macro_processor( cfg1_out const& cfg1out, std::vector< static_api > const& api_array ) const
674 {
675 typedef macro_processor::element element;
676 typedef macro_processor::var_t var_t;
677 std::auto_ptr< macro_processor > mproc( new macro_processor );
678 element e;
679
680 e.s = " "; mproc->set_var( "SPC", var_t( 1, e ) ); // $SPC$
681 e.s = "\t"; mproc->set_var( "TAB", var_t( 1, e ) ); // $TAB$
682 e.s = "\n"; mproc->set_var( "NL", var_t( 1, e ) ); // $NL$
683
684 // バージョン情報
685 e.s = toppers::get_global< std::string >( "version" );
686 e.i = toppers::get_global< std::tr1::int64_t >( "timestamp" );
687 mproc->set_var( "CFG_VERSION", var_t( 1, e ) ); // $CFG_VERSION$
688
689 // その他の組み込み変数の設定
690 set_object_vars( api_array, *mproc );
691 set_clsid_vars( cfg1out.get_clsid_table(), cfg1out, *mproc );
692 set_domid_vars( cfg1out.get_domid_table(), *mproc );
693 set_platform_vars( cfg1out, *mproc );
694 e.s = cfg1out.get_includes();
695 mproc->set_var( "INCLUDES", var_t( 1, e ) );
696
697 // パス情報
698 e.s = boost::lexical_cast< std::string >(toppers::get_global< int >( "pass" ));
699 e.i = toppers::get_global< int >( "pass" );
700 mproc->set_var( "CFG_PASS", var_t( 1, e ) );
701
702 return mproc;
703 }
704
705 std::auto_ptr< cfg1_out > factory::do_create_cfg1_out( std::string const& filename ) const
706 {
707 return std::auto_ptr< itronx::cfg1_out >( new cfg1_out( filename, get_cfg1_def_table() ) );
708 }
709
710 std::auto_ptr< checker > factory::do_create_checker() const
711 {
712 return std::auto_ptr< itronx::checker >( new checker );
713 }
714
715 }
716}
Note: See TracBrowser for help on using the repository browser.