mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
More progress bar aesthetic changes
This commit introduces two new changes to how the progress bar looks: 1. Support the --progress=bar:noscroll option which will prevent the filename from scrolling in the progress bar 2. Print human readable value for the amount already downloaded for any file
This commit is contained in:
parent
f2b9004e8f
commit
4eeabffee6
@ -1,3 +1,7 @@
|
|||||||
|
2014-05-24 Darshit Shah <darnir@gmail.com>
|
||||||
|
|
||||||
|
* wget.texi: Document noscroll parameter to progress=bar
|
||||||
|
|
||||||
2014-05-01 Darshit Shah <darnir@gmail.com>
|
2014-05-01 Darshit Shah <darnir@gmail.com>
|
||||||
|
|
||||||
* wget.texi: Add documentation for --show-progress
|
* wget.texi: Add documentation for --show-progress
|
||||||
|
@ -732,7 +732,12 @@ Use @samp{--progress=dot} to switch to the ``dot'' display. It traces
|
|||||||
the retrieval by printing dots on the screen, each dot representing a
|
the retrieval by printing dots on the screen, each dot representing a
|
||||||
fixed amount of downloaded data.
|
fixed amount of downloaded data.
|
||||||
|
|
||||||
When using the dotted retrieval, you may also set the @dfn{style} by
|
The progress @var{type} can also take one or more parameters. The parameters
|
||||||
|
vary based on the @var{type} selected. Parameters to @var{type} are passed by
|
||||||
|
appending them to the type sperated by a colon (:) like this:
|
||||||
|
@samp{--progress=@var{type}:@var{parameter1}:@var{parameter2}}.
|
||||||
|
|
||||||
|
When using the dotted retrieval, you may set the @dfn{style} by
|
||||||
specifying the type as @samp{dot:@var{style}}. Different styles assign
|
specifying the type as @samp{dot:@var{style}}. Different styles assign
|
||||||
different meaning to one dot. With the @code{default} style each dot
|
different meaning to one dot. With the @code{default} style each dot
|
||||||
represents 1K, there are ten dots in a cluster and 50 dots in a line.
|
represents 1K, there are ten dots in a cluster and 50 dots in a line.
|
||||||
@ -745,11 +750,25 @@ If @code{mega} is not enough then you can use the @code{giga}
|
|||||||
style---each dot represents 1M retrieved, there are eight dots in a
|
style---each dot represents 1M retrieved, there are eight dots in a
|
||||||
cluster, and 32 dots on each line (so each line contains 32M).
|
cluster, and 32 dots on each line (so each line contains 32M).
|
||||||
|
|
||||||
|
With @samp{--progress=bar}, there are currently two possible parameters,
|
||||||
|
@var{force} and @var{noscroll}.
|
||||||
|
|
||||||
|
When the output is not a TTY, the progress bar always falls back to ``dot'',
|
||||||
|
even if @samp{--progress=bar} was passed to Wget during invokation. This
|
||||||
|
behaviour can be overridden and the ``bar'' output forced by using the ``force''
|
||||||
|
parameter as @samp{--progress=bar:force}.
|
||||||
|
|
||||||
|
By default, the @samp{bar} style progress bar scroll the name of the file from
|
||||||
|
left to right for the file being downloaded if the filename exceeds the maximum
|
||||||
|
length allotted for its display. In certain cases, such as with
|
||||||
|
@samp{--progress=bar:force}, one may not want the scrolling filename in the
|
||||||
|
progress bar. By passing the ``noscroll'' parameter, Wget can be forced to
|
||||||
|
display as much of the filename as possible without scrolling through it.
|
||||||
|
|
||||||
Note that you can set the default style using the @code{progress}
|
Note that you can set the default style using the @code{progress}
|
||||||
command in @file{.wgetrc}. That setting may be overridden from the
|
command in @file{.wgetrc}. That setting may be overridden from the
|
||||||
command line. The exception is that, when the output is not a TTY, the
|
command line. For example, to force the bar output without scrolling,
|
||||||
``dot'' progress will be favored over ``bar''. To force the bar output,
|
use @samp{--progress=bar:force:noscroll}.
|
||||||
use @samp{--progress=bar:force}.
|
|
||||||
|
|
||||||
@item --show-progress
|
@item --show-progress
|
||||||
Force wget to display the progress bar in any verbosity.
|
Force wget to display the progress bar in any verbosity.
|
||||||
|
@ -1,3 +1,21 @@
|
|||||||
|
2014-05-20 Darshit Shah <darnir@gmail.com>
|
||||||
|
|
||||||
|
* utils.c (human_readable): Add new parameters, acc and decimals for the
|
||||||
|
function. acc decides the number under which decimal values are shown for a
|
||||||
|
certain value, while decimals decides the number of decimal digits displayed
|
||||||
|
* utils.h (human_readable): Update declartion of the function
|
||||||
|
* ftp.c (print_length): Update call to human_readable
|
||||||
|
* http.c (gethttp): Same
|
||||||
|
* init.c (defaults): Enable scrolling filenames by default
|
||||||
|
* main.c (main): Update call to human_readable
|
||||||
|
* options.h (options): Add new option noscroll
|
||||||
|
* progress.c (create_image): Update the look of the progress bar. Human
|
||||||
|
readable download size by default and add support for noscroll.
|
||||||
|
(dot_set_params, bar_set_params): Change paramter to char * since strtok
|
||||||
|
needs to modify the string.
|
||||||
|
(bar_set_params): Add support for noscroll parameter to bar.
|
||||||
|
|
||||||
|
|
||||||
2014-05-03 Tim Ruehsen <tim.ruehsen@gmx.de>
|
2014-05-03 Tim Ruehsen <tim.ruehsen@gmx.de>
|
||||||
|
|
||||||
* ftp-ls.c (ftp_parse_vms_ls): Explicitly typecast strlen's output
|
* ftp-ls.c (ftp_parse_vms_ls): Explicitly typecast strlen's output
|
||||||
|
@ -221,13 +221,13 @@ print_length (wgint size, wgint start, bool authoritative)
|
|||||||
{
|
{
|
||||||
logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size));
|
logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size));
|
||||||
if (size >= 1024)
|
if (size >= 1024)
|
||||||
logprintf (LOG_VERBOSE, " (%s)", human_readable (size));
|
logprintf (LOG_VERBOSE, " (%s)", human_readable (size, 10, 1));
|
||||||
if (start > 0)
|
if (start > 0)
|
||||||
{
|
{
|
||||||
if (size - start >= 1024)
|
if (size - start >= 1024)
|
||||||
logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
|
logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
|
||||||
number_to_static_string (size - start),
|
number_to_static_string (size - start),
|
||||||
human_readable (size - start));
|
human_readable (size - start, 10, 1));
|
||||||
else
|
else
|
||||||
logprintf (LOG_VERBOSE, _(", %s remaining"),
|
logprintf (LOG_VERBOSE, _(", %s remaining"),
|
||||||
number_to_static_string (size - start));
|
number_to_static_string (size - start));
|
||||||
|
@ -2804,13 +2804,13 @@ read_header:
|
|||||||
logputs (LOG_VERBOSE, number_to_static_string (contlen + contrange));
|
logputs (LOG_VERBOSE, number_to_static_string (contlen + contrange));
|
||||||
if (contlen + contrange >= 1024)
|
if (contlen + contrange >= 1024)
|
||||||
logprintf (LOG_VERBOSE, " (%s)",
|
logprintf (LOG_VERBOSE, " (%s)",
|
||||||
human_readable (contlen + contrange));
|
human_readable (contlen + contrange, 10, 1));
|
||||||
if (contrange)
|
if (contrange)
|
||||||
{
|
{
|
||||||
if (contlen >= 1024)
|
if (contlen >= 1024)
|
||||||
logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
|
logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
|
||||||
number_to_static_string (contlen),
|
number_to_static_string (contlen),
|
||||||
human_readable (contlen));
|
human_readable (contlen, 10, 1));
|
||||||
else
|
else
|
||||||
logprintf (LOG_VERBOSE, _(", %s remaining"),
|
logprintf (LOG_VERBOSE, _(", %s remaining"),
|
||||||
number_to_static_string (contlen));
|
number_to_static_string (contlen));
|
||||||
|
@ -413,6 +413,7 @@ defaults (void)
|
|||||||
/* Use a negative value to mark the absence of --start-pos option */
|
/* Use a negative value to mark the absence of --start-pos option */
|
||||||
opt.start_pos = -1;
|
opt.start_pos = -1;
|
||||||
opt.show_progress = false;
|
opt.show_progress = false;
|
||||||
|
opt.noscroll = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the user's home directory (strdup-ed), or NULL if none is
|
/* Return the user's home directory (strdup-ed), or NULL if none is
|
||||||
|
@ -1714,7 +1714,7 @@ outputting to a regular file.\n"));
|
|||||||
datetime_str (time (NULL)),
|
datetime_str (time (NULL)),
|
||||||
wall_time,
|
wall_time,
|
||||||
numurls,
|
numurls,
|
||||||
human_readable (total_downloaded_bytes),
|
human_readable (total_downloaded_bytes, 10, 1),
|
||||||
download_time,
|
download_time,
|
||||||
retr_rate (total_downloaded_bytes, total_download_time));
|
retr_rate (total_downloaded_bytes, total_download_time));
|
||||||
xfree (wall_time);
|
xfree (wall_time);
|
||||||
@ -1724,7 +1724,7 @@ outputting to a regular file.\n"));
|
|||||||
if (opt.quota && total_downloaded_bytes > opt.quota)
|
if (opt.quota && total_downloaded_bytes > opt.quota)
|
||||||
logprintf (LOG_NOTQUIET,
|
logprintf (LOG_NOTQUIET,
|
||||||
_("Download quota of %s EXCEEDED!\n"),
|
_("Download quota of %s EXCEEDED!\n"),
|
||||||
human_readable (opt.quota));
|
human_readable (opt.quota, 10, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.cookies_output)
|
if (opt.cookies_output)
|
||||||
|
@ -135,6 +135,7 @@ struct options
|
|||||||
char *base_href;
|
char *base_href;
|
||||||
char *progress_type; /* progress indicator type. */
|
char *progress_type; /* progress indicator type. */
|
||||||
bool show_progress; /* Show only the progress bar */
|
bool show_progress; /* Show only the progress bar */
|
||||||
|
bool noscroll; /* Don't scroll the filename in the progressbar */
|
||||||
char *proxy_user; /*oli*/
|
char *proxy_user; /*oli*/
|
||||||
char *proxy_passwd;
|
char *proxy_passwd;
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ struct progress_implementation {
|
|||||||
void (*update) (void *, wgint, double);
|
void (*update) (void *, wgint, double);
|
||||||
void (*draw) (void *);
|
void (*draw) (void *);
|
||||||
void (*finish) (void *, double);
|
void (*finish) (void *, double);
|
||||||
void (*set_params) (const char *);
|
void (*set_params) (char *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Necessary forward declarations. */
|
/* Necessary forward declarations. */
|
||||||
@ -60,13 +60,13 @@ static void *dot_create (const char *, wgint, wgint);
|
|||||||
static void dot_update (void *, wgint, double);
|
static void dot_update (void *, wgint, double);
|
||||||
static void dot_finish (void *, double);
|
static void dot_finish (void *, double);
|
||||||
static void dot_draw (void *);
|
static void dot_draw (void *);
|
||||||
static void dot_set_params (const char *);
|
static void dot_set_params (char *);
|
||||||
|
|
||||||
static void *bar_create (const char *, wgint, wgint);
|
static void *bar_create (const char *, wgint, wgint);
|
||||||
static void bar_update (void *, wgint, double);
|
static void bar_update (void *, wgint, double);
|
||||||
static void bar_draw (void *);
|
static void bar_draw (void *);
|
||||||
static void bar_finish (void *, double);
|
static void bar_finish (void *, double);
|
||||||
static void bar_set_params (const char *);
|
static void bar_set_params (char *);
|
||||||
|
|
||||||
static struct progress_implementation implementations[] = {
|
static struct progress_implementation implementations[] = {
|
||||||
{ "dot", 0, dot_create, dot_update, dot_draw, dot_finish, dot_set_params },
|
{ "dot", 0, dot_create, dot_update, dot_draw, dot_finish, dot_set_params },
|
||||||
@ -112,7 +112,7 @@ set_progress_implementation (const char *name)
|
|||||||
{
|
{
|
||||||
size_t i, namelen;
|
size_t i, namelen;
|
||||||
struct progress_implementation *pi = implementations;
|
struct progress_implementation *pi = implementations;
|
||||||
const char *colon;
|
char *colon;
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
name = DEFAULT_PROGRESS_IMPLEMENTATION;
|
name = DEFAULT_PROGRESS_IMPLEMENTATION;
|
||||||
@ -419,7 +419,7 @@ dot_finish (void *progress, double dltime)
|
|||||||
giga. */
|
giga. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dot_set_params (const char *params)
|
dot_set_params (char *params)
|
||||||
{
|
{
|
||||||
if (!params || !*params)
|
if (!params || !*params)
|
||||||
params = opt.dot_style;
|
params = opt.dot_style;
|
||||||
@ -889,7 +889,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
|||||||
int orig_filename_len = strlen (bp->f_download);
|
int orig_filename_len = strlen (bp->f_download);
|
||||||
|
|
||||||
/* The progress bar should look like this:
|
/* The progress bar should look like this:
|
||||||
file xx% [=======> ] nn,nnn 12.34KB/s eta 36m 51s
|
file xx% [=======> ] nnn.nnK 12.34KB/s eta 36m 51s
|
||||||
|
|
||||||
Calculate the geometry. The idea is to assign as much room as
|
Calculate the geometry. The idea is to assign as much room as
|
||||||
possible to the progress bar. The other idea is to never let
|
possible to the progress bar. The other idea is to never let
|
||||||
@ -898,17 +898,26 @@ 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 MAX_FILENAME_LEN chars + 1
|
"file " - Downloaded filename - MAX_FILENAME_LEN 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,nnn,nnn" - downloaded bytes - 12 chars or very rarely more
|
" nnn.nnK" - downloaded bytes - 7 chars + 1
|
||||||
" 12.5KB/s" - download rate - 9 chars
|
" 12.5KB/s" - download rate - 8 chars + 1
|
||||||
" eta 36m 51s" - ETA - 14 chars
|
" eta 36m 51s" - ETA - 14 chars
|
||||||
|
|
||||||
"=====>..." - progress bar - the rest
|
"=====>..." - progress bar - the rest
|
||||||
*/
|
*/
|
||||||
int dlbytes_size = 1 + MAX (size_grouped_len, 11);
|
|
||||||
int progress_size = bp->width - (MAX_FILENAME_LEN + 1 + 4 + 2 + dlbytes_size + 8 + 14);
|
#define PROGRESS_FILENAME_LEN MAX_FILENAME_LEN + 1
|
||||||
|
#define PROGRESS_PERCENT_LEN 4
|
||||||
|
#define PROGRESS_DECORAT_LEN 2
|
||||||
|
#define PROGRESS_FILESIZE_LEN 7 + 1
|
||||||
|
#define PROGRESS_DWNLOAD_RATE 8 + 1
|
||||||
|
#define PROGRESS_ETA_LEN 14
|
||||||
|
|
||||||
|
int progress_size = bp->width - (PROGRESS_FILENAME_LEN + PROGRESS_PERCENT_LEN +
|
||||||
|
PROGRESS_DECORAT_LEN + PROGRESS_FILESIZE_LEN +
|
||||||
|
PROGRESS_DWNLOAD_RATE + PROGRESS_ETA_LEN);
|
||||||
|
|
||||||
/* The difference between the number of bytes used,
|
/* The difference between the number of bytes used,
|
||||||
and the number of columns used. */
|
and the number of columns used. */
|
||||||
@ -929,7 +938,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
|||||||
{
|
{
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
if (orig_filename_len > MAX_FILENAME_LEN)
|
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_len - MAX_FILENAME_LEN);
|
||||||
else
|
else
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@ -1014,13 +1023,20 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
|||||||
}
|
}
|
||||||
++bp->tick;
|
++bp->tick;
|
||||||
|
|
||||||
/* " 234,567,890" */
|
/* " 234.56M" */
|
||||||
sprintf (p, " %s", size_grouped);
|
const char * down_size = human_readable (size, 1000, 2);
|
||||||
|
int cols_diff = 7 - count_cols (down_size);
|
||||||
|
while (cols_diff > 0)
|
||||||
|
{
|
||||||
|
*p++=' ';
|
||||||
|
cols_diff--;
|
||||||
|
}
|
||||||
|
sprintf (p, " %s", down_size);
|
||||||
move_to_end (p);
|
move_to_end (p);
|
||||||
/* Pad with spaces to 11 chars for the size_grouped field;
|
/* Pad with spaces to 7 chars for the size_grouped field;
|
||||||
* couldn't use the field width specifier in sprintf, because
|
* couldn't use the field width specifier in sprintf, because
|
||||||
* it counts in bytes, not characters. */
|
* it counts in bytes, not characters. */
|
||||||
for (size_grouped_pad = 11 - size_grouped_len;
|
for (size_grouped_pad = PROGRESS_FILESIZE_LEN - 7;
|
||||||
size_grouped_pad > 0;
|
size_grouped_pad > 0;
|
||||||
--size_grouped_pad)
|
--size_grouped_pad)
|
||||||
{
|
{
|
||||||
@ -1030,20 +1046,20 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
|||||||
/* " 12.52Kb/s or 12.52KB/s" */
|
/* " 12.52Kb/s or 12.52KB/s" */
|
||||||
if (hist->total_time > 0 && hist->total_bytes)
|
if (hist->total_time > 0 && hist->total_bytes)
|
||||||
{
|
{
|
||||||
static const char *short_units[] = { "B/s", "KB/s", "MB/s", "GB/s" };
|
static const char *short_units[] = { " B/s", "KB/s", "MB/s", "GB/s" };
|
||||||
static const char *short_units_bits[] = { "b/s", "Kb/s", "Mb/s", "Gb/s" };
|
static const char *short_units_bits[] = { " b/s", "Kb/s", "Mb/s", "Gb/s" };
|
||||||
int units = 0;
|
int units = 0;
|
||||||
/* Calculate the download speed using the history ring and
|
/* Calculate the download speed using the history ring and
|
||||||
recent data that hasn't made it to the ring yet. */
|
recent data that hasn't made it to the ring yet. */
|
||||||
wgint dlquant = hist->total_bytes + bp->recent_bytes;
|
wgint dlquant = hist->total_bytes + bp->recent_bytes;
|
||||||
double dltime = hist->total_time + (dl_total_time - bp->recent_start);
|
double dltime = hist->total_time + (dl_total_time - bp->recent_start);
|
||||||
double dlspeed = calc_rate (dlquant, dltime, &units);
|
double dlspeed = calc_rate (dlquant, dltime, &units);
|
||||||
sprintf (p, "%4.*f%s", dlspeed >= 99.95 ? 0 : dlspeed >= 9.995 ? 1 : 2,
|
sprintf (p, " %4.*f%s", dlspeed >= 99.95 ? 0 : dlspeed >= 9.995 ? 1 : 2,
|
||||||
dlspeed, !opt.report_bps ? short_units[units] : short_units_bits[units]);
|
dlspeed, !opt.report_bps ? short_units[units] : short_units_bits[units]);
|
||||||
move_to_end (p);
|
move_to_end (p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
APPEND_LITERAL ("--.-KB/s");
|
APPEND_LITERAL (" --.-KB/s");
|
||||||
|
|
||||||
if (!done)
|
if (!done)
|
||||||
{
|
{
|
||||||
@ -1126,13 +1142,21 @@ display_image (char *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bar_set_params (const char *params)
|
bar_set_params (char *params)
|
||||||
{
|
{
|
||||||
char *term = getenv ("TERM");
|
char *term = getenv ("TERM");
|
||||||
|
|
||||||
if (params
|
if (params)
|
||||||
&& 0 == strcmp (params, "force"))
|
{
|
||||||
current_impl_locked = 1;
|
char *param = strtok (params, ":");
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (0 == strcmp (param, "force"))
|
||||||
|
current_impl_locked = 1;
|
||||||
|
else if (0 == strcmp (param, "noscroll"))
|
||||||
|
opt.noscroll = true;
|
||||||
|
} while ((param = strtok (NULL, ":")) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if ((opt.lfilename
|
if ((opt.lfilename
|
||||||
#ifdef HAVE_ISATTY
|
#ifdef HAVE_ISATTY
|
||||||
|
@ -1523,7 +1523,7 @@ with_thousand_seps (wgint n)
|
|||||||
some detail. */
|
some detail. */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
human_readable (HR_NUMTYPE n)
|
human_readable (HR_NUMTYPE n, const int acc, const int decimals)
|
||||||
{
|
{
|
||||||
/* These suffixes are compatible with those of GNU `ls -lh'. */
|
/* These suffixes are compatible with those of GNU `ls -lh'. */
|
||||||
static char powers[] =
|
static char powers[] =
|
||||||
@ -1556,10 +1556,10 @@ human_readable (HR_NUMTYPE n)
|
|||||||
if ((n / 1024) < 1024 || i == countof (powers) - 1)
|
if ((n / 1024) < 1024 || i == countof (powers) - 1)
|
||||||
{
|
{
|
||||||
double val = n / 1024.0;
|
double val = n / 1024.0;
|
||||||
/* Print values smaller than 10 with one decimal digits, and
|
/* Print values smaller than the accuracy level (acc) with (decimal)
|
||||||
others without any decimals. */
|
* decimal digits, and others without any decimals. */
|
||||||
snprintf (buf, sizeof (buf), "%.*f%c",
|
snprintf (buf, sizeof (buf), "%.*f%c",
|
||||||
val < 10 ? 1 : 0, val, powers[i]);
|
val < acc ? decimals : 0, val, powers[i]);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
n /= 1024;
|
n /= 1024;
|
||||||
|
@ -121,7 +121,7 @@ const char *with_thousand_seps (wgint);
|
|||||||
#else
|
#else
|
||||||
# define HR_NUMTYPE double
|
# define HR_NUMTYPE double
|
||||||
#endif
|
#endif
|
||||||
char *human_readable (HR_NUMTYPE);
|
char *human_readable (HR_NUMTYPE, const int, const int);
|
||||||
|
|
||||||
|
|
||||||
int numdigit (wgint);
|
int numdigit (wgint);
|
||||||
|
Loading…
Reference in New Issue
Block a user