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>
|
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
|
||||||
|
151
src/html-parse.c
151
src/html-parse.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
55
src/wget.h
55
src/wget.h
@ -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
|
||||||
@ -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
|
will realloc BASEVAR as necessary so that it can hold at least
|
||||||
NEEDED_SIZE objects. The reallocing is done by doubling, which
|
NEEDED_SIZE objects. The reallocing is done by doubling, which
|
||||||
ensures constant amortized time per element. */
|
ensures constant amortized time per element. */
|
||||||
#define DO_REALLOC(basevar, sizevar, needed_size, 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 = 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 \
|
|
||||||
{ \
|
{ \
|
||||||
/* Avoid side-effectualness. */ \
|
/* Avoid side-effectualness. */ \
|
||||||
long do_realloc_needed_size = (needed_size); \
|
long do_realloc_needed_size = (needed_size); \
|
||||||
long do_realloc_newsize = (sizevar); \
|
long do_realloc_newsize = 0; \
|
||||||
while (do_realloc_newsize < do_realloc_needed_size) { \
|
while ((sizevar) < (do_realloc_needed_size)) { \
|
||||||
do_realloc_newsize <<= 1; \
|
do_realloc_newsize = 2*(sizevar); \
|
||||||
if (do_realloc_newsize < 16) \
|
if (do_realloc_newsize < 32) \
|
||||||
do_realloc_newsize = 16; \
|
do_realloc_newsize = 32; \
|
||||||
|
(sizevar) = do_realloc_newsize; \
|
||||||
} \
|
} \
|
||||||
if (do_realloc_newsize != (sizevar)) \
|
if (do_realloc_newsize) \
|
||||||
{ \
|
basevar = (type *)xrealloc (basevar, do_realloc_newsize * sizeof (type)); \
|
||||||
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. */
|
||||||
|
Loading…
Reference in New Issue
Block a user