|
|
cfg_contents.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/fdmp/cfg_contents.cpp 00039 */ 00040 #include "toppers/itron/fdmp/cfg_contents.hpp" 00041 #include "toppers/itron/fdmp/class_id.hpp" 00042 #include "toppers/itron/static_api.hpp" 00043 #include "toppers/itron/include.hpp" 00044 #include "toppers/parser.hpp" 00045 #include "toppers/text.hpp" 00046 #include "toppers/reporter.hpp" 00047 #include <map> 00048 #include <algorithm> 00049 #include <iterator> 00050 #include <sstream> 00051 #include <boost/filesystem/path.hpp> 00052 #include <boost/filesystem/operations.hpp> 00053 #include <boost/filesystem/fstream.hpp> 00054 #include <boost/filesystem/exception.hpp> 00055 00056 namespace toppers 00057 { 00058 namespace itron 00059 { 00060 namespace fdmp 00061 { 00062 00068 const boost::shared_ptr<std::vector<boost::shared_ptr<itron::cfg_contents> > > cfg_contents::do_classify( bool ucn, codeset_t codeset ) const 00069 { 00070 typedef std::vector<boost::shared_ptr<itron::cfg_contents> > vector_t; 00071 00072 // 現状ではクラス=ローカルクラスとして処理 00073 // 他のクラスについては仕様未定のため、特に対応は行わない。 00074 typedef std::map<std::string, cfg_group::object_container > map_t; 00075 00076 boost::shared_ptr<vector_t> v( new vector_t ); 00077 map_t m; 00078 class_id cls_id; 00079 00080 // 分散定義されたクラスをマージ 00081 // 注) この時点では既にマージされているはずであるが念のため 00082 for ( group_container::const_iterator iter( groups().begin() ), last( groups().end() ); iter != last; ++iter ) 00083 { 00084 boost::shared_ptr<cfg_group> group( *iter ); 00085 std::string class_name( group->name() ); 00086 std::copy( group->objects().begin(), group->objects().end(), std::back_inserter( m[class_name] ) ); 00087 } 00088 00089 // クラス外オブジェクト群の取り出し 00090 map_t::iterator miter( m.find( "" ) ); 00091 cfg_group::object_container globals; 00092 if ( miter != m.end() ) 00093 { 00094 globals = miter->second; 00095 m.erase( miter ); 00096 } 00097 00098 // ID番号の割付け 00099 for ( map_t::iterator iter( m.begin() ), last( m.end() ); iter != last; ++iter ) 00100 { 00101 // クラス外オブジェクトのマージ 00102 std::copy( globals.begin(), globals.end(), std::back_inserter( iter->second ) ); 00103 00104 if ( !kernel_object::assign_id( iter->second.begin(), iter->second.end() ) ) 00105 { 00106 v.reset(); 00107 return v; 00108 } 00109 } 00110 00111 // "class_id.h"の出力 00112 for ( map_t::const_iterator iter( m.begin() ), last( m.end() ); iter != last; ++iter ) 00113 { 00114 group_container groups; 00115 boost::shared_ptr<cfg_group> g( new cfg_group ); 00116 00117 g->objects( iter->second ); 00118 groups.push_back( g ); 00119 boost::shared_ptr<itron::cfg_contents> contents( new cfg_contents( iter->first, ucn, codeset ) ); 00120 contents->groups( groups ); 00121 v->push_back( boost::shared_ptr<itron::cfg_contents>( contents ) ); 00122 00123 std::string class_name( iter->first ); 00124 try 00125 { 00126 boost::filesystem::path dir( class_name, boost::filesystem::native ); 00127 boost::filesystem::create_directory( dir ); 00128 } 00129 catch ( boost::filesystem::filesystem_error& ) 00130 { 00131 toppers::fatal( _( "cannot make directory `%1%\'" ) % class_name ); 00132 } 00133 cls_id.load( contents ); 00134 } 00135 cls_id.save(); 00136 return v; 00137 } 00138 00139 bool cfg_contents::do_parse( text::const_iterator& next, text::const_iterator last, bool ucn, codeset_t codeset ) 00140 { 00141 text::const_iterator iter( next ); 00142 while ( iter != last ) 00143 { 00144 using namespace boost::spirit; 00145 parse_info<text::const_iterator> info; 00146 std::string kernel_class; 00147 std::string class_name; 00148 00149 // クラス外の静的API並びの解析(現時点では"INCLUDE"のみ対応) 00150 boost::shared_ptr<cfg_group> g1( new cfg_group ); 00151 text::const_iterator i( iter ); 00152 static_api api; 00153 if ( api.parse( i, last, ucn, codeset ) ) 00154 { 00155 boost::shared_ptr<kernel_object> obj( include::build( api, g1->objects() ) ); 00156 if ( !!obj ) 00157 { 00158 groups().push_back( g1 ); 00159 iter = i; 00160 } 00161 } 00162 if ( iter == last ) 00163 { 00164 break; 00165 } 00166 00167 // 「 local_class クラス名 { 」部分の解析 00168 info = boost::spirit::parse( iter, last, 00169 lexeme_d[ 00170 c_ident_p[ assign_a( kernel_class ) ] >> space_p >> 00171 c_ident_p[ assign_a( class_name ) ] 00172 ] >> '{', 00173 space_p 00174 ); 00175 if ( !info.hit ) 00176 { 00177 continue; 00178 // error( get_text_line( info.stop ), _( "syntax error" ) ); 00179 // return false; 00180 } 00181 iter = info.stop; 00182 00183 // クラス内の静的API並びの解析 00184 boost::shared_ptr<cfg_group> g2; 00185 bool new_group = true; 00186 for ( group_container::const_iterator iter2( groups().begin() ), last2( groups().end() ); iter2 != last2; ++iter2 ) 00187 { 00188 if ( ( *iter2 )->name() == class_name && ( *iter2 )->group_type() == kernel_class ) 00189 { 00190 g2 = *iter2; 00191 new_group = false; 00192 break; 00193 } 00194 } 00195 if ( new_group ) 00196 { 00197 g2.reset( new cfg_group( class_name, kernel_class ) ); 00198 } 00199 if ( !g2->parse( iter, last, ucn, codeset ) ) 00200 { 00201 return false; 00202 } 00203 00204 // 「 } 」部分の解析 00205 info = boost::spirit::parse( iter, last, ch_p( '}' ), space_p ); 00206 if ( !info.hit ) 00207 { 00208 error( get_text_line( info.stop ), _( "missing `}\'" ) ); 00209 return false; 00210 } 00211 iter = info.stop; 00212 00213 if ( new_group ) 00214 { 00215 groups().push_back( g2 ); 00216 } 00217 } 00218 next = iter; 00219 return true; 00220 } 00221 00222 } 00223 } 00224 } Copyright © 2006 by TAKAGI Nobuhisa. このページは Wed Apr 12 16:31:56 2006 に Doxygen によって生成されました。 |