const char *CPLGetBasename( const char *pszFullFilename ) { size_t iFileStart = CPLFindFilenameStart( pszFullFilename ); size_t iExtStart, nLength; char *pszStaticResult = CPLGetStaticResult(); CPLAssert( ! (pszFullFilename >= pszStaticResult && pszFullFilename < pszStaticResult + CPL_PATH_BUF_SIZE) ); for( iExtStart = strlen(pszFullFilename); iExtStart > iFileStart && pszFullFilename[iExtStart] != '.'; iExtStart-- ) {} if( iExtStart == iFileStart ) iExtStart = strlen(pszFullFilename); nLength = iExtStart - iFileStart; if (nLength >= CPL_PATH_BUF_SIZE) return CPLStaticBufferTooSmall(pszStaticResult); CPLStrlcpy( pszStaticResult, pszFullFilename + iFileStart, nLength + 1 ); return pszStaticResult; }
const char *CPLGetDirname( const char *pszFilename ) { int iFileStart = CPLFindFilenameStart(pszFilename); char *pszStaticResult = CPLGetStaticResult(); if( iFileStart >= CPL_PATH_BUF_SIZE ) return CPLStaticBufferTooSmall(pszStaticResult); CPLAssert( ! (pszFilename >= pszStaticResult && pszFilename < pszStaticResult + CPL_PATH_BUF_SIZE) ); if( iFileStart == 0 ) { strcpy( pszStaticResult, "." ); return pszStaticResult; } CPLStrlcpy( pszStaticResult, pszFilename, iFileStart+1 ); if( iFileStart > 1 && (pszStaticResult[iFileStart-1] == '/' || pszStaticResult[iFileStart-1] == '\\') ) pszStaticResult[iFileStart-1] = '\0'; return pszStaticResult; }
const char *CPLProjectRelativeFilename( const char *pszProjectDir, const char *pszSecondaryFilename ) { char *pszStaticResult = CPLGetStaticResult(); CPLAssert( ! (pszProjectDir >= pszStaticResult && pszProjectDir < pszStaticResult + CPL_PATH_BUF_SIZE) ); CPLAssert( ! (pszSecondaryFilename >= pszStaticResult && pszSecondaryFilename < pszStaticResult + CPL_PATH_BUF_SIZE) ); if( !CPLIsFilenameRelative( pszSecondaryFilename ) ) return pszSecondaryFilename; if( pszProjectDir == NULL || strlen(pszProjectDir) == 0 ) return pszSecondaryFilename; if (CPLStrlcpy( pszStaticResult, pszProjectDir, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE) goto error; if( pszProjectDir[strlen(pszProjectDir)-1] != '/' && pszProjectDir[strlen(pszProjectDir)-1] != '\\' ) { if (CPLStrlcat( pszStaticResult, SEP_STRING, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE) goto error; } if (CPLStrlcat( pszStaticResult, pszSecondaryFilename, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE) goto error; return pszStaticResult; error: return CPLStaticBufferTooSmall(pszStaticResult); }
const char *CPLFormFilename( const char * pszPath, const char * pszBasename, const char * pszExtension ) { char *pszStaticResult = CPLGetStaticResult(); const char *pszAddedPathSep = ""; const char *pszAddedExtSep = ""; CPLAssert( ! (pszPath >= pszStaticResult && pszPath < pszStaticResult + CPL_PATH_BUF_SIZE) ); CPLAssert( ! (pszBasename >= pszStaticResult && pszBasename < pszStaticResult + CPL_PATH_BUF_SIZE) ); if( pszPath == NULL ) pszPath = ""; else if( strlen(pszPath) > 0 && pszPath[strlen(pszPath)-1] != '/' && pszPath[strlen(pszPath)-1] != '\\' ) pszAddedPathSep = SEP_STRING; if( pszExtension == NULL ) pszExtension = ""; else if( pszExtension[0] != '.' && strlen(pszExtension) > 0 ) pszAddedExtSep = "."; if (CPLStrlcpy( pszStaticResult, pszPath, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE || CPLStrlcat( pszStaticResult, pszAddedPathSep, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE || CPLStrlcat( pszStaticResult, pszBasename, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE || CPLStrlcat( pszStaticResult, pszAddedExtSep, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE || CPLStrlcat( pszStaticResult, pszExtension, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE) return CPLStaticBufferTooSmall(pszStaticResult); return pszStaticResult; }
const char *CPLFormFilename( const char * pszPath, const char * pszBasename, const char * pszExtension ) { char *pszStaticResult = CPLGetStaticResult(); const char *pszAddedPathSep = ""; const char *pszAddedExtSep = ""; CPLAssert( ! (pszPath >= pszStaticResult && pszPath < pszStaticResult + CPL_PATH_BUF_SIZE) ); CPLAssert( ! (pszBasename >= pszStaticResult && pszBasename < pszStaticResult + CPL_PATH_BUF_SIZE) ); if( pszBasename[0] == '.' && pszBasename[1] == '/' ) pszBasename += 2; if( pszPath == NULL ) pszPath = ""; else if( strlen(pszPath) > 0 && pszPath[strlen(pszPath)-1] != '/' && pszPath[strlen(pszPath)-1] != '\\' ) { /* FIXME? would be better to ask the filesystems what they */ /* prefer as directory separator */ if (strncmp(pszPath, "/vsicurl/", 9) == 0) pszAddedPathSep = "/"; else if (strncmp(pszPath, "/vsizip/", 8) == 0) pszAddedPathSep = "/"; else pszAddedPathSep = SEP_STRING; } if( pszExtension == NULL ) pszExtension = ""; else if( pszExtension[0] != '.' && strlen(pszExtension) > 0 ) pszAddedExtSep = "."; if (CPLStrlcpy( pszStaticResult, pszPath, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE || CPLStrlcat( pszStaticResult, pszAddedPathSep, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE || CPLStrlcat( pszStaticResult, pszBasename, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE || CPLStrlcat( pszStaticResult, pszAddedExtSep, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE || CPLStrlcat( pszStaticResult, pszExtension, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE) return CPLStaticBufferTooSmall(pszStaticResult); return pszStaticResult; }
const char *CPLCleanTrailingSlash( const char *pszPath ) { char *pszStaticResult = CPLGetStaticResult(); int iPathLength = strlen(pszPath); CPLAssert( ! (pszPath >= pszStaticResult && pszPath < pszStaticResult + CPL_PATH_BUF_SIZE) ); if (iPathLength >= CPL_PATH_BUF_SIZE) return CPLStaticBufferTooSmall(pszStaticResult); CPLStrlcpy( pszStaticResult, pszPath, iPathLength+1 ); if( iPathLength > 0 && (pszStaticResult[iPathLength-1] == '\\' || pszStaticResult[iPathLength-1] == '/')) pszStaticResult[iPathLength-1] = '\0'; return pszStaticResult; }
const char *CPLGetExtension( const char *pszFullFilename ) { size_t iFileStart = CPLFindFilenameStart( pszFullFilename ); size_t iExtStart; char *pszStaticResult = CPLGetStaticResult(); CPLAssert( ! (pszFullFilename >= pszStaticResult && pszFullFilename < pszStaticResult + CPL_PATH_BUF_SIZE) ); for( iExtStart = strlen(pszFullFilename); iExtStart > iFileStart && pszFullFilename[iExtStart] != '.'; iExtStart-- ) {} if( iExtStart == iFileStart ) iExtStart = strlen(pszFullFilename)-1; if (CPLStrlcpy( pszStaticResult, pszFullFilename+iExtStart+1, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE) return CPLStaticBufferTooSmall(pszStaticResult); return pszStaticResult; }
const char *CPLProjectRelativeFilename( const char *pszProjectDir, const char *pszSecondaryFilename ) { char *pszStaticResult = CPLGetStaticResult(); CPLAssert( ! (pszProjectDir >= pszStaticResult && pszProjectDir < pszStaticResult + CPL_PATH_BUF_SIZE) ); CPLAssert( ! (pszSecondaryFilename >= pszStaticResult && pszSecondaryFilename < pszStaticResult + CPL_PATH_BUF_SIZE) ); if( !CPLIsFilenameRelative( pszSecondaryFilename ) ) return pszSecondaryFilename; if( pszProjectDir == NULL || strlen(pszProjectDir) == 0 ) return pszSecondaryFilename; if (CPLStrlcpy( pszStaticResult, pszProjectDir, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE) goto error; if( pszProjectDir[strlen(pszProjectDir)-1] != '/' && pszProjectDir[strlen(pszProjectDir)-1] != '\\' ) { /* FIXME? would be better to ask the filesystems what they */ /* prefer as directory separator */ const char* pszAddedPathSep; if (strncmp(pszStaticResult, "/vsicurl/", 9) == 0) pszAddedPathSep = "/"; else pszAddedPathSep = SEP_STRING; if (CPLStrlcat( pszStaticResult, pszAddedPathSep, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE) goto error; } if (CPLStrlcat( pszStaticResult, pszSecondaryFilename, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE) goto error; return pszStaticResult; error: return CPLStaticBufferTooSmall(pszStaticResult); }
const char *CPLResetExtension( const char *pszPath, const char *pszExt ) { char *pszStaticResult = CPLGetStaticResult(); size_t i; CPLAssert( ! (pszPath >= pszStaticResult && pszPath < pszStaticResult + CPL_PATH_BUF_SIZE) ); /* -------------------------------------------------------------------- */ /* First, try and strip off any existing extension. */ /* -------------------------------------------------------------------- */ if (CPLStrlcpy( pszStaticResult, pszPath, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE) return CPLStaticBufferTooSmall(pszStaticResult); if (*pszStaticResult) { for( i = strlen(pszStaticResult) - 1; i > 0; i-- ) { if( pszStaticResult[i] == '.' ) { pszStaticResult[i] = '\0'; break; } if( pszStaticResult[i] == '/' || pszStaticResult[i] == '\\' || pszStaticResult[i] == ':' ) break; } } /* -------------------------------------------------------------------- */ /* Append the new extension. */ /* -------------------------------------------------------------------- */ if (CPLStrlcat( pszStaticResult, ".", CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE || CPLStrlcat( pszStaticResult, pszExt, CPL_PATH_BUF_SIZE) >= CPL_PATH_BUF_SIZE) return CPLStaticBufferTooSmall(pszStaticResult); return pszStaticResult; }