summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/playlist.c9
-rw-r--r--firmware/common/pathfuncs.c51
-rw-r--r--firmware/export/pathfuncs.h1
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 */
347void 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);
82size_t path_dirname(const char *name, const char **nameptr); 82size_t path_dirname(const char *name, const char **nameptr);
83size_t path_strip_trailing_separators(const char *name, const char **nameptr); 83size_t path_strip_trailing_separators(const char *name, const char **nameptr);
84void path_correct_separators(char *dstpath, const char *path); 84void path_correct_separators(char *dstpath, const char *path);
85void 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 */