kernel_object.cpp

00001 /*
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 によって生成されました。