Par.cc

00001 // --8<--8<--8<--8<--
00002 //
00003 // Copyright (C) 2006 Smithsonian Astrophysical Observatory
00004 //
00005 // This file is part of paramxx
00006 //
00007 // paramxx is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // paramxx is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with this program; if not, write to the 
00019 //       Free Software Foundation, Inc. 
00020 //       51 Franklin Street, Fifth Floor
00021 //       Boston, MA  02110-1301, USA
00022 //
00023 // -->8-->8-->8-->8--
00024 
00025 #include <memory>
00026 
00027 #include <stdio.h>
00028 #include <cstdlib>
00029 #include <cstring>
00030 
00031 using namespace std;
00032 
00033 #include "Par.h"
00034 #include <suplib/str.h>
00035 
00036 Par::Par( ParTxt& par ) {
00037 
00038   char** my_argv = (char**) par;
00039 
00040   if ( my_argv ) {
00041 
00042     // A boolean, integer, real or string parameter
00043     int ii = 0;
00044     while( my_argv[ ii ] )
00045       parameter.push_back( my_argv[ ii++ ] );
00046 
00047   } else {
00048 
00049     // A comment parameter
00050     char* str = (char*) par;
00051     str_trunc( str );
00052     parameter.push_back( str );
00053 
00054   }
00055 
00056 }
00057 
00058 int Par::check_value( const char* str ) const {
00059   try {
00060     string tmp( str );
00061     validate( tmp );
00062     between_limits( tmp );
00063     return EXIT_SUCCESS;
00064   } catch( ParFileException& pfe ) {
00065     cerr << pfe;
00066     return EXIT_FAILURE;
00067   } catch( Exception& e ) {
00068     cerr << e;
00069     return EXIT_FAILURE;
00070   }
00071 
00072 }
00073 
00074 bool Par::is_indirrect( const string& str, char delimit ) {
00075 
00076   if ( delimit == str[ 0 ] )
00077     return true;
00078   else
00079     return false;
00080 
00081 }
00082 
00083 // Either min <= val or val <= max is not met
00084 void Par::not_between_limits( char str[], 
00085                               const char* left, const string& left_val,
00086                               const char* right, const string& right_val )
00087   const {
00088 
00089   const char* format = "Par::not_between_limits( ) : "
00090     "For variable `%s',  %s (%s) >= %s (%s)\n";
00091 
00092   sprintf( str, format, parameter [ PARNAME ].c_str( ),
00093            left, left_val.c_str( ), 
00094            right, right_val.c_str( ) );
00095 
00096   return;
00097 
00098 }
00099 
00100 //
00101 // Output
00102 //    name = val  prompt
00103 // to ostream os
00104 //
00105 void Par::plist( ostream& os ) const {
00106 
00107   const char* plist_format = "%15s = %-15s %s";
00108   const char* hidden_plist_format = "(%15s = %-15s) %s";
00109 
00110   if ( parameter[ PARMODE ] == "H" )
00111     return;
00112   
00113   const char* format = NULL;
00114   if ( parameter[ PARMODE ] == "h" )
00115     format = hidden_plist_format;
00116   else
00117     format = plist_format;
00118 
00119   size_t length = strlen( format ) + parameter[ PARNAME ].size() + 
00120     parameter[ PARVALUE ].size() + parameter[ PARPROMPT ].size() + 256;
00121 
00122   auto_ptr< char > mystr( new char[ length ] );
00123 
00124   char* ptr = &(*mystr);
00125     
00126   sprintf( ptr, format, parameter[ PARNAME ].data( ),
00127              parameter[ PARVALUE ].data( ), parameter[ PARPROMPT ].c_str( ) );
00128   
00129   os << ptr;
00130 
00131 }
00132 
00133 static char mymsg[ 256 ];
00134 
00135 void Par::pget_wrong_type( char msg[], const char* strtype ) const {
00136 
00137   const char* format = "Par::pgetb( ) : Parameter `%s' is not a %s type\n";
00138 
00139   if ( NUMTOKENS == parameter.size( ) )
00140     sprintf( msg, format, parameter[ PARNAME ].c_str( ), strtype );
00141   else
00142     sprintf( msg, format, "", strtype );
00143 
00144 }
00145 
00146 bool Par::pgetb( void ) const throw ( ParFileException ) {
00147 
00148   pget_wrong_type( mymsg, "boolean" );
00149   throw ParFileException( mymsg );
00150 
00151 }
00152 
00153 double Par::pgetd( void ) const throw ( ParFileException ) {
00154 
00155   pget_wrong_type( mymsg, "double" );
00156   throw ParFileException( mymsg );
00157 
00158 }
00159 
00160 int Par::pgeti( void ) const throw ( ParFileException ) {
00161 
00162   pget_wrong_type( mymsg, "int" );
00163   throw ParFileException( mymsg );
00164 
00165 }
00166 
00167 long Par::pgetl( void ) const throw ( ParFileException ) {
00168 
00169   pget_wrong_type( mymsg, "long" );
00170   throw ParFileException( mymsg );
00171 
00172 }
00173 
00174 void Par::pgetstr( char result[], size_t size ) const
00175   throw ( ParFileException ) {
00176 
00177   pget_wrong_type( mymsg, "string" );
00178   throw ParFileException( mymsg );
00179 
00180 }
00181 
00182 string Par::pgetstring( ) const throw ( ParFileException ) {
00183 
00184   pget_wrong_type( mymsg, "string" );
00185   throw ParFileException( mymsg );
00186 
00187 }
00188 
00189 void Par::print( ostream& os ) const {
00190 
00191   vector< string >::const_iterator iter_begin =
00192     parameter.begin( );
00193 
00194   vector< string >::const_iterator iter_end =
00195     parameter.end( );
00196 
00197   for ( vector< string >::const_iterator iter = iter_begin;
00198         iter != iter_end; iter++ ) {
00199     os << *iter;
00200     vector< string >::const_iterator tmp = iter;
00201     if ( ++tmp != iter_end )
00202       os << char( DELIMIT );
00203   }
00204 
00205 }
00206 
00207 char* Par::save_string( char* str ) throw ( Exception ) {
00208 
00209   if ( '\0' == str || '\0' == *str )
00210     return NULL;
00211 
00212   try {
00213 
00214     char* new_str = new char[ strlen( str ) + 1 ];
00215     strcpy( new_str, str );
00216     return new_str;
00217 
00218   } catch ( bad_alloc& ba ) {
00219 
00220     string msg( "Par::save_string( " );
00221     msg.append( str );
00222     msg.append( " ) : Unable to allocate memory\n" );
00223     throw Exception( msg );
00224 
00225   }
00226 
00227 }
00228 
00229 int Par::count_tokens( char* str, char* delimit ) throw ( Exception ) {
00230 
00231   try {
00232 
00233     int ntoken = 0;
00234     char* new_str = save_string( str );
00235 
00236     {
00237       char* token = strtok( new_str, delimit );
00238       while( NULL != token ) {
00239         ntoken++;
00240         token = strtok( NULL, delimit );
00241       }
00242     }
00243 
00244     delete [] new_str;
00245 
00246     return ntoken;
00247 
00248   } catch( Exception& e ) {
00249     throw;
00250   }
00251 
00252 }
00253 
00254 //
00255 // A simple parser to tokenize a string.
00256 // The tokens are stored in tokens, ntoken contains the number of tokens
00257 //
00258 int Par::my_tokenize( char *str, char *delimit, char ***tokens )
00259   throw ( Exception ) {
00260 
00261     try {
00262 
00263       char* new_str = save_string( str );
00264 
00265       int ntoken = count_tokens( new_str, delimit );
00266 
00267       *tokens = new char* [ ntoken + 1 ];
00268 
00269       int num = 0;
00270 
00271       char* token = strtok( new_str, delimit );
00272       while( NULL != token ) {
00273         char* tmp = save_string( token );
00274         (*tokens)[ num++ ] = tmp;
00275         token = strtok( NULL, delimit );
00276       }
00277       (*tokens)[ num ] = (char *) NULL;   
00278 
00279       delete [] new_str;
00280 
00281       return num;
00282 
00283     } catch( Exception& e ) {
00284       throw e;
00285     }
00286 
00287 }
00288 
00289 void Par::delete_tokens( char** ptr ) {
00290 
00291   if ( ptr ) {
00292     int i=0;
00293     while( ptr[ i ] )  {
00294       delete [] ptr[ i ];
00295       i++;
00296     }
00297     delete [] ptr;
00298   }
00299 
00300   return;
00301 
00302 }
00303 
00305 void Par::print_tokens( char* str, char** str_argv, ostream& os ) {
00306 
00307   int i = 0;
00308   os << "The tokens for string `" << str << "' are :\n";
00309 
00310   while( str_argv[ i ] ) {
00311     os << "token[ " << i << " ] = `" << str_argv[ i ] << "'\n";
00312     i++;
00313   }
00314 
00315   return;
00316 
00317 }
00318 
00319 void Par::set_val( const string& str ) throw ( ParFileException, Exception ) {
00320 
00321   throw ParFileException( "Par::set_val( " + str + " ) : Define me!\n" );
00322 
00323 }
00324 
00325 void Par::between_limits( const string& str ) const
00326   throw ( ParFileException, Exception ) {
00327 
00328     throw ParFileException( "Par::between_limits( " + str +
00329                             " ) : Define me!\n" );
00330 
00331 }
00332 
00333 void Par::validate( const string& str ) const throw ( ParFileException ) {
00334 
00335     throw ParFileException( "Par::validate( " + str +
00336                             " ) : Define me!\n" );
00337 
00338 }

Generated on Thu Oct 2 17:54:19 2008 for paramxx by  doxygen 1.5.6