source: cfg_oil/trunk/toppers/oil/cfg1_out.cpp@ 8

Last change on this file since 8 was 8, checked in by msugi, 13 years ago

ディレクトリ構造の作成,ソース一式とReleaseビルドのコミット.

File size: 13.3 KB
Line 
1/*
2 * TOPPERS Software
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 *
5 * Copyright (C) 2007-2009 by TAKAGI Nobuhisa
6 * Copyright (C) 2010 by Meika Sugimoto
7 *
8 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
9 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
10 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
11 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
12 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
13 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
14 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
15 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
16ƒƒ“ƒgi—˜—p
17 * ŽÒƒ}ƒjƒ…
18ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
19 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
20 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
21 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
22 * ‚ƁD
23 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
24ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
25ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
26 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
27 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
28 * •ñ‚·‚邱‚ƁD
29 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
30 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
31 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
32 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
33 * –Ɛӂ·‚邱‚ƁD
34 *
35 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
36 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
37 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
38 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
39 * ‚̐ӔC‚𕉂í‚È‚¢D
40 *
41 */
42#include <cstdlib>
43#include <cerrno>
44#include <iostream>
45#include <fstream>
46#include <sstream>
47#include <iterator>
48#include <algorithm>
49#include <stack>
50#include "toppers/text.hpp"
51#include "toppers/diagnostics.hpp"
52#include "toppers/c_expr.hpp"
53#include "toppers/global.hpp"
54#include "toppers/macro_processor.hpp"
55#include "toppers/s_record.hpp"
56#include "toppers/nm_symbol.hpp"
57#include "toppers/oil/cfg1_out.hpp"
58#include "toppers/oil/preprocess.hpp"
59#include "toppers/oil/configuration_manager.hpp"
60#include <boost/spirit.hpp>
61#include <boost/filesystem/path.hpp>
62
63using namespace toppers::oil::oil_definition;
64using namespace toppers::configuration_manager;
65
66namespace toppers
67{
68 namespace oil
69 {
70 namespace
71 {
72 struct block_t
73 {
74 std::string type;
75 std::string id;
76 text_line line;
77 };
78 }
79
80 //! cfg_out ƒNƒ‰ƒX‚ÌŽÀ‘•Ú×
81 struct cfg1_out::implementation
82 {
83 protected:
84 output_file ofile_;
85 oil_def *oil_def_array;
86 std::string cfg1_out_list_;
87 std::string includes_;
88 std::vector< block_t > block_table_;
89
90 std::tr1::shared_ptr< s_record > srec_;
91 std::tr1::shared_ptr< nm_symbol > syms_;
92 bool little_endian_;
93 std::size_t base_;
94 cfg1_def_table const* def_table_;
95 config_manage oil_configuration;
96
97 implementation( std::string const& filename, std::ios_base::openmode omode, cfg1_def_table const* def_table = 0 )
98 : ofile_( filename, omode ), little_endian_( true ), base_( 1 ), def_table_( def_table )
99 {
100 }
101 virtual ~implementation()
102 {
103 }
104 virtual void do_load_cfg( std::string const& input_file, codeset_t codeset, std::vector<std::string> const& obj_info );
105 virtual void do_generate_includes() const
106 {
107 }
108 virtual void do_generate_cfg1_def() const
109 {
110 ofile_ << "const uint32_t TOPPERS_cfg_magic_number = 0x12345678;\n"
111 "const uint32_t TOPPERS_cfg_sizeof_signed_t = sizeof(signed_t);\n"
112 "const unsigned_t TOPPERS_cfg_CHAR_BIT = CHAR_BIT;\n"
113 "const unsigned_t TOPPERS_cfg_CHAR_MAX = CHAR_MAX;\n"
114 "const unsigned_t TOPPERS_cfg_CHAR_MIN = CHAR_MIN;\n"
115 "const unsigned_t TOPPERS_cfg_SCHAR_MAX = SCHAR_MAX;\n"
116 "const unsigned_t TOPPERS_cfg_SHRT_MAX = SHRT_MAX;\n"
117 "const unsigned_t TOPPERS_cfg_INT_MAX = INT_MAX;\n"
118 "const unsigned_t TOPPERS_cfg_LONG_MAX = LONG_MAX;\n"
119 "\n";
120 if ( def_table_ != 0 )
121 {
122 for ( cfg1_def_table::const_iterator iter( def_table_->begin() ), last( def_table_->end() );
123 iter != last;
124 ++iter )
125 {
126 // Ž®‚̍ŏ‰‚É # ‚ª‚ ‚ê‚΁A‚»‚ê‚Í‘Oˆ—Ž®
127 bool is_pp = ( iter->expression[ 0 ] == '#' );
128
129 std::string definition = ( iter->is_signed ? "const signed_t " : "const unsigned_t " );
130 definition += "TOPPERS_cfg_" + iter->name;
131 if ( is_pp )
132 {
133 definition +=
134 " = \n"
135 "#if " + iter->expression.substr( 1 ) + "\n"
136 "1;\n"
137 "#else\n"
138 "0;\n"
139 "#endif\n";
140 }
141 else
142 {
143 definition +=
144 " = " + iter->expression + ";\n";
145 }
146 ofile_ << definition;
147 }
148 }
149 }
150 virtual void do_assign_params();
151 virtual implementation* do_clone() const
152 {
153 return new implementation( *this );
154 }
155
156 void preprocess( std::string const& input_file, codeset_t codeset, text& txt );
157
158 friend class cfg1_out;
159 };
160
161
162 /*!
163 * \brief ƒRƒ“ƒXƒgƒ‰ƒNƒ^
164 * \param[in] filename cfg1_out.c ‚Ü‚½‚Í cfg1_out.srec Žá‚µ‚­‚Í‚»‚ê‚ç‚Ì‘ã‘Ö–¼
165 * \param[in] def_table cfg1_out.c ¶¬—p‚Ì’è‹`ƒe[ƒuƒ‹
166 */
167 cfg1_out::cfg1_out( std::string const& filename, cfg1_def_table const* def_table )
168 : pimpl_( new implementation( filename, std::ios_base::out, def_table ) )
169 {
170 }
171
172 /*!
173 * \brief ƒRƒs[ƒRƒ“ƒXƒgƒ‰ƒNƒ^
174 * \param[in] other ƒRƒs[Œ³
175 */
176 cfg1_out::cfg1_out( cfg1_out const& other )
177 : pimpl_( other.pimpl_->do_clone() )
178 {
179 }
180
181 //! ƒfƒXƒgƒ‰ƒNƒ^
182 cfg1_out::~cfg1_out()
183 {
184 delete pimpl_;
185 pimpl_ = 0;
186 }
187
188 /*!
189 * \brief ƒVƒXƒeƒ€ƒRƒ“ƒtƒBƒMƒ…
190ƒŒ[ƒVƒ‡ƒ“ƒtƒ@ƒCƒ‹‚̃[ƒh
191 * \param[in] input_file “ü—̓tƒ@ƒCƒ‹–¼
192 * \param[in] codeset •¶ŽšƒR[ƒh
193 * \param[in] obj_info ƒIƒuƒWƒFƒNƒgî•ñ‚̘A‘z”z—ñ
194 */
195 void cfg1_out::load_cfg( std::string const& input_file, codeset_t codeset,
196 std::vector<std::string> const* obj_info )
197 {
198 return pimpl_->do_load_cfg( input_file, codeset, *obj_info );
199 }
200
201 //! ‘Oˆ—
202 void cfg1_out::implementation::preprocess( std::string const& input_file, codeset_t codeset, text& txt )
203 {
204 boost::any print_depend = global( "print-dependencies" );
205 if ( !print_depend.empty() )
206 {
207 std::set< std::string > depend, onces;
208 oil::preprocess( input_file, txt, codeset, &depend, &onces );
209
210 // ˆË‘¶ŠÖŒW‚̏o—́iGNU make‚É“K‚µ‚½Œ`Ž®j
211 std::string target_file = boost::any_cast< std::string& >( print_depend );
212 std::cout << target_file << ": " << input_file << ' ';
213 std::copy( depend.begin(), depend.end(), std::ostream_iterator< std::string >( std::cout, " " ) );
214 std::cout << std::endl;
215 exit();
216 }
217 else
218 {
219 std::set< std::string > onces;
220 oil::preprocess( input_file, txt, codeset, 0, &onces );
221 }
222 }
223
224 /*!
225 * \brief ƒVƒXƒeƒ€ƒRƒ“ƒtƒBƒMƒ…
226ƒŒ[ƒVƒ‡ƒ“ƒtƒ@ƒCƒ‹‚̃[ƒhˆ—‚ÌŽÀ‘Ì
227 * \param[in] input_file “ü—̓tƒ@ƒCƒ‹–¼
228 * \param[in] codeset •¶ŽšƒR[ƒh
229 * \param[in] obj_info ƒIƒuƒWƒFƒNƒgî•ñ‚̘A‘z”z—ñ
230 */
231 void cfg1_out::implementation::do_load_cfg( std::string const& input_file,
232 codeset_t codeset, std::vector<std::string> const& obj_info )
233 {
234
235 text txt;
236 // ƒVƒXƒeƒ€ƒRƒ“ƒtƒBƒMƒ…
237ƒŒ[ƒVƒ‡ƒ“ƒtƒ@ƒCƒ‹‚̉ðÍ
238 std::ostringstream oss, includes_oss;
239
240 preprocess( input_file, codeset, txt );
241
242 // OILî•ñ‚̓ǂݏo‚µ
243 if(oil_configuration.read_configuration(&txt , obj_info) == true)
244 {
245 oil_def_array = oil_configuration.get_obj_def();
246 oil_configuration.validate_and_assign_default_configuration();
247 }
248
249 // ƒf[ƒ^ƒƒ“ƒo‚Ö‚Ì”½‰f
250 std::string cfg1_list_temp( oss.str() );
251 std::string includes_temp( includes_oss.str() );
252
253 cfg1_out_list_.swap( cfg1_list_temp );
254 includes_.swap( includes_temp );
255 }
256
257 /*!
258 * \brief cfg1_out.c ‚Ì“à—e¶¬
259 * \param[in] type ”z—ñ cfg1_out[] ‚Ì—v‘fŒ^B‹óƒ|ƒCƒ“ƒ^‚̏ꍇ‚Í uint32_t ‚Æ‚µ‚Ĉµ‚í‚ê‚éB
260 */
261 void cfg1_out::generate( char const* type ) const
262 {
263 if ( type == 0 )
264 {
265 type = "uint32_t";
266 }
267 pimpl_->ofile_ << "/* cfg1_out.c */\n"
268 "#define TOPPERS_CFG1_OUT 1\n"
269 "#include \"osek_kernel.h\"\n"
270 "#include \"target_cfg1_out.h\"\n";
271 pimpl_->do_generate_includes();
272 pimpl_->ofile_ << pimpl_->includes_ << '\n';
273
274 // int128_t‚͌̈ӂɖ³Ž‹
275 // int128_t‚É‘µ‚¦‚é‚Əˆ—‚ªd‚­‚È‚è‚·‚¬‚邽‚ß
276 pimpl_->ofile_ << "\n#ifdef INT64_MAX\n"
277 " typedef int64_t signed_t;\n"
278 " typedef uint64_t unsigned_t;\n"
279 "#else\n"
280 " typedef int32_t signed_t;\n"
281 " typedef uint32_t unsigned_t;\n"
282 "#endif\n";
283
284 pimpl_->ofile_ << "\n#include <target_cfg1_out.h>\n\n";
285
286 pimpl_->do_generate_cfg1_def();
287 pimpl_->ofile_ << pimpl_->cfg1_out_list_ << '\n';
288 }
289
290 /*!
291 * \brief #includeŽw—ß‚Ì•À‚Ñ‚ðŽæ“¾‚·‚é
292 * \return #includeŽw—ß‚Ì•À‚Ñ
293 *
294 * ‚±‚̃ƒ“ƒoŠÖ”‚́A
295 * \code
296 * #include <...>
297 * #include "..."
298 * \endcode
299 * ‚Æ‚¢‚Á‚½#includeŽw—ß‚Ì•À‚т𕶎š—ñ‚Æ‚µ‚Ä•Ô‚·B
300 */
301 std::string const& cfg1_out::get_includes() const
302 {
303 return pimpl_->includes_;
304 }
305
306 /*!
307 * \brief SƒŒƒR[ƒh‚̃[ƒh
308 */
309 void cfg1_out::load_srec()
310 {
311 std::ifstream srec_ifs( ( pimpl_->ofile_.file_name() + ".srec" ).c_str() );
312 if ( !srec_ifs.is_open() )
313 {
314 fatal( _( "cannot open file `%1%\'" ), pimpl_->ofile_.file_name() + ".srec" );
315 }
316 pimpl_->srec_ = std::tr1::shared_ptr< s_record >( new s_record( srec_ifs ) );
317
318 std::ifstream syms_ifs( ( pimpl_->ofile_.file_name() + ".syms" ).c_str() );
319 if ( !syms_ifs.is_open() )
320 {
321 fatal( _( "cannot open file `%1%\'" ), pimpl_->ofile_.file_name() + ".syms" );
322 }
323 pimpl_->syms_ = std::tr1::shared_ptr< nm_symbol >( new nm_symbol( syms_ifs ) );
324
325 nm_symbol::entry nm_entry = pimpl_->syms_->find( "TOPPERS_cfg_magic_number" );
326 if ( nm_entry.type < 0 )
327 {
328 fatal( _( "magic number is not found in `%1%\'" ), ( pimpl_->ofile_.file_name() + ".srec/.syms" ) );
329 }
330 unsigned long magic[ 4 ];
331 magic[ 0 ] = ( *pimpl_->srec_ )[ nm_entry.address + 0 ];
332 magic[ 1 ] = ( *pimpl_->srec_ )[ nm_entry.address + 1 ];
333 magic[ 2 ] = ( *pimpl_->srec_ )[ nm_entry.address + 2 ];
334 magic[ 3 ] = ( *pimpl_->srec_ )[ nm_entry.address + 3 ];
335 unsigned long magic_number = ( magic[ 0 ] << 24 ) | ( magic[ 1 ] << 16 ) | ( magic[ 2 ] << 8 ) | magic[ 3 ];
336 if ( magic_number == 0x12345678 )
337 {
338 pimpl_->little_endian_ = false;
339 }
340 else if ( magic_number == 0x78563412 )
341 {
342 pimpl_->little_endian_ = true;
343 }
344 else
345 {
346 fatal( _( "magic number is not found in `%1%\'" ), ( pimpl_->ofile_.file_name() + ".srec/.syms" ) );
347 }
348 pimpl_->do_assign_params();
349 }
350
351 /*!
352 * \brief "cfg1_out.srec" ‚©‚ç“Ç‚ÝŽæ‚Á‚½î•ñ‚ÌŽQÆ
353 */
354 std::tr1::shared_ptr< s_record > cfg1_out::get_srec() const
355 {
356 return pimpl_->srec_;
357 }
358
359 /*!
360 * \brief "cfg1_out.syms" ‚©‚ç“Ç‚ÝŽæ‚Á‚½î•ñ‚ÌŽQÆ
361 */
362 std::tr1::shared_ptr< nm_symbol > cfg1_out::get_syms() const
363 {
364 return pimpl_->syms_;
365 }
366
367 cfg1_out::cfg1_def_table const* cfg1_out::get_def_table() const
368 {
369 return pimpl_->def_table_;
370 }
371
372 /*!
373 * \brief ƒIƒuƒWƒFƒNƒg‚²‚Æ‚ÉOILƒIƒuƒWƒFƒNƒgî•ñ‚ð‚Ü‚Æ‚ß‚é
374 * \return Ã“IAPIî•ñ
375 *
376 * ‚±‚̊֐”‚́A"tsk"‚â"sem"‚Æ‚¢‚Á‚½Ží•Ê‚ðƒL[‚Æ‚µ‚āA‚»‚ÌŽí•Ê‚É•ª—Þ‚³‚ê‚éÃ“IAPIî•ñ‚̘A‘z”z—ñ‚𐶐¬‚·‚éB
377 */
378 cfg1_out::cfg_obj_map cfg1_out::merge() const
379 {
380 cfg_obj_map result;
381
382 result = oil_definition::merge(pimpl_->oil_def_array , result);
383
384 return result;
385
386 }
387
388 /*!
389 * \brief ƒŠƒgƒ‹ƒGƒ“ƒfƒBƒAƒ“‚©‚Ç‚¤‚©‚Ì”»’è
390 * \retval true ƒŠƒgƒ‹ƒGƒ“ƒfƒBƒAƒ“
391 * \retval false ƒrƒbƒOƒGƒ“ƒfƒBƒAƒ“
392 * \attention load_srec ŒÄ‚яo‚µ‘O‚͐³‚µ‚¢Œ‹‰Ê‚𓾂ç‚ê‚È‚¢B
393 */
394 bool cfg1_out::is_little_endian() const
395 {
396 return pimpl_->little_endian_;
397 }
398
399 /*!
400 * \brief Ã“IAPI‚̃pƒ‰ƒ[ƒ^‚ÉSƒŒƒR[ƒh‚©‚çŽæ“¾‚µ‚½’l‚ð‘ã“ü‚·‚é
401 */
402 void cfg1_out::implementation::do_assign_params()
403 {
404 }
405
406 }
407}
Note: See TracBrowser for help on using the repository browser.