3 * Toyohashi Open Platform for Embedded Real-Time Systems
5 * Copyright (C) 2007-2011 by TAKAGI Nobuhisa
7 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
17 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
20 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
22 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
24 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
30 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
39 #include "toppers/diagnostics.hpp"
40 #include "toppers/s_record.hpp"
41 #include "toppers/macro_processor.hpp"
42 #include "toppers/itronx/component.hpp"
44 #include <boost/spirit/include/classic.hpp>
45 #include <boost/filesystem/path.hpp>
46 #include <boost/filesystem/operations.hpp>
49 * \brief オブジェクトID番号の割付け
50 * \param[in] api_map ソースに記述された静的APIを登録したコンテナ
52 void assign_id( toppers::itronx::cfg1_out::static_api_map& api_map )
54 using namespace toppers;
55 using namespace toppers::itronx;
57 std::string id_input_file( get_global< std::string >( "id-input-file" ) );
58 if ( id_input_file.empty() ) // --id-input-file オプションが指定されていない場合...
60 for ( cfg1_out::static_api_map::iterator iter( api_map.begin() ), last( api_map.end() );
64 static_api::assign_id( iter->second.begin(), iter->second.end() );
67 else // --id-input-file オプションが指定されている場合...
69 typedef std::map< std::string, std::pair< long, bool > > id_map_t;
71 std::ifstream ifs( id_input_file.c_str() );
75 std::getline( ifs, linebuf );
78 fatal( _( "I/O error" ) );
80 if ( linebuf.empty() || linebuf == "\r" )
85 std::istringstream iss( linebuf );
90 fatal( _( "id file `%1%\' is invalid" ), id_input_file );
97 fatal( _( "id file `%1%\' is invalid" ), id_input_file );
100 if ( id_map.find( name ) != id_map.end() )
102 fatal( _( "E_OBJ: `%1%\' is duplicated" ), name );
106 id_map[ name ] = std::make_pair( value, false );
110 for ( cfg1_out::static_api_map::iterator iter( api_map.begin() ), last( api_map.end() );
114 for ( std::vector< static_api >::iterator iter2( iter->second.begin() ), last2( iter->second.end() );
118 static_api::info const* info = iter2->get_info();
119 if ( info->id_pos >= 0 )
121 std::string name( iter2->at( info->id_pos ).text );
122 std::string symbol( iter2->at( info->id_pos ).symbol );
123 if ( !info->slave && symbol[0] == '#' )
125 id_map_t::iterator hit( id_map.find( name ) );
126 if ( hit != id_map.end() )
128 long id_value = hit->second.first;
131 iter2->at( info->id_pos ).value = id_value;
132 hit->second.second = true;
138 static_api::assign_id( iter->second.begin(), iter->second.end() );
141 for ( id_map_t::const_iterator iter( id_map.begin() ), last( id_map.end() ); iter != last; ++iter ) // 残り物があれば...
143 if ( !iter->second.second )
145 warning( _( "object identifier `%1%\' is not used" ), iter->first );
150 // --id-output-file オプションが指定されている場合
151 std::string id_output_file( get_global< std::string >( "id-output-file" ) );
152 if ( !id_output_file.empty() )
154 std::ofstream ofs( id_output_file.c_str() );
155 for ( cfg1_out::static_api_map::iterator iter( api_map.begin() ), last( api_map.end() );
159 for ( std::vector< static_api >::const_iterator iter2( iter->second.begin() ), last2( iter->second.end() );
163 static_api::info const* info = iter2->get_info();
164 if ( info->id_pos >= 0 )
166 std::string name( iter2->at( info->id_pos ).text );
167 std::string symbol( iter2->at( info->id_pos ).symbol );
168 if ( !info->slave && symbol[0] == '#' )
170 ofs << name << '\t' << iter2->at( info->id_pos ).value.get() << std::endl;
180 * \brief マクロプロセッサに登録するID割付け関数
181 * \param[in] line 行番号
182 * \param[in] arg_list マクロ実引数リスト
183 * \param[in] p_ctx マクロコンテキスト
186 toppers::macro_processor::var_t bf_assignid( toppers::text_line const& line,
187 std::vector< toppers::macro_processor::var_t > const& arg_list,
188 toppers::macro_processor::context* p_ctx )
190 using namespace toppers;
191 using namespace toppers::itronx;
192 using toppers::text_line;
193 typedef toppers::macro_processor::element element;
194 typedef toppers::macro_processor::var_t var_t;
195 typedef toppers::macro_processor::context context;
200 //! 組み込み関数ASSIGNIDを登録する
201 void register_bf_assignid( toppers::macro_processor* mproc )
204 toppers::macro_processor::func_t func_info = {};
205 func_info.name = "ASSIGNID";
206 func_info.f = &bf_assignid;
207 mproc->add_builtin_function( func_info );
217 using namespace toppers;
218 using namespace toppers::itronx;
220 std::string kernel( get_global< std::string >( "kernel" ) );
221 itronx::factory factory( kernel );
222 global( "factory" ) = &factory;
224 // *.cfgとcfg1_out.srecの読み込み
225 std::string input_file;
228 input_file = get_global< std::string >( "input-file" );
230 catch ( boost::bad_any_cast& )
232 fatal( _( "no input files" ) );
234 std::string cfg1_out_name( get_global< std::string >( "cfg1_out" ) );
235 std::auto_ptr< cfg1_out > cfg1_out( factory.create_cfg1_out( cfg1_out_name ) );
237 codeset_t codeset = get_global< codeset_t >( "codeset" );
238 cfg1_out->load_cfg( input_file, codeset, *factory.get_static_api_info_map() );
239 cfg1_out->load_srec();
241 std::auto_ptr< macro_processor > mproc;
242 std::auto_ptr< component > component_ptr;
244 if ( get_global< bool >( "with-software-components" ) )
246 mproc = factory.create_macro_processor( *cfg1_out, cfg1_out->get_static_api_array() );
247 component_ptr.reset( new component( mproc.get() ) );
249 else // 従来仕様(ソフトウェア部品非対応)
251 cfg1_out::static_api_map api_map( cfg1_out->merge() );
252 assign_id( api_map ); // ID番号の割付け
253 mproc = factory.create_macro_processor( *cfg1_out, api_map );
257 boost::any template_file( global( "template-file" ) );
258 namespace fs = boost::filesystem;
259 // fs::path cfg_dir( get_global< std::string >( "cfg-directory" ), fs::native );
260 fs::path cfg_dir( get_global< std::string >( "cfg-directory" ) ); // filesystem3対応
261 std::vector< std::string > include_paths = get_global< std::vector< std::string > >( "include-path" );
262 // include_paths.push_back( cfg_dir.empty() ? "." : cfg_dir.native_file_string() );
263 include_paths.push_back( cfg_dir.empty() ? "." : cfg_dir.string() ); // filesystem3対応
264 if ( !template_file.empty() )
266 toppers::text in_text;
267 toppers::text pp_text;
268 std::string file_name( boost::any_cast< std::string& >( template_file ) );
270 in_text.set_line( file_name, 1 );
271 std::ifstream ifs( file_name.c_str() );
272 in_text.append( ifs );
273 macro_processor::preprocess( in_text, pp_text );
274 mproc->evaluate( pp_text );
276 else // テンプレートファイルが指定されていないので、共通部分(kernel.tf)のみを処理
278 fs::path kernel_cfg_template_file( cfg_dir/fs::path( "../../kernel/kernel.tf" ) );
279 if ( !fs::exists( kernel_cfg_template_file ) )
281 // error( _( "cannot open file `%1%\'" ), kernel_cfg_template_file.native_file_string() );
282 error( _( "cannot open file `%1%\'" ), kernel_cfg_template_file.string() ); // filesystem3対応
286 toppers::text in_text;
287 toppers::text pp_text;
289 // in_text.set_line( kernel_cfg_template_file.native_file_string(), 1 );
290 in_text.set_line( kernel_cfg_template_file.string(), 1 ); // filesystem3対応
291 // std::ifstream ifs( kernel_cfg_template_file.native_file_string().c_str() );
292 std::ifstream ifs( kernel_cfg_template_file.string().c_str() ); // filesystem3対応
293 in_text.append( ifs );
294 macro_processor::preprocess( in_text, pp_text );
295 mproc->evaluate( pp_text );
299 if ( get_error_count() > 0 )