![]() |
|
|
Bdb packages | Design docs | Source docs | Guidelines | Recent releases |
|
Main Page Modules Namespace List Class Hierarchy Alphabetical List Compound List File List Compound Members File Members /BdbUtil/BdbPathName.cc
Go to the documentation of this file.00001 //--------------------------------------------------------------------------- 00002 // File: 00003 // BdbPathName.cc 00004 // 00005 // Description: 00006 // BdbPathName functions 00007 // 00008 // Environment: 00009 // Software developed for the BaBar Detector at the SLAC B-Factory. 00010 // 00011 // Author List: 00012 // Akbar Mokhtarani original author 00013 // 00014 // Copyright Information: 00015 // Copyright (C) 2001 LBNL 00016 // 00017 //--------------------------------------------------------------------------- 00018 #include "BaBar/BaBar.hh" 00019 00020 //----------------------- 00021 // This Class's Header -- 00022 //----------------------- 00023 #include "BdbUtil/BdbPathName.hh" 00024 00025 00026 //------------- 00027 // C Headers -- 00028 //------------- 00029 extern "C" { 00030 #include <string.h> 00031 } 00032 00033 //------------------------------- 00034 // Collaborating Class Headers -- 00035 //------------------------------- 00036 #include "ErrLogger/ErrLog.hh" 00037 00038 const char localSeparator( '/' ); 00039 00040 BdbPathName::~BdbPathName() 00041 { 00042 } 00043 00044 char* 00045 BdbPathName::relative(const char* refPath, const char* targetPath ) 00046 { 00047 // If no target is specified return nothing 00048 if ( 0 == targetPath ) 00049 { 00050 return( 0 ); 00051 } 00052 00053 // If target path doesn't have a / at the start it is already relative 00054 // copy the targetPath and return that (called owns the string) 00055 if ( localSeparator != targetPath[0] ) 00056 { 00057 char* toReturn = new char[strlen(targetPath) + 1]; 00058 strcpy( toReturn, targetPath ); 00059 return toReturn; 00060 } 00061 00062 // First find any common part 00063 int common = commonDirsLength( refPath, targetPath ); 00064 00065 // Find if there are any directories further down the reference path 00066 const char* refEnd = refPath + common; 00067 00068 int slashes = countSlashes( refEnd ); 00069 00070 // For each slash stick ../ before what is left of the targetPath 00071 static const char* upStr = "../"; 00072 static const int upStrLen = strlen( upStr ); 00073 const char* targetEnd = targetPath + common; 00074 char* toReturn = new char[ upStrLen*slashes + strlen(targetEnd) + 1 ]; 00075 char* toReturnPtr = toReturn; 00076 for ( int i=0; i<slashes; i++ ) 00077 { 00078 strcpy( toReturnPtr, upStr ); 00079 toReturnPtr += upStrLen; 00080 } 00081 strcpy( toReturnPtr, targetEnd ); 00082 00083 return toReturn; 00084 } 00085 00086 char* 00087 BdbPathName::absolute(const char* refPath, const char* targetPath) 00088 { 00089 if( ( ( 0 != refPath ) && 00090 ( localSeparator == *refPath ) ) || 00091 ( ( 0 != targetPath ) && 00092 ( localSeparator == *targetPath ) ) ) { 00093 return( merge( refPath, 00094 targetPath ) ); 00095 } 00096 return( 0 ); 00097 } 00098 00099 char* 00100 BdbPathName::merge( const char* firstPath, const char* secondPath ) 00101 { 00102 // If no target is specified simply copy the firstPath into 00103 // new memory 00104 if ( 0 == secondPath ) { 00105 if( 0 == firstPath ) { 00106 return( 0 ); 00107 } 00108 char* result = new char[ strlen( firstPath ) + 1 ]; 00109 strcpy( result, 00110 firstPath ); 00111 return result; 00112 } 00113 00114 char* result( 0 ); 00115 char* joint( 0 ); 00116 // If target path has a / at the start it is already absolute 00117 // copy the secondPath and return that (called owns the string) 00118 if ( localSeparator == *secondPath ) { 00119 result = new char[ strlen( secondPath ) + 1 ]; 00120 joint = result; 00121 } 00122 00123 else { 00124 00125 // Build the part of the result that is based of the firstPath 00126 const char* emptyString( "" ); 00127 if( 0 == firstPath ) { 00128 firstPath = emptyString; 00129 } 00130 result = new char[ strlen( firstPath ) + strlen( secondPath ) + 1 ]; 00131 const char* firstResult( append( result, 00132 result, 00133 firstPath ) ); 00134 if( 0 == firstResult ) { 00135 delete [] result; 00136 return( 0 ); 00137 } 00138 00139 joint = leafJoint( result ); 00140 if( 0 == joint ) { 00141 joint = result; 00142 } 00143 else { 00144 joint++; 00145 } 00146 } 00147 00148 const char* secondResult( append( result, 00149 joint, 00150 secondPath ) ); 00151 if( 0 == secondResult ) { 00152 delete [] result; 00153 result = 0 ; 00154 } 00155 return( result ); 00156 } 00157 00158 const char* 00159 BdbPathName::append( const char* beginning, 00160 char* cursor, 00161 const char* addition ) 00162 { 00163 if( ( beginning != cursor ) && 00164 ( localSeparator != *( cursor - 1 ) ) ) { 00165 return( 0 ); 00166 } 00167 00168 while( '\0' != *addition ) { 00169 00170 // If end of target is ',' drop it and remove last separator 00171 if( ( '.' == *addition ) && 00172 ( '\0' == *( addition + 1 ) ) ) { 00173 addition++ ; 00174 if( beginning == cursor ) { 00175 delete [] beginning; 00176 beginning = 0; 00177 } 00178 else { 00179 cursor--; 00180 } 00181 } 00182 00183 // If target contains './' simply drop it 00184 else if( ( '.' == *addition ) && 00185 ( localSeparator == *( addition + 1 ) ) ) { 00186 addition += 2; 00187 } 00188 00189 // If end of target is '..' or '../' remove last directory 00190 else if( ( '.' == *addition ) && 00191 ( '.' == *( addition + 1 ) ) && 00192 ( ( '\0' == *( addition + 2 ) ) || 00193 ( localSeparator == *( addition + 2 ) ) ) ) { 00194 addition += 2; 00195 if( beginning == cursor ) { 00196 addition = addition + strlen( addition ); 00197 delete [] beginning; 00198 beginning = 0; 00199 } 00200 else { 00201 cursor--; 00202 *cursor = '\0'; 00203 const char* newCursor( strrchr( beginning, 00204 localSeparator ) ); 00205 if( 0 == newCursor ) { 00206 addition = addition + strlen( addition ); 00207 delete [] beginning; 00208 beginning = 0; 00209 } 00210 else { 00211 cursor = const_cast< char* >( newCursor ); 00212 *cursor = *addition; 00213 if( localSeparator == *addition ) { 00214 addition++; 00215 cursor++; 00216 } 00217 } 00218 } 00219 } 00220 00221 // Otherwise copy next leaf into result 00222 else { 00223 const char* newAddition( strchr( addition, 00224 localSeparator ) ); 00225 if( newAddition == addition ) { 00226 if( beginning == cursor ) { 00227 *cursor = localSeparator; 00228 cursor++; 00229 } 00230 addition++; 00231 } 00232 else { 00233 size_t length( 0 ); 00234 if( 0 == newAddition ) { 00235 length = strlen( addition ); 00236 } 00237 else { 00238 length = newAddition - addition + 1; 00239 } 00240 strncpy( cursor, 00241 addition, 00242 length ); 00243 addition += length; 00244 cursor += length; 00245 } 00246 } 00247 } 00248 00249 *cursor = '\0'; 00250 return( beginning ); 00251 } 00252 00253 char* 00254 BdbPathName::stem( const char* path, 00255 bool trailingSeparator ) 00256 { 00257 const char* joint( leafJoint( path ) ); 00258 if( ( 0 == joint ) || 00259 ( '\0' == *joint ) || 00260 ( ( path == joint ) && 00261 ( ! trailingSeparator ) ) ) { 00262 return( 0 ); 00263 } 00264 size_t length( joint - path ); 00265 if( trailingSeparator ) { 00266 length++; 00267 } 00268 char* result( new char[ length + 1 ] ); 00269 strncpy( result, 00270 path, 00271 length ); 00272 result[ length ] = '\0'; 00273 return( result ); 00274 } 00275 00276 char* 00277 BdbPathName::leaf( const char* path ) 00278 { 00279 if( 0 == path ) { 00280 return( 0 ); 00281 } 00282 const char* joint( leafJoint( path ) ); 00283 if( ( 0 != joint ) && 00284 ( '\0' == *joint ) ) { 00285 return( 0 ); 00286 } 00287 if( 0 == joint ) { 00288 joint = path; 00289 } 00290 if( localSeparator == *joint ) { 00291 if( '\0' == *(joint + 1 ) ) { 00292 return( 0 ) ; 00293 } 00294 joint++; 00295 } 00296 char* result( new char[ strlen( joint ) + 1 ] ); 00297 strcpy( result, 00298 joint ) ; 00299 return( result ); 00300 } 00301 00302 char* 00303 BdbPathName::leaf( const char* path, 00304 unsigned int index ) 00305 { 00306 if( ( 0 == path ) || 00307 ( '\0' == *path ) ) { 00308 return( 0 ); 00309 } 00310 00311 // Ignore first separator 00312 const char* start( path ); 00313 if( localSeparator == *path ) { 00314 start++; 00315 if( '\0' == start ) { 00316 return( 0 ); 00317 } 00318 } 00319 00320 // Move to the beginning of nth leaf 00321 while( ( 0 != start ) && 00322 ( 0 != index ) ) { 00323 start = strchr( start, 00324 localSeparator ); 00325 if( 0 != start ) { 00326 start++ ; 00327 } 00328 index--; 00329 } 00330 if( ( 0 == start ) || 00331 ( '\0' == start ) ) { 00332 return( 0 ); 00333 } 00334 00335 // Create leaf as result 00336 const char* finish( strchr( start, 00337 localSeparator ) ); 00338 unsigned int length( 0 ); 00339 if( 0 == finish ) { 00340 length = strlen( start ); 00341 } 00342 else { 00343 length = finish - start; 00344 } 00345 char* result( new char[ length + 1 ] ); 00346 strncpy( result, 00347 start, 00348 length) ; 00349 result[ length ] = '\0'; 00350 return( result ); 00351 } 00352 00353 char 00354 BdbPathName::separator() 00355 { 00356 return( localSeparator ); 00357 } 00358 00359 int 00360 BdbPathName::commonDirsLength( const char* one, const char* two ) 00361 { 00362 int lenOne = strlen( one ), lenTwo = strlen( two ); 00363 int minLen = ( (lenOne>lenTwo)? lenTwo:lenOne ); 00364 00365 bool done( false ); 00366 int i( 0 ); 00367 int result( 0 ) ; 00368 while( !done && 00369 ( i != minLen ) ) { 00370 if ( one[i] != two[i] ) { 00371 done = !false ; 00372 } 00373 else { 00374 if ( localSeparator == one[i] ) { 00375 result = i + 1; 00376 } 00377 i++; 00378 } 00379 } 00380 00381 return result; 00382 } 00383 00384 int 00385 BdbPathName::countSlashes( const char* aString ) 00386 { 00387 int length = strlen( aString ), slashes=0; 00388 00389 for ( int i=0; i<length; i++ ) if ( localSeparator ==aString[i] ) slashes++; 00390 00391 return slashes; 00392 } 00393 00394 char* 00395 BdbPathName::leafJoint( char* path ) 00396 { 00397 if( 0 == path ) { 00398 return( 0 ); 00399 } 00400 char* result( strrchr( path, 00401 localSeparator ) ); 00402 return( result ); 00403 } 00404 00405 const char* 00406 BdbPathName::leafJoint( const char* path ) 00407 { 00408 return( leafJoint( const_cast< char* >( path ) ) ) ; 00409 }
BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us
Page Owner: Jacek Becla
Last Update: October 04, 2002