1
0
Fork 0
forked from len0rd/rockbox

Extend path_append_ex to truncate compname, remove some strmemdupa

remove some duplicated strings previously allocd off the stack

just removing string duplications that are easily handled with truncation
now available with path_append_ex()

this also has an advantage of less stack used in worst case scenarios

Change-Id: I3a43e33ef8a8c36599e4c6c036a0ccdd8ed0c883
This commit is contained in:
William Wilgus 2023-11-11 00:01:34 -05:00 committed by William Wilgus
parent a7d0ff2000
commit dbe20d453d
6 changed files with 122 additions and 56 deletions

View file

@ -2488,44 +2488,81 @@ struct get_path_sub_data
static ssize_t get_path_sub(int idx, struct get_path_sub_data *data)
{
#ifdef HAVE_MULTIVOLUME
#define NAMEBUFLEN (MAX(VOL_MAX_LEN+1, MAX_TINYNAME+1))
#else
#define NAMEBUFLEN (MAX_TINYNAME+1)
#endif
char namebuf[NAMEBUFLEN];
#undef NAMEBUFLEN
if (idx == 0)
return -1; /* entry is an orphan split from any root */
ssize_t len;
char *cename;
char *cename = "";
size_t cename_len = (-1u);
ssize_t len = 0;
int next_idx = idx;
int count = 1; /* +1 for the idx incoming */
int remain;
if (idx > 0)
do /* go all the way up to the root */
{
struct dircache_entry *ce = get_entry(idx);
count++;
if (next_idx > (int)dircache.numentries)
return -1; /* ERROR! */
next_idx = dircache_runinfo.pentry[next_idx].up;
} while (next_idx > 0);
data->serialhash = dc_hash_serialnum(ce->serialnum, data->serialhash);
/* go all the way up then move back down from the root */
len = get_path_sub(ce->up, data) - 1;
if (len < 0)
return -2;
cename = alloca(DC_MAX_NAME + 1);
entry_name_copy(cename, ce);
}
else /* idx < 0 */
if (next_idx < 0) /* root */
{
len = 0;
cename = "";
#ifdef HAVE_MULTIVOLUME
/* prepend the volume specifier */
int volume = IF_MV_VOL(-idx - 1);
cename = alloca(VOL_MAX_LEN+1);
get_volume_name(volume, cename);
#endif /* HAVE_MULTIVOLUME */
data->serialhash = dc_hash_serialnum(get_idx_dcvolp(idx)->serialnum,
data->serialhash = dc_hash_serialnum(get_idx_dcvolp(next_idx)->serialnum,
data->serialhash);
#ifdef HAVE_MULTIVOLUME
/* prepend the volume specifier */
cename = namebuf;
get_volume_name(IF_MV_VOL(-next_idx - 1), cename);
#endif /* HAVE_MULTIVOLUME */
}
return len + path_append(data->buf + len, PA_SEP_HARD, cename,
/* we have the volume name write it to the buffer */
goto write_path_component;
/* if not MULTIVOLUME it will just be adding '/' */
while (next_idx > 0 && count > 0)
{
struct dircache_entry *ce = &dircache_runinfo.pentry[next_idx];
if (remain <= 0)
{
data->serialhash = dc_hash_serialnum(ce->serialnum, data->serialhash);
if (LIKELY(!ce->tinyname))
{
cename = get_name(ce->name);
cename_len = CE_NAMESIZE(ce->namelen);
}
else
{
cename = namebuf;
entry_name_copy(cename, ce);
cename_len = -1u;
}
write_path_component:
len += path_append_ex(data->buf + len, PA_SEP_HARD, -1u, cename, cename_len,
data->size > (size_t)len ? data->size - len : 0);
count--;
remain = count - 1;
next_idx = idx;
}
else
{
remain--;
next_idx = ce->up;
}
}
return len;
}
/**