From 3a1fc8f0abe73421506511d7fc077579039b4249 Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Sun, 16 Jan 2005 18:49:19 +0000
Subject: [PATCH] start making multibyte equivalents of the string functions in
 utils.c

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2277 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog   |  27 +++--
 src/chars.c | 315 +++++++++++++++++++++++++++++++++++++++++++---------
 src/nano.h  |  20 ++--
 src/proto.h |  40 +++----
 src/utils.c |  95 +---------------
 5 files changed, 308 insertions(+), 189 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d4edc961..7c0a1297 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -96,17 +96,22 @@ CVS code -
 	  file chars.c; new functions is_alnum_char(),
 	  is_alnum_mbchar(), is_alnum_wchar(), is_blank_mbchar(),
 	  is_blank_wchar(), is_cntrl_mbchar(), is_cntrl_wchar(),
-	  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), move_left() (renamed
-	  move_mbleft() and moved to chars.c), move_right() (renamed
-	  move_mbright() and moved to chars.c), do_home(),
-	  do_verbatim_input(), do_delete(), do_tab(), do_next_word(),
-	  do_prev_word(), do_input(), do_output(), get_buffer(),
-	  unget_input(), unget_kbinput(), get_input(), parse_kbinput(),
-	  unparse_kbinput(), parse_verbatim_kbinput(),
+	  control_mbrep(), control_wrep(), mbwidth(), mb_cur_max(),
+	  make_mbchar(), mbstrnlen(), mbstrcasecmp(), and
+	  mbstrncasecmp(); changes to is_blank_char() (moved to
+	  chars.c), is_cntrl_char() (moved to chars.c), nstricmp()
+	  (renamed nstrcasecmp() and moved to chars.c), nstrnicmp()
+	  (renamed nstrncasecmp() and moved to chars.c), nstristr()
+	  (renamed nstrcasestr() and moved to chars.c), revstrstr()
+	  (moved to chars.c), revstristr() (renamed revstrcasestr() and
+	  moved to chars.c), nstrnlen() (moved to chars.c),
+	  parse_char() (renamed parse_mbchar() and moved to chars.c),
+	  move_left() (renamed move_mbleft() and moved to chars.c),
+	  move_right() (renamed move_mbright() and moved to chars.c),
+	  do_home(), do_verbatim_input(), do_delete(), do_tab(),
+	  do_next_word(), do_prev_word(), do_input(), do_output(),
+	  get_buffer(), unget_input(), unget_kbinput(), get_input(),
+	  parse_kbinput(), unparse_kbinput(), parse_verbatim_kbinput(),
 	  do_statusbar_input(), do_statusbar_home(),
 	  do_statusbar_verbatim_kbinput(), do_statusbar_output(), and
 	  display_string(); removal of buffer_to_keys() and
diff --git a/src/chars.c b/src/chars.c
index 1e7acfb2..f54441b6 100644
--- a/src/chars.c
+++ b/src/chars.c
@@ -160,59 +160,6 @@ 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);
-
-	    if (s_mb_len > maxlen)
-		break;
-
-	    maxlen -= s_mb_len;
-	    n += s_mb_len;
-	}
-
-	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)
@@ -475,3 +422,265 @@ size_t move_mbright(const char *buf, size_t pos)
 #endif
 	, NULL);
 }
+
+#ifndef HAVE_STRCASECMP
+/* This function is equivalent to strcasecmp(). */
+int nstrcasecmp(const char *s1, const char *s2)
+{
+    assert(s1 != NULL && s2 != NULL);
+
+    for (; *s1 != '\0' && *s2 != '\0'; s1++, s2++) {
+	if (tolower(*s1) != tolower(*s2))
+	    break;
+    }
+
+    return (tolower(*s1) - tolower(*s2));
+}
+#endif
+
+/* This function is equivalent to strcasecmp() for multibyte strings. */
+int mbstrcasecmp(const char *s1, const char *s2)
+{
+    assert(s1 != NULL && s2 != NULL);
+
+#ifdef NANO_WIDE
+    if (!ISSET(NO_UTF8)) {
+	char *s1_mb = charalloc(mb_cur_max());
+	char *s2_mb = charalloc(mb_cur_max());
+	int s1_mb_len, s2_mb_len;
+	wchar_t ws1, ws2;
+
+	while (*s1 != '\0' && *s2 != '\0') {
+	    s1_mb_len = parse_mbchar(s1, s1_mb
+#ifdef NANO_WIDE
+		, NULL
+#endif
+		, NULL);
+
+	    if (mbtowc(&ws1, s1_mb, s1_mb_len) <= 0) {
+		mbtowc(NULL, NULL, 0);
+		ws1 = (unsigned char)*s1_mb;
+	    }
+
+
+	    s2_mb_len = parse_mbchar(s2, s2_mb
+#ifdef NANO_WIDE
+		, NULL
+#endif
+		, NULL);
+
+	    if (mbtowc(&ws2, s2_mb, s2_mb_len) <= 0) {
+		mbtowc(NULL, NULL, 0);
+		ws2 = (unsigned char)*s2_mb;
+	    }
+
+
+	    if (towlower(ws1) != towlower(ws2))
+		break;
+
+	    s1 += s1_mb_len;
+	    s2 += s2_mb_len;
+	}
+
+	free(s1_mb);
+	free(s2_mb);
+
+	return (towlower(ws1) - towlower(ws2));
+    } else
+#endif
+	return
+#ifdef HAVE_STRCASECMP
+		strcasecmp(s1, s2);
+#else
+		nstrcasecmp(s1, s2);
+#endif
+}
+
+#ifndef HAVE_STRNCASECMP
+/* This function is equivalent to strncasecmp(). */
+int nstrncasecmp(const char *s1, const char *s2, size_t n)
+{
+    assert(s1 != NULL && s2 != NULL);
+
+    for (; n > 0 && *s1 != '\0' && *s2 != '\0'; n--, s1++, s2++) {
+	if (tolower(*s1) != tolower(*s2))
+	    break;
+    }
+
+    if (n > 0)
+	return (tolower(*s1) - tolower(*s2));
+    else
+	return 0;
+}
+#endif
+
+/* This function is equivalent to strncasecmp() for multibyte
+ * strings. */
+int mbstrncasecmp(const char *s1, const char *s2, size_t n)
+{
+    assert(s1 != NULL && s2 != NULL);
+
+#ifdef NANO_WIDE
+    if (!ISSET(NO_UTF8)) {
+	char *s1_mb = charalloc(mb_cur_max());
+	char *s2_mb = charalloc(mb_cur_max());
+	int s1_mb_len, s2_mb_len;
+	wchar_t ws1, ws2;
+
+	while (n > 0 && *s1 != '\0' && *s2 != '\0') {
+	    s1_mb_len = parse_mbchar(s1, s1_mb
+#ifdef NANO_WIDE
+		, NULL
+#endif
+		, NULL);
+
+	    if (mbtowc(&ws1, s1_mb, s1_mb_len) <= 0) {
+		mbtowc(NULL, NULL, 0);
+		ws1 = (unsigned char)*s1_mb;
+	    }
+
+	    s2_mb_len = parse_mbchar(s2, s2_mb
+#ifdef NANO_WIDE
+		, NULL
+#endif
+		, NULL);
+
+	    if (mbtowc(&ws2, s2_mb, s2_mb_len) <= 0) {
+		mbtowc(NULL, NULL, 0);
+		ws2 = (unsigned char)*s2_mb;
+	    }
+
+	    if (s1_mb_len > n || towlower(ws1) != towlower(ws2))
+		break;
+
+	    s1 += s1_mb_len;
+	    s2 += s2_mb_len;
+	    n -= s1_mb_len;
+	}
+
+	free(s1_mb);
+	free(s2_mb);
+
+	return (towlower(ws1) - towlower(ws2));
+    } else
+#endif
+	return
+#ifdef HAVE_STRNCASECMP
+		strncasecmp(s1, s2, n);
+#else
+		nstrncasecmp(s1, s2, n);
+#endif
+}
+
+#ifndef HAVE_STRCASESTR
+/* This function is equivalent to strcasestr().  It was adapted from
+ * mutt's mutt_stristr() function. */
+const char *nstrcasestr(const char *haystack, const char *needle)
+{
+    assert(haystack != NULL && needle != NULL);
+
+    for (; *haystack != '\0'; haystack++) {
+	const char *p = haystack, *q = needle;
+
+	for (; tolower(*p) == tolower(*q) && *q != '\0'; p++, q++)
+	    ;
+
+	if (*q == '\0')
+	    return haystack;
+    }
+
+    return NULL;
+}
+#endif
+
+/* None of this is needed if we're using NANO_SMALL! */
+#ifndef NANO_SMALL
+const char *revstrstr(const char *haystack, const char *needle, const
+	char *rev_start)
+{
+    assert(haystack != NULL && needle != NULL && rev_start != NULL);
+
+    for (; rev_start >= haystack; rev_start--) {
+	const char *r, *q;
+
+	for (r = rev_start, q = needle; *q == *r && *q != '\0'; r++, q++)
+	    ;
+
+	if (*q == '\0')
+	    return rev_start;
+    }
+
+    return NULL;
+}
+
+const char *revstrcasestr(const char *haystack, const char *needle,
+	const char *rev_start)
+{
+    assert(haystack != NULL && needle != NULL && rev_start != NULL);
+
+    for (; rev_start >= haystack; rev_start--) {
+	const char *r = rev_start, *q = needle;
+
+	for (; tolower(*q) == tolower(*r) && *q != '\0'; r++, q++)
+	    ;
+
+	if (*q == '\0')
+	    return rev_start;
+    }
+
+    return NULL;
+}
+#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
+
+/* This function is equivalent to strnlen() for multibyte strings. */
+size_t mbstrnlen(const char *s, size_t maxlen)
+{
+    assert(s != NULL);
+
+#ifdef NANO_WIDE
+    if (!ISSET(NO_UTF8)) {
+	size_t n = 0;
+	char *s_mb = charalloc(mb_cur_max());
+	int s_mb_len;
+
+	while (*s != '\0') {
+	    s_mb_len = parse_mbchar(s + n, s_mb
+#ifdef NANO_WIDE
+		, NULL
+#endif
+		, NULL);
+
+	    if (s_mb_len > maxlen)
+		break;
+
+	    maxlen -= s_mb_len;
+	    n += s_mb_len;
+	}
+
+	free(s_mb);
+
+	return n;
+    } else
+#endif
+	return
+#ifdef HAVE_STRNLEN
+		strnlen(s, maxlen);
+#else
+		nstrnlen(s, maxlen);
+#endif
+}
diff --git a/src/nano.h b/src/nano.h
index 270321d6..4d765a93 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -89,23 +89,19 @@
 #include <sys/stat.h>
 #include "config.h"
 
-/* If no snprintf()/vsnprintf(), use the versions from glib. */
+/* If no snprintf() or vsnprintf(), use the versions from glib. */
 #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
 #include <glib.h>
-# ifndef HAVE_SNPRINTF
-#  define snprintf g_snprintf
-# endif
-# ifndef HAVE_VSNPRINTF
-#  define vsnprintf g_vsnprintf
-# endif
+#ifndef HAVE_SNPRINTF
+#define snprintf g_snprintf
+#endif
+#ifndef HAVE_VSNPRINTF
+#define vsnprintf g_vsnprintf
 #endif
-
-/* If no strcasecmp(), strncasecmp(), strcasestr(), getdelim(), or
- * getline(), use the versions we have. */
-#ifndef HAVE_STRCASECMP
-#define strcasecmp nstricmp
 #endif
 
+/* If no strcasestr(), getdelim(), or getline(), use the versions we
+ * have. */
 #ifndef HAVE_STRNCASECMP
 #define strncasecmp nstrnicmp
 #endif
diff --git a/src/proto.h b/src/proto.h
index fe545bb6..6ed7a290 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -166,10 +166,6 @@ 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
@@ -185,6 +181,27 @@ int parse_mbchar(const char *buf, char *chr
 	, size_t *col);
 size_t move_mbleft(const char *buf, size_t pos);
 size_t move_mbright(const char *buf, size_t pos);
+#ifndef HAVE_STRCASECMP
+int nstrcasecmp(const char *s1, const char *s2);
+#endif
+int mbstrcasecmp(const char *s1, const char *s2);
+#ifndef HAVE_STRNCASECMP
+int nstrncasecmp(const char *s1, const char *s2, size_t n);
+#endif
+int mbstrncasecmp(const char *s1, const char *s2, size_t n);
+#ifndef HAVE_STRCASESTR
+const char *nstrcasestr(const char *haystack, const char *needle);
+#endif
+#ifndef NANO_SMALL
+const char *revstrstr(const char *haystack, const char *needle, const
+	char *rev_start);
+const char *revstrcasestr(const char *haystack, const char *needle, const
+	char *rev_start);
+#endif
+#ifndef HAVE_STRNLEN
+size_t nstrnlen(const char *s, size_t maxlen);
+#endif
+size_t mbstrnlen(const char *s, size_t maxlen);
 
 /* Public functions in color.c. */
 #ifdef ENABLE_COLOR
@@ -513,21 +530,6 @@ void align(char **strp);
 void null_at(char **data, size_t index);
 void unsunder(char *str, size_t true_len);
 void sunder(char *str);
-#ifndef HAVE_STRCASECMP
-int nstricmp(const char *s1, const char *s2);
-#endif
-#ifndef HAVE_STRNCASECMP
-int nstrnicmp(const char *s1, const char *s2, size_t n);
-#endif
-#ifndef HAVE_STRCASESTR
-const char *nstristr(const char *haystack, const char *needle);
-#endif
-#ifndef NANO_SMALL
-const char *revstrstr(const char *haystack, const char *needle, const
-	char *rev_start);
-const char *revstristr(const char *haystack, const char *needle, const
-	char *rev_start);
-#endif
 #if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
 #ifndef HAVE_GETLINE
 ssize_t ngetline(char **lineptr, size_t *n, FILE *stream);
diff --git a/src/utils.c b/src/utils.c
index 865a1f57..4ece1358 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -131,99 +131,6 @@ void sunder(char *str)
     }
 }
 
-#ifndef HAVE_STRCASECMP
-/* This function is equivalent to strcasecmp(). */
-int nstricmp(const char *s1, const char *s2)
-{
-    assert(s1 != NULL && s2 != NULL);
-
-    for (; *s1 != '\0' && *s2 != '\0'; s1++, s2++) {
-	if (tolower(*s1) != tolower(*s2))
-	    break;
-    }
-
-    return (tolower(*s1) - tolower(*s2));
-}
-#endif
-
-#ifndef HAVE_STRNCASECMP
-/* This function is equivalent to strncasecmp(). */
-int nstrnicmp(const char *s1, const char *s2, size_t n)
-{
-    assert(s1 != NULL && s2 != NULL);
-
-    for (; n > 0 && *s1 != '\0' && *s2 != '\0'; n--, s1++, s2++) {
-	if (tolower(*s1) != tolower(*s2))
-	    break;
-    }
-
-    if (n > 0)
-	return (tolower(*s1) - tolower(*s2));
-    else
-	return 0;
-}
-#endif
-
-#ifndef HAVE_STRCASESTR
-/* This function is equivalent to strcasestr().  It was adapted from
- * mutt's mutt_stristr() function. */
-const char *nstristr(const char *haystack, const char *needle)
-{
-    assert(haystack != NULL && needle != NULL);
-
-    for (; *haystack != '\0'; haystack++) {
-	const char *p = haystack, *q = needle;
-
-	for (; tolower(*p) == tolower(*q) && *q != '\0'; p++, q++)
-	    ;
-
-	if (*q == '\0')
-	    return haystack;
-    }
-
-    return NULL;
-}
-#endif
-
-/* None of this is needed if we're using NANO_SMALL! */
-#ifndef NANO_SMALL
-const char *revstrstr(const char *haystack, const char *needle, const
-	char *rev_start)
-{
-    assert(haystack != NULL && needle != NULL && rev_start != NULL);
-
-    for (; rev_start >= haystack; rev_start--) {
-	const char *r, *q;
-
-	for (r = rev_start, q = needle; *q == *r && *q != '\0'; r++, q++)
-	    ;
-
-	if (*q == '\0')
-	    return rev_start;
-    }
-
-    return NULL;
-}
-
-const char *revstristr(const char *haystack, const char *needle, const
-	char *rev_start)
-{
-    assert(haystack != NULL && needle != NULL && rev_start != NULL);
-
-    for (; rev_start >= haystack; rev_start--) {
-	const char *r = rev_start, *q = needle;
-
-	for (; tolower(*q) == tolower(*r) && *q != '\0'; r++, q++)
-	    ;
-
-	if (*q == '\0')
-	    return rev_start;
-    }
-
-    return NULL;
-}
-#endif /* !NANO_SMALL */
-
 #if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
 #ifndef HAVE_GETLINE
 /* This function is equivalent to getline().  It was adapted from
@@ -341,7 +248,7 @@ const char *strstrwrapper(const char *haystack, const char *needle,
 #endif /* !DISABLE_SPELLER || !NANO_SMALL */
 #ifndef NANO_SMALL
     else if (ISSET(REVERSE_SEARCH))
-	return revstristr(haystack, needle, start);
+	return revstrcasestr(haystack, needle, start);
 #endif
     return strcasestr(start, needle);
 }
-- 
GitLab