diff options
author | William Wilgus <wilgus.william@gmail.com> | 2023-11-11 00:01:34 -0500 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2023-11-19 12:00:02 -0500 |
commit | dbe20d453d5e93bd0f1188a8851c6cf4fd230b26 (patch) | |
tree | 943a01d0aaf051bb7ad47d390bcb848058cb2404 /firmware/common/dircache.c | |
parent | a7d0ff200066ff4d102ffff9e24d3c2b8ef7fde5 (diff) | |
download | rockbox-dbe20d453d5e93bd0f1188a8851c6cf4fd230b26.tar.gz rockbox-dbe20d453d5e93bd0f1188a8851c6cf4fd230b26.zip |
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
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r-- | firmware/common/dircache.c | 89 |
1 files changed, 63 insertions, 26 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 41564194d0..c5062d47ed 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -2488,44 +2488,81 @@ struct get_path_sub_data | |||
2488 | 2488 | ||
2489 | static ssize_t get_path_sub(int idx, struct get_path_sub_data *data) | 2489 | static ssize_t get_path_sub(int idx, struct get_path_sub_data *data) |
2490 | { | 2490 | { |
2491 | |||
2492 | #ifdef HAVE_MULTIVOLUME | ||
2493 | #define NAMEBUFLEN (MAX(VOL_MAX_LEN+1, MAX_TINYNAME+1)) | ||
2494 | #else | ||
2495 | #define NAMEBUFLEN (MAX_TINYNAME+1) | ||
2496 | #endif | ||
2497 | char namebuf[NAMEBUFLEN]; | ||
2498 | #undef NAMEBUFLEN | ||
2499 | |||
2491 | if (idx == 0) | 2500 | if (idx == 0) |
2492 | return -1; /* entry is an orphan split from any root */ | 2501 | return -1; /* entry is an orphan split from any root */ |
2493 | 2502 | ||
2494 | ssize_t len; | 2503 | char *cename = ""; |
2495 | char *cename; | 2504 | size_t cename_len = (-1u); |
2505 | ssize_t len = 0; | ||
2506 | int next_idx = idx; | ||
2507 | int count = 1; /* +1 for the idx incoming */ | ||
2508 | int remain; | ||
2496 | 2509 | ||
2497 | if (idx > 0) | 2510 | do /* go all the way up to the root */ |
2498 | { | 2511 | { |
2499 | struct dircache_entry *ce = get_entry(idx); | 2512 | count++; |
2513 | if (next_idx > (int)dircache.numentries) | ||
2514 | return -1; /* ERROR! */ | ||
2515 | next_idx = dircache_runinfo.pentry[next_idx].up; | ||
2516 | } while (next_idx > 0); | ||
2500 | 2517 | ||
2501 | data->serialhash = dc_hash_serialnum(ce->serialnum, data->serialhash); | 2518 | if (next_idx < 0) /* root */ |
2519 | { | ||
2520 | data->serialhash = dc_hash_serialnum(get_idx_dcvolp(next_idx)->serialnum, | ||
2521 | data->serialhash); | ||
2522 | #ifdef HAVE_MULTIVOLUME | ||
2523 | /* prepend the volume specifier */ | ||
2524 | cename = namebuf; | ||
2525 | get_volume_name(IF_MV_VOL(-next_idx - 1), cename); | ||
2526 | #endif /* HAVE_MULTIVOLUME */ | ||
2527 | } | ||
2502 | 2528 | ||
2503 | /* go all the way up then move back down from the root */ | 2529 | /* we have the volume name write it to the buffer */ |
2504 | len = get_path_sub(ce->up, data) - 1; | 2530 | goto write_path_component; |
2505 | if (len < 0) | 2531 | /* if not MULTIVOLUME it will just be adding '/' */ |
2506 | return -2; | ||
2507 | 2532 | ||
2508 | cename = alloca(DC_MAX_NAME + 1); | 2533 | while (next_idx > 0 && count > 0) |
2509 | entry_name_copy(cename, ce); | ||
2510 | } | ||
2511 | else /* idx < 0 */ | ||
2512 | { | 2534 | { |
2513 | len = 0; | 2535 | struct dircache_entry *ce = &dircache_runinfo.pentry[next_idx]; |
2514 | cename = ""; | 2536 | if (remain <= 0) |
2537 | { | ||
2538 | data->serialhash = dc_hash_serialnum(ce->serialnum, data->serialhash); | ||
2539 | if (LIKELY(!ce->tinyname)) | ||
2540 | { | ||
2541 | cename = get_name(ce->name); | ||
2542 | cename_len = CE_NAMESIZE(ce->namelen); | ||
2543 | } | ||
2544 | else | ||
2545 | { | ||
2546 | cename = namebuf; | ||
2547 | entry_name_copy(cename, ce); | ||
2548 | cename_len = -1u; | ||
2549 | } | ||
2550 | write_path_component: | ||
2551 | len += path_append_ex(data->buf + len, PA_SEP_HARD, -1u, cename, cename_len, | ||
2552 | data->size > (size_t)len ? data->size - len : 0); | ||
2515 | 2553 | ||
2516 | #ifdef HAVE_MULTIVOLUME | 2554 | count--; |
2517 | /* prepend the volume specifier */ | 2555 | remain = count - 1; |
2518 | int volume = IF_MV_VOL(-idx - 1); | 2556 | next_idx = idx; |
2519 | cename = alloca(VOL_MAX_LEN+1); | 2557 | } |
2520 | get_volume_name(volume, cename); | 2558 | else |
2521 | #endif /* HAVE_MULTIVOLUME */ | 2559 | { |
2560 | remain--; | ||
2561 | next_idx = ce->up; | ||
2562 | } | ||
2522 | 2563 | ||
2523 | data->serialhash = dc_hash_serialnum(get_idx_dcvolp(idx)->serialnum, | ||
2524 | data->serialhash); | ||
2525 | } | 2564 | } |
2526 | 2565 | return len; | |
2527 | return len + path_append(data->buf + len, PA_SEP_HARD, cename, | ||
2528 | data->size > (size_t)len ? data->size - len : 0); | ||
2529 | } | 2566 | } |
2530 | 2567 | ||
2531 | /** | 2568 | /** |