diff options
-rw-r--r-- | apps/playlist.c | 58 | ||||
-rw-r--r-- | firmware/common/pathfuncs.c | 29 | ||||
-rw-r--r-- | firmware/export/pathfuncs.h | 1 |
3 files changed, 47 insertions, 41 deletions
diff --git a/apps/playlist.c b/apps/playlist.c index 173d445f8c..015e41ae0e 100644 --- a/apps/playlist.c +++ b/apps/playlist.c | |||
@@ -1712,23 +1712,59 @@ static int check_subdir_for_music(char *dir, const char *subdir, bool recurse) | |||
1712 | static ssize_t format_track_path(char *dest, char *src, int buf_length, | 1712 | static ssize_t format_track_path(char *dest, char *src, int buf_length, |
1713 | const char *dir) | 1713 | const char *dir) |
1714 | { | 1714 | { |
1715 | size_t len; | 1715 | size_t len = 0; |
1716 | |||
1717 | /* Look for the end of the string */ | ||
1718 | while (1) | ||
1719 | { | ||
1720 | int c = src[len]; | ||
1721 | if (c == '\n' || c == '\r' || c == '\0') | ||
1722 | break; | ||
1723 | len++; | ||
1724 | } | ||
1725 | |||
1726 | /* Now work back killing white space */ | ||
1727 | while (len > 0) | ||
1728 | { | ||
1729 | int c = src[len - 1]; | ||
1730 | if (c != '\t' && c != ' ') | ||
1731 | break; | ||
1732 | len--; | ||
1733 | } | ||
1716 | 1734 | ||
1717 | /* strip whitespace at beginning and end */ | ||
1718 | len = path_trim_whitespace(src, (const char **)&src); | ||
1719 | src[len] = '\0'; | 1735 | src[len] = '\0'; |
1720 | 1736 | ||
1721 | /* replace backslashes with forward slashes */ | 1737 | /* Replace backslashes with forward slashes */ |
1722 | path_correct_separators(src, src); | 1738 | path_correct_separators(src, src); |
1723 | 1739 | ||
1724 | /* handle DOS style drive letter and parse non-greedily so that: | 1740 | /* Drive letters have no meaning here; handle DOS style drive letter |
1725 | * 1) "c:/foo" becomes "/foo" and the result is absolute | 1741 | * and parse greedily so that: |
1726 | * 2) "c:foo becomes "foo" and the result is relative | 1742 | * |
1727 | * This is how Windows seems to handle it except drive letters are of no | 1743 | * 1) "c:/foo" is fully qualified, use directory volume only |
1728 | * meaning here. */ | 1744 | * 2) "c:foo" is relative to current directory on C, use directory path |
1729 | path_strip_drive(src, (const char **)&src, false); | 1745 | * |
1746 | * Assume any volume on the beginning of the directory path is actually | ||
1747 | * the volume on which it resides. This may not be the case if the dir | ||
1748 | * param contains a path such as "/<1>/foo/../../<0>/bar", which refers | ||
1749 | * to "/<0>/bar" (aka "/bar" at this time). *fingers crossed* | ||
1750 | * | ||
1751 | * If any stripped drive spec was absolute, prepend the playlist | ||
1752 | * directory's volume spec, or root if none. Relative paths remain | ||
1753 | * relative and the playlist's directory fully qualifies them. Absolute | ||
1754 | * UNIX-style paths remain unaltered. | ||
1755 | */ | ||
1756 | if (path_strip_drive(src, (const char **)&src, true) >= 0 && | ||
1757 | src[-1] == PATH_SEPCH) | ||
1758 | { | ||
1759 | #ifdef HAVE_MULTIVOLUME | ||
1760 | const char *p; | ||
1761 | path_strip_volume(dir, &p, false); | ||
1762 | dir = strmemdupa(dir, p - dir); /* empty if no volspec on dir */ | ||
1763 | #else | ||
1764 | dir = ""; /* only volume is root */ | ||
1765 | #endif | ||
1766 | } | ||
1730 | 1767 | ||
1731 | /* prepends directory only if src is relative */ | ||
1732 | len = path_append(dest, *dir ? dir : PATH_ROOTSTR, src, buf_length); | 1768 | len = path_append(dest, *dir ? dir : PATH_ROOTSTR, src, buf_length); |
1733 | if (len >= (size_t)buf_length) | 1769 | if (len >= (size_t)buf_length) |
1734 | return -1; /* buffer too small */ | 1770 | return -1; /* buffer too small */ |
diff --git a/firmware/common/pathfuncs.c b/firmware/common/pathfuncs.c index 1ee5fe9886..f5674983d9 100644 --- a/firmware/common/pathfuncs.c +++ b/firmware/common/pathfuncs.c | |||
@@ -197,35 +197,6 @@ int path_strip_drive(const char *name, const char **nameptr, bool greedy) | |||
197 | return -1; | 197 | return -1; |
198 | } | 198 | } |
199 | 199 | ||
200 | /* Strips leading and trailing whitespace from a path | ||
201 | * " a/b \txyz" *nameptr->a, len=3: "a/b" | ||
202 | */ | ||
203 | size_t path_trim_whitespace(const char *name, const char **nameptr) | ||
204 | { | ||
205 | /* NOTE: this won't currently treat DEL (0x7f) as non-printable */ | ||
206 | const unsigned char *p = name; | ||
207 | int c; | ||
208 | |||
209 | while ((c = *p) <= ' ' && c) | ||
210 | ++p; | ||
211 | |||
212 | const unsigned char *first = p; | ||
213 | const unsigned char *last = p; | ||
214 | |||
215 | while (1) | ||
216 | { | ||
217 | if (c < ' ') | ||
218 | { | ||
219 | *nameptr = first; | ||
220 | return last - first; | ||
221 | } | ||
222 | |||
223 | while ((c = *++p) > ' '); | ||
224 | last = p; | ||
225 | while (c == ' ') c = *++p; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | /* Strips directory components from the path | 200 | /* Strips directory components from the path |
230 | * "" *nameptr->NUL, len=0: "" | 201 | * "" *nameptr->NUL, len=0: "" |
231 | * "/" *nameptr->/, len=1: "/" | 202 | * "/" *nameptr->/, len=1: "/" |
diff --git a/firmware/export/pathfuncs.h b/firmware/export/pathfuncs.h index 26eb4a1067..92539c54c1 100644 --- a/firmware/export/pathfuncs.h +++ b/firmware/export/pathfuncs.h | |||
@@ -78,7 +78,6 @@ int get_volume_name(int volume, char *name); | |||
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | int path_strip_drive(const char *name, const char **nameptr, bool greedy); | 80 | int path_strip_drive(const char *name, const char **nameptr, bool greedy); |
81 | size_t path_trim_whitespace(const char *name, const char **nameptr); | ||
82 | size_t path_basename(const char *name, const char **nameptr); | 81 | size_t path_basename(const char *name, const char **nameptr); |
83 | size_t path_dirname(const char *name, const char **nameptr); | 82 | size_t path_dirname(const char *name, const char **nameptr); |
84 | 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); |