|
MoochoPack: Miscellaneous Utilities for MOOCHO Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization 00005 // Copyright (2003) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #include <string> 00030 #include <ostream> 00031 #include <istream> 00032 00033 #include "OptionsFromStreamPack_OptionsFromStream.hpp" 00034 #include "InputStreamHelperPack_EatInputComment.hpp" 00035 #include "Teuchos_TestForException.hpp" 00036 00037 // Define this if you want to debug the parser 00038 //#define PRINT_OPTIONS_FROM_STREAM_TRACE 00039 00040 namespace { 00041 00042 // Remove white space from beginning and end. 00043 inline 00044 void clip_ws( std::string* str ) { 00045 // Remove the first non ' ' characters 00046 { 00047 std::string::iterator itr; 00048 for( itr = str->begin(); itr != str->end(); ++itr ) 00049 if( *itr != ' ' ) break; 00050 str->erase( str->begin(), itr ); 00051 } 00052 // Remove the last non ' ' characters 00053 { 00054 std::string::iterator itr; 00055 for( itr = str->end() - 1; itr > str->begin() - 1; --itr ) 00056 if( *itr != ' ' ) break; 00057 str->erase( itr + 1, str->end() ); 00058 } 00059 } 00060 00061 } // end namespace 00062 00063 namespace OptionsFromStreamPack { 00064 00065 namespace OptionsFromStreamUtilityPack { 00066 00067 // class OptionsGroup 00068 00069 std::string OptionsGroup::option_does_not_exist_; 00070 00071 } // end namespace OptionsFromStreamUtilityPack 00072 00073 // class OptionsFromStream 00074 00075 OptionsFromStream::options_group_t 00076 OptionsFromStream::options_group( const std::string& options_group_name ) 00077 { 00078 options_group_map_t::iterator itr = options_group_map_.find( options_group_name ); 00079 if( itr != options_group_map_.end() ) { 00080 (*itr).second.second.set(true); // flag that we have accessed this options group 00081 return options_group_t(&(*itr).second.first); 00082 } 00083 return options_group_t(NULL); 00084 } 00085 00086 const OptionsFromStream::options_group_t 00087 OptionsFromStream::options_group( const std::string& options_group_name ) const 00088 { 00089 options_group_map_t::const_iterator itr = options_group_map_.find( options_group_name ); 00090 if( itr != options_group_map_.end() ) { 00091 const_cast<false_bool_t&>((*itr).second.second).set(true); // flag that we have accessed this options group 00092 return options_group_t(const_cast<option_to_value_map_t*>(&(*itr).second.first)); 00093 } 00094 return options_group_t(NULL); 00095 } 00096 00097 void OptionsFromStream::reset_unaccessed_options_groups() 00098 { 00099 for( iterator og_itr = begin() ; og_itr != end(); ++og_itr ) { 00100 (*og_itr).second.second.set(false); // rest to not accessed yet. 00101 } 00102 } 00103 00104 void OptionsFromStream::print_unaccessed_options_groups( std::ostream& out ) const 00105 { 00106 const_iterator og_itr = begin(); 00107 for( ; og_itr != end(); ++og_itr ) { 00108 if( (*og_itr).second.second == false ) // if options group was not accessed 00109 out << "options_group " << options_group_name( og_itr ) << " {}\n"; 00110 } 00111 } 00112 00113 void OptionsFromStream::read_options( std::istream& in ) 00114 { 00115 using std::getline; 00116 00117 using InputStreamHelperPack::eat_comment_lines; 00118 00119 std::string curr_word; 00120 00121 if(!in) 00122 return; // No options to read! 00123 00124 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00125 std::cout << "\n*** Entering OptionsFromStream::read_options(...)!\n\n"; 00126 #endif 00127 00128 // Eat words until you get to begin_options. 00129 while( curr_word != "begin_options" && !in.eof() ) 00130 in >> curr_word; 00131 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00132 std::cout << "Found begin_options, start parsing options!\n"; 00133 #endif 00134 // Loop through each options group. 00135 while( !in.eof() ) { 00136 eat_comment_lines(in,'*'); 00137 // read options_group 00138 in >> curr_word; 00139 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00140 std::cout << "\ncurr_word = \""<<curr_word<<"\"\n"; 00141 #endif 00142 if( curr_word == "}" ) { 00143 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00144 std::cout << "Found \'}\', Moving on to the next options group or the end!\n"; 00145 #endif 00146 break; 00147 } 00148 if( curr_word == "end_options" ) { 00149 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00150 std::cout << "Found \'end_options\', stoping parsing options!\n"; 00151 #endif 00152 break; 00153 } 00154 TEST_FOR_EXCEPTION( 00155 curr_word != "options_group", InputStreamError 00156 ,"OptionsFromStream::read_options(...) : " 00157 "Error, curr_word = \'" << curr_word << " != \'options_group\'" ); 00158 // read the name of the options group up to { 00159 std::getline(in,curr_word,'{'); 00160 clip_ws( &curr_word ); 00161 const std::string optgroup_name = curr_word; 00162 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00163 std::cout << "\noptgroup_name = \"" << optgroup_name << "\"\n"; 00164 #endif 00165 // Access the options and values map for this options group. 00166 option_to_value_map_t& optval = options_group_map_[optgroup_name].first; 00167 // Grap all of the options for this options group 00168 eat_comment_lines(in,'*'); 00169 std::string optgroup_options; 00170 getline(in,optgroup_options,'}'); 00171 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00172 std::cout << "optgroup_options = \"" << optgroup_options << "\"\n"; 00173 #endif 00174 std::istringstream optgroup_options_in(optgroup_options); 00175 // Loop through and add the options. 00176 while(true) { 00177 eat_comment_lines(optgroup_options_in,'*'); 00178 // Get an option and its value 00179 std::string option_and_value; 00180 getline(optgroup_options_in,option_and_value,';'); 00181 // Note: above If ';' is missing it will take the rest of the string to 00182 // the end of '}' for the end of the options group. These means that if 00183 // there is no comments after the last option=value pair then the last 00184 // semicolon is optional! This turns out to work nicely for the 00185 // CommandLineOptionsFromStreamProcessor class so this is good behavior! 00186 clip_ws(&option_and_value); 00187 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00188 std::cout << " option_and_value = \"" << option_and_value << "\"\n"; 00189 #endif 00190 if(!option_and_value.length()) 00191 break; 00192 // Process the option and value 00193 const std::string::size_type equal_idx = option_and_value.find('=',0); 00194 TEST_FOR_EXCEPTION( 00195 equal_idx==std::string::npos, std::logic_error, 00196 "Error, for the option group \"" << optgroup_name << "\"" 00197 << " the option value string \"" << option_and_value << "\" is missing the \"=\" separator!" 00198 ); 00199 std::string option = option_and_value.substr(0,equal_idx); 00200 std::string value = option_and_value.substr(equal_idx+1); 00201 clip_ws(&option); 00202 clip_ws(&value); 00203 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00204 std::cout << " option = \"" << option << "\"\n"; 00205 std::cout << " value = \"" << value << "\"\n"; 00206 #endif 00207 optval[option] = value; 00208 } 00209 } 00210 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00211 std::cout << "\n*** Leaving OptionsFromStream::read_options(...)!\n\n"; 00212 #endif 00213 } 00214 00215 void OptionsFromStream::print_options( std::ostream& out ) const { 00216 out << "\nbegin_options\n"; 00217 const_iterator og_itr = begin(); 00218 for( ; og_itr != end(); ++og_itr ) { 00219 const options_group_t optgrp = OptionsFromStreamPack::options_group( og_itr ); 00220 options_group_t::const_iterator itr = optgrp.begin(); 00221 if(itr == optgrp.end()) continue; 00222 out << "\noptions_group " << options_group_name( og_itr ) << " {\n"; 00223 for( ; itr != optgrp.end(); ++itr ) { 00224 const std::string 00225 &name = option_name(itr), 00226 &value = option_value(itr); 00227 out << " " << name << " = " << value << ";\n"; 00228 } 00229 out << "}\n"; 00230 } 00231 out << "\nend_options\n\n"; 00232 } 00233 00234 } // end namespace OptionsFromStreamPack
1.7.4