summaryrefslogtreecommitdiff
path: root/lib/mbswidth.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2000-07-24 16:29:57 +0000
committerJim Meyering <jim@meyering.net>2000-07-24 16:29:57 +0000
commit18051fbbb315f781e9e816d46988ea74b84b1fa7 (patch)
tree04af0e93fdc10162ba3504c2f1eac1e4a736ec08 /lib/mbswidth.c
parentddc825a0f0a38d090ac900bb9ad7357b0461b642 (diff)
downloadcoreutils-18051fbbb315f781e9e816d46988ea74b84b1fa7.tar.xz
(mbswidth): Add a flags argument.
(mbsnwidth): New function.
Diffstat (limited to 'lib/mbswidth.c')
-rw-r--r--lib/mbswidth.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/lib/mbswidth.c b/lib/mbswidth.c
index 09777c5b5..d187bc068 100644
--- a/lib/mbswidth.c
+++ b/lib/mbswidth.c
@@ -69,7 +69,6 @@ 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
@@ -85,15 +84,27 @@ int wcwidth ();
#undef ISPRINT
#define ISPRINT(c) (ISASCII (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)
+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
+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 +138,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 +146,32 @@ 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)
+ break;
+ else
+ return -1;
+ }
if (bytes == (size_t) -2)
/* An incomplete multibyte character at the end. */
- return -1;
+ {
+ if (flags & MBSW_ACCEPT_INVALID)
+ break;
+ else
+ return -1;
+ }
+
+ if (bytes == 0)
+ /* A null wide character was encountered. */
+ bytes = 1;
w = wcwidth (wc);
if (w >= 0)
@@ -158,7 +179,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 +198,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;