cpl/cpl_path.cpp
const char *CPLProjectRelativeFilename( const char *pszProjectDir, 
                                        const char *pszSecondaryFilename )

{
    char *pszStaticResult = CPLGetStaticResult();

    if( !CPLIsFilenameRelative( pszSecondaryFilename ) )
        return pszSecondaryFilename;

    if( pszProjectDir == NULL || strlen(pszProjectDir) == 0 )
        return pszSecondaryFilename;

    strncpy( pszStaticResult, pszProjectDir, CPL_PATH_BUF_SIZE );
    pszStaticResult[CPL_PATH_BUF_SIZE - 1] = '\0';

    if( pszProjectDir[strlen(pszProjectDir)-1] != '/' 
        && pszProjectDir[strlen(pszProjectDir)-1] != '\\' )
    {
        CPLAssert( strlen(SEP_STRING) + 1 < CPL_PATH_BUF_SIZE );

        strcat( pszStaticResult, SEP_STRING );
    }

    CPLAssert( strlen(pszSecondaryFilename) + 1 < CPL_PATH_BUF_SIZE );

    strcat( pszStaticResult, pszSecondaryFilename );
        
    return pszStaticResult;
}
/**
 * Find a file relative to a project file. 
 *
 * Given the path to a "project" directory, and a path to a secondary file
 * referenced from that project, build a path to the secondary file
 * that the current application can use.  If the secondary path is already
 * absolute, rather than relative, then it will be returned unaltered. 
 * 
 * Examples:
 * <pre>
 * CPLProjectRelativeFilename("abc/def","tmp/abc.gif") == "abc/def/tmp/abc.gif"
 * CPLProjectRelativeFilename("abc/def","/tmp/abc.gif") == "/tmp/abc.gif"
 * CPLProjectRelativeFilename("/xy", "abc.gif") == "/xy/abc.gif"
 * CPLProjectRelativeFilename("/abc/def","../abc.gif") == "/abc/def/../abc.gif"
 * CPLProjectRelativeFilename("C:\WIN","abc.gif") == "C:\WIN\abc.gif"
 * </pre>
 *
 * @param pszProjectDir the directory relative to which the secondary files 
 * path should be interpreted.
 * @param pszSecondaryFilename the filename (potentially with path) that
 * is to be interpreted relative to the project directory.
 *
 * @return a composed path to the secondary file.  The returned string is
 * internal and should not be altered, freed, or depending on past the next
 * CPL call. 
 */
Find a file relative to a project file.
Given the path to a "project" directory, and a path to a secondary file
referenced from that project, build a path to the secondary file
that the current application can use.  If the secondary path is already
absolute, rather than relative, then it will be returned unaltered.



@param pszProjectDir the directory relative to which the secondary files
path should be interpreted.
@param pszSecondaryFilename the filename (potentially with path) that
is to be interpreted relative to the project directory.

@return a composed path to the secondary file.  The returned string is
internal and should not be altered, freed, or depending on past the next
CPL call.
Find a file relative to a project file . Given the path to a " project " directory and a path to a secondary file referenced from that project build a path to the secondary file that the current application can use . If the secondary path is already absolute rather than relative then it will be returned unaltered . @param pszProjectDir the directory relative to which the secondary files path should be interpreted . @param pszSecondaryFilename the filename ( potentially with path ) that is to be interpreted relative to the project directory . @return a composed path to the secondary file . The returned string is internal and should not be altered freed or depending on past the next CPL call .
const char *CPLProjectRelativeFilename( const char *pszProjectDir, 
                                        const char *pszSecondaryFilename )
{
    char *pszStaticResult = CPLGetStaticResult();
    if( !CPLIsFilenameRelative( pszSecondaryFilename ) )
        return pszSecondaryFilename;
    if( pszProjectDir == NULL || strlen(pszProjectDir) == 0 )
        return pszSecondaryFilename;
    strncpy( pszStaticResult, pszProjectDir, CPL_PATH_BUF_SIZE );
    pszStaticResult[CPL_PATH_BUF_SIZE - 1] = '\0';
    if( pszProjectDir[strlen(pszProjectDir)-1] != '/' 
        && pszProjectDir[strlen(pszProjectDir)-1] != '\\' )
    {
        CPLAssert( strlen(SEP_STRING) + 1 < CPL_PATH_BUF_SIZE );
        strcat( pszStaticResult, SEP_STRING );
    }
    CPLAssert( strlen(pszSecondaryFilename) + 1 < CPL_PATH_BUF_SIZE );
    strcat( pszStaticResult, pszSecondaryFilename );
    return pszStaticResult;
}
const char * CPLProjectRelativeFilename ( const char * pszProjectDir , const char * pszSecondaryFilename ) { char * pszStaticResult = CPLGetStaticResult ( ) ; if ( ! CPLIsFilenameRelative ( pszSecondaryFilename ) ) return pszSecondaryFilename ; if ( pszProjectDir == NULL || strlen ( pszProjectDir ) == 0 ) return pszSecondaryFilename ; strncpy ( pszStaticResult , pszProjectDir , CPL_PATH_BUF_SIZE ) ; pszStaticResult [ CPL_PATH_BUF_SIZE - 1 ] = ' \0 ' ; if ( pszProjectDir [ strlen ( pszProjectDir ) - 1 ] != ' ' && pszProjectDir [ strlen ( pszProjectDir ) - 1 ] != ' \\ ' ) { CPLAssert ( strlen ( SEP_STRING ) + 1 < CPL_PATH_BUF_SIZE ) ; strcat ( pszStaticResult , SEP_STRING ) ; } CPLAssert ( strlen ( pszSecondaryFilename ) + 1 < CPL_PATH_BUF_SIZE ) ; strcat ( pszStaticResult , pszSecondaryFilename ) ; return pszStaticResult ; }
Find a file relative to a project file.
Find a file relative to a project file .