diff options
author | James D. Smith <smithjd15@gmail.com> | 2021-09-18 21:09:24 -0600 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2021-09-19 21:05:58 -0400 |
commit | 760277e096cd35629166367352c108d6ab3b59c2 (patch) | |
tree | 75967beb624e48f51943ffa98ff562110e5c1d97 | |
parent | 67716c6b46a7780bff6b80408b3452c01bfbfdc4 (diff) | |
download | rockbox-760277e096cd35629166367352c108d6ab3b59c2.tar.gz rockbox-760277e096cd35629166367352c108d6ab3b59c2.zip |
Dir cache: Fix resume of relative path playlists.
Slightly modified from original patch by Fabrice Bellard.
Change-Id: I9ae04fa460f0f1b9c616e6f99505d4c5d4358f68
-rw-r--r-- | apps/playlist.c | 9 | ||||
-rw-r--r-- | firmware/common/pathfuncs.c | 51 | ||||
-rw-r--r-- | firmware/export/pathfuncs.h | 1 |
3 files changed, 57 insertions, 4 deletions
diff --git a/apps/playlist.c b/apps/playlist.c index 49c52a9b7e..0d02be3d48 100644 --- a/apps/playlist.c +++ b/apps/playlist.c | |||
@@ -1762,9 +1762,8 @@ static ssize_t format_track_path(char *dest, char *src, int buf_length, | |||
1762 | * to "/<0>/bar" (aka "/bar" at this time). *fingers crossed* | 1762 | * to "/<0>/bar" (aka "/bar" at this time). *fingers crossed* |
1763 | * | 1763 | * |
1764 | * If any stripped drive spec was absolute, prepend the playlist | 1764 | * If any stripped drive spec was absolute, prepend the playlist |
1765 | * directory's volume spec, or root if none. Relative paths remain | 1765 | * directory's volume spec, or root if none. Absolute UNIX-style paths |
1766 | * relative and the playlist's directory fully qualifies them. Absolute | 1766 | * remain unaltered. |
1767 | * UNIX-style paths remain unaltered. | ||
1768 | */ | 1767 | */ |
1769 | if (path_strip_drive(src, (const char **)&src, true) >= 0 && | 1768 | if (path_strip_drive(src, (const char **)&src, true) >= 0 && |
1770 | src[-1] == PATH_SEPCH) | 1769 | src[-1] == PATH_SEPCH) |
@@ -1782,7 +1781,9 @@ static ssize_t format_track_path(char *dest, char *src, int buf_length, | |||
1782 | if (len >= (size_t)buf_length) | 1781 | if (len >= (size_t)buf_length) |
1783 | return -1; /* buffer too small */ | 1782 | return -1; /* buffer too small */ |
1784 | 1783 | ||
1785 | return len; | 1784 | path_remove_dot_segments (dest, dest); |
1785 | |||
1786 | return strlen (dest); | ||
1786 | } | 1787 | } |
1787 | 1788 | ||
1788 | /* | 1789 | /* |
diff --git a/firmware/common/pathfuncs.c b/firmware/common/pathfuncs.c index 1c48a54972..2b4e6a8eb0 100644 --- a/firmware/common/pathfuncs.c +++ b/firmware/common/pathfuncs.c | |||
@@ -340,6 +340,57 @@ void path_correct_separators(char *dstpath, const char *path) | |||
340 | strcpy(dstp, p); | 340 | strcpy(dstp, p); |
341 | } | 341 | } |
342 | 342 | ||
343 | /* Remove dot segments from the path | ||
344 | * | ||
345 | * 'path' and 'dstpath' may either be the same buffer or non-overlapping | ||
346 | */ | ||
347 | void path_remove_dot_segments (char *dstpath, const char *path) | ||
348 | { | ||
349 | char *dstp = dstpath; | ||
350 | char *odstp = dstpath; | ||
351 | const char *p = path; | ||
352 | |||
353 | while (*p) | ||
354 | { | ||
355 | if (p[0] == '.' && p[1] == PATH_SEPCH) | ||
356 | p += 2; | ||
357 | else if (p[0] == '.' && p[1] == '.' && p[2] == PATH_SEPCH) | ||
358 | p += 3; | ||
359 | else if (p[0] == PATH_SEPCH && p[1] == '.' && p[2] == PATH_SEPCH) | ||
360 | p += 2; | ||
361 | else if (p[0] == PATH_SEPCH && p[1] == '.' && !p[2]) | ||
362 | { | ||
363 | *dstp++ = PATH_SEPCH; | ||
364 | break; | ||
365 | } | ||
366 | else if (p[0] == PATH_SEPCH && p[1] == '.' && | ||
367 | p[2] == '.' && p[3] == PATH_SEPCH) | ||
368 | { | ||
369 | dstp = odstp; | ||
370 | p += 3; | ||
371 | } | ||
372 | else if (p[0] == PATH_SEPCH && p[1] == '.' && p[2] == '.' && !p[3]) | ||
373 | { | ||
374 | dstp = odstp; | ||
375 | *dstp++ = PATH_SEPCH; | ||
376 | break; | ||
377 | } | ||
378 | else if (p[0] == '.' && !p[1]) | ||
379 | break; | ||
380 | else if (p[0] == '.' && p[1] == '.' && !p[2]) | ||
381 | break; | ||
382 | else | ||
383 | { | ||
384 | odstp = dstp; | ||
385 | if (p[0] == PATH_SEPCH) | ||
386 | *dstp++ = *p++; | ||
387 | while (p[0] && p[0] != PATH_SEPCH) | ||
388 | *dstp++ = *p++; | ||
389 | } | ||
390 | } | ||
391 | *dstp = 0; | ||
392 | } | ||
393 | |||
343 | /* Appends one path to another, adding separators between components if needed. | 394 | /* Appends one path to another, adding separators between components if needed. |
344 | * Return value and behavior is otherwise as strlcpy so that truncation may be | 395 | * Return value and behavior is otherwise as strlcpy so that truncation may be |
345 | * detected. | 396 | * detected. |
diff --git a/firmware/export/pathfuncs.h b/firmware/export/pathfuncs.h index 92539c54c1..350dd4e548 100644 --- a/firmware/export/pathfuncs.h +++ b/firmware/export/pathfuncs.h | |||
@@ -82,6 +82,7 @@ size_t path_basename(const char *name, const char **nameptr); | |||
82 | size_t path_dirname(const char *name, const char **nameptr); | 82 | size_t path_dirname(const char *name, const char **nameptr); |
83 | size_t path_strip_trailing_separators(const char *name, const char **nameptr); | 83 | size_t path_strip_trailing_separators(const char *name, const char **nameptr); |
84 | void path_correct_separators(char *dstpath, const char *path); | 84 | void path_correct_separators(char *dstpath, const char *path); |
85 | void path_remove_dot_segments(char *dstpath, const char *path); | ||
85 | 86 | ||
86 | /* constants useable in basepath and component */ | 87 | /* constants useable in basepath and component */ |
87 | #define PA_SEP_HARD NULL /* separate even if base is empty */ | 88 | #define PA_SEP_HARD NULL /* separate even if base is empty */ |