[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>
* retr.c (retrieve_url): Initialize DUMMY storage for DT. Caught

View 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 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);
}

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);
/* 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++)
{

View 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. */