[libvirt] [PATCH v5 1/3] vsh: Add API for printing tables.
Michal Privoznik
mprivozn at redhat.com
Fri Aug 24 08:59:05 UTC 2018
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 at 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
More information about the libvir-list
mailing list