]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/mbalign: report also size in bytes
authorKarel Zak <kzak@redhat.com>
Tue, 15 Apr 2014 13:25:18 +0000 (15:25 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 15 Apr 2014 13:25:18 +0000 (15:25 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
include/mbsalign.h
lib/mbsalign.c

index 3c91900a0ff6ad113b396d4c270a38f95bf936a0..5eaf606e57182290d0c3106203b18e8eb56edf0e 100644 (file)
@@ -46,6 +46,7 @@ extern size_t mbsalign (const char *src, char *dest,
                        size_t dest_size,  size_t *width,
                        mbs_align_t align, int flags);
 
+extern size_t mbs_safe_nwidth(const char *buf, size_t bufsz, size_t *sz);
 extern size_t mbs_safe_width(const char *s);
 
 extern char *mbs_safe_encode(const char *s, size_t *width);
index ef59f41edaed6144820431f55aec4b64aed9a9be..b307d19f7cb1a13a6607a94f1209deb155d8950f 100644 (file)
  * Counts number of cells in multibyte string. For all control and
  * non-printable chars is the result width enlarged to store \x?? hex
  * sequence. See mbs_safe_encode().
+ *
+ * Returns: number of cells, @sz returns number of bytes.
  */
-size_t mbs_safe_width(const char *s)
+size_t mbs_safe_nwidth(const char *buf, size_t bufsz, size_t *sz)
 {
        mbstate_t st;
-       const char *p = s;
-       size_t width = 0;
+       const char *p = buf, *last = buf;
+       size_t width = 0, bytes = 0;
 
        memset(&st, 0, sizeof(st));
 
-       while (p && *p) {
+       if (p && *p && bufsz)
+               last = p + (bufsz - 1);
+
+       while (p && *p && p <= last) {
                if (iscntrl((unsigned char) *p)) {
-                       width += 4;                     /* *p encoded to \x?? */
+                       width += 4, bytes += 4;         /* *p encoded to \x?? */
                        p++;
                }
 #ifdef HAVE_WIDECHAR
@@ -62,28 +67,43 @@ size_t mbs_safe_width(const char *s)
 
                        if (len == (size_t) -1 || len == (size_t) -2) {
                                len = 1;
-                               width += (isprint((unsigned char) *p) ? 1 : 4);
+                               if (isprint((unsigned char) *p))
+                                       width += 1, bytes += 1;
+                               else
+                                       width += 4, bytes += 4;
 
-                       } if (!iswprint(wc))
+                       } else if (!iswprint(wc)) {
                                width += len * 4;       /* hex encode whole sequence */
-                       else
+                               bytes += len * 4;
+                       } else {
                                width += wcwidth(wc);   /* number of cells */
+                               bytes += len;           /* number of bytes */
+                       }
                        p += len;
                }
 #else
                else if (!isprint((unsigned char) *p)) {
-                       width += 4;                     /* *p encoded to \x?? */
+                       width += 4, bytes += 4;         /* *p encoded to \x?? */
                        p++;
                } else {
-                       width++;
+                       width++, bytes++;
                        p++;
                }
 #endif
        }
 
+       if (sz)
+               *sz = bytes;
        return width;
 }
 
+size_t mbs_safe_width(const char *s)
+{
+       if (!s || !*s)
+               return 0;
+       return mbs_safe_nwidth(s, strlen(s), NULL);
+}
+
 /*
  * Copy @s to @buf and replace control and non-printable chars with
  * \x?? hex sequence. The @width returns number of cells.