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