This makes it so expand_intermediate_segment knows about the case
where it's last, only followed by a "/".
When it is, it can do without the file_id for finding links (we don't
resolve the files we get here), which allows us to remove a stat()
call.
This speeds up the case of `...*/` by quite a bit.
If that last component was a directory with 1000 subdirectories we
could skip 1000 stat calls!
One slight weirdness: We refuse to add links to directories that we already visited, even if they are the last component and we don't actually follow them. That means we can't do the fast path here either, but we do know if something is a link (if we get d_type), so it still works in common cases.
- This is untested and unused, string ownership is very much subject to change
- Ports the minimally necessary parts of complete.rs as well
- This should fix an infinite loop in `create_directory` in `path.rs`, the first
`wstat` loop only breaks if it fails with an error that's different from
EAGAIN
- wildcard_match is now closer to the original that is linked in a comment, as
pointer-arithmetic translates very poorly. The act of calling wildcard
patterns wc or wildcard is kinda confusing when wc elsewhere is widechar.
Most of it is duplicated, hence untested.
Functions like mbrtowc are not exposed by the libc crate, so declare them
ourselves.
Since we don't know the definition of C macros, add two big hacks to make
this work:
1. Replace MB_LEN_MAX and mbstate_t with values (resp types) that should
be large enough for any implementation.
2. Detect the definition of MB_CUR_MAX in the build script. This requires
more changes for each new libc. We could also use this approach for 1.
Additionally, this commit brings a small behavior change to
read_unquoted_escape(): we cannot decode surrogate code points like \UDE01
into a Rust char, so use � (\UFFFD, replacement character) instead.
Previously, we added such code points to a wcstring; looks like they were
ignored when printed.