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(a)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