mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
Handle multibyte characters in progressbar
This commit fixes a bug in the progressbar implementation wherein filenames with multibyte characters were not handled correctly.
This commit is contained in:
parent
f8e9a64ec7
commit
efe090df89
@ -1,3 +1,7 @@
|
|||||||
|
2014-09-12 Darshit Shah <darnir@gmail.com>
|
||||||
|
|
||||||
|
* bootstrap.conf: Add GNULib module mbiter
|
||||||
|
|
||||||
2014-07-25 Darshit Shah <darnir@gmail.com>
|
2014-07-25 Darshit Shah <darnir@gmail.com>
|
||||||
|
|
||||||
* .gitignore: Add a gitignore file for the project.
|
* .gitignore: Add a gitignore file for the project.
|
||||||
|
@ -49,6 +49,7 @@ iconv
|
|||||||
iconv-h
|
iconv-h
|
||||||
listen
|
listen
|
||||||
maintainer-makefile
|
maintainer-makefile
|
||||||
|
mbiter
|
||||||
mbtowc
|
mbtowc
|
||||||
mkdir
|
mkdir
|
||||||
mkstemp
|
mkstemp
|
||||||
|
@ -37,6 +37,7 @@ as that of the covered work. */
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
#include <mbiter.h>
|
||||||
|
|
||||||
#include "progress.h"
|
#include "progress.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@ -812,8 +813,37 @@ count_cols (const char *mbs)
|
|||||||
}
|
}
|
||||||
return cols;
|
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
|
#else
|
||||||
# define count_cols(mbs) ((int)(strlen(mbs)))
|
# define count_cols(mbs) ((int)(strlen(mbs)))
|
||||||
|
# define cols_to_bytes(mbs, cols, *ncols) do { \
|
||||||
|
*ncols = cols; \
|
||||||
|
bytes = cols; \
|
||||||
|
}while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
@ -873,7 +903,7 @@ get_eta (int *bcd)
|
|||||||
static void
|
static void
|
||||||
create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
||||||
{
|
{
|
||||||
const int MAX_FILENAME_LEN = bp->width / 4;
|
const int MAX_FILENAME_COLS = bp->width / 4;
|
||||||
char *p = bp->buffer;
|
char *p = bp->buffer;
|
||||||
wgint size = bp->initial_length + bp->count;
|
wgint size = bp->initial_length + bp->count;
|
||||||
|
|
||||||
@ -884,7 +914,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
|||||||
int size_grouped_pad; /* Used to pad the field width for size_grouped. */
|
int size_grouped_pad; /* Used to pad the field width for size_grouped. */
|
||||||
|
|
||||||
struct bar_progress_hist *hist = &bp->hist;
|
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:
|
/* The progress bar should look like this:
|
||||||
file xx% [=======> ] nnn.nnK 12.34KB/s eta 36m 51s
|
file xx% [=======> ] nnn.nnK 12.34KB/s eta 36m 51s
|
||||||
@ -896,7 +926,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
|||||||
It would be especially bad for the progress bar to be resized
|
It would be especially bad for the progress bar to be resized
|
||||||
randomly.
|
randomly.
|
||||||
|
|
||||||
"file " - Downloaded filename - MAX_FILENAME_LEN chars + 1
|
"file " - Downloaded filename - MAX_FILENAME_COLS chars + 1
|
||||||
"xx% " or "100%" - percentage - 4 chars
|
"xx% " or "100%" - percentage - 4 chars
|
||||||
"[]" - progress bar decorations - 2 chars
|
"[]" - progress bar decorations - 2 chars
|
||||||
" nnn.nnK" - downloaded bytes - 7 chars + 1
|
" nnn.nnK" - downloaded bytes - 7 chars + 1
|
||||||
@ -906,7 +936,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
|||||||
"=====>..." - progress bar - the rest
|
"=====>..." - progress bar - the rest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PROGRESS_FILENAME_LEN MAX_FILENAME_LEN + 1
|
#define PROGRESS_FILENAME_LEN MAX_FILENAME_COLS + 1
|
||||||
#define PROGRESS_PERCENT_LEN 4
|
#define PROGRESS_PERCENT_LEN 4
|
||||||
#define PROGRESS_DECORAT_LEN 2
|
#define PROGRESS_DECORAT_LEN 2
|
||||||
#define PROGRESS_FILESIZE_LEN 7 + 1
|
#define PROGRESS_FILESIZE_LEN 7 + 1
|
||||||
@ -924,24 +954,31 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
|||||||
if (progress_size < 5)
|
if (progress_size < 5)
|
||||||
progress_size = 0;
|
progress_size = 0;
|
||||||
|
|
||||||
if (orig_filename_len <= MAX_FILENAME_LEN)
|
if (orig_filename_cols <= MAX_FILENAME_COLS)
|
||||||
{
|
{
|
||||||
int padding = MAX_FILENAME_LEN - orig_filename_len;
|
int padding = MAX_FILENAME_COLS - orig_filename_cols;
|
||||||
sprintf (p, "%s ", bp->f_download);
|
sprintf (p, "%s ", bp->f_download);
|
||||||
p += orig_filename_len + 1;
|
p += orig_filename_cols + 1;
|
||||||
for (;padding;padding--)
|
for (;padding;padding--)
|
||||||
*p++ = ' ';
|
*p++ = ' ';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int offset;
|
int offset_cols;
|
||||||
|
int bytes_in_filename, offset_bytes, col;
|
||||||
|
int *cols_ret = &col;
|
||||||
|
|
||||||
if (((orig_filename_len > MAX_FILENAME_LEN) && !opt.noscroll) && !done)
|
if (((orig_filename_cols > MAX_FILENAME_COLS) && !opt.noscroll) && !done)
|
||||||
offset = ((int) bp->tick) % (orig_filename_len - MAX_FILENAME_LEN);
|
offset_cols = ((int) bp->tick) % (orig_filename_cols - MAX_FILENAME_COLS);
|
||||||
else
|
else
|
||||||
offset = 0;
|
offset_cols = 0;
|
||||||
memcpy (p, bp->f_download + offset, MAX_FILENAME_LEN);
|
offset_bytes = cols_to_bytes (bp->f_download, offset_cols, cols_ret);
|
||||||
p += MAX_FILENAME_LEN;
|
bytes_in_filename = cols_to_bytes (bp->f_download + offset_bytes, MAX_FILENAME_COLS, cols_ret);
|
||||||
|
memcpy (p, bp->f_download + offset_bytes, bytes_in_filename);
|
||||||
|
p += bytes_in_filename;
|
||||||
|
int padding = MAX_FILENAME_COLS - *cols_ret;
|
||||||
|
for (;padding;padding--)
|
||||||
|
*p++ = ' ';
|
||||||
*p++ = ' ';
|
*p++ = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user