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 }