From 5508cc5b0ac67c3e7b1e9ed759e169e949d61c66 Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Fri, 14 Jan 2005 04:22:14 +0000
Subject: [PATCH] move nstrnlen() to chars.c, and add a multibyte equivalent of
 strnlen() to it

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2259 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog    |  7 ++++---
 src/chars.c  | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/nano.h   |  8 ++------
 src/proto.h  |  4 ++++
 src/search.c |  2 +-
 src/utils.c  | 15 ---------------
 6 files changed, 65 insertions(+), 25 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3c8217ab..e5f1b82b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -94,9 +94,10 @@ CVS code -
 	  character-specific functions to their own source file.  New
 	  file chars.c; new functions is_blank_mbchar(),
 	  is_blank_wchar(), is_cntrl_mbchar(), is_cntrl_wchar(),
-	  control_mbrep(), control_wrep(), mbwidth(), mb_cur_max(), and
-	  make_mbchar(); changes to is_blank_char() (moved to chars.c),
-	  is_cntrl_char() (moved to chars.c), parse_char() (renamed
+	  mbstrnlen(), control_mbrep(), control_wrep(), mbwidth(),
+	  mb_cur_max(), and make_mbchar(); changes to is_blank_char()
+	  (moved to chars.c), is_cntrl_char() (moved to chars.c),
+	  nstrnlen() (moved to chars.c), parse_char() (renamed
 	  parse_mbchar() and moved to chars.c), do_home(),
 	  do_verbatim_input(), do_delete(), do_tab(), do_input(),
 	  do_output(), get_buffer(), unget_input(), unget_kbinput(),
diff --git a/src/chars.c b/src/chars.c
index 64a15e44..b97813b9 100644
--- a/src/chars.c
+++ b/src/chars.c
@@ -24,6 +24,7 @@
 #endif
 
 #include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 #include <assert.h>
 #include "proto.h"
@@ -124,6 +125,59 @@ bool is_cntrl_wchar(wchar_t wc)
 }
 #endif
 
+#ifndef HAVE_STRNLEN
+/* This function is equivalent to strnlen(). */
+size_t nstrnlen(const char *s, size_t maxlen)
+{
+    size_t n = 0;
+
+    assert(s != NULL);
+
+    for (; maxlen > 0 && *s != '\0'; maxlen--, n++, s++)
+	;
+
+    return n;
+}
+#endif
+
+/* This function is equivalent to strnlen() for multibyte strings. */
+size_t mbstrnlen(const char *s, size_t maxlen)
+{
+#ifdef NANO_WIDE
+    if (ISSET(NO_UTF8)) {
+	size_t n = 0;
+	char *s_mb = charalloc(mb_cur_max());
+	int s_mb_len;
+
+	assert(s != NULL);
+
+	while (*s != '\0') {
+	    s_mb_len = parse_mbchar(s + n, s_mb
+#ifdef NANO_WIDE
+		, NULL
+#endif
+		, NULL);
+
+	    maxlen -= s_mb_len;
+	    n += s_mb_len;
+
+	    if (maxlen == 0)
+		break;
+	}
+
+	free(s_mb);
+
+	return n;
+    } else
+#endif
+	return
+#ifdef HAVE_STRNLEN
+		strnlen(s, maxlen);
+#else
+		nstrnlen(s, maxlen);
+#endif
+}
+
 /* c is a control character.  It displays as ^@, ^?, or ^[ch] where ch
  * is c + 64.  We return that character. */
 unsigned char control_rep(unsigned char c)
diff --git a/src/nano.h b/src/nano.h
index cd64b492..270321d6 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -100,8 +100,8 @@
 # endif
 #endif
 
-/* If no strcasecmp(), strncasecmp(), strcasestr(), strnlen(),
- * getdelim(), or getline(), use the versions we have. */
+/* If no strcasecmp(), strncasecmp(), strcasestr(), getdelim(), or
+ * getline(), use the versions we have. */
 #ifndef HAVE_STRCASECMP
 #define strcasecmp nstricmp
 #endif
@@ -114,10 +114,6 @@
 #define strcasestr nstristr
 #endif
 
-#ifndef HAVE_STRNLEN
-#define strnlen nstrnlen
-#endif
-
 #ifndef HAVE_GETDELIM
 #define getdelim ngetdelim
 #endif
diff --git a/src/proto.h b/src/proto.h
index 6b6396da..b35862b7 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -161,6 +161,10 @@ bool is_cntrl_mbchar(const char *c);
 #ifdef NANO_WIDE
 bool is_cntrl_wchar(wchar_t wc);
 #endif
+#ifndef HAVE_STRNLEN
+size_t nstrnlen(const char *s, size_t maxlen);
+#endif
+size_t mbstrnlen(const char *s, size_t maxlen);
 unsigned char control_rep(unsigned char c);
 char *control_mbrep(const char *c, char *crep, int *crep_len);
 #ifdef NANO_WIDE
diff --git a/src/search.c b/src/search.c
index 02c054d5..7fb3c81f 100644
--- a/src/search.c
+++ b/src/search.c
@@ -84,7 +84,7 @@ void not_found_msg(const char *str)
     assert(str != NULL);
 
     disp = display_string(str, 0, (COLS / 2) + 1, FALSE);
-    numchars = strnlen(disp, COLS / 2);
+    numchars = mbstrnlen(disp, COLS / 2);
 
     statusbar(_("\"%.*s%s\" not found"), numchars, disp,
 	(disp[numchars] == '\0') ? "" : "...");
diff --git a/src/utils.c b/src/utils.c
index f471ef5f..46b1d616 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -261,21 +261,6 @@ const char *revstristr(const char *haystack, const char *needle, const
 }
 #endif /* !NANO_SMALL */
 
-#ifndef HAVE_STRNLEN
-/* This function is equivalent to strnlen(). */
-size_t nstrnlen(const char *s, size_t maxlen)
-{
-    size_t n = 0;
-
-    assert(s != NULL);
-
-    for (; maxlen > 0 && *s != '\0'; maxlen--, n++, s++)
-	;
-
-    return n;
-}
-#endif
-
 #if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
 #ifndef HAVE_GETLINE
 /* This function is equivalent to getline().  It was adapted from
-- 
GitLab