|
|
kernel_object.cpp00001 /* 00002 * TOPPERS/FDMP Kernel 00003 * Toyohashi Open Platform for Embedded Real-Time Systems/ 00004 * Function Distributed Multiprocessor Kernel 00005 * 00006 * Copyright (C) 2005 by Takagi Nobuhisa 00007 * 00008 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 00009 * によって公表されている GNU General Public License の Version 2 に記 00010 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア 00011 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下, 00012 * 利用と呼ぶ)することを無償で許諾する. 00013 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 00014 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー 00015 * スコード中に含まれていること. 00016 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 00017 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 00018 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 00019 * の無保証規定を掲載すること. 00020 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 00021 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ 00022 * と. 00023 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 00024 * 作権表示,この利用条件および下記の無保証規定を掲載すること. 00025 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに 00026 * 報告すること. 00027 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 00028 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 00029 * 00030 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お 00031 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も 00032 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直 00033 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない. 00034 * 00035 */ 00036 00037 /* 00038 * toppers/itron/kernel_object.cpp 00039 */ 00040 #include "toppers/itron/kernel_object.hpp" 00041 #include "toppers/itron/static_api.hpp" 00042 #include "toppers/parser.hpp" 00043 #include <sstream> 00044 #include <set> 00045 #include <iterator> 00046 #include <algorithm> 00047 #include <limits> 00048 00049 namespace toppers 00050 { 00051 namespace itron 00052 { 00053 00059 const std::string& kernel_object::get( const std::string& key ) const 00060 { 00061 arg_type::const_iterator iter( args_.find( key ) ); 00062 if ( iter == args_.end() ) 00063 { 00064 static const std::string dummy; 00065 return dummy; 00066 } 00067 return iter->second; 00068 } 00069 00074 void kernel_object::swap( kernel_object& other ) throw() 00075 { 00076 std::swap( id_, other.id_ ); 00077 name_.swap( other.name_ ); 00078 args_.swap( other.args_ ); 00079 } 00080 00109 bool kernel_object::analyze_parameters( const static_api& api, const std::string& parameters ) 00110 { 00111 std::istringstream istr( parameters ); 00112 std::vector<std::string> params; 00113 typedef std::istream_iterator<std::string> istream_iterator; 00114 std::copy( istream_iterator( istr ), istream_iterator(), std::back_inserter( params ) ); 00115 static_api::const_iterator iter( api.begin() ); 00116 static_api::const_iterator last( api.end() ); 00117 00118 ++iter; // API名をスキップ 00119 00120 typedef std::vector<std::string>::const_iterator params_iterator; 00121 for ( params_iterator i( params.begin() ), t( params.end() ); i != t; ++i, ++iter ) 00122 { 00123 std::string param( *i ); 00124 00125 char ch = param[0]; 00126 switch ( ch ) 00127 { 00128 case '{': 00129 case '}': 00130 if ( iter == last || *iter != param ) 00131 { 00132 static_api::line_type line( api.line() ); 00133 std::string token( ")" ); 00134 if ( iter != last ) 00135 { 00136 token = *iter; 00137 } 00138 error( line.file_.native_file_string(), line.line_, _( "missing `%1%\' before `%2%\'" ) % ch % token ); 00139 return false; 00140 } 00141 break; 00142 case '$': // 自動割付け対応整数パラメータ 00143 case '%': // 自動割付け非対応整数パラメータ 00144 if ( iter == last || !analyze_id( *iter ) ) 00145 { 00146 static_api::line_type line( api.line() ); 00147 std::string token( ")" ); 00148 if ( iter != last ) 00149 { 00150 token = *iter; 00151 } 00152 error( line.file_.native_file_string(), line.line_, _( "illegal argument `%1%'" ) % token ); 00153 return false; 00154 } 00155 set( param, *iter ); 00156 break; 00157 case ':': 00158 set( param, param.substr( 1 ) ); 00159 break; 00160 case '#': // プリプロセッサ定数式パラメータ 00161 default: // 一般定数式パラメータ 00162 if ( iter == last ) 00163 { 00164 static_api::line_type line( api.line() ); 00165 error( line.file_.native_file_string(), line.line_, _( "illegal argument `%1%'" ) % ")" ); 00166 return false; 00167 } 00168 set( param, *iter ); 00169 break; 00170 } 00171 } 00172 return true; 00173 } 00174 00182 void kernel_object::set( const std::string& key, const std::string& value ) 00183 { 00184 args_[key] = value; 00185 } 00186 00191 const kernel_object::inib_ptr kernel_object::do_get_inib() const 00192 { 00193 std::auto_ptr<kernel_cfg::initial_block> ptr( new kernel_cfg::initial_block ); 00194 ptr->id( id_ ); 00195 if ( !name_.empty() ) 00196 { 00197 ptr->set( "name", name_ ); 00198 // 割り込みやCPU例外等、ID番号自動割付を行わないオブジェクトのための仮番号。 00199 // 静的APIで即値が使用されていない場合に、ID番号が負になり、初期化コードが 00200 // 正しく生成されない不具合の対策 00201 if ( id_ < 0 ) 00202 { 00203 ptr->id( std::numeric_limits<long>::max() ); 00204 } 00205 } 00206 else 00207 { 00208 std::ostringstream osstr; 00209 osstr << id_; 00210 ptr->set( "name", osstr.str() ); 00211 } 00212 for ( arg_type::const_iterator iter( args_.begin() ), last( args_.end() ); iter != last; ++iter ) 00213 { 00214 ptr->set( iter->first, iter->second ); 00215 } 00216 return inib_ptr( ptr.release() ); 00217 } 00218 00223 const kernel_object::idb_ptr kernel_object::do_get_idb() const 00224 { 00225 std::auto_ptr<kernel_id::id_number> ptr( new kernel_id::id_number ); 00226 ptr->set( name_, id_ ); 00227 return idb_ptr( ptr.release() ); 00228 } 00229 00238 bool kernel_object::analyze_id( const std::string& arg ) 00239 { 00240 using namespace boost::spirit; 00241 id_ = -1L; 00242 name_.clear(); 00243 if ( parse( arg.begin(), arg.end(), c_int_parser<long>()[ assign_a( id_ ) ] ).full ) 00244 { 00245 if ( !do_check_id_range( id_ ) ) 00246 { 00247 return false; 00248 } 00249 } 00250 else 00251 { 00252 if ( !parse( arg.begin(), arg.end(), c99_ident_p[ assign_a( name_ ) ] ).full ) 00253 { 00254 return false; 00255 } 00256 } 00257 return true; 00258 } 00259 00266 bool kernel_object::assign_id_helper( std::vector<kernel_object*>::const_iterator first, std::vector<kernel_object*>::const_iterator last ) 00267 { 00268 typedef std::vector<kernel_object*> vector_t; 00269 vector_t::size_type size = last - first; 00270 vector_t t( size, static_cast<kernel_object*>( 0 ) ); 00271 std::set<std::string> set; 00272 00273 // 1パス目で決め打ちのID番号を調べる 00274 for ( vector_t::const_iterator iter( first ); iter != last; ++iter ) 00275 { 00276 kernel_object* pobj = *iter; 00277 long id = pobj->id(); 00278 if ( id > 0 ) 00279 { 00280 if ( t[id-1] != 0 ) 00281 { 00282 error( _( "id `%1%\' of %2% is duplicated" ) % id % pobj->get_object_type() ); 00283 return false; 00284 } 00285 t[id-1] = pobj; 00286 } 00287 else 00288 { 00289 std::string id( pobj->name() ); 00290 if ( !set.insert( id ).second ) 00291 { 00292 error( _( "id `%1%\' of %2% is duplicated" ) % id % pobj->get_object_type() ); 00293 } 00294 } 00295 } 00296 // 2パス目で空きID番号を順番に割り付ける 00297 vector_t::size_type pos = 0; 00298 for ( vector_t::const_iterator iter( first ); iter != last; ++iter ) 00299 { 00300 kernel_object* pobj = *iter; 00301 long id = pobj->id(); 00302 if ( id < 0 ) 00303 { 00304 while ( t[pos] != 0 ) 00305 { 00306 ++pos; 00307 } 00308 t[pos] = pobj; 00309 pobj->id_ = pos+1; 00310 } 00311 } 00312 return true; 00313 } 00314 00335 } 00336 } Copyright © 2006 by TAKAGI Nobuhisa. このページは Wed Apr 12 16:31:57 2006 に Doxygen によって生成されました。 |