From 29f55fb7c9e2d7d3923d796216a9506d95b1fd60 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Fri, 22 Feb 2008 20:57:45 -0600 Subject: Fix wide character output for download progress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we have a Chinese translation, all of the problems with new character sets crop up. Assumptions were made in the past that all characters occupied one column, which is not true with a Chinese character set. In addition, the download code even failed on such things as 'ö', which is two bytes wide but only 1 column. This code will need to also be ported to the add/remove/upgrade/conflicts progress printouts. Note that the tests below try to incorporate a number of things: 1. download filenames too long to fit 2. download filenames cut off in the middle of a multibyte sequence 3. download filenames incorporating multicolumn chars 4. download filenames incorporating multibyte, single-column chars 5. 'plain' download filenames that have always worked Before: :: 正在同步软件包数据库…… 正在解决倚赖��... 0.0K 199.8K/s 00:00:00 [-----------------] 100% 错误:无法升级正在解决倚赖关系junköëjunköëjunköëäää (未预计的系统错误) 正在解决倚赖��... 0.0K 308.4K/s 00:00:00 [-----------------] 100% 错误:无法升级正在解决倚赖关系 (未预计的系统错误) junköëä 0.0K 390.6K/s 00:00:00 [-----------------] 100% 错误:无法升级junköëä (未预计的系统错误) pacman-git 0.5K 4.3M/s 00:00:00 [-----------------] 100% 本地数据库已是最新的 After: :: 正在同步软件包数据库…… 正在解决倚赖关系jun... 0.0K 89.7K/s 00:00:00 [-----------------] 100% 错误:无法升级正在解决倚赖关系junköëjunköëjunköëäää (未预计的系统错误) 正在解决倚赖关系 0.0K 147.7K/s 00:00:00 [-----------------] 100% 错误:无法升级正在解决倚赖关系 (未预计的系统错误) junköëä 0.0K 156.9K/s 00:00:00 [-----------------] 100% 错误:无法升级junköëä (未预计的系统错误) pacman-git 0.5K 1515.9K/s 00:00:00 [-----------------] 100% 本地数据库已是最新的 Signed-off-by: Dan McGee --- src/pacman/callback.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/pacman/callback.c b/src/pacman/callback.c index cf07a09d..5865550e 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -36,7 +36,6 @@ /* TODO this should not have to be defined twice- trans.c & log.c */ #define LOG_STR_LEN 256 -#define FILENAME_TRIM_LEN 23 /* download progress bar */ static float rate_last; @@ -421,7 +420,11 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total, int list_xfered, int list_total) { const int infolen = 50; + const int filenamelen = infolen - 27; char *fname, *p; + /* used for wide character width determination and printing */ + int len, wclen, wcwid, padwid; + wchar_t *wcfname; float rate = 0.0, timediff = 0.0, f_xfered = 0.0; unsigned int eta_h = 0, eta_m = 0, eta_s = 0; @@ -501,8 +504,30 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total, if((p = strstr(fname, PKGEXT)) || (p = strstr(fname, DBEXT))) { *p = '\0'; } - if(strlen(fname) > FILENAME_TRIM_LEN) { - strcpy(fname + FILENAME_TRIM_LEN -3,"..."); + /* 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 = filename len + null */ + len = strlen(filename) + 1; + wcfname = calloc(len, sizeof(wchar_t)); + wclen = mbstowcs(wcfname, fname, len); + wcwid = wcswidth(wcfname, wclen); + padwid = filenamelen - wcwid; + /* if padwid is < 0, we need to trim the string so padwid = 0 */ + if(padwid < 0) { + int i = filenamelen - 3; + wchar_t *p = wcfname; + /* 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; + } /* Awesome formatting for progress bar. We need a mess of Kb->Mb->Gb stuff @@ -532,10 +557,12 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total, } } - printf(" %-*s %6.1f%c %#6.1f%c/s %02u:%02u:%02u", FILENAME_TRIM_LEN, fname, - f_xfered, xfered_size, rate, rate_size, eta_h, eta_m, eta_s); + printf(" %ls%-*s %6.1f%c %#6.1f%c/s %02u:%02u:%02u", wcfname, + padwid, "", f_xfered, xfered_size, + rate, rate_size, eta_h, eta_m, eta_s); free(fname); + free(wcfname); /* The progress bar is based on the file percent regardless of the * TotalDownload option. */ @@ -548,7 +575,7 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total, /* Callback to handle notifications from the library */ void cb_log(pmloglevel_t level, char *fmt, va_list args) { - if(!strlen(fmt)) { + if(strlen(fmt) == 0) { return; } -- cgit v1.2.3-24-g4f1b