X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fmbswidth.c;h=bb6aa1a6d8e83587591ca558483f212d371be947;hb=aaea9d07f672ec45a4687a5e99c3994ef41d4491;hp=09777c5b5ee3e1fb34b521c60e7b3d2ced34c4a3;hpb=ec482f5cb9a59b3b8d5eb6263bc690983986d1ed;p=gnulib.git diff --git a/lib/mbswidth.c b/lib/mbswidth.c index 09777c5b5..bb6aa1a6d 100644 --- a/lib/mbswidth.c +++ b/lib/mbswidth.c @@ -69,31 +69,40 @@ int wcwidth (); /* 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; @@ -127,8 +136,6 @@ mbswidth (const char *string) p++; width++; break; - case '\0': - break; default: /* If we have a multibyte sequence, scan it up to its end. */ { @@ -137,20 +144,40 @@ mbswidth (const char *string) 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) @@ -158,7 +185,10 @@ mbswidth (const char *string) width += w; else /* An unprintable multibyte character. */ - return -1; + if (flags & MBSW_ACCEPT_UNPRINTABLE) + width += 1; + else + return -1; p += bytes; } @@ -174,10 +204,7 @@ mbswidth (const char *string) { unsigned char c = (unsigned char) *p++; - if (c == '\0') - break; - - if (ISPRINT (c)) + if ((flags & MBSW_ACCEPT_UNPRINTABLE) || ISPRINT (c)) width++; else return -1;