diff options
author | Dan McGee <dan@archlinux.org> | 2008-02-23 05:00:15 +0100 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2008-02-23 05:00:15 +0100 |
commit | a6470956bc2db5acb821485e590822953966586a (patch) | |
tree | 4821069ebe14931d8cdf52445d700de1319a9595 /src | |
parent | 29f55fb7c9e2d7d3923d796216a9506d95b1fd60 (diff) | |
download | pacman-a6470956bc2db5acb821485e590822953966586a.tar.gz pacman-a6470956bc2db5acb821485e590822953966586a.tar.xz |
Fix wide character output for add/remove/upgrade/conflict progress
Due to the addition of the Chinese translation, our column widths were all
messed up as mentioned in the download progress commit fixing this same
problem there. This is a port of the code and ideas from that fix to the
installation progress bars. Once again, a handful of examples were tested to
ensure we work in all locales and with varying byte and char widths.
English (before & after):
(1/1) checking for file conflicts [-----------------] 100%
(1/1) upgrading man-pages [-----------------] 100%
German (before & after):
(1/1) Prüfe auf Dateikonflikte [-----------------] 100%
(1/1) Aktualisiere man-pages [-----------------] 100%
Chinese (before):
(1/1) 正在检查文件冲突 [-----------------] 100%
(1/1) 生在升级 man-pages [c o o o o o ] (1/1) 生在升级 man-pages [----------C o o ] (1/1) 生在升级 man-pages [-----------------] 100%
Chinese (after):
(1/1) 正在检查文件冲突 [-----------------] 100%
(1/1) 生在升级 man-pages [-----------------] 100%
Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/pacman/callback.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 5865550e..629c2e1c 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -328,8 +328,11 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent, /* size of line to allocate for text printing (e.g. not progressbar) */ const int infolen = 50; - int tmp, digits, oprlen, textlen, remainlen; + int tmp, digits, textlen; char *opr = NULL; + /* used for wide character width determination and printing */ + int len, wclen, wcwid, padwid; + wchar_t *wcstr; if(config->noprogressbar) { return; @@ -378,27 +381,41 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent, while((tmp /= 10)) { ++digits; } - /* determine room left for non-digits text [not ( 1/12) part] */ textlen = infolen - 3 - (2 * digits); - oprlen = mbstowcs(NULL, opr, 0); - /* room left (eg for package name) */ - remainlen = textlen - oprlen - 1; + /* In order to deal with characters from all locales, we have to worry + * about wide characters and their column widths. A lot of stuff is + * done here to figure out the actual number of screen columns used + * by the output, and then pad it accordingly so we fill the terminal. + */ + /* len = opr len + pkgname len (if available) + space + null */ + len = strlen(opr) + ((pkgname) ? strlen(pkgname) : 0) + 2; + wcstr = calloc(len, sizeof(wchar_t)); + /* print our strings to the alloc'ed memory */ + wclen = swprintf(wcstr, len, L"%s %s", opr, pkgname); + wcwid = wcswidth(wcstr, wclen); + padwid = textlen - wcwid; + /* if padwid is < 0, we need to trim the string so padwid = 0 */ + if(padwid < 0) { + int i = textlen - 3; + wchar_t *p = wcstr; + /* grab the max number of char columns we can fill */ + while(i > 0 && wcwidth(*p) < i) { + i -= wcwidth(*p); + p++; + } + /* then add the ellipsis and fill out any extra padding */ + wcscpy(p, L"..."); + padwid = i; - switch (event) { - case PM_TRANS_PROGRESS_ADD_START: - case PM_TRANS_PROGRESS_UPGRADE_START: - case PM_TRANS_PROGRESS_REMOVE_START: - printf("(%*d/%*d) %s %-*.*s", digits, remain, digits, howmany, - opr, remainlen, remainlen, pkgname); - break; - case PM_TRANS_PROGRESS_CONFLICTS_START: - printf("(%*d/%*d) %s %-*s", digits, remain, digits, howmany, - opr, remainlen, ""); - break; } + printf("(%*d/%*d) %ls%-*s", digits, remain, digits, howmany, + wcstr, padwid, ""); + + free(wcstr); + /* call refactored fill progress function */ fill_progress(percent, percent, getcols() - infolen); |