
On 08/23/2018 05:53 PM, Simon Kobyda wrote:
It solves problems with alignment of columns. Width of each column is calculated by its biggest cell. Should solve unicode bug. In future, it may be implemented in virsh, virt-admin...
This API has 5 public functions: - vshTableNew - adds new table and defines its header - vshTableRowAppend - appends new row (for same number of columns as in header) - vshTablePrintToStdout - vshTablePrintToString - vshTableFree
https://bugzilla.redhat.com/show_bug.cgi?id=1574624 https://bugzilla.redhat.com/show_bug.cgi?id=1584630
Signed-off-by: Simon Kobyda <skobyda@redhat.com> --- tools/Makefile.am | 4 +- tools/vsh-table.c | 449 ++++++++++++++++++++++++++++++++++++++++++++++ tools/vsh-table.h | 42 +++++ 3 files changed, 494 insertions(+), 1 deletion(-) create mode 100644 tools/vsh-table.c create mode 100644 tools/vsh-table.h
diff --git a/tools/vsh-table.c b/tools/vsh-table.c new file mode 100644 index 0000000000..ca4e9265c5 --- /dev/null +++ b/tools/vsh-table.c
+/** + * Function pulled from util-linux + * + * Function's name in util-linux: mbs_safe_encode_to_buffer + * + * Returns allocated string where all control and non-printable chars are + * replaced with \x?? hex sequence, or NULL. + */ +static char * +vshTableSafeEncode(const char *s, size_t *width) +{ + const char *p = s; + size_t sz = s ? strlen(s) : 0; + char *buf; + char *ret; + mbstate_t st; + + memset(&st, 0, sizeof(st)); + + if (VIR_ALLOC_N(buf, (sz * HEX_ENCODE_LENGTH) + 1) < 0) + return NULL; + + if (!sz) + return NULL;
You need to swap these two lines otherwise @buf is leaked.
+ + ret = buf; + *width = 0; + + while (p && *p) { + if ((*p == '\\' && *(p + 1) == 'x') || + c_iscntrl(*p)) { + snprintf(buf, HEX_ENCODE_LENGTH + 1, "\\x%02x", *p); + buf += HEX_ENCODE_LENGTH; + *width += HEX_ENCODE_LENGTH; + p++; + } 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 (!c_isprint(*p)) { + snprintf(buf, HEX_ENCODE_LENGTH + 1, "\\x%02x", *p); + buf += HEX_ENCODE_LENGTH; + *width += HEX_ENCODE_LENGTH; + } else { + (*width)++; + *buf++ = *p; + } + } else if (!iswprint(wc)) { + size_t i; + for (i = 0; i < len; i++) { + snprintf(buf, HEX_ENCODE_LENGTH + 1, "\\x%02x", p[i]); + buf += HEX_ENCODE_LENGTH; + *width += HEX_ENCODE_LENGTH; + } + } else { + memcpy(buf, p, len); + buf += len; + *width += wcwidth(wc); + } + p += len; + } + } + + *buf = '\0'; + return ret; +} +
ACK Michal