ParFilename.cc
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <unistd.h>
00026 #include <fcntl.h>
00027 #include <fstream>
00028 #include <cstdlib>
00029 #include <cstring>
00030
00031 using namespace std;
00032
00033 #include <suplibxx/str.h>
00034
00035 #include "ParFilename.h"
00036
00037
00038 static const char* environment_variables[] = { "PDIRS", "PFILES", "UPARM" };
00039 #define NUM_ENV_VAR sizeof(environment_variables)/sizeof(char *)
00040
00041
00042 static const char* pfile_extension[] = { ".par" };
00043 #define NUM_EXTENSION sizeof(pfile_extension)/sizeof(char *)
00044
00045 typedef vector< string > myVector;
00046 typedef myVector::const_iterator myVectorIterator;
00047
00048 ParFilename::ParFilename( int argc, char** argv, const char* file )
00049 throw ( ParFileException ) {
00050
00051 try {
00052 init_ParFilename( argc, argv, file );
00053 } catch( ParFileException& pfe ) {
00054 throw;
00055 }
00056
00057 }
00058
00059 int ParFilename::accessible( const char* str ) throw ( ParFileException ) {
00060
00061 try {
00062
00063
00064 if ( 0 == str || 0 == *str )
00065 return EXIT_FAILURE;
00066
00067 if ( 0 == ::access( str, R_OK ) ) {
00068 if ( '/' == str[ 0 ] ) {
00069
00070
00071
00072
00073
00074
00075 }
00076 filename = str;
00077
00078 return EXIT_SUCCESS;
00079 }
00080
00081 } catch( ParFileException& pfe ) {
00082
00083 string msg( "ParFilename::accessible( " );
00084 msg.append( str );
00085 msg.append( " )\n" );
00086 pfe.set_message( msg );
00087 throw pfe;
00088
00089 }
00090
00091 return EXIT_FAILURE;
00092
00093 }
00094
00095 void ParFilename::check_environment_variables( ) throw ( ParFileException ) {
00096
00097
00098
00099 int env_var_counter = 0;
00100 {
00101 for ( size_t i = 0; i < NUM_ENV_VAR; i++ )
00102 if ( NULL == getenv( environment_variables[ i ] ) )
00103 env_var_counter++;
00104 }
00105
00106 if ( NUM_ENV_VAR == env_var_counter ) {
00107
00108
00109
00110 string msg = "ParFilename::check_environment_variables( ) : "
00111 "One of the following environment variables ";
00112
00113 for ( size_t i = 0; i < NUM_ENV_VAR; i++ ) {
00114 msg.append( "`" );
00115 msg.append( environment_variables[ i ] );
00116 msg.append( "'" );
00117 if ( i != NUM_ENV_VAR - 1 )
00118 msg.append( ", " );
00119 }
00120
00121 msg.append( " must be defined\n" );
00122
00123 throw ParFileException( msg );
00124
00125 }
00126
00127 return;
00128
00129 }
00130
00131 void ParFilename::copy_pfile( const char* str )
00132 const throw ( ParFileException ) {
00133
00134 int f1, f2, n;
00135 char buf[BUFSIZ];
00136
00137 if ( -1 == (f1 = open( str, O_RDONLY, 0 ) ) ) {
00138 string msg( "ParFilename::copy_pfile( " );
00139 msg.append( str );
00140 msg.append( " ) : Unable to open file for reading\n" );
00141 throw ParFileException( msg );
00142 }
00143
00144 if ( -1 == (f2 = creat( get_basename( str ), 0644 ) ) ) {
00145 string msg( "ParFilename::copy_pfile( " );
00146 msg.append( str );
00147 msg.append( ", ostream& ) : Unable to open file for writing\n" );
00148 close( f1 );
00149 throw ParFileException( msg );
00150 }
00151
00152 while( (n = read( f1, buf, BUFSIZ ) ) > 0 )
00153 if ( n != write( f2, buf, n ) ) {
00154 string msg( "ParFilename::copy_pfile( " );
00155 msg.append( str );
00156 msg.append( " ) : Error writing to file" );
00157 close( f1 );
00158 close( f2 );
00159 throw ParFileException( msg );
00160 }
00161
00162 close( f1 );
00163 close( f2 );
00164
00165 return;
00166
00167 }
00168
00169 int ParFilename::find_pfile( const char* name ) throw ( ParFileException ) {
00170
00171 try {
00172
00173
00174
00175
00176 if ( strstr( name, "." ) && EXIT_SUCCESS == accessible( name ) )
00177 return EXIT_SUCCESS;
00178
00179 for ( size_t ii = 0; ii < NUM_ENV_VAR; ii++ ) {
00180
00181 char* env_var = getenv( environment_variables[ ii ] );
00182
00183 if ( env_var ) {
00184
00185 string directories( env_var );
00186
00187 vector< string > directory;
00188 suplib::tok( directory, directories, ":;" );
00189
00190
00191
00192
00193
00194
00195 for ( myVectorIterator iter = directory.begin( );
00196 iter != directory.end( ); ++iter ) {
00197
00198 char fname[ 1024 ];
00199 sprintf( fname, "%s/%s.par", iter->data( ), name );
00200
00201 if( EXIT_SUCCESS == accessible( fname ) )
00202 return EXIT_SUCCESS;
00203
00204 }
00205
00206 }
00207
00208 }
00209
00210 return EXIT_FAILURE;
00211
00212 } catch ( ParFileException& pfe ) {
00213
00214 throw;
00215
00216 }
00217
00218 }
00219
00220 const char* ParFilename::get_basename( const char* name ) const {
00221
00222 if ( name || *name ) {
00223
00224 const char* progname = name;
00225
00226 char dirdelimit[ 2 ] = { dir_delimit, '\0' };
00227
00228 const char* ptr = name;
00229
00230 do {
00231
00232 ptr = strstr( progname, dirdelimit );
00233 if ( ptr )
00234 progname = ptr + 1;
00235
00236 } while( ptr );
00237
00238 return progname;
00239
00240 } else
00241 return NULL;
00242
00243 }
00244
00245 void ParFilename::init_ParFilename( int argc, char** argv,
00246 const char* file )
00247 throw ( ParFileException ) {
00248
00249 try {
00250
00251 check_environment_variables( );
00252
00253
00254
00255 for ( int i = 1; i < argc; i++ ) {
00256
00257 const char* ptr = strstr( argv[ i ], PFILE );
00258 if ( ptr ) {
00259
00260 ptr += strlen( PFILE );
00261 if ( EXIT_SUCCESS == find_pfile( ptr ) )
00262 return;
00263
00264 }
00265
00266 }
00267
00268
00269
00270
00271
00272 if ( file ) {
00273 if ( EXIT_SUCCESS == find_pfile( file ) )
00274 return;
00275
00276 string msg( "ParFilename::init_ParFilename( ) : "
00277 "Unable to find parfile `" );
00278 msg.append( file );
00279 msg.append( "'\n" );
00280
00281 throw ParFileException( msg ) ;
00282
00283 }
00284
00285
00286
00287 const char* progname = get_basename( argv[ 0 ] );
00288
00289 if ( EXIT_SUCCESS == find_pfile( progname ) )
00290 return;
00291
00292 } catch ( ParFileException& pfe ) {
00293
00294 throw pfe;
00295
00296 }
00297
00298 string msg( "ParFilename::init_ParFilename( ) : "
00299 "Unable to find parfile for `" );
00300 msg.append( argv[ 0 ] );
00301 msg.append( "'\n" );
00302
00303 throw ParFileException( msg );
00304
00305 }
00306
00315 vector<string> ParFilename::parse_string( string& str, char delimit ) {
00316
00317 vector<string> tokens;
00318
00319 if ( str.size( ) ) {
00320
00321 size_t st0 = 0, st1 = 0;
00322 do {
00323
00324 st1 = str.find( delimit, st0 );
00325 if ( str.size( ) < st1 )
00326 st1 = str.size( );
00327
00328 tokens.push_back( str.substr( st0, st1 - st0 ) );
00329
00330 st0 = st1 + 1;
00331
00332 } while ( str.size( ) > st1 );
00333
00334 }
00335
00336 return tokens;
00337 }
00338
00339 #undef NUM_ENV_VAR
00340 #undef NUM_EXTENSION