|
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 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #include <string> 00043 #include <ostream> 00044 #include <istream> 00045 00046 #include "OptionsFromStreamPack_OptionsFromStream.hpp" 00047 #include "InputStreamHelperPack_EatInputComment.hpp" 00048 #include "Teuchos_Assert.hpp" 00049 00050 // Define this if you want to debug the parser 00051 //#define PRINT_OPTIONS_FROM_STREAM_TRACE 00052 00053 namespace { 00054 00055 // Remove white space from beginning and end. 00056 inline 00057 void clip_ws( std::string* str ) { 00058 // Remove the first non ' ' characters 00059 { 00060 std::string::iterator itr; 00061 for( itr = str->begin(); itr != str->end(); ++itr ) 00062 if( *itr != ' ' ) break; 00063 str->erase( str->begin(), itr ); 00064 } 00065 // Remove the last non ' ' characters 00066 { 00067 std::string::iterator itr; 00068 for( itr = str->end() - 1; itr > str->begin() - 1; --itr ) 00069 if( *itr != ' ' ) break; 00070 str->erase( itr + 1, str->end() ); 00071 } 00072 } 00073 00074 } // end namespace 00075 00076 namespace OptionsFromStreamPack { 00077 00078 namespace OptionsFromStreamUtilityPack { 00079 00080 // class OptionsGroup 00081 00082 std::string OptionsGroup::option_does_not_exist_; 00083 00084 } // end namespace OptionsFromStreamUtilityPack 00085 00086 // class OptionsFromStream 00087 00088 OptionsFromStream::options_group_t 00089 OptionsFromStream::options_group( const std::string& options_group_name ) 00090 { 00091 options_group_map_t::iterator itr = options_group_map_.find( options_group_name ); 00092 if( itr != options_group_map_.end() ) { 00093 (*itr).second.second.set(true); // flag that we have accessed this options group 00094 return options_group_t(&(*itr).second.first); 00095 } 00096 return options_group_t(NULL); 00097 } 00098 00099 const OptionsFromStream::options_group_t 00100 OptionsFromStream::options_group( const std::string& options_group_name ) const 00101 { 00102 options_group_map_t::const_iterator itr = options_group_map_.find( options_group_name ); 00103 if( itr != options_group_map_.end() ) { 00104 const_cast<false_bool_t&>((*itr).second.second).set(true); // flag that we have accessed this options group 00105 return options_group_t(const_cast<option_to_value_map_t*>(&(*itr).second.first)); 00106 } 00107 return options_group_t(NULL); 00108 } 00109 00110 void OptionsFromStream::reset_unaccessed_options_groups() 00111 { 00112 for( iterator og_itr = begin() ; og_itr != end(); ++og_itr ) { 00113 (*og_itr).second.second.set(false); // rest to not accessed yet. 00114 } 00115 } 00116 00117 void OptionsFromStream::print_unaccessed_options_groups( std::ostream& out ) const 00118 { 00119 const_iterator og_itr = begin(); 00120 for( ; og_itr != end(); ++og_itr ) { 00121 if( (*og_itr).second.second == false ) // if options group was not accessed 00122 out << "options_group " << options_group_name( og_itr ) << " {}\n"; 00123 } 00124 } 00125 00126 void OptionsFromStream::read_options( std::istream& in ) 00127 { 00128 using std::getline; 00129 00130 using InputStreamHelperPack::eat_comment_lines; 00131 00132 std::string curr_word; 00133 00134 if(!in) 00135 return; // No options to read! 00136 00137 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00138 std::cout << "\n*** Entering OptionsFromStream::read_options(...)!\n\n"; 00139 #endif 00140 00141 // Eat words until you get to begin_options. 00142 while( curr_word != "begin_options" && !in.eof() ) 00143 in >> curr_word; 00144 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00145 std::cout << "Found begin_options, start parsing options!\n"; 00146 #endif 00147 // Loop through each options group. 00148 while( !in.eof() ) { 00149 eat_comment_lines(in,'*'); 00150 // read options_group 00151 in >> curr_word; 00152 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00153 std::cout << "\ncurr_word = \""<<curr_word<<"\"\n"; 00154 #endif 00155 if( curr_word == "}" ) { 00156 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00157 std::cout << "Found \'}\', Moving on to the next options group or the end!\n"; 00158 #endif 00159 break; 00160 } 00161 if( curr_word == "end_options" ) { 00162 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00163 std::cout << "Found \'end_options\', stoping parsing options!\n"; 00164 #endif 00165 break; 00166 } 00167 TEUCHOS_TEST_FOR_EXCEPTION( 00168 curr_word != "options_group", InputStreamError 00169 ,"OptionsFromStream::read_options(...) : " 00170 "Error, curr_word = \'" << curr_word << " != \'options_group\'" ); 00171 // read the name of the options group up to { 00172 std::getline(in,curr_word,'{'); 00173 clip_ws( &curr_word ); 00174 const std::string optgroup_name = curr_word; 00175 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00176 std::cout << "\noptgroup_name = \"" << optgroup_name << "\"\n"; 00177 #endif 00178 // Access the options and values map for this options group. 00179 option_to_value_map_t& optval = options_group_map_[optgroup_name].first; 00180 // Grap all of the options for this options group 00181 eat_comment_lines(in,'*'); 00182 std::string optgroup_options; 00183 getline(in,optgroup_options,'}'); 00184 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00185 std::cout << "optgroup_options = \"" << optgroup_options << "\"\n"; 00186 #endif 00187 std::istringstream optgroup_options_in(optgroup_options); 00188 // Loop through and add the options. 00189 while(true) { 00190 eat_comment_lines(optgroup_options_in,'*'); 00191 // Get an option and its value 00192 std::string option_and_value; 00193 getline(optgroup_options_in,option_and_value,';'); 00194 // Note: above If ';' is missing it will take the rest of the string to 00195 // the end of '}' for the end of the options group. These means that if 00196 // there is no comments after the last option=value pair then the last 00197 // semicolon is optional! This turns out to work nicely for the 00198 // CommandLineOptionsFromStreamProcessor class so this is good behavior! 00199 clip_ws(&option_and_value); 00200 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00201 std::cout << " option_and_value = \"" << option_and_value << "\"\n"; 00202 #endif 00203 if(!option_and_value.length()) 00204 break; 00205 // Process the option and value 00206 const std::string::size_type equal_idx = option_and_value.find('=',0); 00207 TEUCHOS_TEST_FOR_EXCEPTION( 00208 equal_idx==std::string::npos, std::logic_error, 00209 "Error, for the option group \"" << optgroup_name << "\"" 00210 << " the option value string \"" << option_and_value << "\" is missing the \"=\" separator!" 00211 ); 00212 std::string option = option_and_value.substr(0,equal_idx); 00213 std::string value = option_and_value.substr(equal_idx+1); 00214 clip_ws(&option); 00215 clip_ws(&value); 00216 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00217 std::cout << " option = \"" << option << "\"\n"; 00218 std::cout << " value = \"" << value << "\"\n"; 00219 #endif 00220 optval[option] = value; 00221 } 00222 } 00223 #ifdef PRINT_OPTIONS_FROM_STREAM_TRACE 00224 std::cout << "\n*** Leaving OptionsFromStream::read_options(...)!\n\n"; 00225 #endif 00226 } 00227 00228 void OptionsFromStream::print_options( std::ostream& out ) const { 00229 out << "\nbegin_options\n"; 00230 const_iterator og_itr = begin(); 00231 for( ; og_itr != end(); ++og_itr ) { 00232 const options_group_t optgrp = OptionsFromStreamPack::options_group( og_itr ); 00233 options_group_t::const_iterator itr = optgrp.begin(); 00234 if(itr == optgrp.end()) continue; 00235 out << "\noptions_group " << options_group_name( og_itr ) << " {\n"; 00236 for( ; itr != optgrp.end(); ++itr ) { 00237 const std::string 00238 &name = option_name(itr), 00239 &value = option_value(itr); 00240 out << " " << name << " = " << value << ";\n"; 00241 } 00242 out << "}\n"; 00243 } 00244 out << "\nend_options\n\n"; 00245 } 00246 00247 } // end namespace OptionsFromStreamPack
1.7.6.1