1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] Better document html-parse macros.

This commit is contained in:
hniksic 2003-10-02 15:20:44 -07:00
parent f70c6cacb9
commit eec3ea392d
4 changed files with 112 additions and 105 deletions

View 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> 2003-10-02 Hrvoje Niksic <hniksic@xemacs.org>
* retr.c (retrieve_url): Initialize DUMMY storage for DT. Caught * retr.c (retrieve_url): Initialize DUMMY storage for DT. Caught

View File

@ -147,60 +147,58 @@ static struct options opt;
struct pool { struct pool {
char *contents; /* pointer to the contents. */ char *contents; /* pointer to the contents. */
int size; /* size of the pool. */ int size; /* size of the pool. */
int index; /* next unoccupied position in int tail; /* next available position index. */
contents. */ int resized; /* whether the pool has been resized
using malloc. */
int alloca_p; /* whether contents was allocated char *orig_contents; /* original pool contents, usually
using alloca(). */ stack-allocated. used by POOL_FREE
char *orig_contents; /* orig_contents, allocated by to restore the pool to the initial
alloca(). this is used by state. */
POOL_FREE to restore the pool to
the "initial" state. */
int orig_size; int orig_size;
}; };
/* Initialize the pool to hold INITIAL_SIZE bytes of storage. */ /* Initialize the pool to hold INITIAL_SIZE bytes of storage. */
#define POOL_INIT(pool, initial_size) do { \ #define POOL_INIT(p, initial_storage, initial_size) do { \
(pool).size = (initial_size); \ struct pool *P = (p); \
(pool).contents = ALLOCA_ARRAY (char, (pool).size); \ P->contents = (initial_storage); \
(pool).index = 0; \ P->size = (initial_size); \
(pool).alloca_p = 1; \ P->tail = 0; \
(pool).orig_contents = (pool).contents; \ P->resized = 0; \
(pool).orig_size = (pool).size; \ P->orig_contents = P->contents; \
P->orig_size = P->size; \
} while (0) } while (0)
/* Grow the pool to accomodate at least SIZE new bytes. If the pool /* 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. */ already has room to accomodate SIZE bytes of data, this is a no-op. */
#define POOL_GROW(pool, increase) do { \ #define POOL_GROW(p, increase) \
int PG_newsize = (pool).index + increase; \ GROW_ARRAY ((p)->contents, (p)->size, (p)->tail + increase, \
DO_REALLOC_FROM_ALLOCA ((pool).contents, (pool).size, PG_newsize, \ (p)->resized, char)
(pool).alloca_p, char); \
} while (0)
/* Append text in the range [beg, end) to POOL. No zero-termination /* Append text in the range [beg, end) to POOL. No zero-termination
is done. */ is done. */
#define POOL_APPEND(pool, beg, end) do { \ #define POOL_APPEND(p, beg, end) do { \
const char *PA_beg = (beg); \ const char *PA_beg = (beg); \
int PA_size = (end) - PA_beg; \ int PA_size = (end) - PA_beg; \
POOL_GROW (pool, PA_size); \ POOL_GROW (p, PA_size); \
memcpy ((pool).contents + (pool).index, PA_beg, PA_size); \ memcpy ((p)->contents + (p)->tail, PA_beg, PA_size); \
(pool).index += PA_size; \ (p)->tail += PA_size; \
} while (0) } while (0)
/* Append one character to the pool. Can be used to zero-terminate /* Append one character to the pool. Can be used to zero-terminate
pool strings. */ pool strings. */
#define POOL_APPEND_CHR(pool, ch) do { \ #define POOL_APPEND_CHR(p, ch) do { \
char PAC_char = (ch); \ char PAC_char = (ch); \
POOL_GROW (pool, 1); \ POOL_GROW (p, 1); \
(pool).contents[(pool).index++] = PAC_char; \ (p)->contents[(p)->tail++] = PAC_char; \
} while (0) } while (0)
/* Forget old pool contents. The allocated memory is not freed. */ /* 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 /* Free heap-allocated memory for contents of POOL. This calls
xfree() if the memory was allocated through malloc. It also 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 values. That way after POOL_FREE, the pool is fully usable, just
as if it were freshly initialized with POOL_INIT. */ as if it were freshly initialized with POOL_INIT. */
#define POOL_FREE(pool) do { \ #define POOL_FREE(p) do { \
if (!(pool).alloca_p) \ struct pool *P = p; \
xfree ((pool).contents); \ if (P->resized) \
(pool).contents = (pool).orig_contents; \ xfree (P->contents); \
(pool).size = (pool).orig_size; \ P->contents = P->orig_contents; \
(pool).index = 0; \ P->size = P->orig_size; \
(pool).alloca_p = 1; \ P->tail = 0; \
P->resized = 0; \
} while (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)
#define AP_DOWNCASE 1 #define AP_DOWNCASE 1
#define AP_PROCESS_ENTITIES 2 #define AP_PROCESS_ENTITIES 2
@ -239,7 +269,7 @@ struct pool {
static void static void
convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags) 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; int size;
/* First, skip blanks if required. We must do this before entities /* 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 It's safe (and necessary) to grow the pool in advance because
processing the entities can only *shorten* the string, it can processing the entities can only *shorten* the string, it can
never lengthen it. */ never lengthen it. */
POOL_GROW (*pool, end - beg); POOL_GROW (pool, end - beg);
const char *from = beg; const char *from = beg;
char *to = pool->contents + pool->index; char *to = pool->contents + pool->tail;
while (from < end) 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 /* Verify that we haven't exceeded the original size. (It
shouldn't happen, hence the assert.) */ 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 /* Make POOL's tail point to the position following the string
we've written. */ we've written. */
pool->index = to - pool->contents; pool->tail = to - pool->contents;
POOL_APPEND_CHR (*pool, '\0'); POOL_APPEND_CHR (pool, '\0');
} }
else else
{ {
/* Just copy the text to the pool. */ /* Just copy the text to the pool. */
POOL_APPEND (*pool, beg, end); POOL_APPEND (pool, beg, end);
POOL_APPEND_CHR (*pool, '\0'); POOL_APPEND_CHR (pool, '\0');
} }
if (flags & AP_DOWNCASE) if (flags & AP_DOWNCASE)
{ {
char *p = pool->contents + old_index; char *p = pool->contents + old_tail;
for (; *p; p++) for (; *p; p++)
*p = TOLOWER (*p); *p = TOLOWER (*p);
} }
@ -681,18 +711,23 @@ map_html_tags (const char *text, int size,
void (*mapfun) (struct taginfo *, void *), void (*mapfun) (struct taginfo *, void *),
void *closure) 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 *p = text;
const char *end = text + size; const char *end = text + size;
int attr_pair_count = 8; struct attr_pair attr_pair_initial_storage[8];
int attr_pair_alloca_p = 1; int attr_pair_size = countof (attr_pair_initial_storage);
struct attr_pair *pairs = ALLOCA_ARRAY (struct attr_pair, attr_pair_count); int attr_pair_resized = 0;
struct pool pool; struct attr_pair *pairs = attr_pair_initial_storage;
if (!size) if (!size)
return; return;
POOL_INIT (pool, 256); POOL_INIT (&pool, pool_initial_storage, countof (pool_initial_storage));
{ {
int nattrs, end_tag; int nattrs, end_tag;
@ -701,7 +736,7 @@ map_html_tags (const char *text, int size,
int uninteresting_tag; int uninteresting_tag;
look_for_tag: look_for_tag:
POOL_REWIND (pool); POOL_REWIND (&pool);
nattrs = 0; nattrs = 0;
end_tag = 0; end_tag = 0;
@ -906,13 +941,13 @@ map_html_tags (const char *text, int size,
attr_name_end)) attr_name_end))
continue; continue;
DO_REALLOC_FROM_ALLOCA (pairs, attr_pair_count, nattrs + 1, GROW_ARRAY (pairs, attr_pair_size, nattrs + 1, attr_pair_resized,
attr_pair_alloca_p, struct attr_pair); 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); 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); convert_and_copy (&pool, attr_value_begin, attr_value_end, operation);
pairs[nattrs].value_raw_beginning = attr_raw_value_begin; pairs[nattrs].value_raw_beginning = attr_raw_value_begin;
pairs[nattrs].value_raw_size = (attr_raw_value_end pairs[nattrs].value_raw_size = (attr_raw_value_end
@ -964,8 +999,8 @@ map_html_tags (const char *text, int size,
} }
finish: finish:
POOL_FREE (pool); POOL_FREE (&pool);
if (!attr_pair_alloca_p) if (attr_pair_resized)
xfree (pairs); xfree (pairs);
} }

View File

@ -804,7 +804,7 @@ Can't timestamp and not clobber old files at the same time.\n"));
set_progress_implementation (opt.progress_type); set_progress_implementation (opt.progress_type);
/* Allocate basic pointer. */ /* Allocate basic pointer. */
url = ALLOCA_ARRAY (char *, nurl + 1); url = (char **) alloca ((nurl + 1) * sizeof (char *));
/* Fill in the arguments. */ /* Fill in the arguments. */
for (i = 0; i < nurl; i++, optind++) for (i = 0; i < nurl; i++, optind++)
{ {

View File

@ -235,11 +235,6 @@ char *xstrdup_debug PARAMS ((const char *, const char *, int));
strcpy (ptr, str); \ strcpy (ptr, str); \
} while (0) } 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 /* Generally useful if you want to avoid arbitrary size limits but
don't need a full dynamic array. Assumes that BASEVAR points to a don't need a full dynamic array. Assumes that BASEVAR points to a
malloced array of TYPE objects (or possibly a NULL pointer, if malloced array of TYPE objects (or possibly a NULL pointer, if
@ -259,39 +254,7 @@ char *xstrdup_debug PARAMS ((const char *, const char *, int));
(sizevar) = do_realloc_newsize; \ (sizevar) = do_realloc_newsize; \
} \ } \
if (do_realloc_newsize) \ if (do_realloc_newsize) \
XREALLOC_ARRAY (basevar, type, do_realloc_newsize); \ basevar = (type *)xrealloc (basevar, do_realloc_newsize * sizeof (type)); \
} 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 \
{ \
/* 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; \
} \
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; \
} \
} while (0) } while (0)
/* Free FOO if it is non-NULL. */ /* Free FOO if it is non-NULL. */