[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