in FreeRTOS-Plus/Source/Reliance-Edge/posix/path.c [63:185]
REDSTATUS RedPathSplit(
const char *pszPath,
uint8_t *pbVolNum,
const char **ppszLocalPath)
{
REDSTATUS ret = 0;
if(pszPath == NULL)
{
ret = -RED_EINVAL;
}
else
{
const char *pszLocalPath = pszPath;
uint8_t bMatchVol = UINT8_MAX;
uint32_t ulMatchLen = 0U;
uint8_t bDefaultVolNum = UINT8_MAX;
uint8_t bVolNum;
for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++)
{
const char *pszPrefix = gaRedVolConf[bVolNum].pszPathPrefix;
uint32_t ulPrefixLen = RedStrLen(pszPrefix);
if(ulPrefixLen == 0U)
{
/* A volume with a path prefix of an empty string is the
default volume, used when the path does not match the
prefix of any other volume.
The default volume should only be found once. During
initialization, RedCoreInit() ensures that all volume
prefixes are unique (including empty prefixes).
*/
REDASSERT(bDefaultVolNum == UINT8_MAX);
bDefaultVolNum = bVolNum;
}
/* For a path to match, it must either be the prefix exactly, or
be followed by a path separator character. Thus, with a volume
prefix of "/foo", both "/foo" and "/foo/bar" are matches, but
"/foobar" is not.
*/
else if( (RedStrNCmp(pszPath, pszPrefix, ulPrefixLen) == 0)
&& ((pszPath[ulPrefixLen] == '\0') || (pszPath[ulPrefixLen] == REDCONF_PATH_SEPARATOR)))
{
/* The length of this match should never exactly equal the
length of a previous match: that would require a duplicate
volume name, which should have been detected during init.
*/
REDASSERT(ulPrefixLen != ulMatchLen);
/* If multiple prefixes match, the longest takes precedence.
Thus, if there are two prefixes "Flash" and "Flash/Backup",
the path "Flash/Backup/" will not be erroneously matched
with the "Flash" volume.
*/
if(ulPrefixLen > ulMatchLen)
{
bMatchVol = bVolNum;
ulMatchLen = ulPrefixLen;
}
}
else
{
/* No match, keep looking.
*/
}
}
if(bMatchVol != UINT8_MAX)
{
/* The path matched a volume path prefix.
*/
bVolNum = bMatchVol;
pszLocalPath = &pszPath[ulMatchLen];
}
else if(bDefaultVolNum != UINT8_MAX)
{
/* The path didn't match any of the prefixes, but one of the
volumes has a path prefix of "", so an unprefixed path is
assigned to that volume.
*/
bVolNum = bDefaultVolNum;
REDASSERT(pszLocalPath == pszPath);
}
else
{
/* The path cannot be assigned a volume.
*/
ret = -RED_ENOENT;
}
if(ret == 0)
{
if(pbVolNum != NULL)
{
*pbVolNum = bVolNum;
}
if(ppszLocalPath != NULL)
{
*ppszLocalPath = pszLocalPath;
}
else
{
/* If no local path is expected, then the string should either
terminate after the path prefix or the local path should name
the root directory. Allowing path separators here means that
red_mount("/data/") is OK with a path prefix of "/data".
*/
if(pszLocalPath[0U] != '\0')
{
if(!IsRootDir(pszLocalPath))
{
ret = -RED_ENOENT;
}
}
}
}
}
return ret;
}