/* HTML parser for Wget.
- Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998-2006 Free Software Foundation, Inc.
This file is part of GNU Wget.
GNU Wget is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
+the Free Software Foundation; either version 3 of the License, or (at
your option) any later version.
GNU Wget is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with Wget; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+along with Wget. If not, see <http://www.gnu.org/licenses/>.
In addition, as a special exception, the Free Software Foundation
gives permission to link the code of its release of Wget with the
#include <stdio.h>
#include <stdlib.h>
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
#include <assert.h>
#include "wget.h"
char *contents; /* pointer to the contents. */
int size; /* size of the pool. */
int tail; /* next available position index. */
- int resized; /* whether the pool has been resized
+ bool resized; /* whether the pool has been resized
using malloc. */
char *orig_contents; /* original pool contents, usually
P->contents = (initial_storage); \
P->size = (initial_size); \
P->tail = 0; \
- P->resized = 0; \
+ P->resized = false; \
P->orig_contents = P->contents; \
P->orig_size = P->size; \
} while (0)
P->contents = P->orig_contents; \
P->size = P->orig_size; \
P->tail = 0; \
- P->resized = 0; \
+ P->resized = false; \
} while (0)
/* Used for small stack-allocated memory chunks that might grow. Like
if (ga_newsize != (sizevar)) \
{ \
if (resized) \
- basevar = (type *)xrealloc (basevar, ga_newsize * sizeof (type)); \
+ basevar = 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; \
+ resized = true; \
} \
(sizevar) = ga_newsize; \
} \
the ASCII range when copying the string.
* AP_TRIM_BLANKS -- ignore blanks at the beginning and at the end
- of text. */
+ of text, as well as embedded newlines. */
static void
convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags)
{
int old_tail = pool->tail;
- int size;
- /* First, skip blanks if required. We must do this before entities
- are processed, so that blanks can still be inserted as, for
- instance, ` '. */
+ /* Skip blanks if required. We must do this before entities are
+ processed, so that blanks can still be inserted as, for instance,
+ ` '. */
if (flags & AP_TRIM_BLANKS)
{
while (beg < end && ISSPACE (*beg))
while (end > beg && ISSPACE (end[-1]))
--end;
}
- size = end - beg;
if (flags & AP_DECODE_ENTITIES)
{
never lengthen it. */
const char *from = beg;
char *to;
+ bool squash_newlines = !!(flags & AP_TRIM_BLANKS);
POOL_GROW (pool, end - beg);
to = pool->contents + pool->tail;
while (from < end)
{
- if (*from != '&')
- *to++ = *from++;
- else
+ if (*from == '&')
{
int entity = decode_entity (&from, end);
if (entity != -1)
else
*to++ = *from++;
}
+ else if ((*from == '\n' || *from == '\r') && squash_newlines)
+ ++from;
+ else
+ *to++ = *from++;
}
/* Verify that we haven't exceeded the original size. (It
shouldn't happen, hence the assert.) */
return NULL;
}
\f
-/* Return non-zero of the string inside [b, e) are present in hash
- table HT. */
+/* Return true if the string containing of characters inside [b, e) is
+ present in hash table HT. */
-static int
+static bool
name_allowed (const struct hash_table *ht, const char *b, const char *e)
{
char *copy;
if (!ht)
- return 1;
+ return true;
BOUNDED_TO_ALLOCA (b, e, copy);
return hash_table_get (ht, copy) != NULL;
}
MAPFUN will be called with two arguments: pointer to an initialized
struct taginfo, and MAPARG.
- ALLOWED_TAG_NAMES should be a NULL-terminated array of tag names to
- be processed by this function. If it is NULL, all the tags are
- allowed. The same goes for attributes and ALLOWED_ATTRIBUTE_NAMES.
+ ALLOWED_TAGS and ALLOWED_ATTRIBUTES are hash tables the keys of
+ which are the tags and attribute names that this function should
+ use. If ALLOWED_TAGS is NULL, all tags are processed; if
+ ALLOWED_ATTRIBUTES is NULL, all attributes are returned.
(Obviously, the caller can filter out unwanted tags and attributes
just as well, but this is just an optimization designed to avoid
- unnecessary copying for tags/attributes which the caller doesn't
- want to know about. These lists are searched linearly; therefore,
- if you're interested in a large number of tags or attributes, you'd
- better set these to NULL and filter them out yourself with a
- hashing process most appropriate for your application.) */
+ unnecessary copying of tags/attributes which the caller doesn't
+ care about.) */
void
map_html_tags (const char *text, int size,
struct attr_pair attr_pair_initial_storage[8];
int attr_pair_size = countof (attr_pair_initial_storage);
- int attr_pair_resized = 0;
+ bool attr_pair_resized = false;
struct attr_pair *pairs = attr_pair_initial_storage;
if (!size)
int nattrs, end_tag;
const char *tag_name_begin, *tag_name_end;
const char *tag_start_position;
- int uninteresting_tag;
+ bool uninteresting_tag;
look_for_tag:
POOL_REWIND (&pool);
if (!name_allowed (allowed_tags, tag_name_begin, tag_name_end))
/* We can't just say "goto look_for_tag" here because we need
the loop below to properly advance over the tag's attributes. */
- uninteresting_tag = 1;
+ uninteresting_tag = true;
else
{
- uninteresting_tag = 0;
+ uninteresting_tag = false;
convert_and_copy (&pool, tag_name_begin, tag_name_end, AP_DOWNCASE);
}
SKIP_WS (p);
if (*p == '\"' || *p == '\'')
{
- int newline_seen = 0;
+ bool newline_seen = false;
char quote_char = *p;
attr_raw_value_begin = p;
ADVANCE (p);
comes first. Such a tag terminated at `>'
is discarded. */
p = attr_value_begin;
- newline_seen = 1;
+ newline_seen = true;
continue;
}
else if (newline_seen && *p == '>')
taginfo.attrs = pairs;
taginfo.start_position = tag_start_position;
taginfo.end_position = p + 1;
- /* Ta-dam! */
- (*mapfun) (&taginfo, maparg);
+ mapfun (&taginfo, maparg);
ADVANCE (p);
}
goto look_for_tag;
int main ()
{
int size = 256;
- char *x = (char *)xmalloc (size);
+ char *x = xmalloc (size);
int length = 0;
int read_count;
int tag_counter = 0;
{
length += read_count;
size <<= 1;
- x = (char *)xrealloc (x, size);
+ x = xrealloc (x, size);
}
map_html_tags (x, length, test_mapper, &tag_counter, 0, NULL, NULL);