summaryrefslogtreecommitdiff
path: root/firmware/common/dircache.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-06-20 20:12:10 +0000
committerThomas Martitz <kugel@rockbox.org>2011-06-20 20:12:10 +0000
commit38da400e58b78f0fd399bdb8e52e1ba63aca75a7 (patch)
tree1646ffcf66ed7f7218a9486622eac41e2c11259a /firmware/common/dircache.c
parent60e4f20c38853337c4f54a677eb96c0a4488486f (diff)
downloadrockbox-38da400e58b78f0fd399bdb8e52e1ba63aca75a7.tar.gz
rockbox-38da400e58b78f0fd399bdb8e52e1ba63aca75a7.zip
Dircache: Rework and simplify dircache_copy_path().
Use a recursive helper function with strlcat to build up the path backwards. This way the tree doesn't need to be walked twice and no extraneous size calculation is needed. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30033 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r--firmware/common/dircache.c56
1 files changed, 28 insertions, 28 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 69e3f16ec8..dc662bb9cd 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -907,41 +907,41 @@ const struct dircache_entry *dircache_get_entry_ptr(const char *filename)
907 return dircache_get_entry(filename, false); 907 return dircache_get_entry(filename, false);
908} 908}
909 909
910/*
911 * build a path from an entry upto the root using recursion
912 *
913 * it appends '/' after strlcat, therefore buf[0] needs to be prepared with '/'
914 * and it will leave a trailing '/'
915 *
916 * returns the position of that trailing '/' so it can be deleted afterwards
917 * (or, in case of truncation, the position of the nul byte */
918static size_t copy_path_helper(const struct dircache_entry *entry, char *buf, size_t size)
919{
920 /* has parent? */
921 if (entry->up)
922 copy_path_helper(entry->up, buf, size);
923
924 size_t len = strlcat(buf, entry->d_name, size);
925 if (len < size)
926 {
927 buf[len++] = '/';
928 buf[len] = '\0';
929 }
930 return len-1;
931}
910/** 932/**
911 * Function to copy the full absolute path from dircache to the given buffer 933 * Function to copy the full absolute path from dircache to the given buffer
912 * using the given dircache_entry pointer. 934 * using the given dircache_entry pointer.
913 */ 935 */
914void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size) 936void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size)
915{ 937{
916 int path_size = 0; 938 if (size <= 0 || !buf)
917 int idx;
918 const struct dircache_entry *temp = entry;
919
920 if (size <= 0)
921 return ; 939 return ;
922 940
923 /* first compute the necessary size */ 941 buf[0] = '/';
924 while(temp != NULL) 942 size_t res = copy_path_helper(entry, buf, size);
925 { 943 /* fixup trailing '/' */
926 path_size += strlen(temp->d_name) + sizeof('/'); 944 buf[res] = '\0';
927 temp = temp->up;
928 }
929
930 /* now copy the path */
931 idx = path_size;
932 while(entry != NULL)
933 {
934 idx -= strlen(entry->d_name);
935 /* available size */
936 int rem = size - idx;
937
938 if(rem >= 1)
939 {
940 buf[idx] = '/';
941 strlcpy(buf + idx + 1, entry->d_name, rem - 1);
942 }
943 entry = entry->up;
944 }
945} 945}
946 946
947/* --- Directory cache live updating functions --- */ 947/* --- Directory cache live updating functions --- */