void FF_CreateShortName()

in ff_dir.c [2187:2367]


    void FF_CreateShortName( FF_FindParams_t * pxFindParams,
                             const FF_T_WCHAR * pcLongName )
#else
    void FF_CreateShortName( FF_FindParams_t * pxFindParams,
                             const char * pcLongName )
#endif
{
    BaseType_t xIndex, xPosition, xLastDot;
    uint16_t NameLen;

    #if ( ffconfigSHORTNAME_CASE != 0 )
        uint8_t testAttrib = FF_FAT_CASE_ATTR_BASE;
    #endif

    /* Examples:
     * "readme.TXT" will get the attribute FF_FAT_CASE_ATTR_BASE
     * "README.txt" will get the attribute FF_FAT_CASE_ATTR_EXT
     * "Readme.txt" can not be store as a short name */

    pxFindParams->ucCaseAttrib = 0;     /* May get the value FF_FAT_CASE_ATTR_BASE or FF_FAT_CASE_ATTR_EXT */
    pxFindParams->ucFirstTilde = 6;     /* The numerical position of the ~ */
    pxFindParams->ulFlags |= FIND_FLAG_SHORTNAME_SET | FIND_FLAG_FITS_SHORT | FIND_FLAG_SIZE_OK;

    #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
        {
            NameLen = ( uint16_t ) wcslen( pcLongName );
        }
    #else
        {
            NameLen = ( uint16_t ) strlen( pcLongName );
        }
    #endif

    /* Does pcLongName fit a shortname? */

    for( xIndex = 0, xPosition = 0, xLastDot = NameLen; xIndex < NameLen; xIndex++ )
    {
        if( pcLongName[ xIndex ] != '.' )
        {
            xPosition++;
        }
        else
        {
            xLastDot = xIndex;
        }
    }

    /* For example:
     * "FILENAME.EXT": NameLen = 12, xLastDot = 8, xPosition = 11
     * ".cproject"   : NameLen =  9, xLastDot = 0, xPosition =  8
     */

    if( ( NameLen > 12 ) ||             /* If name is longer than 12 characters (8.3). */
        ( NameLen - xPosition > 1 ) ||  /* If it contains more than 1 dot. */
        ( NameLen - xLastDot > 4 ) ||   /* If the file name extension is longer than 3 characters. */
        ( xLastDot > 8 ) )              /* If the file name base is too long. */
    {
        pxFindParams->ulFlags &= ~FIND_FLAG_SIZE_OK;
    }

    for( xIndex = 0, xPosition = 0; xIndex < 11; xPosition++ )
    {
        char ch = pcLongName[ xPosition ];

        if( !ch )
        {
            break;
        }

        if( ( xIndex == 0 ) && ( ch == '.' ) )
        {
            pxFindParams->ulFlags &= ~FIND_FLAG_FITS_SHORT;
            continue;
        }

        if( xPosition == xLastDot )
        {
            /* Remember where we put the first space. */
            if( pxFindParams->ucFirstTilde > xIndex )
            {
                pxFindParams->ucFirstTilde = xIndex;
            }

            while( xIndex < 8 )
            {
                pxFindParams->pcEntryBuffer[ xIndex++ ] = 0x20;
            }

            #if ( ffconfigSHORTNAME_CASE != 0 )
                {
                    testAttrib = FF_FAT_CASE_ATTR_EXT;
                }
            #endif
        }
        else
        {
            if( xIndex == 8 )
            {
                if( xPosition <= xLastDot )
                {
                    xPosition = xLastDot;
                    ch = ( int8_t ) pcLongName[ xPosition ];

                    if( ch == '\0' )
                    {
                        break;
                    }

                    ch = ( int8_t ) pcLongName[ ++xPosition ];
                    #if ( ffconfigSHORTNAME_CASE != 0 )
                        {
                            testAttrib = FF_FAT_CASE_ATTR_EXT;
                        }
                    #endif
                }
            }

            if( !FF_ValidShortChar( ch ) )
            {
                pxFindParams->ulFlags &= ~FIND_FLAG_FITS_SHORT;
                continue;
            }

            #if ( ffconfigSHORTNAME_CASE != 0 )
                {
                    if( ( ch >= 'a' ) && ( ch <= 'z' ) )
                    {
                        ch -= 0x20;

                        if( testAttrib )
                        {
                            pxFindParams->ucCaseAttrib |= testAttrib;
                        }
                        else
                        {
                            pxFindParams->ulFlags &= ~FIND_FLAG_FITS_SHORT; /* We had capital: does not fit. */
                        }
                    }
                    else if( ( ch >= 'A' ) && ( ch <= 'Z' ) )
                    {
                        if( ( pxFindParams->ucCaseAttrib & testAttrib ) != 0 )
                        {
                            pxFindParams->ulFlags &= ~FIND_FLAG_FITS_SHORT; /* We had lower-case: does not fit. */
                        }

                        testAttrib = 0;
                    }
                }
            #else /* if ( ffconfigSHORTNAME_CASE != 0 ) */
                {
                    if( ( ch >= 'a' ) && ( ch <= 'z' ) )
                    {
                        ch -= 0x20;
                    }
                }
            #endif /* ffconfigSHORTNAME_CASE */
            pxFindParams->pcEntryBuffer[ xIndex++ ] = ch;
        }
    }

    if( ( xLastDot == 0 ) && ( xIndex < 6 ) )
    {
        /* This is a file name like ".info" or ".root" */
        pxFindParams->ucFirstTilde = xIndex;
    }

    while( xIndex < 11 )
    {
        pxFindParams->pcEntryBuffer[ xIndex++ ] = 0x20;
    }

    if( ( xLastDot < pxFindParams->ucFirstTilde ) && ( xLastDot > 0 ) )
    {
        pxFindParams->ucFirstTilde = xLastDot;
    }

    if( NameLen < pxFindParams->ucFirstTilde )  /* Names like "Abc" will become "~Abc". */
    {
        pxFindParams->ucFirstTilde = ( uint8_t ) NameLen;
    }
}   /* FF_CreateShortName() */