forked from len0rd/rockbox
Fix track formatting problems in playlist.c
Some changes in behavior were made with filesystem code commit for the sake of compatibility that changed expected behavior. * Restore substitution of drive spec in fully-qualified DOS paths with the playlists's volume spec (or root on univolume targets). Drive-relative paths of the form "c:foo" (no separator after ':') will be treated as purely relative. * Restore old behavior of preserving leading whitespace in the source path and trimming only trailing tabs and spaces. * Multivolume: Volume substition on fully-qualified UNIX/RB paths has NOT been reintroduced (and perhaps wasn't intended in the first place). They will not be modified because there is no ambiguity to resolve. Doing so would prevent a playlist on external storage from referencing a file on main storage without qualifying it with "/<0>...". * Plain relative paths are and always have been interpreted as relative to the location of the playlist. Change-Id: Ic0800cea79c59563b7bac20f8b08abb5051906c7
This commit is contained in:
parent
5a0a7b8b58
commit
5c6ccb43b5
3 changed files with 47 additions and 41 deletions
|
|
@ -1712,23 +1712,59 @@ static int check_subdir_for_music(char *dir, const char *subdir, bool recurse)
|
||||||
static ssize_t format_track_path(char *dest, char *src, int buf_length,
|
static ssize_t format_track_path(char *dest, char *src, int buf_length,
|
||||||
const char *dir)
|
const char *dir)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len = 0;
|
||||||
|
|
||||||
|
/* Look for the end of the string */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int c = src[len];
|
||||||
|
if (c == '\n' || c == '\r' || c == '\0')
|
||||||
|
break;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now work back killing white space */
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
int c = src[len - 1];
|
||||||
|
if (c != '\t' && c != ' ')
|
||||||
|
break;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
/* strip whitespace at beginning and end */
|
|
||||||
len = path_trim_whitespace(src, (const char **)&src);
|
|
||||||
src[len] = '\0';
|
src[len] = '\0';
|
||||||
|
|
||||||
/* replace backslashes with forward slashes */
|
/* Replace backslashes with forward slashes */
|
||||||
path_correct_separators(src, src);
|
path_correct_separators(src, src);
|
||||||
|
|
||||||
/* handle DOS style drive letter and parse non-greedily so that:
|
/* Drive letters have no meaning here; handle DOS style drive letter
|
||||||
* 1) "c:/foo" becomes "/foo" and the result is absolute
|
* and parse greedily so that:
|
||||||
* 2) "c:foo becomes "foo" and the result is relative
|
*
|
||||||
* This is how Windows seems to handle it except drive letters are of no
|
* 1) "c:/foo" is fully qualified, use directory volume only
|
||||||
* meaning here. */
|
* 2) "c:foo" is relative to current directory on C, use directory path
|
||||||
path_strip_drive(src, (const char **)&src, false);
|
*
|
||||||
|
* Assume any volume on the beginning of the directory path is actually
|
||||||
|
* the volume on which it resides. This may not be the case if the dir
|
||||||
|
* param contains a path such as "/<1>/foo/../../<0>/bar", which refers
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
if (path_strip_drive(src, (const char **)&src, true) >= 0 &&
|
||||||
|
src[-1] == PATH_SEPCH)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_MULTIVOLUME
|
||||||
|
const char *p;
|
||||||
|
path_strip_volume(dir, &p, false);
|
||||||
|
dir = strmemdupa(dir, p - dir); /* empty if no volspec on dir */
|
||||||
|
#else
|
||||||
|
dir = ""; /* only volume is root */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* prepends directory only if src is relative */
|
|
||||||
len = path_append(dest, *dir ? dir : PATH_ROOTSTR, src, buf_length);
|
len = path_append(dest, *dir ? dir : PATH_ROOTSTR, src, buf_length);
|
||||||
if (len >= (size_t)buf_length)
|
if (len >= (size_t)buf_length)
|
||||||
return -1; /* buffer too small */
|
return -1; /* buffer too small */
|
||||||
|
|
|
||||||
|
|
@ -197,35 +197,6 @@ int path_strip_drive(const char *name, const char **nameptr, bool greedy)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Strips leading and trailing whitespace from a path
|
|
||||||
* " a/b \txyz" *nameptr->a, len=3: "a/b"
|
|
||||||
*/
|
|
||||||
size_t path_trim_whitespace(const char *name, const char **nameptr)
|
|
||||||
{
|
|
||||||
/* NOTE: this won't currently treat DEL (0x7f) as non-printable */
|
|
||||||
const unsigned char *p = name;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
while ((c = *p) <= ' ' && c)
|
|
||||||
++p;
|
|
||||||
|
|
||||||
const unsigned char *first = p;
|
|
||||||
const unsigned char *last = p;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (c < ' ')
|
|
||||||
{
|
|
||||||
*nameptr = first;
|
|
||||||
return last - first;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((c = *++p) > ' ');
|
|
||||||
last = p;
|
|
||||||
while (c == ' ') c = *++p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Strips directory components from the path
|
/* Strips directory components from the path
|
||||||
* "" *nameptr->NUL, len=0: ""
|
* "" *nameptr->NUL, len=0: ""
|
||||||
* "/" *nameptr->/, len=1: "/"
|
* "/" *nameptr->/, len=1: "/"
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,6 @@ int get_volume_name(int volume, char *name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int path_strip_drive(const char *name, const char **nameptr, bool greedy);
|
int path_strip_drive(const char *name, const char **nameptr, bool greedy);
|
||||||
size_t path_trim_whitespace(const char *name, const char **nameptr);
|
|
||||||
size_t path_basename(const char *name, const char **nameptr);
|
size_t path_basename(const char *name, const char **nameptr);
|
||||||
size_t path_dirname(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);
|
size_t path_strip_trailing_separators(const char *name, const char **nameptr);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue