source: cfg_itronx+oil_gcc/cfg/cfg2.cpp

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

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

File size: 10.5 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 <fstream>
38#include <sstream>
39#include "toppers/diagnostics.hpp"
40#include "toppers/s_record.hpp"
41#include "toppers/macro_processor.hpp"
42#include "toppers/itronx/component.hpp"
43#include "cfg.hpp"
44#include <boost/spirit/include/classic.hpp>
45#include <boost/filesystem/path.hpp>
46#include <boost/filesystem/operations.hpp>
47
48/*!
49 * \brief オブジェクトID番号の割付け
50 * \param[in] api_map ソースに記述された静的APIを登録したコンテナ
51 */
52namespace toppers{ namespace itronx{
53void assign_id( toppers::itronx::cfg1_out::static_api_map& api_map )
54{
55 using namespace toppers;
56 using namespace toppers::itronx;
57
58 std::string id_input_file( get_global< std::string >( "id-input-file" ) );
59 if ( id_input_file.empty() ) // --id-input-file オプションが指定されていない場合...
60 {
61 for ( cfg1_out::static_api_map::iterator iter( api_map.begin() ), last( api_map.end() );
62 iter != last;
63 ++iter )
64 {
65 static_api::assign_id( iter->second.begin(), iter->second.end() );
66 }
67 }
68 else // --id-input-file オプションが指定されている場合...
69 {
70 typedef std::map< std::string, std::pair< long, bool > > id_map_t;
71 id_map_t id_map;
72 std::ifstream ifs( id_input_file.c_str() );
73 while ( ifs )
74 {
75 std::string linebuf;
76 std::getline( ifs, linebuf );
77 if ( ifs.bad() )
78 {
79 fatal( _( "I/O error" ) );
80 }
81 if ( linebuf.empty() || linebuf == "\r" )
82 {
83 break;
84 }
85
86 std::istringstream iss( linebuf );
87 std::string name;
88 iss >> name;
89 if ( iss.fail() )
90 {
91 fatal( _( "id file `%1%\' is invalid" ), id_input_file );
92 }
93
94 long value;
95 iss >> value;
96 if ( iss.fail() )
97 {
98 fatal( _( "id file `%1%\' is invalid" ), id_input_file );
99 }
100
101 if ( id_map.find( name ) != id_map.end() )
102 {
103 fatal( _( "E_OBJ: `%1%\' is duplicated" ), name );
104 }
105 else
106 {
107 id_map[ name ] = std::make_pair( value, false );
108 }
109 }
110
111 for ( cfg1_out::static_api_map::iterator iter( api_map.begin() ), last( api_map.end() );
112 iter != last;
113 ++iter )
114 {
115 for ( std::vector< static_api >::iterator iter2( iter->second.begin() ), last2( iter->second.end() );
116 iter2 != last2;
117 ++iter2 )
118 {
119 static_api::info const* info = iter2->get_info();
120 if ( info->id_pos >= 0 )
121 {
122 std::string name( iter2->at( info->id_pos ).text );
123 std::string symbol( iter2->at( info->id_pos ).symbol );
124 if ( !info->slave && symbol[0] == '#' )
125 {
126 id_map_t::iterator hit( id_map.find( name ) );
127 if ( hit != id_map.end() )
128 {
129 long id_value = hit->second.first;
130 if ( id_value > 0 )
131 {
132 iter2->at( info->id_pos ).value = id_value;
133 hit->second.second = true;
134 }
135 }
136 }
137 }
138 }
139 static_api::assign_id( iter->second.begin(), iter->second.end() );
140 }
141
142 for ( id_map_t::const_iterator iter( id_map.begin() ), last( id_map.end() ); iter != last; ++iter ) // 残り物があれば...
143 {
144 if ( !iter->second.second )
145 {
146 warning( _( "object identifier `%1%\' is not used" ), iter->first );
147 }
148 }
149 }
150
151 // --id-output-file オプションが指定されている場合
152 std::string id_output_file( get_global< std::string >( "id-output-file" ) );
153 if ( !id_output_file.empty() )
154 {
155 std::ofstream ofs( id_output_file.c_str() );
156 for ( cfg1_out::static_api_map::iterator iter( api_map.begin() ), last( api_map.end() );
157 iter != last;
158 ++iter )
159 {
160 for ( std::vector< static_api >::const_iterator iter2( iter->second.begin() ), last2( iter->second.end() );
161 iter2 != last2;
162 ++iter2 )
163 {
164 static_api::info const* info = iter2->get_info();
165 if ( info->id_pos >= 0 )
166 {
167 std::string name( iter2->at( info->id_pos ).text );
168 std::string symbol( iter2->at( info->id_pos ).symbol );
169 if ( !info->slave && symbol[0] == '#' )
170 {
171 ofs << name << '\t' << iter2->at( info->id_pos ).value.get() << std::endl;
172 }
173 }
174 }
175 }
176 }
177}
178}}
179namespace toppers{ namespace oil{
180void assign_id( toppers::oil::cfg1_out::cfg_obj_map& cfg_obj_map )
181{
182}
183}}
184
185using namespace toppers;
186using namespace toppers::itronx;
187using namespace toppers::oil;
188
189static inline bool cfg2_main_tf( std::auto_ptr< macro_processor > mproc )
190{
191 // テンプレート処理
192 boost::any template_file( global( "template-file" ) );
193 namespace fs = boost::filesystem;
194 fs::path cfg_dir( get_global< std::string >( "cfg-directory" ) ); // filesystem3対応
195 std::vector< std::string > include_paths = get_global< std::vector< std::string > >( "include-path" );
196 include_paths.push_back( cfg_dir.empty() ? "." : cfg_dir.string() ); // filesystem3対応
197 if ( !template_file.empty() )
198 {
199 toppers::text in_text;
200 toppers::text pp_text;
201 std::string file_name( boost::any_cast< std::string& >( template_file ) );
202
203 in_text.set_line( file_name, 1 );
204 std::ifstream ifs( file_name.c_str() );
205 if ( !ifs.is_open() )
206 {
207 fatal( _( "`%1%` can not be found." ), file_name );
208 }
209 in_text.append( ifs );
210 macro_processor::preprocess( in_text, pp_text );
211 mproc->evaluate( pp_text );
212 }
213 else // テンプレートファイルが指定されていないので、共通部分(kernel.tf)のみを処理
214 {
215 fs::path kernel_cfg_template_file( cfg_dir/fs::path( "../../kernel/kernel.tf" ) );
216 if ( !fs::exists( kernel_cfg_template_file ) )
217 {
218 error( _( "cannot open file `%1%\'" ), kernel_cfg_template_file.string() ); // filesystem3対応
219 }
220 else
221 {
222 toppers::text in_text;
223 toppers::text pp_text;
224
225 in_text.set_line( kernel_cfg_template_file.string(), 1 ); // filesystem3対応
226 std::ifstream ifs( kernel_cfg_template_file.string().c_str() ); // filesystem3対応
227 in_text.append( ifs );
228 macro_processor::preprocess( in_text, pp_text );
229 mproc->evaluate( pp_text );
230 }
231 }
232
233 if ( get_error_count() > 0 )
234 {
235 return false;
236 }
237 output_file::save();
238 return true;
239}
240
241namespace toppers{ namespace itronx{
242 bool cfg2_main_mproc( itronx::factory factory, std::auto_ptr< itronx::cfg1_out > cfg1_out )
243 {
244 std::auto_ptr< macro_processor > mproc;
245 std::auto_ptr< component > component_ptr;
246
247 if ( get_global< bool >( "with-software-components" ) )
248 {
249 mproc = factory.create_macro_processor( *cfg1_out, cfg1_out->get_static_api_array() );
250 component_ptr.reset( new component( mproc.get() ) );
251 }
252 else // 従来仕様(ソフトウェア部品非対応)
253 {
254 cfg1_out::static_api_map api_map( cfg1_out->merge() );
255 itronx::assign_id( api_map ); // ID番号の割付け
256 mproc = factory.create_macro_processor( *cfg1_out, api_map );
257 }
258 return cfg2_main_tf( mproc );
259 }
260}}
261
262namespace toppers{ namespace oil{
263 bool cfg2_main_mproc( oil::factory factory, std::auto_ptr< oil::cfg1_out > cfg1_out )
264 {
265 std::auto_ptr< macro_processor > mproc;
266 //std::auto_ptr< component > component_ptr;
267
268 if ( get_global< bool >( "with-software-components" ) )
269 {
270 error( _( "with-software-components is not supported." ) );
271 }
272 else // 従来仕様(ソフトウェア部品非対応)
273 {
274 cfg1_out::cfg_obj_map cfg_obj_map( cfg1_out->merge() );
275 oil::assign_id(cfg_obj_map); // ID番号の割付け
276 mproc = factory.create_macro_processor( *cfg1_out, cfg_obj_map );
277 }
278 return cfg2_main_tf( mproc );
279 }
280}}
281
282template < class T, class U, class V, class W >
283static inline bool cfg2_main_init( U factory, V cfg2_info, W* p_func_mproc )
284{
285 global( "factory" ) = &factory;
286
287 // *.cfgとcfg1_out.srecの読み込み
288 std::string input_file;
289 try
290 {
291 input_file = get_global< std::string >( "input-file" );
292 }
293 catch ( boost::bad_any_cast& )
294 {
295 fatal( _( "no input files" ) );
296 }
297 std::string cfg1_out_name( get_global< std::string >( "cfg1_out" ) );
298 std::auto_ptr< T > cfg1_out( factory.create_cfg1_out( cfg1_out_name ) );
299
300 codeset_t codeset = get_global< codeset_t >( "codeset" );
301 cfg1_out->load_cfg( input_file, codeset, cfg2_info );
302 cfg1_out->load_srec();
303
304 return p_func_mproc( factory, cfg1_out );
305}
306
307/*!
308 * \brief パス2処理
309 * \retval true 成功
310 * \retval false 失敗
311 */
312bool cfg2_main()
313{
314 std::string kernel( get_global< std::string >( "kernel" ) );
315 if ( kernel == "atk1" )
316 {
317 oil::factory factory( kernel );
318 return cfg2_main_init< oil::cfg1_out >( factory, factory.get_object_definition_info(), &oil::cfg2_main_mproc );
319 }
320 else
321 {
322 itronx::factory factory( kernel );
323 return cfg2_main_init< itronx::cfg1_out >( factory, *factory.get_static_api_info_map(), &itronx::cfg2_main_mproc );
324 }
325}
Note: See TracBrowser for help on using the repository browser.