diff options
author | Karel Zak | 2014-01-29 14:09:54 +0100 |
---|---|---|
committer | Karel Zak | 2014-03-11 11:35:13 +0100 |
commit | 1b1f66e477f229fe9f3d4b5f9d8484ca50db02f2 (patch) | |
tree | 64cd6a69f582b00d3e2e92283e64df880e81eaab | |
parent | fdisk: fix 'p'rint error on empty PT (diff) | |
download | kernel-qcow2-util-linux-1b1f66e477f229fe9f3d4b5f9d8484ca50db02f2.tar.gz kernel-qcow2-util-linux-1b1f66e477f229fe9f3d4b5f9d8484ca50db02f2.tar.xz kernel-qcow2-util-linux-1b1f66e477f229fe9f3d4b5f9d8484ca50db02f2.zip |
lib/mbalign: add mbs_safe_width() from tt.c
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r-- | include/mbsalign.h | 11 | ||||
-rw-r--r-- | lib/mbsalign.c | 137 | ||||
-rw-r--r-- | lib/tt.c | 135 |
3 files changed, 145 insertions, 138 deletions
diff --git a/include/mbsalign.h b/include/mbsalign.h index 8c9f2db07..d290f61aa 100644 --- a/include/mbsalign.h +++ b/include/mbsalign.h @@ -1,5 +1,6 @@ /* Align/Truncate a string in a given screen width Copyright (C) 2009-2010 Free Software Foundation, Inc. + Copyright (C) 2010-2013 Karel Zak <kzak@redhat.com> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -13,8 +14,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#include <stddef.h> +#ifndef UTIL_LINUX_MBSALIGN_H +# define UTIL_LINUX_MBSALIGN_H +# include <stddef.h> typedef enum { MBS_ALIGN_LEFT, MBS_ALIGN_RIGHT, MBS_ALIGN_CENTER } mbs_align_t; @@ -43,3 +45,8 @@ extern size_t mbs_truncate(char *str, size_t *width); 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_width(const char *s); +extern char *mbs_safe_encode(const char *s, size_t *width); + +#endif /* UTIL_LINUX_MBSALIGN_H */ diff --git a/lib/mbsalign.c b/lib/mbsalign.c index 89ef03298..5933f1863 100644 --- a/lib/mbsalign.c +++ b/lib/mbsalign.c @@ -23,17 +23,152 @@ #include <stdio.h> #include <stdbool.h> #include <limits.h> +#include <ctype.h> #include "c.h" #include "mbsalign.h" #include "widechar.h" - #ifdef HAVE_WIDECHAR /* Replace non printable chars. Note \t and \n etc. are non printable. Return 1 if replacement made, 0 otherwise. */ +/* + * 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(). + */ +size_t mbs_safe_width(const char *s) +{ + mbstate_t st; + const char *p = s; + size_t width = 0; + + memset(&st, 0, sizeof(st)); + + while (p && *p) { + if (iscntrl((unsigned char) *p)) { + width += 4; /* *p encoded to \x?? */ + p++; + } +#ifdef HAVE_WIDECHAR + else { + wchar_t wc; + size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &st); + + if (len == 0) + break; + + if (len == (size_t) -1 || len == (size_t) -2) { + len = 1; + width += (isprint((unsigned char) *p) ? 1 : 4); + + } if (!iswprint(wc)) + width += len * 4; /* hex encode whole sequence */ + else + width += wcwidth(wc); /* number of cells */ + p += len; + } +#else + else if (!isprint((unsigned char) *p)) { + width += 4; /* *p encoded to \x?? */ + p++; + } else { + width++; + p++; + } +#endif + } + + return width; +} + +/* + * Returns allocated string where all control and non-printable chars are + * replaced with \x?? hex sequence. + */ +char *mbs_safe_encode(const char *s, size_t *width) +{ + mbstate_t st; + const char *p = s; + char *res, *r; + size_t sz = s ? strlen(s) : 0; + + + if (!sz) + return NULL; + + memset(&st, 0, sizeof(st)); + + res = malloc((sz * 4) + 1); + if (!res) + return NULL; + + r = res; + *width = 0; + + while (p && *p) { + if (iscntrl((unsigned char) *p)) { + sprintf(r, "\\x%02x", (unsigned char) *p); + r += 4; + *width += 4; + p++; + } +#ifdef HAVE_WIDECHAR + else { + wchar_t wc; + size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &st); + + if (len == 0) + break; /* end of string */ + + if (len == (size_t) -1 || len == (size_t) -2) { + len = 1; + /* + * Not valid multibyte sequence -- maybe it's + * printable char according to the current locales. + */ + if (!isprint((unsigned char) *p)) { + sprintf(r, "\\x%02x", (unsigned char) *p); + r += 4; + *width += 4; + } else { + width++; + *r++ = *p; + } + } else if (!iswprint(wc)) { + size_t i; + for (i = 0; i < len; i++) { + sprintf(r, "\\x%02x", (unsigned char) *p); + r += 4; + *width += 4; + } + } else { + memcpy(r, p, len); + r += len; + *width += wcwidth(wc); + } + p += len; + } +#else + else if (!isprint((unsigned char) *p)) { + sprintf(r, "\\x%02x", (unsigned char) *p); + p++; + r += 4; + *width += 4; + } else { + *r++ = *p++; + *width++; + } +#endif + } + + *r = '\0'; + + return res; +} + static bool wc_ensure_printable (wchar_t *wchars) { @@ -53,141 +53,6 @@ static const struct tt_symbols utf8_tt_symbols = { list_entry_is_last(&(_cl)->cl_columns, &(_tb)->tb_columns) /* - * 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(). - */ -static size_t mbs_safe_width(const char *s) -{ - mbstate_t st; - const char *p = s; - size_t width = 0; - - memset(&st, 0, sizeof(st)); - - while (p && *p) { - if (iscntrl((unsigned char) *p)) { - width += 4; /* *p encoded to \x?? */ - p++; - } -#ifdef HAVE_WIDECHAR - else { - wchar_t wc; - size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &st); - - if (len == 0) - break; - - if (len == (size_t) -1 || len == (size_t) -2) { - len = 1; - width += (isprint((unsigned char) *p) ? 1 : 4); - - } if (!iswprint(wc)) - width += len * 4; /* hex encode whole sequence */ - else - width += wcwidth(wc); /* number of cells */ - p += len; - } -#else - else if (!isprint((unsigned char) *p)) { - width += 4; /* *p encoded to \x?? */ - p++; - } else { - width++; - p++; - } -#endif - } - - return width; -} - -/* - * Returns allocated string where all control and non-printable chars are - * replaced with \x?? hex sequence. - */ -static char *mbs_safe_encode(const char *s, size_t *width) -{ - mbstate_t st; - const char *p = s; - char *res, *r; - size_t sz = s ? strlen(s) : 0; - - - if (!sz) - return NULL; - - memset(&st, 0, sizeof(st)); - - res = malloc((sz * 4) + 1); - if (!res) - return NULL; - - r = res; - *width = 0; - - while (p && *p) { - if (iscntrl((unsigned char) *p)) { - sprintf(r, "\\x%02x", (unsigned char) *p); - r += 4; - *width += 4; - p++; - } -#ifdef HAVE_WIDECHAR - else { - wchar_t wc; - size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &st); - - if (len == 0) - break; /* end of string */ - - if (len == (size_t) -1 || len == (size_t) -2) { - len = 1; - /* - * Not valid multibyte sequence -- maybe it's - * printable char according to the current locales. - */ - if (!isprint((unsigned char) *p)) { - sprintf(r, "\\x%02x", (unsigned char) *p); - r += 4; - *width += 4; - } else { - width++; - *r++ = *p; - } - } else if (!iswprint(wc)) { - size_t i; - for (i = 0; i < len; i++) { - sprintf(r, "\\x%02x", (unsigned char) *p); - r += 4; - *width += 4; - } - } else { - memcpy(r, p, len); - r += len; - *width += wcwidth(wc); - } - p += len; - } -#else - else if (!isprint((unsigned char) *p)) { - sprintf(r, "\\x%02x", (unsigned char) *p); - p++; - r += 4; - *width += 4; - } else { - *r++ = *p++; - *width++; - } -#endif - } - - *r = '\0'; - - return res; -} - -/* * @flags: TT_FL_* flags (usually TT_FL_{ASCII,RAW}) * * Returns: newly allocated table |