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(),
#endif
#include <stdlib.h>
+#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "proto.h"
}
#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)
# 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
#define strcasestr nstristr
#endif
-#ifndef HAVE_STRNLEN
-#define strnlen nstrnlen
-#endif
-
#ifndef HAVE_GETDELIM
#define getdelim ngetdelim
#endif
#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
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') ? "" : "...");
}
#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