From b6b65a05c03b34b4b7064b2153b6ddf851100044 Mon Sep 17 00:00:00 2001
From: Darshit Shah
Date: Fri, 12 Sep 2014 13:33:20 +0530
Subject: [PATCH] Handle multibyte characters in progressbar
This commit fixes a bug in the progressbar implementation wherein
filenames with multibyte characters were not handled correctly.
---
ChangeLog | 4 ++++
bootstrap.conf | 1 +
src/progress.c | 44 +++++++++++++++++++++++++++++++++++++++++---
3 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8b693be..c4e7809 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-09-12 Darshit Shah
+
+ * bootstrap.conf: Add GNULib module mbiter
+
2014-07-25 Darshit Shah
* .gitignore: Add a gitignore file for the project.
diff --git a/bootstrap.conf b/bootstrap.conf
index 516bbb6..bbfb38f 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -49,6 +49,7 @@ iconv
iconv-h
listen
maintainer-makefile
+mbiter
mbtowc
mkdir
mkstemp
diff --git a/src/progress.c b/src/progress.c
index e9182cc..86cdbce 100644
--- a/src/progress.c
+++ b/src/progress.c
@@ -37,6 +37,7 @@ as that of the covered work. */
#include
#include
#include
+#include
#include "progress.h"
#include "utils.h"
@@ -812,8 +813,37 @@ count_cols (const char *mbs)
}
return cols;
}
+
+static int
+cols_to_bytes (const char *mbs, const int cols, int *ncols)
+{
+ int p_cols = 0, bytes = 0;
+ mbchar_t mbc;
+ mbi_iterator_t iter;
+ mbi_init (iter, mbs, strlen(mbs));
+ while (p_cols < cols && mbi_avail (iter))
+ {
+ mbc = mbi_cur (iter);
+ p_cols += mb_width (mbc);
+ /* The multibyte character has exceeded the total number of columns we
+ * have available. The remaining bytes will be padded with a space. */
+ if (p_cols > cols)
+ {
+ p_cols -= mb_width (mbc);
+ break;
+ }
+ bytes += mb_len (mbc);
+ mbi_advance (iter);
+ }
+ *ncols = p_cols;
+ return bytes;
+}
#else
# define count_cols(mbs) ((int)(strlen(mbs)))
+# define cols_to_bytes(mbs, cols, *ncols) do { \
+ *ncols = cols; \
+ bytes = cols; \
+}while (0)
#endif
static const char *
@@ -885,6 +915,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
struct bar_progress_hist *hist = &bp->hist;
int orig_filename_len = strlen (bp->f_download);
+ int orig_filename_cols = count_cols (bp->f_download);
/* The progress bar should look like this:
file xx% [=======> ] nnn.nnK 12.34KB/s eta 36m 51s
@@ -935,13 +966,20 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
else
{
int offset;
+ int offset_bytes, offset_start, col;
+ int *cols_ret = &col;
if (((orig_filename_len > MAX_FILENAME_LEN) && !opt.noscroll) && !done)
- offset = ((int) bp->tick) % (orig_filename_len - MAX_FILENAME_LEN);
+ offset = ((int) bp->tick) % (orig_filename_cols - MAX_FILENAME_LEN);
else
offset = 0;
- memcpy (p, bp->f_download + offset, MAX_FILENAME_LEN);
- p += MAX_FILENAME_LEN;
+ offset_start = cols_to_bytes (bp->f_download, offset, cols_ret);
+ offset_bytes = cols_to_bytes (bp->f_download + offset_start, MAX_FILENAME_LEN, cols_ret);
+ memcpy (p, bp->f_download + offset_start, offset_bytes);
+ p += offset_bytes;
+ int padding = MAX_FILENAME_LEN - *cols_ret;
+ for (;padding;padding--)
+ *p++ = ' ';
*p++ = ' ';
}
--
2.1.0