Here is the new version of the patch, with print_*_number_to_string
replaced with a single number_to_static_string, which does the buffer
ring stunt we discussed (and has a more accurate name to boot).

Please try it out and let me know if it works for you.  I'd especially
be interested in compilation reports from 64-bit systems, systems
without LFS, and non-Linux systems.  Tips for making it work on
Windows would also be appreciated.

Mauro, what do you think of the patch?  If you agree with the patch,
I'd like to commit it to CVS once it gets sufficient testing.

ChangeLog:
2005-02-20  Hrvoje Niksic  <[EMAIL PROTECTED]>

        * configure.in: Check for LFS.  Determine SIZEOF_OFF_T.

src/ChangeLog:
2005-02-20  Hrvoje Niksic  <[EMAIL PROTECTED]>

        * wget.h: Define a `wgint' type, normally aliased to (a possibly
        64-bit) off_t.

        * all: Use `wgint' instead of `long' for numeric variables that
        can hold file sizes.

        * utils.c (number_to_string): Accept a `wgint' number argument.
        (number_to_static_string): New function.

        * all: Replace printf("%ld", long_value) with printf("%s",
        number_to_static_string(wgint_value)).

Index: configure.in
===================================================================
RCS file: /pack/anoncvs/wget/configure.in,v
retrieving revision 1.73
diff -u -r1.73 configure.in
--- configure.in        2003/11/26 22:46:13     1.73
+++ configure.in        2005/02/20 13:44:15
@@ -183,6 +183,14 @@
 AC_CHECK_SIZEOF(long long)
 
 dnl
+dnl Check for large file support.  This check needs to come fairly
+dnl early because it could (in principle) affect whether functions and
+dnl headers are available, whether they work, etc.
+dnl
+AC_SYS_LARGEFILE
+AC_CHECK_SIZEOF(off_t)
+
+dnl
 dnl Checks for non-universal or system-specific types.
 dnl
 AC_TYPE_SIZE_T
Index: src/ftp-basic.c
===================================================================
RCS file: /pack/anoncvs/wget/src/ftp-basic.c,v
retrieving revision 1.36
diff -u -r1.36 ftp-basic.c
--- src/ftp-basic.c     2003/11/21 01:48:05     1.36
+++ src/ftp-basic.c     2005/02/20 13:44:16
@@ -897,15 +897,13 @@
 
 /* Sends REST command to the FTP server.  */
 uerr_t
-ftp_rest (int csock, long offset)
+ftp_rest (int csock, wgint offset)
 {
   char *request, *respline;
   int nwritten;
   uerr_t err;
-  static char numbuf[24]; /* Buffer for the number */
 
-  number_to_string (numbuf, offset);
-  request = ftp_request ("REST", numbuf);
+  request = ftp_request ("REST", number_to_static_string (offset));
   nwritten = fd_write (csock, request, strlen (request), -1);
   if (nwritten < 0)
     {
@@ -1114,7 +1112,7 @@
 /* Sends the SIZE command to the server, and returns the value in 'size'.
  * If an error occurs, size is set to zero. */
 uerr_t
-ftp_size (int csock, const char *file, long int *size)
+ftp_size (int csock, const char *file, wgint *size)
 {
   char *request, *respline;
   int nwritten;
@@ -1150,7 +1148,7 @@
     }
 
   errno = 0;
-  *size = strtol (respline + 4, NULL, 0);
+  *size = str_to_wgint (respline + 4, NULL, 0);
   if (errno) 
     {
       /* 
Index: src/ftp-ls.c
===================================================================
RCS file: /pack/anoncvs/wget/src/ftp-ls.c,v
retrieving revision 1.28
diff -u -r1.28 ftp-ls.c
--- src/ftp-ls.c        2004/12/09 01:20:39     1.28
+++ src/ftp-ls.c        2005/02/20 13:44:18
@@ -213,7 +213,7 @@
              if (i != 12)
                {
                  char *t = tok - 2;
-                 long mul = 1;
+                 wgint mul = 1;
 
                  for (cur.size = 0; t > line && ISDIGIT (*t); mul *= 10, t--)
                    cur.size += mul * (*t - '0');
@@ -368,14 +368,14 @@
 
       if (!dir)
        {
-         l = dir = (struct fileinfo *)xmalloc (sizeof (struct fileinfo));
+         l = dir = xnew (struct fileinfo);
          memcpy (l, &cur, sizeof (cur));
          l->prev = l->next = NULL;
        }
       else
        {
          cur.prev = l;
-         l->next = (struct fileinfo *)xmalloc (sizeof (struct fileinfo));
+         l->next = xnew (struct fileinfo);
          l = l->next;
          memcpy (l, &cur, sizeof (cur));
          l->next = NULL;
@@ -517,9 +517,9 @@
       else
        {
          cur.type  = FT_PLAINFILE;
-         cur.size  = atoi(tok);
+         cur.size  = str_to_wgint (tok, NULL, 10);
          cur.perms = 0644;
-         DEBUGP(("File, size %ld bytes\n", cur.size));
+         DEBUGP(("File, size %s bytes\n", number_to_static_string (cur.size)));
        }
 
       cur.linkto = NULL;
@@ -527,14 +527,14 @@
       /* And put everything into the linked list */
       if (!dir)
        {
-         l = dir = (struct fileinfo *)xmalloc (sizeof (struct fileinfo));
+         l = dir = xnew (struct fileinfo);
          memcpy (l, &cur, sizeof (cur));
          l->prev = l->next = NULL;
        }
       else
        {
          cur.prev = l;
-         l->next = (struct fileinfo *)xmalloc (sizeof (struct fileinfo));
+         l->next = xnew (struct fileinfo);
          l = l->next;
          memcpy (l, &cur, sizeof (cur));
          l->next = NULL;
Index: src/ftp.c
===================================================================
RCS file: /pack/anoncvs/wget/src/ftp.c,v
retrieving revision 1.88
diff -u -r1.88 ftp.c
--- src/ftp.c   2004/02/25 23:45:24     1.88
+++ src/ftp.c   2005/02/20 13:44:20
@@ -83,12 +83,12 @@
 
 
 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
-   the string S, and return the number converted to long, if found, 0
+   the string S, and return the number converted to wgint, if found, 0
    otherwise.  */
-static long
+static wgint
 ftp_expected_bytes (const char *s)
 {
-  long res;
+  wgint res;
 
   while (1)
     {
@@ -234,7 +234,7 @@
    connection to the server.  It always closes the data connection,
    and closes the control connection in case of error.  */
 static uerr_t
-getftp (struct url *u, long *len, long restval, ccon *con)
+getftp (struct url *u, wgint *len, wgint restval, ccon *con)
 {
   int csock, dtsock, local_sock, res;
   uerr_t err;
@@ -243,10 +243,10 @@
   char *tms, *tmrate;
   int cmd = con->cmd;
   int pasv_mode_open = 0;
-  long expected_bytes = 0L;
+  wgint expected_bytes = 0L;
   int rest_failed = 0;
   int flags;
-  long rd_size;
+  wgint rd_size;
 
   assert (con != NULL);
   assert (con->target != NULL);
@@ -770,7 +770,7 @@
   if (restval && (cmd & DO_RETR))
     {
       if (!opt.server_response)
-       logprintf (LOG_VERBOSE, "==> REST %ld ... ", restval);
+       logprintf (LOG_VERBOSE, "==> REST %s ... ", number_to_static_string 
(restval));
       err = ftp_rest (csock, restval);
 
       /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
@@ -1123,7 +1123,7 @@
 ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
 {
   int count, orig_lp;
-  long restval, len = 0;
+  wgint restval, len = 0;
   char *tms, *locf;
   char *tmrate = NULL;
   uerr_t err;
@@ -1263,16 +1263,16 @@
          con->csock = -1;
        }
       if (!opt.spider)
-        logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
-                  tms, tmrate, locf, len);
+        logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%s]\n\n"),
+                  tms, tmrate, locf, number_to_static_string (len));
       if (!opt.verbose && !opt.quiet)
        {
          /* Need to hide the password from the URL.  The `if' is here
              so that we don't do the needless allocation every
              time. */
          char *hurl = url_string (u, 1);
-         logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
-                    tms, hurl, len, locf, count);
+         logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
+                    tms, hurl, number_to_static_string (len), locf, count);
          xfree (hurl);
        }
 
@@ -1389,7 +1389,7 @@
   static int depth = 0;
   uerr_t err;
   struct fileinfo *orig;
-  long local_size;
+  wgint local_size;
   time_t tml;
   int dlthis;
 
@@ -1482,7 +1482,8 @@
                 {
                   /* Sizes do not match */
                   logprintf (LOG_VERBOSE, _("\
-The sizes do not match (local %ld) -- retrieving.\n\n"), local_size);
+The sizes do not match (local %s) -- retrieving.\n\n"),
+                            number_to_static_string (local_size));
                 }
             }
        }       /* opt.timestamping && f->type == FT_PLAINFILE */
@@ -1843,14 +1844,14 @@
                  if (!opt.output_document)
                    {
                      struct stat st;
-                     long sz;
+                     wgint sz;
                      if (stat (filename, &st) == 0)
                        sz = st.st_size;
                      else
                        sz = -1;
                      logprintf (LOG_NOTQUIET,
-                                _("Wrote HTML-ized index to `%s' [%ld].\n"),
-                                filename, sz);
+                                _("Wrote HTML-ized index to `%s' [%s].\n"),
+                                filename, number_to_static_string (sz));
                    }
                  else
                    logprintf (LOG_NOTQUIET,
Index: src/ftp.h
===================================================================
RCS file: /pack/anoncvs/wget/src/ftp.h,v
retrieving revision 1.23
diff -u -r1.23 ftp.h
--- src/ftp.h   2003/11/30 23:39:04     1.23
+++ src/ftp.h   2005/02/20 13:44:20
@@ -56,11 +56,11 @@
 uerr_t ftp_type PARAMS ((int, int));
 uerr_t ftp_cwd PARAMS ((int, const char *));
 uerr_t ftp_retr PARAMS ((int, const char *));
-uerr_t ftp_rest PARAMS ((int, long));
+uerr_t ftp_rest PARAMS ((int, wgint));
 uerr_t ftp_list PARAMS ((int, const char *));
 uerr_t ftp_syst PARAMS ((int, enum stype *));
 uerr_t ftp_pwd PARAMS ((int, char **));
-uerr_t ftp_size PARAMS ((int, const char *, long int *));
+uerr_t ftp_size PARAMS ((int, const char *, wgint *));
 
 #ifdef USE_OPIE
 const char *skey_response PARAMS ((int, const char *, const char *));
@@ -89,7 +89,7 @@
 {
   enum ftype type;             /* file type */
   char *name;                  /* file name */
-  long size;                   /* file size */
+  wgint size;                  /* file size */
   long tstamp;                 /* time-stamp */
   int perms;                   /* file permissions */
   char *linkto;                        /* link to which file points */
Index: src/html-url.c
===================================================================
RCS file: /pack/anoncvs/wget/src/html-url.c,v
retrieving revision 1.41
diff -u -r1.41 html-url.c
--- src/html-url.c      2003/11/26 16:37:04     1.41
+++ src/html-url.c      2005/02/20 13:44:21
@@ -599,7 +599,7 @@
       logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
       return NULL;
     }
-  DEBUGP (("Loaded %s (size %ld).\n", file, fm->length));
+  DEBUGP (("Loaded %s (size %s).\n", file, number_to_static_string 
(fm->length)));
 
   ctx.text = fm->content;
   ctx.head = ctx.tail = NULL;
@@ -651,7 +651,7 @@
       logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
       return NULL;
     }
-  DEBUGP (("Loaded %s (size %ld).\n", file, fm->length));
+  DEBUGP (("Loaded %s (size %s).\n", file, number_to_static_string 
(fm->length)));
 
   head = tail = NULL;
   text = fm->content;
Index: src/http.c
===================================================================
RCS file: /pack/anoncvs/wget/src/http.c,v
retrieving revision 1.144
diff -u -r1.144 http.c
--- src/http.c  2004/11/19 00:44:38     1.144
+++ src/http.c  2005/02/20 13:44:25
@@ -219,7 +219,8 @@
      request_set_header (req, "Referer", opt.referer, rel_none);
 
      // Value freshly allocated, free it when done.
-     request_set_header (req, "Range", aprintf ("bytes=%ld-", hs->restval),
+     request_set_header (req, "Range",
+                         aprintf ("bytes=%s-", number_to_static_string 
(hs->restval)),
                         rel_value);
    */
 
@@ -359,10 +360,10 @@
    longer, read only that much; if the file is shorter, report an error.  */
 
 static int
-post_file (int sock, const char *file_name, long promised_size)
+post_file (int sock, const char *file_name, wgint promised_size)
 {
   static char chunk[8192];
-  long written = 0;
+  wgint written = 0;
   int write_error;
   FILE *fp;
 
@@ -705,10 +706,10 @@
 /* Parse the `Content-Range' header and extract the information it
    contains.  Returns 1 if successful, -1 otherwise.  */
 static int
-parse_content_range (const char *hdr, long *first_byte_ptr,
-                    long *last_byte_ptr, long *entity_length_ptr)
+parse_content_range (const char *hdr, wgint *first_byte_ptr,
+                    wgint *last_byte_ptr, wgint *entity_length_ptr)
 {
-  long num;
+  wgint num;
 
   /* Ancient versions of Netscape proxy server, presumably predating
      rfc2068, sent out `Content-Range' without the "bytes"
@@ -751,7 +752,7 @@
    which need to be read anyway.  */
 
 static void
-skip_short_body (int fd, long contlen)
+skip_short_body (int fd, wgint contlen)
 {
   /* Skipping the body doesn't make sense if the content length is
      unknown because, in that case, persistent connections cannot be
@@ -759,7 +760,7 @@
      still be used with the magic of the "chunked" transfer!)  */
   if (contlen == -1)
     return;
-  DEBUGP (("Skipping %ld bytes of body data... ", contlen));
+  DEBUGP (("Skipping %s bytes of body data... ", number_to_static_string 
(contlen)));
 
   while (contlen > 0)
     {
@@ -974,15 +975,15 @@
 
 struct http_stat
 {
-  long len;                    /* received length */
-  long contlen;                        /* expected length */
-  long restval;                        /* the restart value */
+  wgint len;                   /* received length */
+  wgint contlen;                       /* expected length */
+  wgint restval;                       /* the restart value */
   int res;                     /* the result of last read */
   char *newloc;                        /* new location (redirection) */
   char *remote_time;           /* remote time-stamp string */
   char *error;                 /* textual HTTP error */
   int statcode;                        /* status code */
-  long rd_size;                        /* amount of data read from socket */
+  wgint rd_size;                       /* amount of data read from socket */
   double dltime;               /* time it took to download the data */
   const char *referer;         /* value of the referer header. */
   char **local_file;           /* local file. */
@@ -1034,7 +1035,7 @@
   char *proxyauth;
   int statcode;
   int write_error;
-  long contlen, contrange;
+  wgint contlen, contrange;
   struct url *conn;
   FILE *fp;
 
@@ -1060,7 +1061,7 @@
   int inhibit_keep_alive = !opt.http_keep_alive || opt.ignore_length;
 
   /* Headers sent when using POST. */
-  long post_data_size = 0;
+  wgint post_data_size = 0;
 
   int host_lookup_failed = 0;
 
@@ -1134,7 +1135,9 @@
     request_set_header (req, "Pragma", "no-cache", rel_none);
   if (hs->restval)
     request_set_header (req, "Range",
-                       aprintf ("bytes=%ld-", hs->restval), rel_value);
+                       aprintf ("bytes=%s-",
+                                number_to_static_string (hs->restval)),
+                       rel_value);
   if (opt.useragent)
     request_set_header (req, "User-Agent", opt.useragent, rel_none);
   else
@@ -1259,7 +1262,8 @@
            }
        }
       request_set_header (req, "Content-Length",
-                         aprintf ("%ld", post_data_size), rel_value);
+                         xstrdup (number_to_static_string (post_data_size)),
+                         rel_value);
     }
 
   /* Add the user headers. */
@@ -1463,7 +1467,20 @@
 
   if (!opt.ignore_length
       && response_header_copy (resp, "Content-Length", hdrval, sizeof 
(hdrval)))
-    contlen = strtol (hdrval, NULL, 10);
+    {
+      wgint parsed;
+      errno = 0;
+      parsed = str_to_wgint (hdrval, NULL, 10);
+      if (parsed == WGINT_MAX && errno == ERANGE)
+       /* Out of range.
+          #### If Content-Length is out of range, it most likely
+          means that the file is larger than 2G and that we're
+          compiled without LFS.  In that case we should probably
+          refuse to even attempt to download the file.  */
+       contlen = -1;
+      else
+       contlen = parsed;
+    }
 
   /* Check for keep-alive related responses. */
   if (!inhibit_keep_alive && contlen != -1)
@@ -1562,7 +1579,7 @@
   }
   if (response_header_copy (resp, "Content-Range", hdrval, sizeof (hdrval)))
     {
-      long first_byte_pos, last_byte_pos, entity_length;
+      wgint first_byte_pos, last_byte_pos, entity_length;
       if (parse_content_range (hdrval, &first_byte_pos, &last_byte_pos,
                               &entity_length))
        contrange = first_byte_pos;
@@ -1768,7 +1785,7 @@
   char *tms, *locf, *tmrate;
   uerr_t err;
   time_t tml = -1, tmr = -1;   /* local and remote time-stamps */
-  long local_size = 0;         /* the size of the local file */
+  wgint local_size = 0;                /* the size of the local file */
   size_t filename_len;
   struct http_stat hstat;      /* HTTP status */
   struct stat st;
@@ -1864,7 +1881,7 @@
             point I profiled Wget, and found that a measurable and
             non-negligible amount of time was lost calling sprintf()
             in url.c.  Replacing sprintf with inline calls to
-            strcpy() and long_to_string() made a difference.
+            strcpy() and number_to_string() made a difference.
             --hniksic */
          memcpy (filename_plus_orig_suffix, *hstat.local_file, filename_len);
          memcpy (filename_plus_orig_suffix + filename_len,
@@ -2097,7 +2114,8 @@
                }
              else if (tml >= tmr)
                logprintf (LOG_VERBOSE, _("\
-The sizes do not match (local %ld) -- retrieving.\n"), local_size);
+The sizes do not match (local %s) -- retrieving.\n"),
+                          number_to_static_string (local_size));
              else
                logputs (LOG_VERBOSE,
                         _("Remote file is newer, retrieving.\n"));
@@ -2141,11 +2159,16 @@
          if (*dt & RETROKF)
            {
              logprintf (LOG_VERBOSE,
-                        _("%s (%s) - `%s' saved [%ld/%ld]\n\n"),
-                        tms, tmrate, locf, hstat.len, hstat.contlen);
+                        _("%s (%s) - `%s' saved [%s/%s]\n\n"),
+                        tms, tmrate, locf,
+                        number_to_static_string (hstat.len),
+                        number_to_static_string (hstat.contlen));
              logprintf (LOG_NONVERBOSE,
-                        "%s URL:%s [%ld/%ld] -> \"%s\" [%d]\n",
-                        tms, u->url, hstat.len, hstat.contlen, locf, count);
+                        "%s URL:%s [%s/%s] -> \"%s\" [%d]\n",
+                        tms, u->url,
+                        number_to_static_string (hstat.len),
+                        number_to_static_string (hstat.contlen),
+                        locf, count);
            }
          ++opt.numurls;
          total_downloaded_bytes += hstat.len;
@@ -2168,11 +2191,13 @@
              if (*dt & RETROKF)
                {
                  logprintf (LOG_VERBOSE,
-                            _("%s (%s) - `%s' saved [%ld]\n\n"),
-                            tms, tmrate, locf, hstat.len);
+                            _("%s (%s) - `%s' saved [%s]\n\n"),
+                            tms, tmrate, locf,
+                            number_to_static_string (hstat.len));
                  logprintf (LOG_NONVERBOSE,
-                            "%s URL:%s [%ld] -> \"%s\" [%d]\n",
-                            tms, u->url, hstat.len, locf, count);
+                            "%s URL:%s [%s] -> \"%s\" [%d]\n",
+                            tms, u->url, number_to_static_string (hstat.len),
+                            locf, count);
                }
              ++opt.numurls;
              total_downloaded_bytes += hstat.len;
@@ -2191,8 +2216,8 @@
                                                 connection too soon */
            {
              logprintf (LOG_VERBOSE,
-                        _("%s (%s) - Connection closed at byte %ld. "),
-                        tms, tmrate, hstat.len);
+                        _("%s (%s) - Connection closed at byte %s. "),
+                        tms, tmrate, number_to_static_string (hstat.len));
              printwhat (count, opt.ntry);
              free_hstat (&hstat);
              continue;
@@ -2200,11 +2225,16 @@
          else if (!opt.kill_longer) /* meaning we got more than expected */
            {
              logprintf (LOG_VERBOSE,
-                        _("%s (%s) - `%s' saved [%ld/%ld])\n\n"),
-                        tms, tmrate, locf, hstat.len, hstat.contlen);
+                        _("%s (%s) - `%s' saved [%s/%s])\n\n"),
+                        tms, tmrate, locf,
+                        number_to_static_string (hstat.len),
+                        number_to_static_string (hstat.contlen));
              logprintf (LOG_NONVERBOSE,
-                        "%s URL:%s [%ld/%ld] -> \"%s\" [%d]\n",
-                        tms, u->url, hstat.len, hstat.contlen, locf, count);
+                        "%s URL:%s [%s/%s] -> \"%s\" [%d]\n",
+                        tms, u->url,
+                        number_to_static_string (hstat.len),
+                        number_to_static_string (hstat.contlen),
+                        locf, count);
              ++opt.numurls;
              total_downloaded_bytes += hstat.len;
 
@@ -2221,8 +2251,10 @@
          else                  /* the same, but not accepted */
            {
              logprintf (LOG_VERBOSE,
-                        _("%s (%s) - Connection closed at byte %ld/%ld. "),
-                        tms, tmrate, hstat.len, hstat.contlen);
+                        _("%s (%s) - Connection closed at byte %s/%s. "),
+                        tms, tmrate,
+                        number_to_static_string (hstat.len),
+                        number_to_static_string (hstat.contlen));
              printwhat (count, opt.ntry);
              free_hstat (&hstat);
              continue;
@@ -2233,8 +2265,9 @@
          if (hstat.contlen == -1)
            {
              logprintf (LOG_VERBOSE,
-                        _("%s (%s) - Read error at byte %ld (%s)."),
-                        tms, tmrate, hstat.len, strerror (errno));
+                        _("%s (%s) - Read error at byte %s (%s)."),
+                        tms, tmrate, number_to_static_string (hstat.len),
+                        strerror (errno));
              printwhat (count, opt.ntry);
              free_hstat (&hstat);
              continue;
@@ -2242,8 +2275,10 @@
          else                  /* hstat.res == -1 and contlen is given */
            {
              logprintf (LOG_VERBOSE,
-                        _("%s (%s) - Read error at byte %ld/%ld (%s). "),
-                        tms, tmrate, hstat.len, hstat.contlen,
+                        _("%s (%s) - Read error at byte %s/%s (%s). "),
+                        tms, tmrate,
+                        number_to_static_string (hstat.len),
+                        number_to_static_string (hstat.contlen),
                         strerror (errno));
              printwhat (count, opt.ntry);
              free_hstat (&hstat);
Index: src/init.c
===================================================================
RCS file: /pack/anoncvs/wget/src/init.c,v
retrieving revision 1.93
diff -u -r1.93 init.c
--- src/init.c  2005/02/19 01:52:01     1.93
+++ src/init.c  2005/02/20 13:44:27
@@ -852,8 +852,8 @@
 
 static int simple_atof PARAMS ((const char *, const char *, double *));
 
-/* Enginge for cmd_bytes and cmd_bytes_large: converts a string such
-   as "100k" or "2.5G" to a floating point number.  */
+/* Engine for cmd_bytes and cmd_bytes_large: converts a string such as
+   "100k" or "2.5G" to a floating point number.  */
 
 static int
 parse_bytes_helper (const char *val, double *result)
@@ -910,7 +910,7 @@
 }
 
 /* Parse VAL as a number and set its value to CLOSURE (which should
-   point to a long int).
+   point to a wgint).
 
    By default, the value is assumed to be in bytes.  If "K", "M", or
    "G" are appended, the value is multiplied with 1<<10, 1<<20, or
@@ -933,7 +933,7 @@
               exec_name, com, val);
       return 0;
     }
-  *(long *)closure = (long)byte_value;
+  *(wgint *)closure = (wgint)byte_value;
   return 1;
 }
 
Index: src/progress.c
===================================================================
RCS file: /pack/anoncvs/wget/src/progress.c,v
retrieving revision 1.43
diff -u -r1.43 progress.c
--- src/progress.c      2004/01/28 01:02:26     1.43
+++ src/progress.c      2005/02/20 13:44:29
@@ -52,21 +52,21 @@
 struct progress_implementation {
   const char *name;
   int interactive;
-  void *(*create) PARAMS ((long, long));
-  void (*update) PARAMS ((void *, long, double));
+  void *(*create) PARAMS ((wgint, wgint));
+  void (*update) PARAMS ((void *, wgint, double));
   void (*finish) PARAMS ((void *, double));
   void (*set_params) PARAMS ((const char *));
 };
 
 /* Necessary forward declarations. */
 
-static void *dot_create PARAMS ((long, long));
-static void dot_update PARAMS ((void *, long, double));
+static void *dot_create PARAMS ((wgint, wgint));
+static void dot_update PARAMS ((void *, wgint, double));
 static void dot_finish PARAMS ((void *, double));
 static void dot_set_params PARAMS ((const char *));
 
-static void *bar_create PARAMS ((long, long));
-static void bar_update PARAMS ((void *, long, double));
+static void *bar_create PARAMS ((wgint, wgint));
+static void bar_update PARAMS ((void *, wgint, double));
 static void bar_finish PARAMS ((void *, double));
 static void bar_set_params PARAMS ((const char *));
 
@@ -156,7 +156,7 @@
    advance.  */
 
 void *
-progress_create (long initial, long total)
+progress_create (wgint initial, wgint total)
 {
   /* Check if the log status has changed under our feet. */
   if (output_redirected)
@@ -184,7 +184,7 @@
    time in milliseconds since the beginning of the download.  */
 
 void
-progress_update (void *progress, long howmuch, double dltime)
+progress_update (void *progress, wgint howmuch, double dltime)
 {
   current_impl->update (progress, howmuch, dltime);
 }
@@ -201,9 +201,9 @@
 /* Dot-printing. */
 
 struct dot_progress {
-  long initial_length;         /* how many bytes have been downloaded
+  wgint initial_length;                /* how many bytes have been downloaded
                                   previously. */
-  long total_length;           /* expected total byte count when the
+  wgint total_length;          /* expected total byte count when the
                                   download finishes */
 
   int accumulated;
@@ -216,7 +216,7 @@
 /* Dot-progress backend for progress_create. */
 
 static void *
-dot_create (long initial, long total)
+dot_create (wgint initial, wgint total)
 {
   struct dot_progress *dp = xnew0 (struct dot_progress);
   dp->initial_length = initial;
@@ -225,10 +225,10 @@
   if (dp->initial_length)
     {
       int dot_bytes = opt.dot_bytes;
-      long row_bytes = opt.dot_bytes * opt.dots_in_line;
+      wgint row_bytes = opt.dot_bytes * opt.dots_in_line;
 
       int remainder = (int) (dp->initial_length % row_bytes);
-      long skipped = dp->initial_length - remainder;
+      wgint skipped = dp->initial_length - remainder;
 
       if (skipped)
        {
@@ -244,7 +244,7 @@
                     2 + skipped_k_len, "", skipped_k);
        }
 
-      logprintf (LOG_VERBOSE, "\n%5ldK", skipped / 1024);
+      logprintf (LOG_VERBOSE, "\n%5ldK", (long) (skipped / 1024));
       for (; remainder >= dot_bytes; remainder -= dot_bytes)
        {
          if (dp->dots % opt.dot_spacing == 0)
@@ -262,14 +262,14 @@
 }
 
 static void
-print_percentage (long bytes, long expected)
+print_percentage (wgint bytes, wgint expected)
 {
   int percentage = (int)(100.0 * bytes / expected);
   logprintf (LOG_VERBOSE, "%3d%%", percentage);
 }
 
 static void
-print_download_speed (struct dot_progress *dp, long bytes, double dltime)
+print_download_speed (struct dot_progress *dp, wgint bytes, double dltime)
 {
   logprintf (LOG_VERBOSE, " %s",
             retr_rate (bytes, dltime - dp->last_timer_value, 1));
@@ -279,11 +279,11 @@
 /* Dot-progress backend for progress_update. */
 
 static void
-dot_update (void *progress, long howmuch, double dltime)
+dot_update (void *progress, wgint howmuch, double dltime)
 {
   struct dot_progress *dp = progress;
   int dot_bytes = opt.dot_bytes;
-  long row_bytes = opt.dot_bytes * opt.dots_in_line;
+  wgint row_bytes = opt.dot_bytes * opt.dots_in_line;
 
   log_set_flush (0);
 
@@ -291,7 +291,7 @@
   for (; dp->accumulated >= dot_bytes; dp->accumulated -= dot_bytes)
     {
       if (dp->dots == 0)
-       logprintf (LOG_VERBOSE, "\n%5ldK", dp->rows * row_bytes / 1024);
+       logprintf (LOG_VERBOSE, "\n%5ldK", (long) (dp->rows * row_bytes / 
1024));
 
       if (dp->dots % opt.dot_spacing == 0)
        logputs (LOG_VERBOSE, " ");
@@ -300,7 +300,7 @@
       ++dp->dots;
       if (dp->dots >= opt.dots_in_line)
        {
-         long row_qty = row_bytes;
+         wgint row_qty = row_bytes;
          if (dp->rows == dp->initial_length / row_bytes)
            row_qty -= dp->initial_length % row_bytes;
 
@@ -323,13 +323,13 @@
 {
   struct dot_progress *dp = progress;
   int dot_bytes = opt.dot_bytes;
-  long row_bytes = opt.dot_bytes * opt.dots_in_line;
+  wgint row_bytes = opt.dot_bytes * opt.dots_in_line;
   int i;
 
   log_set_flush (0);
 
   if (dp->dots == 0)
-    logprintf (LOG_VERBOSE, "\n%5ldK", dp->rows * row_bytes / 1024);
+    logprintf (LOG_VERBOSE, "\n%5ldK", (long) (dp->rows * row_bytes / 1024));
   for (i = dp->dots; i < opt.dots_in_line; i++)
     {
       if (i % opt.dot_spacing == 0)
@@ -345,7 +345,7 @@
     }
 
   {
-    long row_qty = dp->dots * dot_bytes + dp->accumulated;
+    wgint row_qty = dp->dots * dot_bytes + dp->accumulated;
     if (dp->rows == dp->initial_length / row_bytes)
       row_qty -= dp->initial_length % row_bytes;
     print_download_speed (dp, row_qty, dltime);
@@ -443,11 +443,11 @@
 #define STALL_START_TIME 5000
 
 struct bar_progress {
-  long initial_length;         /* how many bytes have been downloaded
+  wgint initial_length;                /* how many bytes have been downloaded
                                   previously. */
-  long total_length;           /* expected total byte count when the
+  wgint total_length;          /* expected total byte count when the
                                   download finishes */
-  long count;                  /* bytes downloaded so far */
+  wgint count;                 /* bytes downloaded so far */
 
   double last_screen_update;   /* time of the last screen update,
                                   measured since the beginning of
@@ -470,18 +470,18 @@
      details.  */
   struct bar_progress_hist {
     int pos;
-    long times[DLSPEED_HISTORY_SIZE];
-    long bytes[DLSPEED_HISTORY_SIZE];
+    wgint times[DLSPEED_HISTORY_SIZE];
+    wgint bytes[DLSPEED_HISTORY_SIZE];
 
     /* The sum of times and bytes respectively, maintained for
        efficiency. */
-    long total_time;
-    long total_bytes;
+    wgint total_time;
+    wgint total_bytes;
   } hist;
 
   double recent_start;         /* timestamp of beginning of current
                                   position. */
-  long recent_bytes;           /* bytes downloaded so far. */
+  wgint recent_bytes;          /* bytes downloaded so far. */
 
   int stalled;                 /* set when no data arrives for longer
                                   than STALL_START_TIME, then reset
@@ -492,14 +492,14 @@
   double last_eta_time;                /* time of the last update to download
                                   speed and ETA, measured since the
                                   beginning of download. */
-  long last_eta_value;
+  wgint last_eta_value;
 };
 
 static void create_image PARAMS ((struct bar_progress *, double));
 static void display_image PARAMS ((char *));
 
 static void *
-bar_create (long initial, long total)
+bar_create (wgint initial, wgint total)
 {
   struct bar_progress *bp = xnew0 (struct bar_progress);
 
@@ -536,10 +536,10 @@
   return bp;
 }
 
-static void update_speed_ring PARAMS ((struct bar_progress *, long, double));
+static void update_speed_ring PARAMS ((struct bar_progress *, wgint, double));
 
 static void
-bar_update (void *progress, long howmuch, double dltime)
+bar_update (void *progress, wgint howmuch, double dltime)
 {
   struct bar_progress *bp = progress;
   int force_screen_update = 0;
@@ -622,7 +622,7 @@
    3-second average would be too erratic.  */
 
 static void
-update_speed_ring (struct bar_progress *bp, long howmuch, double dltime)
+update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
 {
   struct bar_progress_hist *hist = &bp->hist;
   double recent_age = dltime - bp->recent_start;
@@ -719,7 +719,7 @@
 create_image (struct bar_progress *bp, double dl_total_time)
 {
   char *p = bp->buffer;
-  long size = bp->initial_length + bp->count;
+  wgint size = bp->initial_length + bp->count;
 
   char *size_legible = legible (size);
   int size_legible_len = strlen (size_legible);
@@ -838,7 +838,7 @@
       int units = 0;
       /* Calculate the download speed using the history ring and
         recent data that hasn't made it to the ring yet.  */
-      long 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 dlspeed = calc_rate (dlquant, dltime, &units);
       sprintf (p, " %7.2f%s", dlspeed, short_units[units]);
@@ -852,7 +852,7 @@
      reliable.  */
   if (bp->total_length > 0 && bp->count > 0 && dl_total_time > 3000)
     {
-      long eta;
+      wgint eta;
       int eta_hrs, eta_min, eta_sec;
 
       /* Don't change the value of ETA more than approximately once
@@ -871,8 +871,8 @@
             I found that doing that results in a very jerky and
             ultimately unreliable ETA.  */
          double time_sofar = (double)dl_total_time / 1000;
-         long bytes_remaining = bp->total_length - size;
-         eta = (long) (time_sofar * bytes_remaining / bp->count);
+         wgint bytes_remaining = bp->total_length - size;
+         eta = (wgint) (time_sofar * bytes_remaining / bp->count);
          bp->last_eta_value = eta;
          bp->last_eta_time = dl_total_time;
        }
Index: src/progress.h
===================================================================
RCS file: /pack/anoncvs/wget/src/progress.h,v
retrieving revision 1.7
diff -u -r1.7 progress.h
--- src/progress.h      2003/11/08 16:56:52     1.7
+++ src/progress.h      2005/02/20 13:44:29
@@ -34,9 +34,9 @@
 void set_progress_implementation PARAMS ((const char *));
 void progress_schedule_redirect PARAMS ((void));
 
-void *progress_create PARAMS ((long, long));
+void *progress_create PARAMS ((wgint, wgint));
 int progress_interactive_p PARAMS ((void *));
-void progress_update PARAMS ((void *, long, double));
+void progress_update PARAMS ((void *, wgint, double));
 void progress_finish PARAMS ((void *, double));
 
 RETSIGTYPE progress_handle_sigwinch PARAMS ((int));
Index: src/retr.c
===================================================================
RCS file: /pack/anoncvs/wget/src/retr.c,v
retrieving revision 1.86
diff -u -r1.86 retr.c
--- src/retr.c  2004/11/18 21:05:30     1.86
+++ src/retr.c  2005/02/20 13:44:30
@@ -75,7 +75,7 @@
 int output_stream_regular;
 
 static struct {
-  long chunk_bytes;
+  wgint chunk_bytes;
   double chunk_start;
   double sleep_adjust;
 } limit_data;
@@ -92,7 +92,7 @@
    is the timer that started at the beginning of download.  */
 
 static void
-limit_bandwidth (long bytes, struct wget_timer *timer)
+limit_bandwidth (wgint bytes, struct wget_timer *timer)
 {
   double delta_t = wtimer_read (timer) - limit_data.chunk_start;
   double expected;
@@ -110,12 +110,14 @@
       double t0, t1;
       if (slp < 200)
        {
-         DEBUGP (("deferring a %.2f ms sleep (%ld/%.2f).\n",
-                  slp, limit_data.chunk_bytes, delta_t));
+         DEBUGP (("deferring a %.2f ms sleep (%s/%.2f).\n",
+                  slp, number_to_static_string (limit_data.chunk_bytes),
+                  delta_t));
          return;
        }
-      DEBUGP (("\nsleeping %.2f ms for %ld bytes, adjust %.2f ms\n",
-              slp, limit_data.chunk_bytes, limit_data.sleep_adjust));
+      DEBUGP (("\nsleeping %.2f ms for %s bytes, adjust %.2f ms\n",
+              slp, number_to_static_string (limit_data.chunk_bytes),
+              limit_data.sleep_adjust));
 
       t0 = wtimer_read (timer);
       xsleep (slp / 1000);
@@ -142,8 +144,8 @@
    of data written.  */
 
 static int
-write_data (FILE *out, const char *buf, int bufsize, long *skip,
-           long *written)
+write_data (FILE *out, const char *buf, int bufsize, wgint *skip,
+           wgint *written)
 {
   if (!out)
     return 1;
@@ -192,8 +194,8 @@
    writing data, -2 is returned.  */
 
 int
-fd_read_body (int fd, FILE *out, long toread, long startpos,
-             long *qtyread, long *qtywritten, double *elapsed, int flags)
+fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
+             wgint *qtyread, wgint *qtywritten, double *elapsed, int flags)
 {
   int ret = 0;
 
@@ -213,11 +215,11 @@
   int progress_interactive = 0;
 
   int exact = flags & rb_read_exactly;
-  long skip = 0;
+  wgint skip = 0;
 
   /* How much data we've read/written.  */
-  long sum_read = 0;
-  long sum_written = 0;
+  wgint sum_read = 0;
+  wgint sum_written = 0;
 
   if (flags & rb_skip_startpos)
     skip = startpos;
@@ -489,7 +491,7 @@
    appropriate for the speed.  If PAD is non-zero, strings will be
    padded to the width of 7 characters (xxxx.xx).  */
 char *
-retr_rate (long bytes, double msecs, int pad)
+retr_rate (wgint bytes, double msecs, int pad)
 {
   static char res[20];
   static const char *rate_names[] = {"B/s", "KB/s", "MB/s", "GB/s" };
@@ -509,7 +511,7 @@
    UNITS is zero for B/s, one for KB/s, two for MB/s, and three for
    GB/s.  */
 double
-calc_rate (long bytes, double msecs, int *units)
+calc_rate (wgint bytes, double msecs, int *units)
 {
   double dlrate;
 
Index: src/retr.h
===================================================================
RCS file: /pack/anoncvs/wget/src/retr.h,v
retrieving revision 1.19
diff -u -r1.19 retr.h
--- src/retr.h  2003/12/06 02:32:57     1.19
+++ src/retr.h  2005/02/20 13:44:30
@@ -36,7 +36,7 @@
   rb_skip_startpos = 2
 };
 
-int fd_read_body PARAMS ((int, FILE *, long, long, long *, long *, double *,
+int fd_read_body PARAMS ((int, FILE *, wgint, wgint, wgint *, wgint *, double 
*,
                           int));
 
 typedef const char *(*hunk_terminator_t) PARAMS ((const char *, int, int));
@@ -48,8 +48,8 @@
                             const char *, int *));
 uerr_t retrieve_from_file PARAMS ((const char *, int, int *));
 
-char *retr_rate PARAMS ((long, double, int));
-double calc_rate PARAMS ((long, double, int *));
+char *retr_rate PARAMS ((wgint, double, int));
+double calc_rate PARAMS ((wgint, double, int *));
 void printwhat PARAMS ((int, int));
 
 void sleep_between_retrievals PARAMS ((int));
Index: src/sysdep.h
===================================================================
RCS file: /pack/anoncvs/wget/src/sysdep.h,v
retrieving revision 1.34
diff -u -r1.34 sysdep.h
--- src/sysdep.h        2003/11/06 01:12:03     1.34
+++ src/sysdep.h        2005/02/20 13:44:31
@@ -111,7 +111,7 @@
 /* Define a large integral type useful for storing large sizes that
    exceed sizes of one download, such as when printing the sum of all
    downloads.  Note that this has nothing to do with large file
-   support, yet.
+   support, which determines the wgint type.
 
    We use a 64-bit integral type where available, `double' otherwise.
    It's hard to print LARGE_INT's portably, but fortunately it's
@@ -131,6 +131,17 @@
 typedef double LARGE_INT;
 #  define LARGE_INT_FMT "%.0f"
 # endif
+#endif
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#ifndef LONG_MAX
+# define LONG_MAX ((long) ~((unsigned long)1 << (CHAR_BIT * sizeof (long) - 
1)))
+#endif
+#ifndef LLONG_MAX
+# define LLONG_MAX ((long long) ~((unsigned long long)1 << (CHAR_BIT * sizeof 
(long long) - 1)))
 #endif
 
 /* These are defined in cmpt.c if missing, therefore it's generally
Index: src/utils.c
===================================================================
RCS file: /pack/anoncvs/wget/src/utils.c,v
retrieving revision 1.77
diff -u -r1.77 utils.c
--- src/utils.c 2004/01/29 12:38:52     1.77
+++ src/utils.c 2005/02/20 13:44:34
@@ -383,10 +383,10 @@
 
 /* Return the size of file named by FILENAME, or -1 if it cannot be
    opened or seeked into. */
-long
+wgint
 file_size (const char *filename)
 {
-  long size;
+  wgint size;
   /* We use fseek rather than stat to determine the file size because
      that way we can also verify whether the file is readable.
      Inspired by the POST patch by Arnaud Wylie.  */
@@ -799,7 +799,7 @@
 {
   int fd;
   struct file_memory *fm;
-  long size;
+  wgint size;
   int inhibit_close = 0;
 
   /* Some magic in the finest tradition of Perl and its kin: if FILE
@@ -851,7 +851,7 @@
   fm->content = xmalloc (size);
   while (1)
     {
-      long nread;
+      wgint nread;
       if (fm->length > size / 2)
        {
          /* #### I'm not sure whether the whole exponential-growth
@@ -1148,10 +1148,10 @@
   return outbuf;
 }
 
-/* Legible -- return a static pointer to the legibly printed long.  */
+/* Legible -- return a static pointer to the legibly printed wgint.  */
 
 char *
-legible (long l)
+legible (wgint l)
 {
   char inbuf[24];
   /* Print the number into the buffer.  */
@@ -1185,9 +1185,9 @@
   return legible_1 (inbuf);
 }
 
-/* Count the digits in a (long) integer.  */
+/* Count the digits in an integer number.  */
 int
-numdigit (long number)
+numdigit (wgint number)
 {
   int cnt = 1;
   if (number < 0)
@@ -1200,15 +1200,6 @@
   return cnt;
 }
 
-/* Attempt to calculate INT_MAX on machines that don't bother to
-   define it. */
-#ifndef INT_MAX
-# ifndef CHAR_BIT
-#  define CHAR_BIT 8
-# endif
-# define INT_MAX ((int) ~((unsigned)1 << CHAR_BIT * sizeof (int) - 1))
-#endif
-
 #define ONE_DIGIT(figure) *p++ = n / (figure) + '0'
 #define ONE_DIGIT_ADVANCE(figure) (ONE_DIGIT (figure), n %= (figure))
 
@@ -1223,7 +1214,7 @@
 #define DIGITS_9(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_8 ((figure) / 10)
 #define DIGITS_10(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_9 ((figure) / 10)
 
-/* DIGITS_<11-20> are only used on machines with 64-bit longs. */
+/* DIGITS_<11-20> are only used on machines with 64-bit numbers. */
 
 #define DIGITS_11(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_10 ((figure) / 10)
 #define DIGITS_12(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_11 ((figure) / 10)
@@ -1234,14 +1225,23 @@
 #define DIGITS_17(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_16 ((figure) / 10)
 #define DIGITS_18(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_17 ((figure) / 10)
 #define DIGITS_19(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_18 ((figure) / 10)
+
+#if SIZEOF_LONG_LONG != 0
+# define N2S_COERCE_FMT "%lld"
+# define N2S_COERCE_TYPE long long
+#else
+# define N2S_COERCE_FMT "%ld"
+# define N2S_COERCE_TYPE long
+#endif
 
-/* Print NUMBER to BUFFER in base 10.  This should be completely
-   equivalent to `sprintf(buffer, "%ld", number)', only much faster.
+/* Print NUMBER to BUFFER in base 10.  This is equivalent to
+   `sprintf(buffer, "%lld", (long long) number)', only much faster and
+   portable to machines without long long.
 
    The speedup may make a difference in programs that frequently
    convert numbers to strings.  Some implementations of sprintf,
    particularly the one in GNU libc, have been known to be extremely
-   slow compared to this function.
+   slow when converting integers to strings.
 
    Return the pointer to the location where the terminating zero was
    printed.  (Equivalent to calling buffer+strlen(buffer) after the
@@ -1254,25 +1254,25 @@
    terminating '\0'.  */
 
 char *
-number_to_string (char *buffer, long number)
+number_to_string (char *buffer, wgint number)
 {
   char *p = buffer;
-  long n = number;
+  wgint n = number;
 
-#if (SIZEOF_LONG != 4) && (SIZEOF_LONG != 8)
+#if (SIZEOF_WGINT != 4) && (SIZEOF_WGINT != 8)
   /* We are running in a strange or misconfigured environment.  Let
      sprintf cope with it.  */
-  sprintf (buffer, "%ld", n);
+  sprintf (buffer, N2S_COERCE_FMT, (N2S_COERCE_TYPE) n);
   p += strlen (buffer);
-#else  /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */
+#else  /* (SIZEOF_WGINT == 4) || (SIZEOF_WGINT == 8) */
 
   if (n < 0)
     {
-      if (n < -INT_MAX)
+      if (n < -WGINT_MAX)
        {
          /* We cannot print a '-' and assign -n to n because -n would
             overflow.  Let sprintf deal with this border case.  */
-         sprintf (buffer, "%ld", n);
+         sprintf (buffer, N2S_COERCE_FMT, (N2S_COERCE_TYPE) n);
          p += strlen (buffer);
          return p;
        }
@@ -1281,33 +1281,50 @@
       n = -n;
     }
 
-  if      (n < 10)                   { DIGITS_1 (1); }
-  else if (n < 100)                  { DIGITS_2 (10); }
-  else if (n < 1000)                 { DIGITS_3 (100); }
-  else if (n < 10000)                { DIGITS_4 (1000); }
-  else if (n < 100000)               { DIGITS_5 (10000); }
-  else if (n < 1000000)              { DIGITS_6 (100000); }
-  else if (n < 10000000)             { DIGITS_7 (1000000); }
-  else if (n < 100000000)            { DIGITS_8 (10000000); }
-  else if (n < 1000000000)           { DIGITS_9 (100000000); }
-#if SIZEOF_LONG == 4
+  if      (n < 10)                    { DIGITS_1 (1); }
+  else if (n < 100)                   { DIGITS_2 (10); }
+  else if (n < 1000)                  { DIGITS_3 (100); }
+  else if (n < 10000)                 { DIGITS_4 (1000); }
+  else if (n < 100000)                { DIGITS_5 (10000); }
+  else if (n < 1000000)               { DIGITS_6 (100000); }
+  else if (n < 10000000)              { DIGITS_7 (1000000); }
+  else if (n < 100000000)             { DIGITS_8 (10000000); }
+  else if (n < 1000000000)            { DIGITS_9 (100000000); }
+#if SIZEOF_WGINT == 4
+  /* wgint is four bytes long: we're done. */
   /* ``if (1)'' serves only to preserve editor indentation. */
-  else if (1)                        { DIGITS_10 (1000000000); }
-#else  /* SIZEOF_LONG != 4 */
-  else if (n < 10000000000L)         { DIGITS_10 (1000000000L); }
-  else if (n < 100000000000L)        { DIGITS_11 (10000000000L); }
-  else if (n < 1000000000000L)       { DIGITS_12 (100000000000L); }
-  else if (n < 10000000000000L)      { DIGITS_13 (1000000000000L); }
-  else if (n < 100000000000000L)     { DIGITS_14 (10000000000000L); }
-  else if (n < 1000000000000000L)    { DIGITS_15 (100000000000000L); }
-  else if (n < 10000000000000000L)   { DIGITS_16 (1000000000000000L); }
-  else if (n < 100000000000000000L)  { DIGITS_17 (10000000000000000L); }
-  else if (n < 1000000000000000000L) { DIGITS_18 (100000000000000000L); }
-  else                               { DIGITS_19 (1000000000000000000L); }
-#endif /* SIZEOF_LONG != 4 */
+  else if (1)                         { DIGITS_10 (1000000000); }
+#elif SIZEOF_WGINT == SIZEOF_LONG
+  /* wgint is larger than 4 bytes, and is the same size as long.
+     Process the digits using long (nnnL) constants.  */
+  else if (n < 10000000000L)          { DIGITS_10 (1000000000L); }
+  else if (n < 100000000000L)         { DIGITS_11 (10000000000L); }
+  else if (n < 1000000000000L)        { DIGITS_12 (100000000000L); }
+  else if (n < 10000000000000L)       { DIGITS_13 (1000000000000L); }
+  else if (n < 100000000000000L)      { DIGITS_14 (10000000000000L); }
+  else if (n < 1000000000000000L)     { DIGITS_15 (100000000000000L); }
+  else if (n < 10000000000000000L)    { DIGITS_16 (1000000000000000L); }
+  else if (n < 100000000000000000L)   { DIGITS_17 (10000000000000000L); }
+  else if (n < 1000000000000000000L)  { DIGITS_18 (100000000000000000L); }
+  /* ``if (1)'' serves only to preserve editor indentation. */
+  else if (1)                         { DIGITS_19 (1000000000000000000L); }
+#elif SIZEOF_WGINT == SIZEOF_LONG_LONG
+  /* wgint is larger than 4 bytes, and is the same size as long long.
+     Process the digits using long long (nnnLL) constants.  */
+  else if (n < 10000000000LL)         { DIGITS_10 (1000000000LL); }
+  else if (n < 100000000000LL)        { DIGITS_11 (10000000000LL); }
+  else if (n < 1000000000000LL)       { DIGITS_12 (100000000000LL); }
+  else if (n < 10000000000000LL)      { DIGITS_13 (1000000000000LL); }
+  else if (n < 100000000000000LL)     { DIGITS_14 (10000000000000LL); }
+  else if (n < 1000000000000000LL)    { DIGITS_15 (100000000000000LL); }
+  else if (n < 10000000000000000LL)   { DIGITS_16 (1000000000000000LL); }
+  else if (n < 100000000000000000LL)  { DIGITS_17 (10000000000000000LL); }
+  else if (n < 1000000000000000000LL) { DIGITS_18 (100000000000000000LL); }
+  else                                { DIGITS_19 (1000000000000000000LL); }
+#endif
 
   *p = '\0';
-#endif /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */
+#endif /* (SIZEOF_WGINT == 4) || (SIZEOF_WGINT == 8) */
 
   return p;
 }
@@ -1334,6 +1351,49 @@
 #undef DIGITS_17
 #undef DIGITS_18
 #undef DIGITS_19
+
+#define RING_SIZE 3
+
+/* Print NUMBER to a statically allocated string and return a pointer
+   to the printed representation.
+
+   This function is intended to be used in conjunction with printf.
+   It is hard to portably print wgint values:
+    a) you cannot use printf("%ld", number) because wgint can be long
+       long on 32-bit machines with LFS.
+    b) you cannot use printf("%lld", number) because NUMBER could be
+       long on 32-bit machines without LFS, or on 64-bit machines,
+       which do not require LFS.
+    c) you cannot use printf("%j", (int_max_t) number) because not all
+       versions of printf support "%j", the most notable being the one
+       on Windows.
+    d) you cannot #define WGINT_FMT to the appropriate format and use
+       printf(WGINT_FMT, number) because that would break translations
+       for user-visible messages, such as printf("Downloaded: %d
+       bytes\n", number).
+
+   What does work is printf("%s", number_to_static_string (number)).
+
+   CAVEAT: since the function returns pointers to static data, you
+   must be careful to copy its result before calling it again.
+   However, to make it more useful with printf, the function maintains
+   an internal ring of static buffers to return.  That way things like
+   printf("%s %s", number_to_static_string (num1),
+   number_to_static_string (num2)) work as expected.  Three buffers
+   are currently used, which means that "%s %s %s" will work, but "%s
+   %s %s %s" won't.  If you need to print more than three wgints,
+   bump the RING_SIZE (or rethink your message.)  */
+
+char *
+number_to_static_string (wgint number)
+{
+  static char ring[RING_SIZE][24];
+  static int ringpos;
+  char *buf = ring[ringpos];
+  number_to_string (buf, number);
+  ringpos = (ringpos + 1) % RING_SIZE;
+  return buf;
+}
 
 /* Support for timers. */
 
Index: src/utils.h
===================================================================
RCS file: /pack/anoncvs/wget/src/utils.h,v
retrieving revision 1.32
diff -u -r1.32 utils.h
--- src/utils.h 2003/11/29 18:40:01     1.32
+++ src/utils.h 2005/02/20 13:44:34
@@ -45,7 +45,7 @@
 
 struct file_memory {
   char *content;
-  long length;
+  wgint length;
   int mmap_p;
 };
 
@@ -79,7 +79,7 @@
 int remove_link PARAMS ((const char *));
 int file_exists_p PARAMS ((const char *));
 int file_non_directory_p PARAMS ((const char *));
-long file_size PARAMS ((const char *));
+wgint file_size PARAMS ((const char *));
 int make_directory PARAMS ((const char *));
 char *unique_name PARAMS ((const char *, int));
 char *file_merge PARAMS ((const char *, const char *));
@@ -109,10 +109,11 @@
 void string_set_free PARAMS ((struct hash_table *));
 void free_keys_and_values PARAMS ((struct hash_table *));
 
-char *legible PARAMS ((long));
+char *legible PARAMS ((wgint));
 char *legible_large_int PARAMS ((LARGE_INT));
-int numdigit PARAMS ((long));
-char *number_to_string PARAMS ((char *, long));
+int numdigit PARAMS ((wgint));
+char *number_to_string PARAMS ((char *, wgint));
+char *number_to_static_string PARAMS ((wgint));
 
 struct wget_timer *wtimer_allocate PARAMS ((void));
 struct wget_timer *wtimer_new PARAMS ((void));
Index: src/wget.h
===================================================================
RCS file: /pack/anoncvs/wget/src/wget.h,v
retrieving revision 1.52
diff -u -r1.52 wget.h
--- src/wget.h  2003/11/29 18:40:01     1.52
+++ src/wget.h  2005/02/20 13:44:35
@@ -107,6 +107,25 @@
 # define GCC_FORMAT_ATTR(a, b)
 #endif /* not __GNUC__ */
 
+/* Define an integer type that works for LFS.  off_t would be perfect
+   for this, but off_t is always 32-bit under Windows.  */
+#ifndef WINDOWS
+typedef off_t wgint;
+# define SIZEOF_WGINT SIZEOF_OFF_T
+#else
+typedef long long wgint;
+# define SIZEOF_WGINT 8
+#endif
+
+/* Define a strtol/strtoll clone for wgint. */
+#if SIZEOF_WGINT == SIZEOF_LONG
+# define str_to_wgint strtol
+# define WGINT_MAX LONG_MAX
+#else
+# define str_to_wgint strtoll
+# define WGINT_MAX LLONG_MAX
+#endif
+
 /* Everything uses this, so include them here directly.  */
 #include "xmalloc.h"
 

Reply via email to