cfg.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  *  cfg.cpp
00039  */
00040 #include "cfg.hpp"
00041 #include <iostream>
00042 #include <fstream>
00043 #include <cstdlib>
00044 #include <cstdio>
00045 #include <cstring>
00046 #include <algorithm>
00047 #include <iterator>
00048 
00049 namespace
00050 {
00051 
00055   void help_message()
00056   {
00057     static const char message[] =
00058       "Usage: cfg [options] file\n"
00059       "Options:\n"
00060       "  -h   --help              Display this information\n"
00061       "  -lj  --japanese          Use Japanese\n"
00062       "  -le  --english           Use English\n"
00063       "  -cfg --kernel_cfg=<file> Specify the <file> instead of `kernel_cfg.c\'\n"
00064       "  -id  --kernel_id=<file>  Specify the <file> instead of `kernel_id.h\'\n"
00065       "  -ucn                     Enable universal character name in CFG file\n"
00066       "  -sjis                    Enable Shift-JIS in CFG file\n"
00067       "  -n <directory>           Specify the <directory> where output files\n"
00068       "  -kernel <type>           Specify the kernel type, <type> which is JSP or FDMP\n";
00069     
00070     std::cerr << _( message ) << std::endl;
00071   }
00072 
00081   void select_language( const toppers::cmdline::option_array& options )
00082   {
00083     if ( options.find( "-lj" ) )
00084     {
00085       set_language( toppers::reporter::Japanese );
00086     }
00087   }
00088 
00097   std::auto_ptr<std::string> parse_cmdline( int argc, char* argv[], toppers::cmdline::option_array& opts )
00098   {
00099     using namespace toppers;
00100     using namespace toppers::itron;
00101 
00102     cmdline cmdl( argc, argv );
00103     cmdline::option_array options;
00104     const char pattern[] = "-h --help "
00105                            "-lj --japanese "
00106                            "-le --english "
00107                            "-cfg: --kernel_cfg= "
00108                            "-id: --kernel_id= "
00109                            "-cpu: "
00110                            "-system: "
00111                            "-tool: "
00112                            "-obj "
00113                            "-ucn "
00114                            "-sjis "
00115                            "-n: "
00116                            "-kernel: "
00117                            "-s: --source= "
00118                            "-iapi --ignore-api "
00119                            "-t --through "
00120                            "-obj: --dump-object= "
00121                            "-ao: --assign-order= "
00122                            "-var --variable-id "
00123                            "-il --include-libstyle "
00124                            "-oproto --output-prototype "
00125                            "-z -nonzero "
00126                            "-c --check "
00127                            "-x: "
00128                            "-debug";
00129     const std::auto_ptr<std::vector<std::string> > sources( cmdl.parse( pattern, options ) );
00130 
00131     options.remap_option( "--help", "-h" );
00132     options.remap_option( "--japanese", "-lj" );
00133     options.remap_option( "--english", "-le" );
00134     options.remap_option( "--kernel_cfg=", "-cfg:" );
00135     options.remap_option( "--kernel_id=", "-id:" );
00136     options.remap_option( "--source=", "-s:" );
00137     options.remap_option( "--ignore-api", "-iapi" );
00138     options.remap_option( "--through", "-t" );
00139     options.remap_option( "--dump-object=", "-obj:" );
00140     options.remap_option( "--assign-order=", "-ao:" );
00141     options.remap_option( "--variable-id", "-var" );
00142     options.remap_option( "--include-libstyle", "-il" );
00143     options.remap_option( "--output-prototype", "-oproto" );
00144     options.remap_option( "--nonzero", "-z" );
00145     options.remap_option( "--check", "-c" );
00146 
00147     select_language( options );
00148 
00149     if ( options.find( "-h" ) )
00150     {
00151       help_message();
00152       toppers::reporter::terminator x;
00153       throw x;
00154     }
00155 
00156     std::vector<std::string> t;
00157     if ( options.find( "-s", t ) )
00158     {
00159       std::copy( t.begin(), t.end(), std::back_inserter( *sources ) );
00160     }
00161 
00162     if ( !sources->empty() )
00163     {
00164       std::vector<std::string>::const_iterator iter( cmdline::find_illegal_options( sources->begin(), sources->end() ) );
00165       if ( iter == sources->end() )
00166       {
00167         if ( sources->size() > 1 )
00168         {
00169           stop( _( "too many input files" ) );  // 入力ファイルが複数
00170         }
00171       }
00172       else
00173       {
00174         toppers::error( _( "illegal option `%1%\'" ) % *iter ); // 不正なオプションが混在
00175       }
00176     }
00177 
00178     std::auto_ptr<std::string> source;
00179     if ( !sources->empty() )
00180     {
00181       source.reset( new std::string( sources->front() ) );
00182     }
00183     opts.swap( options );
00184     return source;
00185   }
00186 
00192   void analyze_pragmas( const std::vector<toppers::line_buf>& pragmas, toppers::cmdline::option_array& options )
00193   {
00194     typedef std::vector<toppers::line_buf>::const_iterator const_iterator;
00195     for ( const_iterator iter( pragmas.begin() ), last( pragmas.end() ); iter != last; ++iter )
00196     {
00197       using namespace boost::spirit;
00198       std::string kernel_type;
00199       if ( parse( iter->buf_.begin(), iter->buf_.end(),
00200                   str_p( "kernel" ) >> '(' >> '\"' >> ( *( c_escape_ch_p - '\"' ) )[ assign_a( kernel_type ) ] >> '\"' >> ')',
00201                   space_p ).full )
00202       {
00203         if ( !options.replace( "-kernel", kernel_type ) )
00204         {
00205           options.insert( "-kernel", kernel_type );
00206         }
00207         break;
00208       }
00209       else
00210       {
00211         toppers::warning( _( "unknown #pragma directive `%1%\'" ) % iter->buf_ );
00212       }
00213     }
00214   }
00215 
00221   void generate_files( const boost::shared_ptr<toppers::itron::cfg_factory>& factory, const boost::shared_ptr<toppers::itron::cfg_contents>& contents )
00222   {
00223     typedef std::vector<boost::shared_ptr<toppers::itron::cfg_contents> > vector_t;
00224     boost::shared_ptr<vector_t> sub_contents_list( contents->classify() );
00225 
00226     if ( sub_contents_list->empty() )
00227     {
00228       toppers::error( _( "no contents in cfg file" ) );
00229     }
00230 
00231     for ( vector_t::const_iterator iter( sub_contents_list->begin() ), last( sub_contents_list->end() ); iter != last; ++iter )
00232     {
00233       factory->set_contents( *iter );
00234 
00235       boost::shared_ptr<toppers::kernel_cfg> k_cfg( factory->create_kernel_cfg() );
00236       static_cast<toppers::itron::cfg_kernel_cfg*>( k_cfg.get() )->load( *iter );
00237       k_cfg->save();
00238 
00239       try
00240       {
00241         boost::shared_ptr<toppers::kernel_id> k_id( factory->create_kernel_id() );
00242         static_cast<toppers::itron::cfg_kernel_id*>( k_id.get() )->load( *iter );
00243         k_id->save();
00244 
00245         if ( factory->options()->find( "-c" ) )
00246         {
00247           try
00248           {
00249             boost::shared_ptr<toppers::itron::kernel_chk> k_chk( factory->create_kernel_chk() );
00250             k_chk->load( *iter );
00251             k_chk->save();
00252           }
00253           catch ( ... )
00254           {
00255             std::remove( k_id->file().c_str() );
00256             throw;
00257           }
00258         }
00259       }
00260       catch ( ... )
00261       {
00262         std::remove( k_cfg->file().c_str() );
00263         throw;
00264       }
00265     }
00266   }
00267 
00273   int cfg_main( int argc, char** argv )
00274   {
00275     using namespace toppers;
00276     using namespace toppers::itron;
00277     using namespace boost::spirit;
00278 
00279     // コマンドライン引数の解析
00280     cmdline::option_array options;
00281     std::auto_ptr<std::string> source( parse_cmdline( argc, argv, options ) );
00282 
00283     // 前処理
00284     std::istream* istr = &std::cin;
00285     std::ifstream ifstr;
00286     text txt;
00287     c_pp_line<text::container> pp;
00288 
00289     if ( source.get() != 0 )
00290     {
00291       ifstr.open( source->c_str() );
00292       if ( !ifstr.is_open() )
00293       {
00294         error( _( "cannot open file `%1%\'" ) % *source );
00295       }
00296       istr = &ifstr;
00297       std::string t( "#line 1 \"" + *source + "\"\n" );
00298       txt.assign( t.begin(), t.end(), pp );
00299     }
00300     txt.append( *istr, pp );
00301     analyze_pragmas( pp.pragmas(), options );
00302 
00303     std::string lang;
00304     if ( options.find( "-x", lang ) && lang == "c++" )
00305     {
00306       if ( !options.find( "-cfg" ) )
00307       {
00308         options.insert( "-cfg", "kernel_cfg.cpp" );
00309       }
00310     }
00311 
00312     // ファクトリを生成
00313     std::string kernel_type( "JSP" );
00314     options.find( "-kernel", kernel_type );
00315     boost::shared_ptr<cfg_factory> factory( cfg_factory::build( options, kernel_type ) );
00316     if ( !factory )
00317     {
00318       toppers::error( _( "kerne type `%1%\' is not supported" ) % kernel_type );
00319     }
00320     cfg_factory::global( factory );
00321 
00322     // 構文解析
00323     codeset_t codeset = euc_jp;
00324     if ( options.find( "-sjis" ) )
00325     {
00326       codeset = shift_jis;
00327     }
00328     bool ucn = false;
00329     if ( options.find( "-ucn" ) )
00330     {
00331       ucn = true;
00332     }
00333     text::const_iterator next( txt.begin() );
00334     boost::shared_ptr<cfg_contents> contents( factory->create_cfg_contents( next, txt.end(), ucn, codeset ) );
00335     if ( !contents )
00336     {
00337       return EXIT_FAILURE;
00338     }
00339 
00340     // ファイルの生成
00341     generate_files( factory, contents );
00342 
00343     return EXIT_SUCCESS;
00344   }
00345 
00346 }
00347 
00348 int main( int argc, char** argv )
00349 {
00350   int status;
00351   try
00352   {
00353     cfg_init();
00354     status = cfg_main( argc, argv );
00355     if ( status != EXIT_SUCCESS )
00356     {
00357       toppers::error( _( "unknown error" ) );
00358     }
00359   }
00360   catch ( toppers::reporter::terminator& )
00361   {
00362     status = EXIT_FAILURE;
00363   }
00364   catch ( std::exception& e )
00365   {
00366     std::fputs( e.what(), stderr );
00367     std::fputc( '\n', stderr );
00368     status = EXIT_FAILURE;
00369   }
00370   catch ( ... )
00371   {
00372     toppers::stop( _( "internal error" ) );
00373     status = EXIT_FAILURE;
00374   }
00375   return status;
00376 }
00377 

Copyright © 2006 by TAKAGI Nobuhisa.
このページは Wed Apr 12 16:31:55 2006 に Doxygen によって生成されました。