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