]> sjero.net Git - wget/commitdiff
[svn] Moved malloc-related code to xmalloc.c. Defined new macros xnew, xnew0,
authorhniksic <devnull@localhost>
Fri, 31 Oct 2003 14:31:56 +0000 (06:31 -0800)
committerhniksic <devnull@localhost>
Fri, 31 Oct 2003 14:31:56 +0000 (06:31 -0800)
xnew_array, and xnew0_array.  Created xmalloc.h and log.h to unclutter
wget.h.

17 files changed:
src/ChangeLog
src/Makefile.in
src/gen-md5.h
src/http.c
src/log.c
src/log.h [new file with mode: 0644]
src/rbuf.c
src/utils.c
src/utils.h
src/wget.h
src/xmalloc.c [new file with mode: 0644]
src/xmalloc.h [new file with mode: 0644]
windows/Makefile.src
windows/Makefile.src.bor
windows/Makefile.src.mingw
windows/README
windows/wget.dep

index cf06c54484a616de98c208ddfb95297ea75b162a..6b4b222d3739b419a61ea56773aadc0d64c83df2 100644 (file)
@@ -1,3 +1,14 @@
+2003-10-31  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * wget.h: Move declarations of malloc and logging code to
+       xmalloc.h and log.h respectively to unclutter this file.
+       (STRDUP_ALLOCA): Made it side-effect free.
+
+       * xmalloc.h: New files.  Define macros xnew, xnew0, xnew_array,
+       and xnew0_array.
+
+       * xmalloc.c: New file.  Move the xmalloc routines here.
+
 2003-10-31  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * connect.c (sockaddr_set_data): Remove the broken code that
index 01e1f93aa261ac23ad0ad62520674dc015ca5214..705f13103e2b56c9aab9612ece90ebd05218553f 100644 (file)
@@ -77,7 +77,7 @@ OBJ = $(ALLOCA) cmpt$o connect$o convert$o cookies$o              \
       headers$o host$o html-parse$o html-url$o http$o init$o      \
       log$o main$o $(MD5_OBJ) netrc$o progress$o rbuf$o recur$o   \
       res$o retr$o safe-ctype$o snprintf$o $(SSL_OBJ) url$o       \
-      utils$o version$o
+      utils$o version$o xmalloc$o
 
 .SUFFIXES:
 .SUFFIXES: .c .o ._c ._o
@@ -200,3 +200,4 @@ safe-ctype$o: safe-ctype.h
 url$o: wget.h sysdep.h options.h safe-ctype.h utils.h url.h host.h hash.h
 utils$o: wget.h sysdep.h options.h safe-ctype.h utils.h hash.h
 version$o:
+xmalloc$o: wget.h xmalloc.h
index f5d13c3bf3e6f22143244c377decc6ae6b0308a9..14952644a831ba1a1695e21449c8e0719d6131cf 100644 (file)
@@ -36,6 +36,8 @@ typedef struct gen_md5_context gen_md5_context;
    includes.  */
 struct gen_md5_context;
 
+#define MD5_HASHLEN 16
+
 #define ALLOCA_MD5_CONTEXT(var_name)                   \
   gen_md5_context *var_name =                          \
   (gen_md5_context *) alloca (gen_md5_context_size ())
index 88bb450d9d9450c143306c2e129a1f6f26e19d5d..9f523bd1e12567febf9e79f86ef89f886f478b1a 100644 (file)
@@ -1336,9 +1336,9 @@ Accept: %s\r\n\
     {
       char*  last_period_in_local_filename = strrchr(*hs->local_file, '.');
 
-      if (last_period_in_local_filename == NULL ||
-         !(strcasecmp(last_period_in_local_filename, ".htm") == EQ ||
-           strcasecmp(last_period_in_local_filename, ".html") == EQ))
+      if (last_period_in_local_filename == NULL
+         || !(0 == strcasecmp (last_period_in_local_filename, ".htm")
+              || 0 == strcasecmp (last_period_in_local_filename, ".html")))
        {
          size_t  local_filename_len = strlen(*hs->local_file);
          
index 8ef12520e84304e2e700750f07ebe726dd81c87a..5e02bac8bebe679a342d5fa41b51b4c5ad669090 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -62,6 +62,7 @@ so, delete this exception statement from your version.  */
 
 #include "wget.h"
 #include "utils.h"
+#include "log.h"
 
 #ifndef errno
 extern int errno;
diff --git a/src/log.h b/src/log.h
new file mode 100644 (file)
index 0000000..ef59aa7
--- /dev/null
+++ b/src/log.h
@@ -0,0 +1,55 @@
+/* Declarations for log.c.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Wget.
+
+GNU Wget is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+GNU Wget is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Wget; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+In addition, as a special exception, the Free Software Foundation
+gives permission to link the code of its release of Wget with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables.  You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL".  If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so.  If you do not wish to do
+so, delete this exception statement from your version.  */
+
+#ifndef LOG_H
+#define LOG_H
+
+/* Make gcc check for the format of logmsg() and debug_logmsg().  */
+#ifdef __GNUC__
+# define GCC_FORMAT_ATTR(a, b) __attribute__ ((format (printf, a, b)))
+#else  /* not __GNUC__ */
+# define GCC_FORMAT_ATTR(a, b)
+#endif /* not __GNUC__ */
+
+enum log_options { LOG_VERBOSE, LOG_NOTQUIET, LOG_NONVERBOSE, LOG_ALWAYS };
+
+#ifdef HAVE_STDARG_H
+void logprintf PARAMS ((enum log_options, const char *, ...))
+     GCC_FORMAT_ATTR (2, 3);
+void debug_logprintf PARAMS ((const char *, ...)) GCC_FORMAT_ATTR (1, 2);
+#else  /* not HAVE_STDARG_H */
+void logprintf ();
+void debug_logprintf ();
+#endif /* not HAVE_STDARG_H */
+void logputs PARAMS ((enum log_options, const char *));
+void logflush PARAMS ((void));
+void log_set_flush PARAMS ((int));
+int log_set_save_context PARAMS ((int));
+
+#endif /* LOG_H */
index 64320454d628d977262cafb30542c3b38206a408..7b11d67fb364ca7bc36d9721f7b8ba863c77719e 100644 (file)
@@ -123,6 +123,8 @@ rbuf_peek (struct rbuf *rbuf, char *store)
   return 1;
 }
 
+#define MIN(p,q) (((p) <= (q)) ? (p) : (q))
+
 /* Flush RBUF's buffer to WHERE.  Flush MAXSIZE bytes at most.
    Returns the number of bytes actually copied.  If the buffer is
    empty, 0 is returned.  */
@@ -133,7 +135,7 @@ rbuf_flush (struct rbuf *rbuf, char *where, int maxsize)
     return 0;
   else
     {
-      int howmuch = MINVAL (rbuf->buffer_left, maxsize);
+      int howmuch = MIN (rbuf->buffer_left, maxsize);
 
       if (where)
        memcpy (where, rbuf->buffer_pos, howmuch);
index 11c404aef18a71e4727a831a2333bf8049a07a71..7a9ca64260acbb3eeb5d6ded979bb869d8f39641 100644 (file)
@@ -1,6 +1,5 @@
-/* Various functions of utilitarian nature.
-   Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001
-   Free Software Foundation, Inc.
+/* Various utility functions.
+   Copyright (C) 2003 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
@@ -102,238 +101,6 @@ so, delete this exception statement from your version.  */
 extern int errno;
 #endif
 
-/* This section implements several wrappers around the basic
-   allocation routines.  This is done for two reasons: first, so that
-   the callers of these functions need not consistently check for
-   errors.  If there is not enough virtual memory for running Wget,
-   something is seriously wrong, and Wget exits with an appropriate
-   error message.
-
-   The second reason why these are useful is that, if DEBUG_MALLOC is
-   defined, they also provide a handy (if crude) malloc debugging
-   interface that checks memory leaks.  */
-
-/* Croak the fatal memory error and bail out with non-zero exit
-   status.  */
-static void
-memfatal (const char *what)
-{
-  /* Make sure we don't try to store part of the log line, and thus
-     call malloc.  */
-  log_set_save_context (0);
-  logprintf (LOG_ALWAYS, _("%s: %s: Not enough memory.\n"), exec_name, what);
-  exit (1);
-}
-
-/* These functions end with _real because they need to be
-   distinguished from the debugging functions, and from the macros.
-   Explanation follows:
-
-   If memory debugging is not turned on, wget.h defines these:
-
-     #define xmalloc xmalloc_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
-   to call the debugging code.  (The former is the reason why xmalloc
-   and friends need to be macros in the first place.)  Then it looks
-   like this:
-
-     #define xmalloc(a) xmalloc_debug (a, __FILE__, __LINE__)
-     #define xfree(a)   xfree_debug (a, __FILE__, __LINE__)
-     #define xrealloc(a, b) xrealloc_debug (a, b, __FILE__, __LINE__)
-     #define xstrdup(a) xstrdup_debug (a, __FILE__, __LINE__)
-
-   Each of the *_debug function does its magic and calls the real one.  */
-
-#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);
-  if (!ptr)
-    memfatal ("malloc");
-  return ptr;
-}
-
-STATIC_IF_DEBUG void *
-xrealloc_real (void *ptr, size_t newsize)
-{
-  void *newptr;
-
-  /* Not all Un*xes have the feature of realloc() that calling it with
-     a NULL-pointer is the same as malloc(), but it is easy to
-     simulate.  */
-  if (ptr)
-    newptr = realloc (ptr, newsize);
-  else
-    newptr = malloc (newsize);
-  if (!newptr)
-    memfatal ("realloc");
-  return newptr;
-}
-
-STATIC_IF_DEBUG char *
-xstrdup_real (const char *s)
-{
-  char *copy;
-
-#ifndef HAVE_STRDUP
-  int l = strlen (s);
-  copy = malloc (l + 1);
-  if (!copy)
-    memfatal ("strdup");
-  memcpy (copy, s, l + 1);
-#else  /* HAVE_STRDUP */
-  copy = strdup (s);
-  if (!copy)
-    memfatal ("strdup");
-#endif /* HAVE_STRDUP */
-
-  return copy;
-}
-
-#ifdef DEBUG_MALLOC
-
-/* Crude home-grown routines for debugging some malloc-related
-   problems.  Featured:
-
-   * Counting the number of malloc and free invocations, and reporting
-     the "balance", i.e. how many times more malloc was called than it
-     was the case with free.
-
-   * Making malloc store its entry into a simple array and free remove
-     stuff from that array.  At the end, print the pointers which have
-     not been freed, along with the source file and the line number.
-     This also has the side-effect of detecting freeing memory that
-     was never allocated.
-
-   Note that this kind of memory leak checking strongly depends on
-   every malloc() being followed by a free(), even if the program is
-   about to finish.  Wget is careful to free the data structure it
-   allocated in init.c.  */
-
-static int malloc_count, free_count;
-
-static struct {
-  char *ptr;
-  const char *file;
-  int line;
-} malloc_debug[100000];
-
-/* Both register_ptr and unregister_ptr take O(n) operations to run,
-   which can be a real problem.  It would be nice to use a hash table
-   for malloc_debug, but the functions in hash.c are not suitable
-   because they can call malloc() themselves.  Maybe it would work if
-   the hash table were preallocated to a huge size, and if we set the
-   rehash threshold to 1.0.  */
-
-/* Register PTR in malloc_debug.  Abort if this is not possible
-   (presumably due to the number of current allocations exceeding the
-   size of malloc_debug.)  */
-
-static void
-register_ptr (void *ptr, const char *file, int line)
-{
-  int i;
-  for (i = 0; i < countof (malloc_debug); i++)
-    if (malloc_debug[i].ptr == NULL)
-      {
-       malloc_debug[i].ptr = ptr;
-       malloc_debug[i].file = file;
-       malloc_debug[i].line = line;
-       return;
-      }
-  abort ();
-}
-
-/* Unregister PTR from malloc_debug.  Abort if PTR is not present in
-   malloc_debug.  (This catches calling free() with a bogus pointer.)  */
-
-static void
-unregister_ptr (void *ptr)
-{
-  int i;
-  for (i = 0; i < countof (malloc_debug); i++)
-    if (malloc_debug[i].ptr == ptr)
-      {
-       malloc_debug[i].ptr = NULL;
-       return;
-      }
-  abort ();
-}
-
-/* Print the malloc debug stats that can be gathered from the above
-   information.  Currently this is the count of mallocs, frees, the
-   difference between the two, and the dump of the contents of
-   malloc_debug.  The last part are the memory leaks.  */
-
-void
-print_malloc_debug_stats (void)
-{
-  int i;
-  printf ("\nMalloc:  %d\nFree:    %d\nBalance: %d\n\n",
-         malloc_count, free_count, malloc_count - free_count);
-  for (i = 0; i < countof (malloc_debug); i++)
-    if (malloc_debug[i].ptr != NULL)
-      printf ("0x%08ld: %s:%d\n", (long)malloc_debug[i].ptr,
-             malloc_debug[i].file, malloc_debug[i].line);
-}
-
-void *
-xmalloc_debug (size_t size, const char *source_file, int source_line)
-{
-  void *ptr = xmalloc_real (size);
-  ++malloc_count;
-  register_ptr (ptr, source_file, source_line);
-  return ptr;
-}
-
-void
-xfree_debug (void *ptr, const char *source_file, int source_line)
-{
-  assert (ptr != NULL);
-  ++free_count;
-  unregister_ptr (ptr);
-  free (ptr);
-}
-
-void *
-xrealloc_debug (void *ptr, size_t newsize, const char *source_file, int source_line)
-{
-  void *newptr = xrealloc_real (ptr, newsize);
-  if (!ptr)
-    {
-      ++malloc_count;
-      register_ptr (newptr, source_file, source_line);
-    }
-  else if (newptr != ptr)
-    {
-      unregister_ptr (ptr);
-      register_ptr (newptr, source_file, source_line);
-    }
-  return newptr;
-}
-
-char *
-xstrdup_debug (const char *s, const char *source_file, int source_line)
-{
-  char *copy = xstrdup_real (s);
-  ++malloc_count;
-  register_ptr (copy, source_file, source_line);
-  return copy;
-}
-
-#endif /* DEBUG_MALLOC */
-\f
 /* Utility function: like xstrdup(), but also lowercases S.  */
 
 char *
index d49847b7fbd34e985e6db690a5f831861633b619..5630c6ca933ce13be690fc4e0bfd28c4bf0c5258 100644 (file)
@@ -49,6 +49,8 @@ struct file_memory {
   int mmap_p;
 };
 
+#define HYPHENP(x) (*(x) == '-' && !*((x) + 1))
+
 struct wget_timer;
 
 char *time_str PARAMS ((time_t *));
index 496078fe175ffb4f06940f0649e3a1268deec692..f3fb26f49895c5955ef4233953bb4954b50a43be 100644 (file)
@@ -97,101 +97,40 @@ so, delete this exception statement from your version.  */
 # define DEBUGP(x) DO_NOTHING
 #endif /* not ENABLE_DEBUG */
 
-/* Make gcc check for the format of logmsg() and debug_logmsg().  */
-#ifdef __GNUC__
-# define GCC_FORMAT_ATTR(a, b) __attribute__ ((format (printf, a, b)))
-#else  /* not __GNUC__ */
-# define GCC_FORMAT_ATTR(a, b)
-#endif /* not __GNUC__ */
-
-/* These are from log.c, but they are used everywhere, so we declare
-   them here.  */
-enum log_options { LOG_VERBOSE, LOG_NOTQUIET, LOG_NONVERBOSE, LOG_ALWAYS };
-
-#ifdef HAVE_STDARG_H
-void logprintf PARAMS ((enum log_options, const char *, ...))
-     GCC_FORMAT_ATTR (2, 3);
-void debug_logprintf PARAMS ((const char *, ...)) GCC_FORMAT_ATTR (1, 2);
-#else  /* not HAVE_STDARG_H */
-void logprintf ();
-void debug_logprintf ();
-#endif /* not HAVE_STDARG_H */
-void logputs PARAMS ((enum log_options, const char *));
-void logflush PARAMS ((void));
-void log_set_flush PARAMS ((int));
-int log_set_save_context PARAMS ((int));
-
-/* Defined in `utils.c', but used literally everywhere.  */
-#ifndef DEBUG_MALLOC
-
-#define xmalloc  xmalloc_real
-#define xrealloc xrealloc_real
-#define xstrdup  xstrdup_real
-#define xfree    free
-
-void *xmalloc_real PARAMS ((size_t));
-void *xrealloc_real PARAMS ((void *, size_t));
-char *xstrdup_real PARAMS ((const char *));
-
-#else  /* DEBUG_MALLOC */
-
-#define xmalloc(s)     xmalloc_debug (s, __FILE__, __LINE__)
-#define xfree(p)       xfree_debug (p, __FILE__, __LINE__)
-#define xrealloc(p, s) xrealloc_debug (p, s, __FILE__, __LINE__)
-#define xstrdup(p)     xstrdup_debug (p, __FILE__, __LINE__)
-
-void *xmalloc_debug PARAMS ((size_t, const char *, int));
-void xfree_debug PARAMS ((void *, const char *, int));
-void *xrealloc_debug PARAMS ((void *, size_t, const char *, int));
-char *xstrdup_debug PARAMS ((const char *, const char *, int));
-
-#endif /* DEBUG_MALLOC */
+/* Everything uses this, so include them here directly.  */
+#include "xmalloc.h"
+
+/* Likewise for logging functions.  */
+#include "log.h"
 
 /* #### Find a better place for this.  */
 /* The log file to which Wget writes to after HUP.  */
 #define DEFAULT_LOGFILE "wget-log"
-
-#define MD5_HASHLEN 16
 \f
 /* Useful macros used across the code: */
 
-/* Is the string a hpyhen-only?  */
-#define HYPHENP(x) (*(x) == '-' && !*((x) + 1))
+/* The number of elements in an array.  For example:
+   static char a[] = "foo";     -- countof(a) == 4 (for terminating \0)
+   int a[5] = {1, 2};           -- countof(a) == 5
+   char *a[] = {                -- countof(a) == 3
+     "foo", "bar", "baz"
+   }; */
+#define countof(array) (sizeof (array) / sizeof ((array)[0]))
 
-/* The smaller value of the two.  */
-#define MINVAL(x, y) ((x) < (y) ? (x) : (y))
+/* Zero out a value.  */
+#define xzero(x) memset (&(x), '\0', sizeof (x))
 
 /* Convert an ASCII hex digit to the corresponding number between 0
    and 15.  X should be a hexadecimal digit that satisfies isxdigit;
    otherwise, the result is undefined.  */
-#define XDIGIT_TO_NUM(x) ((x) < 'A' ? (x) - '0' : TOUPPER (x) - 'A' + 10)
-
-/* Convert a sequence of ASCII hex digits X and Y to a number betewen
-   0 and 255.  Uses XDIGIT_TO_NUM for conversion of individual
-   digits.  */
+#define XDIGIT_TO_NUM(h) ((h) < 'A' ? (h) - '0' : TOUPPER (h) - 'A' + 10)
 #define X2DIGITS_TO_NUM(h1, h2) ((XDIGIT_TO_NUM (h1) << 4) + XDIGIT_TO_NUM (h2))
 
 /* The reverse of the above: convert a number in the [0, 16) range to
-   its ASCII representation in hex.  The A-F characters are in upper
-   case.  */
-#define XNUM_TO_DIGIT(x) ("0123456789ABCDEF"[x])
-
-/* Like XNUM_TO_DIGIT, but generates lower-case characters. */
-#define XNUM_TO_digit(x) ("0123456789abcdef"[x])
-
-/* Returns the number of elements in an array with fixed
-   initialization.  For example:
-
-   static char a[] = "foo";     -- countof(a) == 4 (for terminating \0)
-
-   int a[5] = {1, 2};           -- countof(a) == 5
-
-   char *a[] = {                -- countof(a) == 3
-     "foo", "bar", "baz"
-   }; */
-#define countof(array) (sizeof (array) / sizeof (*(array)))
-
-#define alloca_array(type, size) ((type *) alloca ((size) * sizeof (type)))
+   the ASCII representation of the corresponding hex digit.  The `+ 0'
+   is so you don't accidentally use it as an lvalue.  */
+#define XNUM_TO_DIGIT(x) ("0123456789ABCDEF"[x] + 0)
+#define XNUM_TO_digit(x) ("0123456789abcdef"[x] + 0)
 
 /* Copy the data delimited with BEG and END to alloca-allocated
    storage, and zero-terminate it.  Arguments are evaluated only once,
@@ -223,12 +162,14 @@ char *xstrdup_debug PARAMS ((const char *, const char *, int));
    #define STRDUP_ALLOCA(str) (strcpy ((char *)alloca (strlen (str) + 1), str))
 
    This is because some compilers don't handle alloca() as argument to
-   function correctly.  Gcc under Intel has been reported to offend in
-   this case.  */
-
-#define STRDUP_ALLOCA(ptr, str) do {           \
-  (ptr) = (char *)alloca (strlen (str) + 1);   \
-  strcpy ((ptr), (str));                       \
+   function correctly.  Gcc on Intel platforms has been reported to
+   offend in this case.  */
+
+#define STRDUP_ALLOCA(ptr, str) do {                   \
+  char **SA_dest = &(ptr);                             \
+  const char *SA_src = (str);                          \
+  *SA_dest = (char *)alloca (strlen (SA_src) + 1);     \
+  strcpy (*SA_dest, SA_src);                           \
 } while (0)
 
 /* Generally useful if you want to avoid arbitrary size limits but
@@ -238,9 +179,8 @@ char *xstrdup_debug PARAMS ((const char *, const char *, int));
    will realloc BASEVAR as necessary so that it can hold at least
    NEEDED_SIZE objects.  The reallocing is done by doubling, which
    ensures constant amortized time per element.  */
-#define DO_REALLOC(basevar, sizevar, needed_size, type)        do                      \
-{                                                                              \
-  /* Avoid side-effectualness.  */                                             \
+#define DO_REALLOC(basevar, sizevar, needed_size, type)        do {                    \
+  /* Avoid side effects by prefixing the local vars.  */                       \
   long do_realloc_needed_size = (needed_size);                                 \
   long do_realloc_newsize = 0;                                                 \
   while ((sizevar) < (do_realloc_needed_size)) {                               \
@@ -254,7 +194,7 @@ char *xstrdup_debug PARAMS ((const char *, const char *, int));
 } while (0)
 
 /* Free FOO if it is non-NULL.  */
-#define FREE_MAYBE(foo) do { if (foo) xfree (foo); } while (0)
+#define FREE_MAYBE(foo) do { if (foo) xfree ((foo)); } while (0)
 
 extern const char *exec_name;
 \f
@@ -291,23 +231,22 @@ typedef enum
   SSLERRCERTFILE,SSLERRCERTKEY,SSLERRCTXCREATE
 } uerr_t;
 
+/* These are not used widely.  They should either be removed or used
+   consistently.  */
 typedef unsigned char  boolean;
 #ifndef FALSE
-#define FALSE 0
+# define FALSE 0
 #endif
 #ifndef TRUE
-#define TRUE  1
+# define TRUE  1
 #endif
 
-/* So we can say strcmp(a, b) == EQ rather than strcmp(a, b) == 0 or
-   the really awful !strcmp(a, b). */
-#define EQ 0
-
-/* For most options, 0 means no limits, but with -p in the picture, that causes
-   a problem on the maximum recursion depth variable.  To retain backwards
-   compatibility we allow users to consider "0" to be synonymous with "inf" for
-   -l, but internally infinite recursion is specified by -1 and 0 means to only
-   retrieve the requisites of a single document. */
+/* For most options, 0 means no limits, but with -p in the picture,
+   that causes a problem on the maximum recursion depth variable.  To
+   retain backwards compatibility we allow users to consider "0" to be
+   synonymous with "inf" for -l, but internally infinite recursion is
+   specified by -1 and 0 means to only retrieve the requisites of a
+   single document. */
 #define INFINITE_RECURSION -1
 
 /* In case old systems don't have EAFNOSUPPORT, which we use below. */
diff --git a/src/xmalloc.c b/src/xmalloc.c
new file mode 100644 (file)
index 0000000..3464cbf
--- /dev/null
@@ -0,0 +1,305 @@
+/* Wrappers around malloc and memory debugging support.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Wget.
+
+GNU Wget is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+GNU Wget is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Wget; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+In addition, as a special exception, the Free Software Foundation
+gives permission to link the code of its release of Wget with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables.  You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL".  If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so.  If you do not wish to do
+so, delete this exception statement from your version.  */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else  /* not HAVE_STRING_H */
+# include <strings.h>
+#endif /* not HAVE_STRING_H */
+#include <sys/types.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "wget.h"
+#include "xmalloc.h"
+
+#ifndef errno
+extern int errno;
+#endif
+
+/* This file implements several wrappers around the basic allocation
+   routines.  This is done for two reasons: first, so that the callers
+   of these functions need not check for errors, which is easy to
+   forget.  If there is not enough virtual memory for running Wget,
+   something is seriously wrong, and Wget exits with an appropriate
+   error message.
+
+   The second reason why these are useful is that, if DEBUG_MALLOC is
+   defined, they also provide a handy (if crude) malloc debugging
+   interface that checks memory leaks.  */
+
+/* Croak the fatal memory error and bail out with non-zero exit
+   status.  */
+
+static void
+memfatal (const char *context, long size)
+{
+  /* Make sure we don't try to store part of the log line, and thus
+     call malloc.  */
+  log_set_save_context (0);
+  logprintf (LOG_ALWAYS, _("%s: %s: Cannot allocate %ld bytes.\n"),
+            exec_name, context, size);
+  exit (1);
+}
+
+/* These functions end with _real because they need to be
+   distinguished from the debugging functions, and from the macros.
+   Explanation follows:
+
+   If memory debugging is not turned on, wget.h defines these:
+
+     #define xmalloc xmalloc_real
+     #define xmalloc0 xmalloc0_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
+   to call the debugging code.  (The former is the reason why xmalloc
+   and friends need to be macros in the first place.)  Then it looks
+   like this:
+
+     #define xmalloc(a) xmalloc_debug (a, __FILE__, __LINE__)
+     #define xmalloc0(a) xmalloc0_debug (a, __FILE__, __LINE__)
+     #define xfree(a)   xfree_debug (a, __FILE__, __LINE__)
+     #define xrealloc(a, b) xrealloc_debug (a, b, __FILE__, __LINE__)
+     #define xstrdup(a) xstrdup_debug (a, __FILE__, __LINE__)
+
+   Each of the *_debug function does its magic and calls the real one.  */
+
+#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);
+  if (!ptr)
+    memfatal ("malloc", size);
+  return ptr;
+}
+
+STATIC_IF_DEBUG void *
+xmalloc0_real (size_t size)
+{
+  /* Using calloc can be faster than malloc+memset because some calloc
+     implementations know when they're dealing with zeroed-out memory
+     from the system and can avoid unnecessary memset.  */
+  void *ptr = calloc (1, size);
+  if (!ptr)
+    memfatal ("calloc", size);
+  return ptr;
+}
+
+STATIC_IF_DEBUG void *
+xrealloc_real (void *ptr, size_t newsize)
+{
+  void *newptr;
+
+  /* Not all Un*xes have the feature of realloc() that calling it with
+     a NULL-pointer is the same as malloc(), but it is easy to
+     simulate.  */
+  if (ptr)
+    newptr = realloc (ptr, newsize);
+  else
+    newptr = malloc (newsize);
+  if (!newptr)
+    memfatal ("realloc", newsize);
+  return newptr;
+}
+
+STATIC_IF_DEBUG char *
+xstrdup_real (const char *s)
+{
+  char *copy;
+
+#ifndef HAVE_STRDUP
+  int l = strlen (s);
+  copy = malloc (l + 1);
+  if (!copy)
+    memfatal ("strdup", l + 1);
+  memcpy (copy, s, l + 1);
+#else  /* HAVE_STRDUP */
+  copy = strdup (s);
+  if (!copy)
+    memfatal ("strdup", 1 + strlen (s));
+#endif /* HAVE_STRDUP */
+
+  return copy;
+}
+
+#ifdef DEBUG_MALLOC
+
+/* Crude home-grown routines for debugging some malloc-related
+   problems.  Featured:
+
+   * Counting the number of malloc and free invocations, and reporting
+     the "balance", i.e. how many times more malloc was called than it
+     was the case with free.
+
+   * Making malloc store its entry into a simple array and free remove
+     stuff from that array.  At the end, print the pointers which have
+     not been freed, along with the source file and the line number.
+     This also has the side-effect of detecting freeing memory that
+     was never allocated.
+
+   Note that this kind of memory leak checking strongly depends on
+   every malloc() being followed by a free(), even if the program is
+   about to finish.  Wget is careful to free the data structure it
+   allocated in init.c.  */
+
+static int malloc_count, free_count;
+
+static struct {
+  char *ptr;
+  const char *file;
+  int line;
+} malloc_debug[100000];
+
+/* Both register_ptr and unregister_ptr take O(n) operations to run,
+   which can be a real problem.  It would be nice to use a hash table
+   for malloc_debug, but the functions in hash.c are not suitable
+   because they can call malloc() themselves.  Maybe it would work if
+   the hash table were preallocated to a huge size, and if we set the
+   rehash threshold to 1.0.  */
+
+/* Register PTR in malloc_debug.  Abort if this is not possible
+   (presumably due to the number of current allocations exceeding the
+   size of malloc_debug.)  */
+
+static void
+register_ptr (void *ptr, const char *file, int line)
+{
+  int i;
+  for (i = 0; i < countof (malloc_debug); i++)
+    if (malloc_debug[i].ptr == NULL)
+      {
+       malloc_debug[i].ptr = ptr;
+       malloc_debug[i].file = file;
+       malloc_debug[i].line = line;
+       return;
+      }
+  abort ();
+}
+
+/* Unregister PTR from malloc_debug.  Abort if PTR is not present in
+   malloc_debug.  (This catches calling free() with a bogus pointer.)  */
+
+static void
+unregister_ptr (void *ptr)
+{
+  int i;
+  for (i = 0; i < countof (malloc_debug); i++)
+    if (malloc_debug[i].ptr == ptr)
+      {
+       malloc_debug[i].ptr = NULL;
+       return;
+      }
+  abort ();
+}
+
+/* Print the malloc debug stats that can be gathered from the above
+   information.  Currently this is the count of mallocs, frees, the
+   difference between the two, and the dump of the contents of
+   malloc_debug.  The last part are the memory leaks.  */
+
+void
+print_malloc_debug_stats (void)
+{
+  int i;
+  printf ("\nMalloc:  %d\nFree:    %d\nBalance: %d\n\n",
+         malloc_count, free_count, malloc_count - free_count);
+  for (i = 0; i < countof (malloc_debug); i++)
+    if (malloc_debug[i].ptr != NULL)
+      printf ("0x%08ld: %s:%d\n", (long)malloc_debug[i].ptr,
+             malloc_debug[i].file, malloc_debug[i].line);
+}
+
+void *
+xmalloc_debug (size_t size, const char *source_file, int source_line)
+{
+  void *ptr = xmalloc_real (size);
+  ++malloc_count;
+  register_ptr (ptr, source_file, source_line);
+  return ptr;
+}
+
+void *
+xmalloc0_debug (size_t size, const char *source_file, int source_line)
+{
+  void *ptr = xmalloc0_real (size);
+  ++malloc_count;
+  register_ptr (ptr, source_file, source_line);
+  return ptr;
+}
+
+void *
+xrealloc_debug (void *ptr, size_t newsize, const char *source_file, int source_line)
+{
+  void *newptr = xrealloc_real (ptr, newsize);
+  if (!ptr)
+    {
+      ++malloc_count;
+      register_ptr (newptr, source_file, source_line);
+    }
+  else if (newptr != ptr)
+    {
+      unregister_ptr (ptr);
+      register_ptr (newptr, source_file, source_line);
+    }
+  return newptr;
+}
+
+char *
+xstrdup_debug (const char *s, const char *source_file, int source_line)
+{
+  char *copy = xstrdup_real (s);
+  ++malloc_count;
+  register_ptr (copy, source_file, source_line);
+  return copy;
+}
+
+void
+xfree_debug (void *ptr, const char *source_file, int source_line)
+{
+  assert (ptr != NULL);
+  ++free_count;
+  unregister_ptr (ptr);
+  free (ptr);
+}
+
+#endif /* DEBUG_MALLOC */
diff --git a/src/xmalloc.h b/src/xmalloc.h
new file mode 100644 (file)
index 0000000..220fc31
--- /dev/null
@@ -0,0 +1,79 @@
+/* xmalloc.c declarations.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Wget.
+
+GNU Wget is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+GNU Wget is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Wget; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+In addition, as a special exception, the Free Software Foundation
+gives permission to link the code of its release of Wget with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables.  You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL".  If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so.  If you do not wish to do
+so, delete this exception statement from your version.  */
+
+#ifndef XMALLOC_H
+#define XMALLOC_H
+
+/* When DEBUG_MALLOC is not defined (which is normally the case), the
+   allocation functions directly map to *_real wrappers.  In the
+   DEBUG_MALLOC mode, they also record the file and line where the
+   offending malloc/free/... was invoked.  */
+
+#ifndef DEBUG_MALLOC
+
+#define xmalloc  xmalloc_real
+#define xmalloc0 xmalloc0_real
+#define xrealloc xrealloc_real
+#define xstrdup  xstrdup_real
+#define xfree    free
+
+void *xmalloc_real PARAMS ((size_t));
+void *xmalloc0_real PARAMS ((size_t));
+void *xrealloc_real PARAMS ((void *, size_t));
+char *xstrdup_real PARAMS ((const char *));
+
+#else  /* DEBUG_MALLOC */
+
+#define xmalloc(s)     xmalloc_debug (s, __FILE__, __LINE__)
+#define xmalloc0(s)    xmalloc0_debug (s, __FILE__, __LINE__)
+#define xfree(p)       xfree_debug (p, __FILE__, __LINE__)
+#define xrealloc(p, s) xrealloc_debug (p, s, __FILE__, __LINE__)
+#define xstrdup(p)     xstrdup_debug (p, __FILE__, __LINE__)
+
+void *xmalloc_debug PARAMS ((size_t, const char *, int));
+void *xmalloc0_debug PARAMS ((size_t, const char *, int));
+void xfree_debug PARAMS ((void *, const char *, int));
+void *xrealloc_debug PARAMS ((void *, size_t, const char *, int));
+char *xstrdup_debug PARAMS ((const char *, const char *, int));
+
+#endif /* DEBUG_MALLOC */
+
+/* Macros that interface to malloc, but know about type sizes, and
+   cast the result to the appropriate type.  The casts are not
+   necessary in standard C, but Wget performs them anyway for the sake
+   of pre-standard environments and possibly C++.  */
+
+#define xnew(type) ((type *) xmalloc (sizeof (type)))
+#define xnew0(type) ((type *) xmalloc0 (sizeof (type)))
+#define xnew_array(type, len) ((type *) xmalloc ((len) * sizeof (type)))
+#define xnew0_array(type, len) ((type *) xmalloc0 ((len) * sizeof (type)))
+
+#define alloca_array(type, size) ((type *) alloca ((size) * sizeof (type)))
+
+#endif /* XMALLOC_H */
index 818d0b8d34c4392092832a82401be085a4e8199a..27a73f4eddc09d6ad12207296648a04b704a8b08 100644 (file)
@@ -66,14 +66,14 @@ RM      = del
 SRC = cmpt.c safe-ctype.c convert.c connect.c host.c http.c netrc.c \
       ftp-basic.c ftp.c ftp-ls.c ftp-opie.c getopt.c hash.c headers.c \
       html-parse.c html-url.c progress.c retr.c recur.c res.c url.c cookies.c \
-      init.c utils.c main.c version.c mswindows.c gen-md5.c \
-      gnu-md5.c rbuf.c log.c $(SSLSRC)
+      init.c utils.c main.c version.c xmalloc.c mswindows.c \
+      gen-md5.c gnu-md5.c rbuf.c log.c $(SSLSRC)
 
 OBJ = cmpt$o safe-ctype$o convert$o connect$o host$o http$o netrc$o \
       ftp-basic$o ftp$o ftp-ls$o ftp-opie$o getopt$o hash$o headers$o \
       html-parse$o html-url$o progress$o retr$o recur$o res$o url$o cookies$o \
-      init$o utils$o main$o version$o mswindows$o gen-md5$o gnu-md5$o\
-      rbuf$o log$o $(SSLOBJ)
+      init$o utils$o main$o version$o xmalloc$o mswindows$o \
+      gen-md5$o gnu-md5$o rbuf$o log$o $(SSLOBJ)
 
 .SUFFIXES: .c .obj
 
index 60f729233e0c2e3ae4abb9c8fd8bc124f7e1d04a..aaba63c33ce9910801965b4dd967ccf1cbe2dbc6 100644 (file)
@@ -12,7 +12,8 @@ OBJS=cmpt.obj connect.obj convert.obj ftp.obj ftp-basic.obj  \
       ftp-ls.obj ftp-opie.obj getopt.obj headers.obj host.obj html-parse.obj html-url.obj \
       http.obj init.obj log.obj main.obj gnu-md5.obj netrc.obj rbuf.obj  \
       safe-ctype.obj hash.obj progress.obj gen-md5.obj cookies.obj \
-      recur.obj res.obj retr.obj url.obj utils.obj version.obj mswindows.obj
+      recur.obj res.obj retr.obj url.obj utils.obj version.obj xmalloc.obj \
+      mswindows.obj
 
 LIBDIR=$(MAKEDIR)\..\lib
 
@@ -20,37 +21,38 @@ wget.exe: $(OBJS)
   $(LINK) @&&|
 $(LFLAGS) -Tpe -ap -c +
 $(LIBDIR)\c0x32.obj+
+cmpt.obj
+connect.obj+
 convert.obj+
 cookies.obj+
-hash.obj+
-safe-ctype.obj+
-version.obj+
-utils.obj+
-url.obj+
-retr.obj+
-res.obj+
-recur.obj+
-rbuf.obj+
-progress.obj+
-netrc.obj+
-mswindows.obj+
-gnu-md5.obj+
+ftp-basic.obj+
+ftp-ls.obj+
+ftp-opie.obj+
+ftp.obj+
 gen-md5.obj+
-main.obj+
-log.obj+
-init.obj+
-http.obj+
+getopt.obj+
+gnu-md5.obj+
+hash.obj+
+headers.obj+
+host.obj+
 html-parse.obj+
 html-url.obj+
-host.obj+
-headers.obj+
-getopt.obj+
-ftp-opie.obj+
-ftp-ls.obj+
-ftp-basic.obj+
-ftp.obj+
-connect.obj+
-cmpt.obj
+http.obj+
+init.obj+
+log.obj+
+main.obj+
+mswindows.obj+
+netrc.obj+
+progress.obj+
+rbuf.obj+
+recur.obj+
+res.obj+
+retr.obj+
+safe-ctype.obj+
+url.obj+
+utils.obj+
+version.obj+
+xmalloc.obj+
 $<,$*
 $(LIBDIR)\import32.lib+
 $(LIBDIR)\cw32.lib
index f825ff104ec0d6bfaf375e7fc22ee2f945bc2127..64f73341a72df8c4dd7aa25686bc8dea71dca145 100644 (file)
@@ -25,7 +25,8 @@ OBJS=cmpt${OBJ_EXT} convert${OBJ_EXT} connect${OBJ_EXT} ftp${OBJ_EXT} ftp-basic$
       ftp-ls${OBJ_EXT} ftp-opie${OBJ_EXT} getopt${OBJ_EXT} headers${OBJ_EXT} host${OBJ_EXT} html-parse${OBJ_EXT} html-url${OBJ_EXT} \
       http${OBJ_EXT} init${OBJ_EXT} log${OBJ_EXT} main${OBJ_EXT} gnu-md5${OBJ_EXT} netrc${OBJ_EXT} rbuf${OBJ_EXT}  \
       safe-ctype${OBJ_EXT} hash${OBJ_EXT} progress${OBJ_EXT} gen-md5${OBJ_EXT} cookies${OBJ_EXT} \
-      recur${OBJ_EXT} res${OBJ_EXT} retr${OBJ_EXT} url${OBJ_EXT} utils${OBJ_EXT} version${OBJ_EXT} mswindows${OBJ_EXT}
+      recur${OBJ_EXT} res${OBJ_EXT} retr${OBJ_EXT} url${OBJ_EXT} utils${OBJ_EXT} \
+      version${OBJ_EXT} xmalloc${OBJ_EXT} mswindows${OBJ_EXT}
 
 ifdef SSL
     ## OPENSSL_PATH is the OpenSSL installed directory
index 990005ce8436be6e67d786d2d1eac8bcb930761a..e804a62ced1d775d365943003347d731983905e2 100644 (file)
@@ -46,3 +46,8 @@ Windows contributors:
 
 * Douglas E. Wegscheid -- maintains configure.bat and various Windows
   makefiles.
+
+* Herold Heiko -- numerous build reports and fixes.
+
+* Gisle Vanem -- many Windows-related improvements to the source and
+  the build system.
index a5b1586b44fef5027ee8ac21115be747d7ba4163..dae1399a4182bad83de59e7e6558913492931cf7 100644 (file)
@@ -32,3 +32,4 @@ snprintf$o: snprintf.c config.h safe-ctype.h
 url$o: url.c config.h wget.h sysdep.h mswindows.h options.h safe-ctype.h utils.h url.h host.h hash.h
 utils$o: utils.c config.h wget.h sysdep.h mswindows.h options.h safe-ctype.h utils.h hash.h
 version$o: version.c
+xmalloc$o: wget.h xmalloc.h