Dir cache: Fix resume of relative path playlists.
Slightly modified from original patch by Fabrice Bellard. Change-Id: I9ae04fa460f0f1b9c616e6f99505d4c5d4358f68
This commit is contained in:
parent
67716c6b46
commit
760277e096
3 changed files with 57 additions and 4 deletions
|
@ -1762,9 +1762,8 @@ static ssize_t format_track_path(char *dest, char *src, int buf_length,
|
|||
* to "/<0>/bar" (aka "/bar" at this time). *fingers crossed*
|
||||
*
|
||||
* If any stripped drive spec was absolute, prepend the playlist
|
||||
* directory's volume spec, or root if none. Relative paths remain
|
||||
* relative and the playlist's directory fully qualifies them. Absolute
|
||||
* UNIX-style paths remain unaltered.
|
||||
* directory's volume spec, or root if none. Absolute UNIX-style paths
|
||||
* remain unaltered.
|
||||
*/
|
||||
if (path_strip_drive(src, (const char **)&src, true) >= 0 &&
|
||||
src[-1] == PATH_SEPCH)
|
||||
|
@ -1782,7 +1781,9 @@ static ssize_t format_track_path(char *dest, char *src, int buf_length,
|
|||
if (len >= (size_t)buf_length)
|
||||
return -1; /* buffer too small */
|
||||
|
||||
return len;
|
||||
path_remove_dot_segments (dest, dest);
|
||||
|
||||
return strlen (dest);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -340,6 +340,57 @@ void path_correct_separators(char *dstpath, const char *path)
|
|||
strcpy(dstp, p);
|
||||
}
|
||||
|
||||
/* Remove dot segments from the path
|
||||
*
|
||||
* 'path' and 'dstpath' may either be the same buffer or non-overlapping
|
||||
*/
|
||||
void path_remove_dot_segments (char *dstpath, const char *path)
|
||||
{
|
||||
char *dstp = dstpath;
|
||||
char *odstp = dstpath;
|
||||
const char *p = path;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (p[0] == '.' && p[1] == PATH_SEPCH)
|
||||
p += 2;
|
||||
else if (p[0] == '.' && p[1] == '.' && p[2] == PATH_SEPCH)
|
||||
p += 3;
|
||||
else if (p[0] == PATH_SEPCH && p[1] == '.' && p[2] == PATH_SEPCH)
|
||||
p += 2;
|
||||
else if (p[0] == PATH_SEPCH && p[1] == '.' && !p[2])
|
||||
{
|
||||
*dstp++ = PATH_SEPCH;
|
||||
break;
|
||||
}
|
||||
else if (p[0] == PATH_SEPCH && p[1] == '.' &&
|
||||
p[2] == '.' && p[3] == PATH_SEPCH)
|
||||
{
|
||||
dstp = odstp;
|
||||
p += 3;
|
||||
}
|
||||
else if (p[0] == PATH_SEPCH && p[1] == '.' && p[2] == '.' && !p[3])
|
||||
{
|
||||
dstp = odstp;
|
||||
*dstp++ = PATH_SEPCH;
|
||||
break;
|
||||
}
|
||||
else if (p[0] == '.' && !p[1])
|
||||
break;
|
||||
else if (p[0] == '.' && p[1] == '.' && !p[2])
|
||||
break;
|
||||
else
|
||||
{
|
||||
odstp = dstp;
|
||||
if (p[0] == PATH_SEPCH)
|
||||
*dstp++ = *p++;
|
||||
while (p[0] && p[0] != PATH_SEPCH)
|
||||
*dstp++ = *p++;
|
||||
}
|
||||
}
|
||||
*dstp = 0;
|
||||
}
|
||||
|
||||
/* Appends one path to another, adding separators between components if needed.
|
||||
* Return value and behavior is otherwise as strlcpy so that truncation may be
|
||||
* detected.
|
||||
|
|
|
@ -82,6 +82,7 @@ size_t path_basename(const char *name, const char **nameptr);
|
|||
size_t path_dirname(const char *name, const char **nameptr);
|
||||
size_t path_strip_trailing_separators(const char *name, const char **nameptr);
|
||||
void path_correct_separators(char *dstpath, const char *path);
|
||||
void path_remove_dot_segments(char *dstpath, const char *path);
|
||||
|
||||
/* constants useable in basepath and component */
|
||||
#define PA_SEP_HARD NULL /* separate even if base is empty */
|
||||
|
|
Loading…
Reference in a new issue