Description of problem:
With a VM that has a unicode name, the 'state' column is incorrectly aligned
Version-Release number of selected component (if applicable):
(Also seen on rhel7)
Steps to Reproduce:
1. Create a VM with a multibyte unicode character in the name (e.g. an alpha symbol, or something more fun like '🐧⃞ '
2. virsh list --all
The 'running' state of the unicode named domain is too far to the left, probably because it's counting bytes not characters
State is still aligned
The core problem is probably that we're using strlen() to check length and thus decide padding, which simply counts bytes. We need to count printable unicode characters - mbstowcs() probably gets us the solution we need, or very close to it.
(In reply to Daniel Berrange from comment #1)
> The core problem is probably that we're using strlen() to check length and
> thus decide padding, which simply counts bytes. We need to count printable
> unicode characters - mbstowcs() probably gets us the solution we need, or
> very close to it.
I'm not sure if mbstowcs is the right one; certainly any utf8 I throw at it returns -1.
Yes, it seems I get that too. Bizarrely mbstowcs() does not work if your locale is set to UTF-8, but if you blank out locale setlocale(LC_CTYPE, ""); it then does the right thing with utf8 strings. Blanking locale in this way is not acceptable, though, so we need to find something better...
It is possible to count the number of utf-8 characters using this:
size_t utf8len(char *s)
size_t len = 0;
for (; *s; ++s) if ((*s & 0xC0) != 0x80) ++len;
IIUC, this should be the same as what mbstowcs() would report.
Note that is not the same as calculating the printable output length though, because of zero-width characters and RTL text, combining characters, etc :-( It would still be somewhat better that what we have today though.
BTW, I was wrong about us using strlen, we in fact rely on printf format string padding
vshPrint(ctl, " %-5s %-30s %-10s %-20s\n", id_buf,
state == -2 ? _("saved")
So whatever solution we choose, we'll need to replace that. Instead of trying to print the entire line at once, we'll need to print each field separately, calculating padding using some unicode aware function.
Might be a bit ambitious, but I'm labelling this a LibvirtFirstBug, since it is non-urgent and fairly self-contained work.
Another case where we get column layout wrong but for non-unicode related reasons:
We need to come up with some general purpose internal API for printing out tables of data, and use that everywhere in virsh to get alignment right, instead of printing tables manually with each command.
Not sure if it handles unicode properly, but:
I think it doesn't handle unicode properly, but should be fixed
to do so. It seems anyway easier to use libsmartcols and fix it
rather than trying to invent something new. It is packaged separately
Main criteria would be platform portability - would need it available on OS-X (homebrew), mingw in Fedora, FreeBSD, and of course the Linuxes.
We (util-linux upstream) compile libsmartcols on
Apple LLVM version 7.3.0 (clang-703.0.31)
It seems Debian has binary packages for kFreeBSD
Not sure about mingw.
Bummer, we've already have some patches that implement our own table (the patches are still being actively worked on).
Patch proposed upstream:
Patches pushed upstream:
bfdd20c5a9 virt-admin: Implement vshTable API to server-list and client-list
95b29fc222 virsh: Implement vshTable API to vol-list
79eec7992b virsh: Implement vshTable API to pool-list
3072ded354 virsh: Implement vshTable API to vcpupin, iothreadinfo, domfsinfo
063509a193 virsh: Implement vshTable API to domiflist
075dd1185d virsh: Implement vshTable API to domblklist
2979bbfb0f virsh: Implement vshTable API to domblkinfo
b9057c639f virsh: Set up cmdDomblkinfo() and cmdDomblkinfoPrint() for vshTable API implementation
b0b1ed2f7b virsh: Implement vshTable API to snapshot-list.
c2b9cf6733 virsh: Implement vshTable API to nwfilter-list and nwfilterbinding-list
cf12efe088 virsh: Implement vshTable API to secret-list
71029ef588 virsh: Implement vshTable API to net-list and net-dhcp-leases
0396cf5336 virsh: Implement vsh-table to iface-list