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:
parent
f70c6cacb9
commit
eec3ea392d
@ -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
|
||||
|
151
src/html-parse.c
151
src/html-parse.c
@ -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 tail; /* next available position index. */
|
||||
int resized; /* whether the pool has been resized
|
||||
using malloc. */
|
||||
|
||||
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. */
|
||||
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)
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
@ -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++)
|
||||
{
|
||||
|
55
src/wget.h
55
src/wget.h
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user