Closed Dr-Emann closed 1 year ago
There are two reasons why the tree_walker
resets the directory iterator to the start:
The primary reason why tree_walker
exists is to have path resolution for sqsh_open()
and the sqsh_easy_
APIs. Resetting the iterator to the beginning of the file is actually a desired behavior for path resolution as we don't need to revert the directory iterator to the beginning when opening paths like /z/../a
.
If we don't rely on "sticky dir entries", the only state that tree_walker
needs to take care is the current directory.
And as long as tree_walker
doesn't need to keep a stack of the visited directories, we can implement it without dynamic allocations. Avoiding malloc()
and free()
is underrated in C. 😜
There's also this issue: What happens if the tree_walker
isn't initialized for the root directory, but for a random other directory. I don't support that through the API yet, but it's a use case that I'm considering to expose. In that case we would need to...
_up()
to find the right directory entry anyway.I think you're trying to use tree_walker
for something that it wasn't made for. To recursively visit every file in an archive, I would suggest use a recursive function in conjuction with directory iterators instead. As an example, you can have a look at sqsh-unpack
s extract() function which does exactly that..
I'm sure I am just trying to use it wrong. I think the name confused me, I associated it with something like WalkDir, that it would be the way to walk the whole tree. It seems like it's probably closer to an internal tool for path resolution, than something I'd want to really use as a caller of the library.
Is your feature request related to a problem? Please describe.
I want to be able to use a walker to navigate to every file in the archive, recursively.
I'd like to use something like:
Code Example
```c void visit_all_entries(struct SqshTreeWalker *walker) { int rc = 0; while (sqsh_tree_walker_next2(walker, &rc)) { char *name = sqsh_tree_walker_name_dup(walker); printf("Visiting %s\n", name); free(name); if (sqsh_tree_walker_type(walker) == SQSH_FILE_TYPE_DIRECTORY) { printf("BEGIN DIR\n"); rc = sqsh_tree_walker_down(walker); assert(rc == 0); visit_all_entries(walker); rc = sqsh_tree_walker_up(walker); assert(rc == 0); printf("END DIR\n"); } } assert(rc == 0); } ```However, this doesn't work, because
sqsh_tree_walker_up
sets the walker to be at the start of the parent directory, not at the entry of the inner directory it was just in.I'm not sure if such a thing is possible to do efficiently.
Describe the solution you'd like
Ideally, it would be better to have
sqsh_tree_walker_up
would return to the entry of the directory just left rather than the beginning of the parent directory.Describe alternatives you've considered
It is probably possible to save the name, and use
sqsh_tree_walker_lookup
to get back to the directory. But presumably that will inefficient.Alternatively, it might require keeping our own stack of
SqshDirectoryIterator
s to do such visitation of files.Additional context