|
|
cmdline.cpp00001 /* 00002 * TOPPERS/FDMP Kernel 00003 * Toyohashi Open Platform for Embedded Real-Time Systems/ 00004 * Function Distributed Multiprocessor Kernel 00005 * 00006 * Copyright (C) 2004 by Witz Corporation, JAPAN 00007 * Copyright (C) 2005 by Takagi Nobuhisa 00008 * 00009 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 00010 * によって公表されている GNU General Public License の Version 2 に記 00011 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア 00012 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下, 00013 * 利用と呼ぶ)することを無償で許諾する. 00014 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 00015 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー 00016 * スコード中に含まれていること. 00017 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 00018 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 00019 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 00020 * の無保証規定を掲載すること. 00021 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 00022 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ 00023 * と. 00024 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 00025 * 作権表示,この利用条件および下記の無保証規定を掲載すること. 00026 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに 00027 * 報告すること. 00028 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 00029 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 00030 * 00031 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お 00032 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も 00033 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直 00034 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない. 00035 * 00036 */ 00037 00038 /* 00039 * toppers/cmdline.cpp 00040 */ 00041 #include "toppers/cmdline.hpp" 00042 #include "toppers/reporter.hpp" 00043 #include <algorithm> 00044 #include <functional> 00045 #include <sstream> 00046 #include <list> 00047 #include <utility> 00048 #include <cctype> 00049 #include <boost/utility.hpp> 00050 00051 namespace toppers 00052 { 00053 00057 cmdline::option_array::option_array() 00058 { 00059 } 00060 00066 bool cmdline::option_array::find( const std::string& key ) const 00067 { 00068 map::const_iterator nil( map_.end() ); 00069 if ( map_.find( key ) == nil ) 00070 { 00071 char ch = *key.rbegin(); 00072 if ( ch == ':' || ch == '=' ) 00073 { 00074 return false; 00075 } 00076 else 00077 { 00078 if ( map_.find( key + ":" ) == nil ) 00079 { 00080 if ( map_.find( key + "=" ) == nil ) 00081 { 00082 return false; 00083 } 00084 } 00085 } 00086 } 00087 return true; 00088 } 00089 00096 bool cmdline::option_array::find( const std::string& key, std::string& arg ) const 00097 { 00098 map::const_iterator nil( map_.end() ); 00099 map::const_iterator iter( map_.find( key ) ); 00100 if ( iter == nil ) 00101 { 00102 char ch = *key.rbegin(); 00103 if ( ch == ':' || ch == '=' ) 00104 { 00105 return false; 00106 } 00107 else 00108 { 00109 iter = map_.find( key + ":" ); 00110 if ( iter == nil ) 00111 { 00112 iter = map_.find( key + ":" ); 00113 if ( iter == nil ) 00114 { 00115 return false; 00116 } 00117 } 00118 } 00119 } 00120 arg = iter->second; 00121 return true; 00122 } 00123 00133 bool cmdline::option_array::find( const std::string& key, std::vector<std::string>& args ) const 00134 { 00135 std::pair<map::const_iterator, map::const_iterator> range( map_.equal_range( key ) ); 00136 std::string opt_key( key ); 00137 if ( range.first == range.second ) 00138 { 00139 char ch = *key.rbegin(); 00140 if ( ch == ':' || ch == '=' ) 00141 { 00142 return false; 00143 } 00144 else 00145 { 00146 opt_key = key + ":"; 00147 range = map_.equal_range( opt_key ); 00148 if ( range.first == range.second ) 00149 { 00150 opt_key = key + "="; 00151 range = map_.equal_range( key ); 00152 if ( range.first == range.second ) 00153 { 00154 return false; 00155 } 00156 } 00157 } 00158 } 00159 00160 std::vector<std::string> t; 00161 for ( map::const_iterator iter( range.first ), last( range.second ); iter != last; ++iter ) 00162 { 00163 if ( iter->first == opt_key ) 00164 { 00165 t.push_back( iter->second ); 00166 } 00167 } 00168 args.swap( t ); 00169 return true; 00170 } 00171 00177 void cmdline::option_array::insert( const std::string& key, const std::string& value ) 00178 { 00179 map_.insert( map::value_type( key, value ) ); 00180 } 00181 00188 bool cmdline::option_array::replace( const std::string& key, const std::string& value ) 00189 { 00190 map::iterator iter( map_.find( key ) ); 00191 if ( iter == map_.end() ) 00192 { 00193 return false; 00194 } 00195 iter->second = value; 00196 return true; 00197 } 00198 00207 void cmdline::option_array::remap_option( const std::string& old_key, const std::string& new_key ) 00208 { 00209 map::iterator iter( map_.find( old_key ) ); 00210 if ( iter != map_.end() ) 00211 { 00212 map::value_type value( new_key, iter->second ); 00213 map_.erase( iter ); 00214 map_.insert( value ); 00215 } 00216 } 00217 00222 void cmdline::option_array::swap( option_array& other ) throw() 00223 { 00224 map_.swap( other.map_ ); 00225 set_.swap( other.set_ ); 00226 } 00227 00228 cmdline::option_array::option_array( const map& options, const set& optset ) 00229 : map_( options ), set_( optset ) 00230 { 00231 } 00232 00233 00239 cmdline::cmdline( int argc, char* argv[] ) : argc_( argc ), argv_( argv ) 00240 { 00241 } 00242 00261 std::auto_ptr<std::vector<std::string> > cmdline::parse( const std::string& pattern, option_array& options ) const 00262 { 00263 std::stringstream sstr( pattern ); 00264 option_array::map optmap; 00265 option_array::set optset; 00266 std::list<const char*> args( argv_+1, argv_+argc_ ); 00267 00268 // `options'文字列内の重複要素をまとめる 00269 std::string name; 00270 while ( sstr >> name ) 00271 { 00272 if ( name[0] == '-' ) // '-'で始まるもの以外はオプションとして認めない 00273 { 00274 optset.insert( name ); 00275 } 00276 } 00277 00278 const std::set<std::string>::const_iterator last( optset.end() ); 00279 for ( std::set<std::string>::const_iterator iter( optset.begin() ); iter != last; ++iter ) 00280 { 00281 std::string name( *iter ); 00282 bool has_arg = false; 00283 char back = *name.rbegin(); 00284 if ( back == ':' ) // ':'で終わるオプションは'='なしの引数を取る 00285 { 00286 has_arg = true; 00287 name.erase( name.size()-1 ); // ':'を除去 00288 } 00289 else if ( back == '=' ) // '='で終わるオプションは'='付きの引数を取る 00290 { 00291 has_arg = true; 00292 } 00293 std::list<const char*>::iterator iter2( args.begin() ); 00294 while ( iter2 != args.end() ) 00295 { 00296 const char* argv = *iter2; 00297 if ( ( back == '=' && strncmp( argv, name.c_str(), name.size() ) == 0 ) 00298 || ( back != '=' && strcmp( argv, name.c_str() ) == 0 ) ) 00299 { 00300 typedef option_array::map::value_type option; 00301 if ( has_arg ) // 引数付きオプション 00302 { 00303 if ( argv[name.size()] != '\0' ) 00304 { 00305 argv = argv+name.size(); 00306 } 00307 else 00308 { 00309 std::list<const char*>::iterator next( boost::next( iter2 ) ); 00310 if ( next != args.end() ) 00311 { 00312 argv = *next; 00313 } 00314 else 00315 { 00316 // このエラーメッセージは翻訳されそうにないが、とりあえず放置する 00317 rout.error( _( "argument to `%1%\' is missing" ) % name ); 00318 } 00319 args.erase( next ); 00320 } 00321 while ( std::isspace( *argv ) ) // 念のため、空白類文字を取り除く 00322 ; 00323 if ( back == ':' ) 00324 { 00325 name += ':'; 00326 } 00327 option opt( name, std::string( argv ) ); 00328 optmap.insert( opt ); 00329 } 00330 else // 引数なしオプション 00331 { 00332 option opt( name, "" ); 00333 optmap.insert( opt ); 00334 } 00335 std::list<const char*>::iterator next = boost::next( iter2 ); 00336 args.erase( iter2 ); 00337 iter2 = next; 00338 } 00339 else // nameが示すオプション以外 00340 { 00341 ++iter2; 00342 } 00343 } 00344 } 00345 00346 // 例外安全のため std::auto_ptr を用いて、ここで返却値を組み立てる 00347 std::auto_ptr<std::vector<std::string> > result( new std::vector<std::string>( args.begin(), args.end() ) ); 00348 00349 option_array t( optmap, optset ); 00350 options.swap( t ); 00351 00352 return result; 00353 } 00354 00362 std::vector<std::string>::const_iterator cmdline::find_illegal_options( std::vector<std::string>::const_iterator first, std::vector<std::string>::const_iterator last ) 00363 { 00364 for ( std::vector<std::string>::const_iterator iter( first ); iter != last; ++iter ) 00365 { 00366 if ( iter->at( 0 ) == '-' ) 00367 { 00368 rout.error( _( "illegal option `%1%\'" ) % *iter ); 00369 return iter; 00370 } 00371 } 00372 return last; 00373 } 00374 00375 } Copyright © 2006 by TAKAGI Nobuhisa. このページは Wed Apr 12 16:31:55 2006 に Doxygen によって生成されました。 |