aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-04-06 21:21:11 +0300
committerZyX <kp-pav@yandex.ru>2017-04-07 23:15:08 +0300
commit19044a15f9d41a7424e94fb3f0e257537e7afa5e (patch)
treed86fd5d6fef870b095b59ed4f88dd0a7f8043bab
parentc501d7c432693705482f76a384a98b4b4c0ef1a9 (diff)
downloadrneovim-19044a15f9d41a7424e94fb3f0e257537e7afa5e.tar.gz
rneovim-19044a15f9d41a7424e94fb3f0e257537e7afa5e.tar.bz2
rneovim-19044a15f9d41a7424e94fb3f0e257537e7afa5e.zip
strings: Replace vim_strchr implementation with a saner one
Removes dead code (enc_utf8, enc_dbcs and has_mbyte now have hardcoded values), relies on libc implementation being more optimized. Also where previously negative character just would never be found it is an assertion error now. Ref #1476
-rw-r--r--src/nvim/strings.c64
1 files changed, 19 insertions, 45 deletions
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index 5dcffe00e0..c4bc9b204a 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -401,54 +401,28 @@ int vim_strnicmp(const char *s1, const char *s2, size_t len)
}
#endif
-/*
- * Version of strchr() and strrchr() that handle unsigned char strings
- * with characters from 128 to 255 correctly. It also doesn't return a
- * pointer to the NUL at the end of the string.
- */
-char_u *vim_strchr(const char_u *string, int c)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
+/// strchr() version which handles multibyte strings
+///
+/// @param[in] string String to search in.
+/// @param[in] c Character to search for. Must be a valid character.
+///
+/// @return Pointer to the first byte of the found character in string or NULL
+/// if it was not found. NUL character is never found, use `strlen()`
+/// instead.
+char_u *vim_strchr(const char_u *const string, const int c)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- int b;
-
- const char_u *p = string;
- if (enc_utf8 && c >= 0x80) {
- while (*p != NUL) {
- int l = (*mb_ptr2len)(p);
-
- // Avoid matching an illegal byte here.
- if (l > 1 && utf_ptr2char(p) == c) {
- return (char_u *) p;
- }
- p += l;
- }
+ assert(c >= 0);
+ if (c == 0) {
return NULL;
+ } else if (c < 0x80) {
+ return (char_u *)strchr((const char *)string, c);
+ } else {
+ char u8char[MB_MAXBYTES + 1];
+ const int len = utf_char2bytes(c, (char_u *)u8char);
+ u8char[len] = NUL;
+ return (char_u *)strstr((const char *)string, u8char);
}
- if (enc_dbcs != 0 && c > 255) {
- int n2 = c & 0xff;
-
- c = ((unsigned)c >> 8) & 0xff;
- while ((b = *p) != NUL) {
- if (b == c && p[1] == n2)
- return (char_u *) p;
- p += (*mb_ptr2len)(p);
- }
- return NULL;
- }
- if (has_mbyte) {
- while ((b = *p) != NUL) {
- if (b == c)
- return (char_u *) p;
- p += (*mb_ptr2len)(p);
- }
- return NULL;
- }
- while ((b = *p) != NUL) {
- if (b == c)
- return (char_u *) p;
- ++p;
- }
- return NULL;
}
/*