diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2024-06-18 13:53:49 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2024-06-18 13:53:49 -0400 |
commit | a7ef73a406b46ec226014afdb6a099c3ea96230f (patch) | |
tree | 4de8a5930e6d2b275d1c8909ee6598055e4f37cc /src | |
parent | cb385e7c80a2926ac9c9fe50e5e0c60665fb022c (diff) | |
download | bfs-a7ef73a406b46ec226014afdb6a099c3ea96230f.tar.xz |
bftw: Only resize the string once in bftw_build_path()
Diffstat (limited to 'src')
-rw-r--r-- | src/bftw.c | 41 |
1 files changed, 22 insertions, 19 deletions
@@ -1529,11 +1529,28 @@ static bool bftw_pop_file(struct bftw_state *state) { return bftw_pop(state, &state->fileq); } +/** Add a path component to the path. */ +static void bftw_prepend_path(char *path, size_t nameoff, size_t namelen, const char *name) { + if (nameoff > 0) { + path[nameoff - 1] = '/'; + } + memcpy(path + nameoff, name, namelen); +} + /** Build the path to the current file. */ static int bftw_build_path(struct bftw_state *state, const char *name) { const struct bftw_file *file = state->file; - size_t pathlen = file ? file->nameoff + file->namelen : 0; + size_t nameoff, namelen; + if (name) { + nameoff = file ? bftw_child_nameoff(file) : 0; + namelen = strlen(name); + } else { + nameoff = file->nameoff; + namelen = file->namelen; + } + + size_t pathlen = nameoff + namelen; if (dstresize(&state->path, pathlen) != 0) { state->error = errno; return -1; @@ -1546,11 +1563,11 @@ static int bftw_build_path(struct bftw_state *state, const char *name) { } // Build the path backwards + if (name) { + bftw_prepend_path(state->path, nameoff, namelen, name); + } while (file && file != ancestor) { - if (file->nameoff > 0) { - state->path[file->nameoff - 1] = '/'; - } - memcpy(state->path + file->nameoff, file->name, file->namelen); + bftw_prepend_path(state->path, file->nameoff, file->namelen, file->name); if (ancestor && ancestor->depth == file->depth) { ancestor = ancestor->parent; @@ -1559,20 +1576,6 @@ static int bftw_build_path(struct bftw_state *state, const char *name) { } state->previous = state->file; - - if (name) { - if (pathlen > 0 && state->path[pathlen - 1] != '/') { - if (dstrapp(&state->path, '/') != 0) { - state->error = errno; - return -1; - } - } - if (dstrcat(&state->path, name) != 0) { - state->error = errno; - return -1; - } - } - return 0; } |