Juan Lang wrote:
+/* find a character from a set in reverse without the string having to be null-terminated */ +static inline WCHAR *memrpbrkW(const WCHAR *ptr, size_t n, const WCHAR *accept) +{
- const WCHAR *end, *ret = NULL;
- for (end = ptr + n; ptr < end; ptr++) if (strchrW(accept, *ptr)) ret
= ptr;
- return (WCHAR *)ret;
+}
Maybe it's because I'm dense and I don't particularly like three levels of indent on a single line, but this doesn't seem to do what I'd expect. The for loop doesn't quit when ret is assigned, thus, this will always find the last character, from left to right, from accept in ptr, rather than the first.
I tested this function so I'm fairly sure it's correct. It's also based on the code of several functions merged into one from include/wine/unicode.h (including strrchrW). Perhaps it would be better to rework the function for efficiency. I'm pretty sure it does the right thing though, as can be shown in the following example: ptr: "abcdefg", size: 6, accept: "bdg"
end = ptr + 8 (end is "g") ptr < end = TRUE strchrW("bdg", 'a') = NULL ptr++ (ptr is now "bcdefg") ptr < end = TRUE strchrW("bdg", 'b') = "bdg" ret = ptr (ret is now "bcdefg") ptr++ (ptr is now "cdefghi") ptr < end = TRUE strchrW("bdg", 'c') = NULL ptr++ (ptr is now "defg") ptr < end = TRUE strchrW("bdg", 'd') = "dg" ret = ptr (ret is now "defg") ptr++ (ptr is now "efg") ptr < end = TRUE strchrW("bdg", 'e') = NULL ptr++ (ptr is now "fg") ptr < end = TRUE strchrW("bdg", 'f') = NULL ptr++ (ptr is now "g") ptr < end = FALSE return ret (ret is "defg")
Don't you mean "ptr < end && !ret"?
I suppose that could be done for safety, but in this case it doesn't a matter as I've calculated size using strlenW.
And in what sense is this "in reverse"?
It returns the position of the last character in the input string that matches a character in accept.