mirror of https://github.com/rusefi/ChibiOS.git
Added a path normalization function, minor doc fixes.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15239 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
2063cec94d
commit
d28faca5e1
|
@ -56,6 +56,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
msg_t vfs_path_append(char *dst, const char *src);
|
||||
msg_t vfs_path_normalize(char *dst, const char *src);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -67,7 +67,7 @@ static struct {
|
|||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief VFS initialization.
|
||||
* @brief VFS path buffers initialization.
|
||||
*
|
||||
* @init
|
||||
*/
|
||||
|
|
|
@ -91,7 +91,8 @@ msg_t vfs_parse_match_end(const char **pathp) {
|
|||
|
||||
/**
|
||||
* @brief Fetches the next path element.
|
||||
* @note Consumes the next path separator, if any.
|
||||
* @note Does not consume the next separator, if any.
|
||||
* @note It can return an empty element, it has to be detected outside.
|
||||
*
|
||||
* @param[in, out] pathp pointer to the path under parsing
|
||||
* @param[out] fname extracted file name
|
||||
|
@ -108,26 +109,21 @@ msg_t vfs_parse_get_fname(const char **pathp, char *fname) {
|
|||
/* Path elements must be terminated by a separator or an end-of-string.*/
|
||||
if (vfs_parse_is_separator(c) || vfs_parse_is_terminator(c)) {
|
||||
|
||||
/* Consecutive separators are not valid.*/
|
||||
if (size == 0U) {
|
||||
return VFS_RET_ENOENT;
|
||||
}
|
||||
|
||||
/* Advancing the path pointer past the file name in the path and
|
||||
closing the file name string.*/
|
||||
*pathp = p;
|
||||
*fname = '\0';
|
||||
return VFS_RET_SUCCESS;
|
||||
return (msg_t)size;
|
||||
}
|
||||
|
||||
/* Valid characters for path names.*/
|
||||
if (!vfs_parse_is_filechar(c)) {
|
||||
return VFS_RET_ENOENT;
|
||||
return VFS_RET_EINVAL;
|
||||
}
|
||||
|
||||
/* Exceeding the path element length.*/
|
||||
if (size > VFS_CFG_NAMELEN_MAX) {
|
||||
return VFS_RET_ENOENT;
|
||||
return VFS_RET_ENAMETOOLONG;
|
||||
}
|
||||
|
||||
*fname++ = c;
|
||||
|
|
|
@ -101,4 +101,81 @@ msg_t vfs_path_append(char *dst, const char *src) {
|
|||
return VFS_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Normalizes an absolute path.
|
||||
*
|
||||
* @param[out] dst The destination buffer.
|
||||
* @param[in] src The source path.
|
||||
* @return The operation status.
|
||||
* @retval VFS_RET_ENAMETOOLONG If the path size exceeded @p VFS_CFG_PATHLEN_MAX.
|
||||
*/
|
||||
msg_t vfs_path_normalize(char *dst, const char *src) {
|
||||
size_t size;
|
||||
|
||||
VFS_RETURN_ON_ERROR(vfs_parse_match_separator(&src));
|
||||
|
||||
*dst++ = '/';
|
||||
size = 1U;
|
||||
while (true) {
|
||||
|
||||
/* Consecutive input separators are consumed.*/
|
||||
while (vfs_parse_is_separator(*src)) {
|
||||
src++;
|
||||
}
|
||||
msg_t ret;
|
||||
size_t n;
|
||||
|
||||
/* Getting next element from the input path and copying it to
|
||||
the output path.*/
|
||||
ret = vfs_parse_get_fname(&src, dst);
|
||||
VFS_RETURN_ON_ERROR(ret);
|
||||
|
||||
n = (size_t)ret;
|
||||
if (n == 0U) {
|
||||
|
||||
/* If the path contains something after the root separator.*/
|
||||
if (size > 1U) {
|
||||
/* No next path element, replacing the last separator with a zero.*/
|
||||
size--;
|
||||
*(dst - 1) = '\0';
|
||||
}
|
||||
|
||||
return (msg_t)size;
|
||||
}
|
||||
|
||||
/* Handling special cases of "." and "..".*/
|
||||
if (strcmp(dst, ".") == 0) {
|
||||
/* Single dot elements are discarded.*/
|
||||
/* Consecutive input separators are consumed.*/
|
||||
continue;
|
||||
}
|
||||
else if (strcmp(dst, "..") == 0) {
|
||||
/* Double dot elements require to remove the last element from
|
||||
the output path.*/
|
||||
if (size > 1) {
|
||||
/* Back on the separator.*/
|
||||
dst--;
|
||||
size--;
|
||||
|
||||
/* Scanning back to just after the previous separator.*/
|
||||
do {
|
||||
dst--;
|
||||
size--;
|
||||
} while(!vfs_parse_is_separator(*(dst - 1)));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
dst += n;
|
||||
size += n;
|
||||
|
||||
/* Adding a single separator to the output.*/
|
||||
*dst++ = '/';
|
||||
size++;
|
||||
|
||||
do {
|
||||
} while (false);
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
Loading…
Reference in New Issue