# define iswprint(wc) 1
#endif
-/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
-#if HAVE_MBRTOWC && defined mbstate_t
-# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
-# define mbsinit(ps) 1
-#endif
-
#ifndef HAVE_DECL_WCWIDTH
"this configure-time declaration test was not run"
#endif
/* wcwidth doesn't exist, so assume all printable characters have
width 1. */
# define wcwidth(wc) ((wc) == 0 ? 0 : iswprint (wc) ? 1 : -1)
-# else
# endif
#endif
/* Get ISPRINT. */
#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
-/* Undefine to protect against the definition in wctype.h of solaris2.6. */
-# undef ISASCII
-# define ISASCII(c) 1
+# define IN_CTYPE_DOMAIN(c) 1
#else
-# define ISASCII(c) isascii (c)
+# define IN_CTYPE_DOMAIN(c) isascii(c)
#endif
/* Undefine to protect against the definition in wctype.h of solaris2.6. */
#undef ISPRINT
-#define ISPRINT(c) (ISASCII (c) && isprint (c))
+#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
+
+#include "mbswidth.h"
/* Returns the number of columns needed to represent the multibyte
character string pointed to by STRING. If a non-printable character
- occurs, -1 is returned.
- This is the multibyte analogon of the wcswidth function. */
+ occurs, -1 is returned, unless MBSW_ACCEPT_UNPRINTABLE is specified.
+ With flags = 0, this is the multibyte analogon of the wcswidth function. */
+int
+mbswidth (const char *string, int flags)
+{
+ return mbsnwidth (string, strlen (string), flags);
+}
+
+/* Returns the number of columns needed to represent the multibyte
+ character string pointed to by STRING of length NBYTES. If a
+ non-printable character occurs, -1 is returned, unless
+ MBSW_ACCEPT_UNPRINTABLE is specified. */
int
-mbswidth (const char *string)
+mbsnwidth (const char *string, size_t nbytes, int flags)
{
const char *p = string;
- const char *plimit = p + strlen (p);
+ const char *plimit = p + nbytes;
int width;
width = 0;
p++;
width++;
break;
- case '\0':
- break;
default:
/* If we have a multibyte sequence, scan it up to its end. */
{
do
{
wchar_t wc;
- size_t bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
+ size_t bytes;
int w;
- if (bytes == 0)
- /* A null wide character was encountered. */
- break;
+ bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
if (bytes == (size_t) -1)
/* An invalid multibyte sequence was encountered. */
- return -1;
+ {
+ if (flags & MBSW_ACCEPT_INVALID)
+ {
+ p++;
+ width++;
+ break;
+ }
+ else
+ return -1;
+ }
if (bytes == (size_t) -2)
/* An incomplete multibyte character at the end. */
- return -1;
+ {
+ if (flags & MBSW_ACCEPT_INVALID)
+ {
+ p = plimit;
+ width++;
+ break;
+ }
+ else
+ return -1;
+ }
+
+ if (bytes == 0)
+ /* A null wide character was encountered. */
+ bytes = 1;
w = wcwidth (wc);
if (w >= 0)
width += w;
else
/* An unprintable multibyte character. */
- return -1;
+ if (flags & MBSW_ACCEPT_UNPRINTABLE)
+ width += 1;
+ else
+ return -1;
p += bytes;
}
{
unsigned char c = (unsigned char) *p++;
- if (c == '\0')
- break;
-
- if (ISPRINT (c))
+ if ((flags & MBSW_ACCEPT_UNPRINTABLE) || ISPRINT (c))
width++;
else
return -1;