changeset 2775:afd68d0b9fc1

(mbswidth): Add a flags argument. (mbsnwidth): New function.
author Jim Meyering <jim@meyering.net>
date Mon, 24 Jul 2000 16:29:57 +0000
parents 5789e57d5d8b
children a1a09a98c937
files lib/mbswidth.c
diffstat 1 files changed, 43 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/lib/mbswidth.c
+++ b/lib/mbswidth.c
@@ -69,7 +69,6 @@
 /* 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 @@
 #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 @@
 	      p++;
 	      width++;
 	      break;
-	    case '\0':
-	      break;
 	    default:
 	      /* If we have a multibyte sequence, scan it up to its end.  */
 	      {
@@ -137,20 +146,32 @@
 		do
 		  {
 		    wchar_t wc;
-		    size_t bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
+		    size_t bytes;
 		    int w;
 
+		    bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
+
+		    if (bytes == (size_t) -1)
+		      /* An invalid multibyte sequence was encountered.  */
+		      {
+			if (flags & MBSW_ACCEPT_INVALID)
+			  break;
+			else
+			  return -1;
+		      }
+
+		    if (bytes == (size_t) -2)
+		      /* An incomplete multibyte character at the end.  */
+		      {
+			if (flags & MBSW_ACCEPT_INVALID)
+			  break;
+			else
+			  return -1;
+		      }
+
 		    if (bytes == 0)
 		      /* A null wide character was encountered.  */
-		      break;
-
-		    if (bytes == (size_t) -1)
-		      /* An invalid multibyte sequence was encountered.  */
-		      return -1;
-
-		    if (bytes == (size_t) -2)
-		      /* An incomplete multibyte character at the end.  */
-		      return -1;
+		      bytes = 1;
 
 		    w = wcwidth (wc);
 		    if (w >= 0)
@@ -158,7 +179,10 @@
 		      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 @@
     {
       unsigned char c = (unsigned char) *p++;
 
-      if (c == '\0')
-	break;
-
-      if (ISPRINT (c))
+      if ((flags & MBSW_ACCEPT_UNPRINTABLE) || ISPRINT (c))
 	width++;
       else
 	return -1;