]> sjero.net Git - wget/commitdiff
[svn] Better document html-parse macros.
authorhniksic <devnull@localhost>
Thu, 2 Oct 2003 22:20:44 +0000 (15:20 -0700)
committerhniksic <devnull@localhost>
Thu, 2 Oct 2003 22:20:44 +0000 (15:20 -0700)
src/ChangeLog
src/html-parse.c
src/main.c
src/wget.h

index 77ade2a907dc5a45c9214c96416414f548828c9c..3ae83a9d09fd2448ddf75e9132115a7c597f13f7 100644 (file)
@@ -1,3 +1,12 @@
+2003-10-02  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * wget.h (XMALLOC_ARRAY): Removed.
+       (ALLOCA_ARRAY): Ditto.
+
+       * html-parse.c: Renamed alloca_p to resized.
+       (GROW_ARRAY): Renamed DO_REALLOC_FROM_ALLOCA to GROW_ARRAY and
+       returned it to html-parse.c, since nothing else was using it.
+
 2003-10-02  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * retr.c (retrieve_url): Initialize DUMMY storage for DT.  Caught
index 86e4195ea5de6ddb63e575ff2562eafb72b930af..16b88d0f617ebee5e51ffed341d2ed35b4e5de49 100644 (file)
@@ -147,60 +147,58 @@ static struct options opt;
 struct pool {
   char *contents;              /* pointer to the contents. */
   int size;                    /* size of the pool. */
-  int index;                   /* next unoccupied position in
-                                   contents. */
-
-  int alloca_p;                        /* whether contents was allocated
-                                   using alloca(). */
-  char *orig_contents;         /* orig_contents, allocated by
-                                   alloca().  this is used by
-                                   POOL_FREE to restore the pool to
-                                   the "initial" state. */
+  int tail;                    /* next available position index. */
+  int resized;                 /* whether the pool has been resized
+                                  using malloc. */
+
+  char *orig_contents;         /* original pool contents, usually
+                                   stack-allocated.  used by POOL_FREE
+                                   to restore the pool to the initial
+                                   state. */
   int orig_size;
 };
 
 /* Initialize the pool to hold INITIAL_SIZE bytes of storage. */
 
-#define POOL_INIT(pool, initial_size) do {             \
-  (pool).size = (initial_size);                                \
-  (pool).contents = ALLOCA_ARRAY (char, (pool).size);  \
-  (pool).index = 0;                                    \
-  (pool).alloca_p = 1;                                 \
-  (pool).orig_contents = (pool).contents;              \
-  (pool).orig_size = (pool).size;                      \
+#define POOL_INIT(p, initial_storage, initial_size) do {       \
+  struct pool *P = (p);                                                \
+  P->contents = (initial_storage);                             \
+  P->size = (initial_size);                                    \
+  P->tail = 0;                                                 \
+  P->resized = 0;                                              \
+  P->orig_contents = P->contents;                              \
+  P->orig_size = P->size;                                      \
 } while (0)
 
 /* Grow the pool to accomodate at least SIZE new bytes.  If the pool
    already has room to accomodate SIZE bytes of data, this is a no-op.  */
 
-#define POOL_GROW(pool, increase) do {                                 \
-  int PG_newsize = (pool).index + increase;                            \
-  DO_REALLOC_FROM_ALLOCA ((pool).contents, (pool).size, PG_newsize,    \
-                         (pool).alloca_p, char);                       \
-} while (0)
+#define POOL_GROW(p, increase)                                 \
+  GROW_ARRAY ((p)->contents, (p)->size, (p)->tail + increase,  \
+             (p)->resized, char)
 
 /* Append text in the range [beg, end) to POOL.  No zero-termination
    is done.  */
 
-#define POOL_APPEND(pool, beg, end) do {                       \
-  const char *PA_beg = (beg);                                  \
-  int PA_size = (end) - PA_beg;                                        \
-  POOL_GROW (pool, PA_size);                                   \
-  memcpy ((pool).contents + (pool).index, PA_beg, PA_size);    \
-  (pool).index += PA_size;                                     \
+#define POOL_APPEND(p, beg, end) do {                  \
+  const char *PA_beg = (beg);                          \
+  int PA_size = (end) - PA_beg;                                \
+  POOL_GROW (p, PA_size);                              \
+  memcpy ((p)->contents + (p)->tail, PA_beg, PA_size); \
+  (p)->tail += PA_size;                                        \
 } while (0)
 
 /* Append one character to the pool.  Can be used to zero-terminate
    pool strings.  */
 
-#define POOL_APPEND_CHR(pool, ch) do {         \
+#define POOL_APPEND_CHR(p, ch) do {            \
   char PAC_char = (ch);                                \
-  POOL_GROW (pool, 1);                         \
-  (pool).contents[(pool).index++] = PAC_char;  \
+  POOL_GROW (p, 1);                            \
+  (p)->contents[(p)->tail++] = PAC_char;       \
 } while (0)
 
 /* Forget old pool contents.  The allocated memory is not freed. */
-#define POOL_REWIND(pool) pool.index = 0
+#define POOL_REWIND(p) (p)->tail = 0
 
 /* Free heap-allocated memory for contents of POOL.  This calls
    xfree() if the memory was allocated through malloc.  It also
@@ -208,15 +206,47 @@ struct pool {
    values.  That way after POOL_FREE, the pool is fully usable, just
    as if it were freshly initialized with POOL_INIT.  */
 
-#define POOL_FREE(pool) do {                   \
-  if (!(pool).alloca_p)                                \
-    xfree ((pool).contents);                   \
-  (pool).contents = (pool).orig_contents;      \
-  (pool).size = (pool).orig_size;              \
-  (pool).index = 0;                            \
-  (pool).alloca_p = 1;                         \
+#define POOL_FREE(p) do {                      \
+  struct pool *P = p;                          \
+  if (P->resized)                              \
+    xfree (P->contents);                       \
+  P->contents = P->orig_contents;              \
+  P->size = P->orig_size;                      \
+  P->tail = 0;                                 \
+  P->resized = 0;                              \
 } while (0)
 
+/* Used for small stack-allocated memory chunks that might grow.  Like
+   DO_REALLOC, this macro grows BASEVAR as necessary to take
+   NEEDED_SIZE items of TYPE.
+
+   The difference is that on the first resize, it will use
+   malloc+memcpy rather than realloc.  That way you can stack-allocate
+   the initial chunk, and only resort to heap allocation if you
+   stumble upon large data.
+
+   After the first resize, subsequent ones are performed with realloc,
+   just like DO_REALLOC.  */
+
+#define GROW_ARRAY(basevar, sizevar, needed_size, resized, type) do {          \
+  long ga_needed_size = (needed_size);                                         \
+  long ga_newsize = (sizevar);                                                 \
+  while (ga_newsize < ga_needed_size)                                          \
+    ga_newsize <<= 1;                                                          \
+  if (ga_newsize != (sizevar))                                                 \
+    {                                                                          \
+      if (resized)                                                             \
+       basevar = (type *)xrealloc (basevar, ga_newsize * sizeof (type));       \
+      else                                                                     \
+       {                                                                       \
+         void *ga_new = xmalloc (ga_newsize * sizeof (type));                  \
+         memcpy (ga_new, basevar, (sizevar) * sizeof (type));                  \
+         (basevar) = ga_new;                                                   \
+         resized = 1;                                                          \
+       }                                                                       \
+      (sizevar) = ga_newsize;                                                  \
+    }                                                                          \
+} while (0)
 \f
 #define AP_DOWNCASE            1
 #define AP_PROCESS_ENTITIES    2
@@ -239,7 +269,7 @@ struct pool {
 static void
 convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags)
 {
-  int old_index = pool->index;
+  int old_tail = pool->tail;
   int size;
 
   /* First, skip blanks if required.  We must do this before entities
@@ -263,9 +293,9 @@ convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags
         It's safe (and necessary) to grow the pool in advance because
         processing the entities can only *shorten* the string, it can
         never lengthen it.  */
-      POOL_GROW (*pool, end - beg);
+      POOL_GROW (pool, end - beg);
       const char *from = beg;
-      char *to = pool->contents + pool->index;
+      char *to = pool->contents + pool->tail;
 
       while (from < end)
        {
@@ -338,23 +368,23 @@ convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags
        }
       /* Verify that we haven't exceeded the original size.  (It
         shouldn't happen, hence the assert.)  */
-      assert (to - (pool->contents + pool->index) <= end - beg);
+      assert (to - (pool->contents + pool->tail) <= end - beg);
 
       /* Make POOL's tail point to the position following the string
         we've written.  */
-      pool->index = to - pool->contents;
-      POOL_APPEND_CHR (*pool, '\0');
+      pool->tail = to - pool->contents;
+      POOL_APPEND_CHR (pool, '\0');
     }
   else
     {
       /* Just copy the text to the pool.  */
-      POOL_APPEND (*pool, beg, end);
-      POOL_APPEND_CHR (*pool, '\0');
+      POOL_APPEND (pool, beg, end);
+      POOL_APPEND_CHR (pool, '\0');
     }
 
   if (flags & AP_DOWNCASE)
     {
-      char *p = pool->contents + old_index;
+      char *p = pool->contents + old_tail;
       for (; *p; p++)
        *p = TOLOWER (*p);
     }
@@ -681,18 +711,23 @@ map_html_tags (const char *text, int size,
               void (*mapfun) (struct taginfo *, void *),
               void *closure)
 {
+  /* storage for strings passed to MAPFUN callback; if 256 bytes is
+     too little, POOL_APPEND allocates more with malloc. */
+  char pool_initial_storage[256];
+  struct pool pool;
+
   const char *p = text;
   const char *end = text + size;
 
-  int attr_pair_count = 8;
-  int attr_pair_alloca_p = 1;
-  struct attr_pair *pairs = ALLOCA_ARRAY (struct attr_pair, attr_pair_count);
-  struct pool pool;
+  struct attr_pair attr_pair_initial_storage[8];
+  int attr_pair_size = countof (attr_pair_initial_storage);
+  int attr_pair_resized = 0;
+  struct attr_pair *pairs = attr_pair_initial_storage;
 
   if (!size)
     return;
 
-  POOL_INIT (pool, 256);
+  POOL_INIT (&pool, pool_initial_storage, countof (pool_initial_storage));
 
   {
     int nattrs, end_tag;
@@ -701,7 +736,7 @@ map_html_tags (const char *text, int size,
     int uninteresting_tag;
 
   look_for_tag:
-    POOL_REWIND (pool);
+    POOL_REWIND (&pool);
 
     nattrs = 0;
     end_tag = 0;
@@ -906,13 +941,13 @@ map_html_tags (const char *text, int size,
                               attr_name_end))
          continue;
 
-       DO_REALLOC_FROM_ALLOCA (pairs, attr_pair_count, nattrs + 1,
-                               attr_pair_alloca_p, struct attr_pair);
+       GROW_ARRAY (pairs, attr_pair_size, nattrs + 1, attr_pair_resized,
+                   struct attr_pair);
 
-       pairs[nattrs].name_pool_index = pool.index;
+       pairs[nattrs].name_pool_index = pool.tail;
        convert_and_copy (&pool, attr_name_begin, attr_name_end, AP_DOWNCASE);
 
-       pairs[nattrs].value_pool_index = pool.index;
+       pairs[nattrs].value_pool_index = pool.tail;
        convert_and_copy (&pool, attr_value_begin, attr_value_end, operation);
        pairs[nattrs].value_raw_beginning = attr_raw_value_begin;
        pairs[nattrs].value_raw_size = (attr_raw_value_end
@@ -964,8 +999,8 @@ map_html_tags (const char *text, int size,
   }
 
  finish:
-  POOL_FREE (pool);
-  if (!attr_pair_alloca_p)
+  POOL_FREE (&pool);
+  if (attr_pair_resized)
     xfree (pairs);
 }
 
index acbb9921567c9702c6dbbe6802fc3e78a46663f1..3fe47de026a8c53741ddfef9af76eebe25deffb2 100644 (file)
@@ -804,7 +804,7 @@ Can't timestamp and not clobber old files at the same time.\n"));
     set_progress_implementation (opt.progress_type);
 
   /* Allocate basic pointer.  */
-  url = ALLOCA_ARRAY (char *, nurl + 1);
+  url = (char **) alloca ((nurl + 1) * sizeof (char *));
   /* Fill in the arguments.  */
   for (i = 0; i < nurl; i++, optind++)
     {
index 45e2fd82f784f3c68a44501823e4dbfbfece4fe9..ea8d69778cc618deac69a7bcc0f26561cf5d1d9a 100644 (file)
@@ -235,11 +235,6 @@ char *xstrdup_debug PARAMS ((const char *, const char *, int));
   strcpy (ptr, str);                           \
 } while (0)
 
-#define ALLOCA_ARRAY(type, len) ((type *) alloca ((len) * sizeof (type)))
-
-#define XREALLOC_ARRAY(ptr, type, len)                                 \
-     ((void) (ptr = (type *) xrealloc (ptr, (len) * sizeof (type))))
-
 /* Generally useful if you want to avoid arbitrary size limits but
    don't need a full dynamic array.  Assumes that BASEVAR points to a
    malloced array of TYPE objects (or possibly a NULL pointer, if
@@ -247,51 +242,19 @@ 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.  */                             \
-  long do_realloc_needed_size = (needed_size);                 \
-  long do_realloc_newsize = 0;                                 \
-  while ((sizevar) < (do_realloc_needed_size)) {               \
-    do_realloc_newsize = 2*(sizevar);                          \
-    if (do_realloc_newsize < 32)                               \
-      do_realloc_newsize = 32;                                 \
-    (sizevar) = do_realloc_newsize;                            \
-  }                                                            \
-  if (do_realloc_newsize)                                      \
-    XREALLOC_ARRAY (basevar, type, do_realloc_newsize);                \
-} while (0)
-
-/* Use this for small stack-allocated memory chunks that might grow.
-   The initial array is created using alloca(), and this macro
-   requests it to grow.  If the needed size is larger than the array,
-   this macro will use malloc to allocate it to new size, and copy the
-   old contents.  After that, successive invocations behave just like
-   DO_REALLOC.  */
-#define DO_REALLOC_FROM_ALLOCA(basevar, sizevar, needed_size, allocap, type) do        \
+#define DO_REALLOC(basevar, sizevar, needed_size, type)        do                      \
 {                                                                              \
   /* Avoid side-effectualness.  */                                             \
   long do_realloc_needed_size = (needed_size);                                 \
-  long do_realloc_newsize = (sizevar);                                         \
-  while (do_realloc_newsize < do_realloc_needed_size) {                                \
-    do_realloc_newsize <<= 1;                                                  \
-    if (do_realloc_newsize < 16)                                               \
-      do_realloc_newsize = 16;                                                 \
+  long do_realloc_newsize = 0;                                                 \
+  while ((sizevar) < (do_realloc_needed_size)) {                               \
+    do_realloc_newsize = 2*(sizevar);                                          \
+    if (do_realloc_newsize < 32)                                               \
+      do_realloc_newsize = 32;                                                 \
+    (sizevar) = do_realloc_newsize;                                            \
   }                                                                            \
-  if (do_realloc_newsize != (sizevar))                                         \
-    {                                                                          \
-      if (!allocap)                                                            \
-       XREALLOC_ARRAY (basevar, type, do_realloc_newsize);                     \
-      else                                                                     \
-       {                                                                       \
-         void *drfa_new_basevar =                                              \
-               xmalloc (do_realloc_newsize * sizeof (type));                   \
-         memcpy (drfa_new_basevar, basevar, (sizevar) * sizeof (type));        \
-         (basevar) = drfa_new_basevar;                                         \
-         allocap = 0;                                                          \
-       }                                                                       \
-      (sizevar) = do_realloc_newsize;                                          \
-    }                                                                          \
+  if (do_realloc_newsize)                                                      \
+    basevar = (type *)xrealloc (basevar, do_realloc_newsize * sizeof (type));  \
 } while (0)
 
 /* Free FOO if it is non-NULL.  */