from sizes.
+2005-06-26 Hrvoje Niksic <hniksic@xemacs.org>
+
+ * main.c (main): Print the downloaded and quota amounts with the
+ "human_readable" function.
+
+ * ftp.c (print_length): Ditto.
+
+ * http.c (gethttp): Don't display thousand separators.
+
+ * utils.c (with_thousand_seps): Rewritten to respect locale
+ settings and to be type size agnostic.
+
2005-06-25 Hrvoje Niksic <hniksic@xemacs.org>
* utils.c (human_readable): Divide with 1024 instead of shifting
putc ('/', fp);
fprintf (fp, "</a> ");
if (f->type == FT_PLAINFILE)
- fprintf (fp, _(" (%s bytes)"), with_thousand_seps (f->size));
+ fprintf (fp, _(" (%s bytes)"), number_to_static_string (f->size));
else if (f->type == FT_SYMLINK)
fprintf (fp, "-> %s", f->linkto ? f->linkto : "(nil)");
putc ('\n', fp);
static void
print_length (wgint size, wgint start, int authoritative)
{
- logprintf (LOG_VERBOSE, _("Length: %s"), with_thousand_seps (size));
+ logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size));
if (size >= 1024)
logprintf (LOG_VERBOSE, " (%s)", human_readable (size));
if (start > 0)
{
if (start >= 1024)
logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
- with_thousand_seps (size - start),
+ number_to_static_string (size - start),
human_readable (size - start));
else
logprintf (LOG_VERBOSE, _(", %s remaining"),
- with_thousand_seps (size - start));
+ number_to_static_string (size - start));
}
logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
}
logputs (LOG_VERBOSE, _("Length: "));
if (contlen != -1)
{
- logputs (LOG_VERBOSE, with_thousand_seps (contlen + contrange));
+ logputs (LOG_VERBOSE, number_to_static_string (contlen + contrange));
if (contlen + contrange >= 1024)
logprintf (LOG_VERBOSE, " (%s)",
human_readable (contlen + contrange));
{
if (contlen >= 1024)
logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
- with_thousand_seps (contlen),
+ number_to_static_string (contlen),
human_readable (contlen));
else
logprintf (LOG_VERBOSE, _(", %s remaining"),
- with_thousand_seps (contlen));
+ number_to_static_string (contlen));
}
}
else
|| (opt.input_filename && total_downloaded_bytes != 0))
{
logprintf (LOG_NOTQUIET,
- _("\nFINISHED --%s--\nDownloaded: %s bytes in %d files\n"),
+ _("\nFINISHED --%s--\nDownloaded: %s in %d files\n"),
time_str (NULL),
- with_thousand_seps_sum (total_downloaded_bytes),
+ human_readable (total_downloaded_bytes),
opt.numurls);
/* Print quota warning, if exceeded. */
if (opt.quota && total_downloaded_bytes > opt.quota)
logprintf (LOG_NOTQUIET,
- _("Download quota (%s bytes) EXCEEDED!\n"),
- with_thousand_seps_sum (opt.quota));
+ _("Download quota of %s EXCEEDED!\n"),
+ human_readable (opt.quota));
}
if (opt.cookies_output)
char *p = bp->buffer;
wgint size = bp->initial_length + bp->count;
- char *size_legible = with_thousand_seps (size);
- int size_legible_len = strlen (size_legible);
+ const char *size_grouped = with_thousand_seps (size);
+ int size_grouped_len = strlen (size_grouped);
struct bar_progress_hist *hist = &bp->hist;
"=====>..." - progress bar - the rest
*/
- int dlbytes_size = 1 + MAX (size_legible_len, 11);
+ int dlbytes_size = 1 + MAX (size_grouped_len, 11);
int progress_size = bp->width - (4 + 2 + dlbytes_size + 11 + 13);
if (progress_size < 5)
}
/* " 234,567,890" */
- sprintf (p, " %-11s", with_thousand_seps (size));
+ sprintf (p, " %-11s", size_grouped);
p += strlen (p);
/* " 1012.45K/s" */
#include <fcntl.h>
#include <assert.h>
#include <stdarg.h>
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
/* For TIOCGWINSZ and friends: */
#ifdef HAVE_SYS_IOCTL_H
}
\f
-/* Add thousand separators to a number already in string form. Used
- by with_thousand_seps and with_thousand_seps_sum. */
+/* Return a printed representation of N with thousand separators.
+ This should respect locale settings, with the exception of the "C"
+ locale which mandates no separator, but we use one anyway.
-static char *
-add_thousand_seps (const char *repr)
+ Unfortunately, we cannot use %'d (in fact it would be %'j) to get
+ the separators because it's too non-portable, and it's hard to test
+ for this feature at configure time. Besides, it wouldn't work in
+ the "C" locale, which many Unix users still work in. */
+
+const char *
+with_thousand_seps (wgint n)
{
static char outbuf[48];
- int i, i1, mod;
- char *outptr;
- const char *inptr;
- /* Reset the pointers. */
- outptr = outbuf;
- inptr = repr;
+ static char loc_sepchar;
+ static const char *loc_grouping;
- /* Ignore the sign for the purpose of adding thousand
- separators. */
- if (*inptr == '-')
- {
- *outptr++ = '-';
- ++inptr;
- }
- /* How many digits before the first separator? */
- mod = strlen (inptr) % 3;
- /* Insert them. */
- for (i = 0; i < mod; i++)
- *outptr++ = inptr[i];
- /* Now insert the rest of them, putting separator before every
- third digit. */
- for (i1 = i, i = 0; inptr[i1]; i++, i1++)
+ int i = 0, groupsize;
+ char *p;
+ const char *atgroup;
+
+ if (!loc_sepchar)
{
- if (i % 3 == 0 && i1 != 0)
- *outptr++ = ',';
- *outptr++ = inptr[i1];
+#ifdef LC_NUMERIC
+ /* Get the grouping character from the locale. */
+ struct lconv *lconv;
+ const char *oldlocale = setlocale (LC_NUMERIC, "");
+ lconv = localeconv ();
+ loc_sepchar = *lconv->thousands_sep;
+ loc_grouping = xstrdup (lconv->grouping);
+ /* Restore the C locale semantics of printing and reading numbers */
+ setlocale (LC_NUMERIC, oldlocale);
+ if (!loc_sepchar)
+#endif
+ /* defaults for C locale or no locale */
+ loc_sepchar = ',', loc_grouping = "\x03";
}
- /* Zero-terminate the string. */
- *outptr = '\0';
- return outbuf;
-}
-
-/* Return a static pointer to the number printed with thousand
- separators inserted at the right places. */
-
-char *
-with_thousand_seps (wgint l)
-{
- char inbuf[24];
- /* Print the number into the buffer. */
- number_to_string (inbuf, l);
- return add_thousand_seps (inbuf);
-}
+ atgroup = loc_grouping;
-/* When SUM_SIZE_INT is wgint, with_thousand_seps_large is #defined to
- with_thousand_seps. The function below is used on non-LFS systems
- where SUM_SIZE_INT typedeffed to double. */
+ p = outbuf + sizeof outbuf;
+ *--p = '\0';
+ groupsize = *atgroup++;
-#ifndef with_thousand_seps_sum
-char *
-with_thousand_seps_sum (SUM_SIZE_INT l)
-{
- char inbuf[32];
- snprintf (inbuf, sizeof (inbuf), "%.0f", l);
- return add_thousand_seps (inbuf);
+ while (1)
+ {
+ *--p = n % 10 + '0';
+ n /= 10;
+ if (n == 0)
+ break;
+ /* Insert the separator on every groupsize'd digit, and get the
+ new groupsize. */
+ if (++i == groupsize)
+ {
+ *--p = loc_sepchar;
+ i = 0;
+ if (*atgroup)
+ groupsize = *atgroup++;
+ }
+ }
+ return p;
}
-#endif /* not with_thousand_seps_sum */
/* N, a byte quantity, is converted to a human-readable abberviated
form a la sizes printed by `ls -lh'. The result is written to a
discusses this in some detail. */
char *
-human_readable (wgint n)
+human_readable (HR_NUMTYPE n)
{
/* These suffixes are compatible with those of GNU `ls -lh'. */
static char powers[] =
void string_set_free (struct hash_table *);
void free_keys_and_values (struct hash_table *);
-char *with_thousand_seps (wgint);
-#ifndef with_thousand_seps_sum
-char *with_thousand_seps_sum (SUM_SIZE_INT);
+const char *with_thousand_seps (wgint);
+
+/* human_readable must be able to accept wgint and SUM_SIZE_INT
+ arguments. On machines where wgint is 32-bit, declare it to accept
+ double. */
+#if SIZEOF_WGINT >= 8
+# define HR_NUMTYPE wgint
+#else
+# define HR_NUMTYPE double
#endif
-char *human_readable (wgint);
+char *human_readable (HR_NUMTYPE);
+
+
int numdigit (wgint);
char *number_to_string (char *, wgint);
char *number_to_static_string (wgint);