Bdb packages | Design docs | Source docs | Guidelines | Recent releases

Search | Site Map .

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