Main Page Class Hierarchy Compound List File List Compound Members File Members Related Pages

# cpl_path.cpp

    00001 /**********************************************************************
    00002  * $Id: cpl_path_cpp-source.html,v 1.13 2002/12/21 19:13:12 warmerda Exp $
    00003  *
    00004  * Project:  CPL - Common Portability Library
    00005  * Purpose:  Portable filename/path parsing, and forming ala "Glob API".
    00006  * Author:   Frank Warmerdam, warmerda@home.com
    00007  *
    00008  **********************************************************************
    00009  * Copyright (c) 1999, Frank Warmerdam
    00010  *
    00011  * Permission is hereby granted, free of charge, to any person obtaining a
    00012  * copy of this software and associated documentation files (the "Software"),
    00013  * to deal in the Software without restriction, including without limitation
    00014  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    00015  * and/or sell copies of the Software, and to permit persons to whom the
    00016  * Software is furnished to do so, subject to the following conditions:
    00017  *
    00018  * The above copyright notice and this permission notice shall be included
    00019  * in all copies or substantial portions of the Software.
    00020  *
    00021  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    00022  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00023  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
    00024  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    00025  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    00026  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    00027  * DEALINGS IN THE SOFTWARE.
    00028  **********************************************************************
    00029  *
    00030  * $Log: cpl_path_cpp-source.html,v $
    00030  * Revision 1.13  2002/12/21 19:13:12  warmerda
    00030  * updated
    00030  *
    00031  * Revision 1.12  2002/12/13 06:14:17  warmerda
    00032  * fixed bug with IsRelative function
    00033  *
    00034  * Revision 1.11  2002/12/13 06:00:54  warmerda
    00035  * added CPLProjectRelativeFilename() and CPLIsFilenameRelative()
    00036  *
    00037  * Revision 1.10  2002/08/15 09:23:24  dron
    00038  * Added CPLGetDirname() function
    00039  *
    00040  * Revision 1.9  2001/08/30 21:20:49  warmerda
    00041  * expand tabs
    00042  *
    00043  * Revision 1.8  2001/07/18 04:00:49  warmerda
    00044  * added CPL_CVSID
    00045  *
    00046  * Revision 1.7  2001/05/12 19:20:55  warmerda
    00047  * Fixed documentation of CPLGetExtension().
    00048  *
    00049  * Revision 1.6  2001/03/16 22:15:08  warmerda
    00050  * added CPLResetExtension
    00051  *
    00052  * Revision 1.5  2001/02/24 01:53:57  warmerda
    00053  * Added CPLFormCIFilename()
    00054  *
    00055  * Revision 1.4  2001/01/19 21:18:25  warmerda
    00056  * expanded tabs
    00057  *
    00058  * Revision 1.3  2000/01/26 17:53:36  warmerda
    00059  * Fixed CPLGetExtension() for filenames with no extension.
    00060  *
    00061  * Revision 1.2  2000/01/24 19:32:59  warmerda
    00062  * Fixed CPLGetExtension() to not include the dot.
    00063  *
    00064  * Revision 1.1  1999/10/14 19:23:39  warmerda
    00065  * New
    00066  *
    00067  **********************************************************************/
    00068
    00069 #include "cpl_conv.h"
    00070 #include "cpl_string.h"
    00071
    00072 CPL_CVSID("$Id: cpl_path_cpp-source.html,v 1.13 2002/12/21 19:13:12 warmerda Exp $");
    00073
    00074
    00075 static char     szStaticResult[2048]; /* should be size of larged possible
    00076                                          filename */
    00077
    00078 #ifdef WIN32
    00079 #define SEP_CHAR '\\'
    00080 #define SEP_STRING "\\"
    00081 #else
    00082 #define SEP_CHAR '/'
    00083 #define SEP_STRING "/"
    00084 #endif
    00085
    00086 /************************************************************************/
    00087 /*                        CPLFindFilenameStart()                        */
    00088 /************************************************************************/
    00089
    00090 static int CPLFindFilenameStart( const char * pszFilename )
    00091
    00092 {
    00093     int         iFileStart;
    00094
    00095     for( iFileStart = strlen(pszFilename);
    00096          iFileStart > 0
    00097              && pszFilename[iFileStart-1] != '/'
    00098              && pszFilename[iFileStart-1] != '\\';
    00099          iFileStart-- ) {}
    00100
    00101     return iFileStart;
    00102 }
    00103
    00104 /************************************************************************/
    00105 /*                             CPLGetPath()                             */
    00106 /************************************************************************/
    00107
    00130 const char *CPLGetPath( const char *pszFilename )
    00131
    00132 {
    00133     int         iFileStart = CPLFindFilenameStart(pszFilename);
    00134
    00135     if( iFileStart == 0 )
    00136     {
    00137         strcpy( szStaticResult, "" );
    00138         return szStaticResult;
    00139     }
    00140
    00141     strncpy( szStaticResult, pszFilename, iFileStart );
    00142     szStaticResult[iFileStart] = '\0';
    00143
    00144     if( iFileStart > 1
    00145         && (szStaticResult[iFileStart-1] == '/'
    00146             || szStaticResult[iFileStart-1] == '\\') )
    00147         szStaticResult[iFileStart-1] = '\0';
    00148
    00149     return szStaticResult;
    00150 }
    00151
    00152 /************************************************************************/
    00153 /*                             CPLGetDirname()                          */
    00154 /************************************************************************/
    00155
    00178 const char *CPLGetDirname( const char *pszFilename )
    00179
    00180 {
    00181     int         iFileStart = CPLFindFilenameStart(pszFilename);
    00182
    00183     if( iFileStart == 0 )
    00184     {
    00185         strcpy( szStaticResult, "." );
    00186         return szStaticResult;
    00187     }
    00188
    00189     strncpy( szStaticResult, pszFilename, iFileStart );
    00190     szStaticResult[iFileStart] = '\0';
    00191
    00192     if( iFileStart > 1
    00193         && (szStaticResult[iFileStart-1] == '/'
    00194             || szStaticResult[iFileStart-1] == '\\') )
    00195         szStaticResult[iFileStart-1] = '\0';
    00196
    00197     return szStaticResult;
    00198 }
    00199
    00200 /************************************************************************/
    00201 /*                           CPLGetFilename()                           */
    00202 /************************************************************************/
    00203
    00224 const char *CPLGetFilename( const char *pszFullFilename )
    00225
    00226 {
    00227     int iFileStart = CPLFindFilenameStart( pszFullFilename );
    00228
    00229     strcpy( szStaticResult, pszFullFilename + iFileStart );
    00230
    00231     return szStaticResult;
    00232 }
    00233
    00234 /************************************************************************/
    00235 /*                           CPLGetBasename()                           */
    00236 /************************************************************************/
    00237
    00258 const char *CPLGetBasename( const char *pszFullFilename )
    00259
    00260 {
    00261     int iFileStart = CPLFindFilenameStart( pszFullFilename );
    00262     int iExtStart, nLength;
    00263
    00264     for( iExtStart = strlen(pszFullFilename);
    00265          iExtStart > iFileStart && pszFullFilename[iExtStart] != '.';
    00266          iExtStart-- ) {}
    00267
    00268     if( iExtStart == iFileStart )
    00269         iExtStart = strlen(pszFullFilename);
    00270
    00271     nLength = iExtStart - iFileStart;
    00272
    00273     strncpy( szStaticResult, pszFullFilename + iFileStart, nLength );
    00274     szStaticResult[nLength] = '\0';
    00275
    00276     return szStaticResult;
    00277 }
    00278
    00279
    00280 /************************************************************************/
    00281 /*                           CPLGetExtension()                          */
    00282 /************************************************************************/
    00283
    00303 const char *CPLGetExtension( const char *pszFullFilename )
    00304
    00305 {
    00306     int iFileStart = CPLFindFilenameStart( pszFullFilename );
    00307     int iExtStart;
    00308
    00309     for( iExtStart = strlen(pszFullFilename);
    00310          iExtStart > iFileStart && pszFullFilename[iExtStart] != '.';
    00311          iExtStart-- ) {}
    00312
    00313     if( iExtStart == iFileStart )
    00314         iExtStart = strlen(pszFullFilename)-1;
    00315
    00316     strcpy( szStaticResult, pszFullFilename+iExtStart+1 );
    00317
    00318     return szStaticResult;
    00319 }
    00320
    00321 /************************************************************************/
    00322 /*                         CPLResetExtension()                          */
    00323 /************************************************************************/
    00324
    00336 const char *CPLResetExtension( const char *pszPath, const char *pszExt )
    00337
    00338 {
    00339     int         i;
    00340
    00341 /* -------------------------------------------------------------------- */
    00342 /*      First, try and strip off any existing extension.                */
    00343 /* -------------------------------------------------------------------- */
    00344     strcpy( szStaticResult, pszPath );
    00345     for( i = strlen(szStaticResult)-1; i > 0; i-- )
    00346     {
    00347         if( szStaticResult[i] == '.' )
    00348         {
    00349             szStaticResult[i] = '\0';
    00350             break;
    00351         }
    00352
    00353         if( szStaticResult[i] == '/' || szStaticResult[i] == '\\'
    00354             || szStaticResult[i] == ':' )
    00355             break;
    00356     }
    00357
    00358 /* -------------------------------------------------------------------- */
    00359 /*      Append the new extension.                                       */
    00360 /* -------------------------------------------------------------------- */
    00361     strcat( szStaticResult, "." );
    00362     strcat( szStaticResult, pszExt );
    00363
    00364     return szStaticResult;
    00365 }
    00366
    00367 /************************************************************************/
    00368 /*                          CPLFormFilename()                           */
    00369 /************************************************************************/
    00370
    00399 const char *CPLFormFilename( const char * pszPath,
    00400                              const char * pszBasename,
    00401                              const char * pszExtension )
    00402
    00403 {
    00404     const char  *pszAddedPathSep = "";
    00405     const char  *pszAddedExtSep = "";
    00406
    00407     if( pszPath == NULL )
    00408         pszPath = "";
    00409     else if( strlen(pszPath) > 0
    00410              && pszPath[strlen(pszPath)-1] != '/'
    00411              && pszPath[strlen(pszPath)-1] != '\\' )
    00412         pszAddedPathSep = SEP_STRING;
    00413
    00414     if( pszExtension == NULL )
    00415         pszExtension = "";
    00416     else if( pszExtension[0] != '.' && strlen(pszExtension) > 0 )
    00417         pszAddedExtSep = ".";
    00418
    00419     sprintf( szStaticResult, "%s%s%s%s%s",
    00420              pszPath, pszAddedPathSep,
    00421              pszBasename,
    00422              pszAddedExtSep, pszExtension );
    00423
    00424     return szStaticResult;
    00425 }
    00426
    00427 /************************************************************************/
    00428 /*                          CPLFormCIFilename()                         */
    00429 /************************************************************************/
    00430
    00455 const char *CPLFormCIFilename( const char * pszPath,
    00456                                const char * pszBasename,
    00457                                const char * pszExtension )
    00458
    00459 {
    00460 #ifdef WIN32
    00461     return CPLFormFilename( pszPath, pszBasename, pszExtension );
    00462 #else
    00463     const char  *pszAddedExtSep = "";
    00464     char        *pszFilename;
    00465     const char  *pszFullPath;
    00466     int         nLen = strlen(pszBasename)+2, i;
    00467     FILE        *fp;
    00468
    00469     if( pszExtension != NULL )
    00470         nLen += strlen(pszExtension);
    00471
    00472     pszFilename = (char *) CPLMalloc(nLen);
    00473
    00474     if( pszExtension == NULL )
    00475         pszExtension = "";
    00476     else if( pszExtension[0] != '.' && strlen(pszExtension) > 0 )
    00477         pszAddedExtSep = ".";
    00478
    00479     sprintf( pszFilename, "%s%s%s",
    00480              pszBasename, pszAddedExtSep, pszExtension );
    00481
    00482     pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL );
    00483     fp = VSIFOpen( pszFullPath, "r" );
    00484     if( fp == NULL )
    00485     {
    00486         for( i = 0; pszFilename[i] != '\0'; i++ )
    00487         {
    00488             if( pszFilename[i] >= 'a' && pszFilename[i] <= 'z' )
    00489                 pszFilename[i] = pszFilename[i] + 'A' - 'a';
    00490         }
    00491
    00492         pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL );
    00493         fp = VSIFOpen( pszFullPath, "r" );
    00494     }
    00495
    00496     if( fp == NULL )
    00497     {
    00498         for( i = 0; pszFilename[i] != '\0'; i++ )
    00499         {
    00500             if( pszFilename[i] >= 'A' && pszFilename[i] <= 'Z' )
    00501                 pszFilename[i] = pszFilename[i] + 'a' - 'A';
    00502         }
    00503
    00504         pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL );
    00505         fp = VSIFOpen( pszFullPath, "r" );
    00506     }
    00507
    00508     if( fp != NULL )
    00509         VSIFClose( fp );
    00510     else
    00511         pszFullPath = CPLFormFilename( pszPath, pszBasename, pszExtension );
    00512
    00513     CPLFree( pszFilename );
    00514
    00515     return pszFullPath;
    00516 #endif
    00517 }
    00518
    00519 /************************************************************************/
    00520 /*                     CPLProjectRelativeFilename()                     */
    00521 /************************************************************************/
    00522
    00550 const char *CPLProjectRelativeFilename( const char *pszProjectDir,
    00551                                         const char *pszSecondaryFilename )
    00552
    00553 {
    00554     if( !CPLIsFilenameRelative( pszSecondaryFilename ) )
    00555         return pszSecondaryFilename;
    00556
    00557     if( pszProjectDir == NULL || strlen(pszProjectDir) == 0 )
    00558         return pszSecondaryFilename;
    00559
    00560     strcpy( szStaticResult, pszProjectDir );
    00561     if( pszProjectDir[strlen(pszProjectDir)-1] != '/'
    00562         && pszProjectDir[strlen(pszProjectDir)-1] != '\\' )
    00563         strcat( szStaticResult, SEP_STRING );
    00564
    00565     strcat( szStaticResult, pszSecondaryFilename );
    00566
    00567     return szStaticResult;
    00568 }
    00569
    00570 /************************************************************************/
    00571 /*                       CPLIsFilenameRelative()                        */
    00572 /************************************************************************/
    00573
    00586 int CPLIsFilenameRelative( const char *pszFilename )
    00587
    00588 {
    00589     if( (strlen(pszFilename) > 2 && strncmp(pszFilename+1,":\\",2) == 0)
    00590         || pszFilename[0] == '\\'
    00591         || pszFilename[0] == '/' )
    00592         return FALSE;
    00593     else
    00594         return TRUE;
    00595 }