]> sjero.net Git - wget/blobdiff - src/utils.c
[svn] Added support for cookies.
[wget] / src / utils.c
index ecf944c3b57c147a8ad8dae58aaa5e6284e04e64..fa9e1028f9a565409d7b905d222f40cde347ef3a 100644 (file)
@@ -26,7 +26,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #else  /* not HAVE_STRING_H */
 # include <strings.h>
 #endif /* not HAVE_STRING_H */
-#include <ctype.h>
 #include <sys/types.h>
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
@@ -102,9 +101,9 @@ memfatal (const char *what)
    If memory debugging is not turned on, wget.h defines these:
 
      #define xmalloc xmalloc_real
-     #define xfree xfree_real
      #define xrealloc xrealloc_real
      #define xstrdup xstrdup_real
+     #define xfree free
 
    In case of memory debugging, the definitions are a bit more
    complex, because we want to provide more information, *and* we want
@@ -119,7 +118,13 @@ memfatal (const char *what)
 
    Each of the *_debug function does its magic and calls the real one.  */
 
-void *
+#ifdef DEBUG_MALLOC
+# define STATIC_IF_DEBUG static
+#else
+# define STATIC_IF_DEBUG
+#endif
+
+STATIC_IF_DEBUG void *
 xmalloc_real (size_t size)
 {
   void *ptr = malloc (size);
@@ -128,13 +133,7 @@ xmalloc_real (size_t size)
   return ptr;
 }
 
-void
-xfree_real (void *ptr)
-{
-  free (ptr);
-}
-
-void *
+STATIC_IF_DEBUG void *
 xrealloc_real (void *ptr, size_t newsize)
 {
   void *newptr;
@@ -151,7 +150,7 @@ xrealloc_real (void *ptr, size_t newsize)
   return newptr;
 }
 
-char *
+STATIC_IF_DEBUG char *
 xstrdup_real (const char *s)
 {
   char *copy;
@@ -273,7 +272,7 @@ xfree_debug (void *ptr, const char *source_file, int source_line)
   assert (ptr != NULL);
   ++free_count;
   unregister_ptr (ptr);
-  xfree_real (ptr);
+  free (ptr);
 }
 
 void *
@@ -285,7 +284,7 @@ xrealloc_debug (void *ptr, size_t newsize, const char *source_file, int source_l
       ++malloc_count;
       register_ptr (newptr, source_file, source_line);
     }
-  else
+  else if (newptr != ptr)
     {
       unregister_ptr (ptr);
       register_ptr (newptr, source_file, source_line);
@@ -353,25 +352,56 @@ sepstring (const char *s)
 }
 \f
 /* Return pointer to a static char[] buffer in which zero-terminated
-   string-representation of TM (in form hh:mm:ss) is printed.  It is
-   shamelessly non-reentrant, but it doesn't matter, really.
+   string-representation of TM (in form hh:mm:ss) is printed.
+
+   If TM is non-NULL, the current time-in-seconds will be stored
+   there.
+
+   (#### This is misleading: one would expect TM would be used instead
+   of the current time in that case.  This design was probably
+   influenced by the design time(2), and should be changed at some
+   points.  No callers use non-NULL TM anyway.)  */
 
-   If TM is non-NULL, the time_t of the current time will be stored
-   there.  */
 char *
 time_str (time_t *tm)
 {
-  static char tms[15];
+  static char output[15];
   struct tm *ptm;
-  time_t tim;
-
-  *tms = '\0';
-  tim = time (tm);
-  if (tim == -1)
-    return tms;
-  ptm = localtime (&tim);
-  sprintf (tms, "%02d:%02d:%02d", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
-  return tms;
+  time_t secs = time (tm);
+
+  if (secs == -1)
+    {
+      /* In case of error, return the empty string.  Maybe we should
+        just abort if this happens?  */
+      *output = '\0';
+      return output;
+    }
+  ptm = localtime (&secs);
+  sprintf (output, "%02d:%02d:%02d", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
+  return output;
+}
+
+/* Like the above, but include the date: YYYY-MM-DD hh:mm:ss.  */
+
+char *
+datetime_str (time_t *tm)
+{
+  static char output[20];      /* "YYYY-MM-DD hh:mm:ss" + \0 */
+  struct tm *ptm;
+  time_t secs = time (tm);
+
+  if (secs == -1)
+    {
+      /* In case of error, return the empty string.  Maybe we should
+        just abort if this happens?  */
+      *output = '\0';
+      return output;
+    }
+  ptm = localtime (&secs);
+  sprintf (output, "%04d-%02d-%02d %02d:%02d:%02d",
+          ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday,
+          ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
+  return output;
 }
 
 /* Returns an error message for ERRNUM.  #### This requires more work.
@@ -970,7 +1000,7 @@ read_file (const char *file)
        efficiency, but at some cost to generality.  */
     fm->content = mmap (NULL, fm->length, PROT_READ | PROT_WRITE,
                        MAP_PRIVATE, fd, 0);
-    if (fm->content == MAP_FAILED)
+    if (fm->content == (char *)MAP_FAILED)
       goto mmap_lose;
     if (!inhibit_close)
       close (fd);
@@ -1297,13 +1327,53 @@ legible (long l)
   return legible_1 (inbuf);
 }
 
+/* Write a string representation of NUMBER into the provided buffer.
+   We cannot use sprintf() because we cannot be sure whether the
+   platform supports printing of what we chose for VERY_LONG_TYPE.
+
+   Example: Gcc supports `long long' under many platforms, but on many
+   of those the native libc knows nothing of it and therefore cannot
+   print it.
+
+   How long BUFFER needs to be depends on the platform and the content
+   of NUMBER.  For 64-bit VERY_LONG_TYPE (the most common case), 24
+   bytes are sufficient.  Using more might be a good idea.
+
+   This function does not go through the hoops that long_to_string
+   goes to because it doesn't need to be fast.  (It's called perhaps
+   once in a Wget run.)  */
+
+static void
+very_long_to_string (char *buffer, VERY_LONG_TYPE number)
+{
+  int i = 0;
+  int j;
+
+  /* Print the number backwards... */
+  do
+    {
+      buffer[i++] = '0' + number % 10;
+      number /= 10;
+    }
+  while (number);
+
+  /* ...and reverse the order of the digits. */
+  for (j = 0; j < i / 2; j++)
+    {
+      char c = buffer[j];
+      buffer[j] = buffer[i - 1 - j];
+      buffer[i - 1 - j] = c;
+    }
+  buffer[i] = '\0';
+}
+
 /* The same as legible(), but works on VERY_LONG_TYPE.  See sysdep.h.  */
 char *
 legible_very_long (VERY_LONG_TYPE l)
 {
   char inbuf[128];
   /* Print the number into the buffer.  */
-  sprintf (inbuf, VERY_LONG_FORMAT, l);
+  very_long_to_string (inbuf, l);
   return legible_1 (inbuf);
 }