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,
|
||||
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 */
|
||||
|
|
|
|||
|
|
@ -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: "/"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue