1
0
Fork 0
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:
Michael Sevakis 2017-01-07 07:12:10 -05:00
parent 5a0a7b8b58
commit 5c6ccb43b5
3 changed files with 47 additions and 41 deletions

View file

@ -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,
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';
/* replace backslashes with forward slashes */
/* Replace backslashes with forward slashes */
path_correct_separators(src, src);
/* handle DOS style drive letter and parse non-greedily so that:
* 1) "c:/foo" becomes "/foo" and the result is absolute
* 2) "c:foo becomes "foo" and the result is relative
* This is how Windows seems to handle it except drive letters are of no
* meaning here. */
path_strip_drive(src, (const char **)&src, false);
/* Drive letters have no meaning here; handle DOS style drive letter
* and parse greedily so that:
*
* 1) "c:/foo" is fully qualified, use directory volume only
* 2) "c:foo" is relative to current directory on C, use directory path
*
* 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);
if (len >= (size_t)buf_length)
return -1; /* buffer too small */

View file

@ -197,35 +197,6 @@ int path_strip_drive(const char *name, const char **nameptr, bool greedy)
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
* "" *nameptr->NUL, len=0: ""
* "/" *nameptr->/, len=1: "/"

View file

@ -78,7 +78,6 @@ int get_volume_name(int volume, char *name);
#endif
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_dirname(const char *name, const char **nameptr);
size_t path_strip_trailing_separators(const char *name, const char **nameptr);