mp_flush(pool);
mp_flush(stack);
bzero(ctx, sizeof(*ctx));
+ ctx->pool = pool;
+ ctx->stack = stack;
xml_do_init(ctx);
}
struct xml_dom_stack *s = xml_do_push(ctx, sizeof(*s));
mp_save(ctx->pool, &s->state);
struct xml_node *n = mp_alloc(ctx->pool, sizeof(*n));
+ n->user = NULL;
if (n->parent = ctx->node)
clist_add_tail(&n->parent->sons, &n->n);
return ctx->node = n;
#include "lib/hashtable.h"
static struct xml_dtd_ent *
-xml_dtd_declare_trivial_ent(struct xml_context *ctx, char *name, char *text)
+xml_dtd_declare_trivial_ent(struct xml_context *ctx, char *name, uns uni)
{
struct xml_dtd *dtd = ctx->dtd;
struct xml_dtd_ent *ent = xml_dtd_ents_lookup(dtd->tab_ents, name);
return NULL;
}
slist_add_tail(&dtd->ents, &ent->n);
- ent->flags = XML_DTD_ENT_DECLARED | XML_DTD_ENT_TRIVIAL;
- ent->text = text;
- ent->len = strlen(text);
+ ent->flags = XML_DTD_ENT_DECLARED | XML_DTD_ENT_TRIVIAL_UNI;
+ ent->uni = uni;
return ent;
}
static void
xml_dtd_declare_default_ents(struct xml_context *ctx)
{
- xml_dtd_declare_trivial_ent(ctx, "lt", "<");
- xml_dtd_declare_trivial_ent(ctx, "gt", ">");
- xml_dtd_declare_trivial_ent(ctx, "amp", "&");
- xml_dtd_declare_trivial_ent(ctx, "apos", "'");
- xml_dtd_declare_trivial_ent(ctx, "quot", "\"");
+ xml_dtd_declare_trivial_ent(ctx, "lt", 60);
+ xml_dtd_declare_trivial_ent(ctx, "gt", 62);
+ xml_dtd_declare_trivial_ent(ctx, "amp", 38);
+ xml_dtd_declare_trivial_ent(ctx, "apos", 39);
+ xml_dtd_declare_trivial_ent(ctx, "quot", 34);
}
struct xml_dtd_ent *
xml_dtd_find_ent(struct xml_context *ctx, char *name)
{
struct xml_dtd *dtd = ctx->dtd;
- if (dtd)
+ if (ctx->h_resolve_entity)
+ return ctx->h_resolve_entity(ctx, name);
+ else if (dtd)
{
struct xml_dtd_ent *ent = xml_dtd_ents_find(dtd->tab_ents, name);
return !ent ? NULL : (ent->flags & XML_DTD_ENT_DECLARED) ? ent : NULL;
}
else
{
-#define ENT(n, t) ent_##n = { .name = #n, .text = t, .len = 1, .flags = XML_DTD_ENT_DECLARED | XML_DTD_ENT_TRIVIAL }
- static struct xml_dtd_ent ENT(lt, "<"), ENT(gt, ">"), ENT(amp, "&"), ENT(apos, "'"), ENT(quot, "\"");
+#define ENT(n, u) ent_##n = { .name = #n, .uni = u, .flags = XML_DTD_ENT_DECLARED | XML_DTD_ENT_TRIVIAL_UNI }
+ static struct xml_dtd_ent ENT(lt, 60), ENT(gt, 62), ENT(amp, 38), ENT(apos, 39), ENT(quot, 34);
#undef ENT
switch (name[0])
{
XML_DTD_ENT_PARAMETER = 0x4, /* Parameter entity, general otherwise */
XML_DTD_ENT_EXTERNAL = 0x8, /* External entity, internal otherwise */
XML_DTD_ENT_UNPARSED = 0x10, /* Unparsed entity, parsed otherwise */
- XML_DTD_ENT_TRIVIAL = 0x20, /* Replacement text is a sequence of characters and character references */
+ XML_DTD_ENT_TRIVIAL_STR = 0x20, /* Replacement text is a sequence of characters and character references */
+ XML_DTD_ENT_TRIVIAL_UNI = 0x40, /* Replacement text is a single Unicode character */
};
struct xml_dtd_ent {
char *name; /* Entity name */
char *text; /* Replacement text / expanded replacement text (XML_DTD_ENT_TRIVIAL) */
uns len; /* Text length */
+ uns uni; /* Unicode value */
struct xml_ext_id eid; /* External ID */
struct xml_dtd_notn *notn; /* Notation (XML_DTD_ENT_UNPARSED only) */
};
bputs(out, name);
bputc(out, ';');
}
- else if (ent->flags & XML_DTD_ENT_TRIVIAL)
+ else if (ent->flags & XML_DTD_ENT_TRIVIAL_UNI)
+ {
+ TRACE(ctx, "Trivial entity &%s;", name);
+ bput_utf8_32(out, ent->uni);
+ }
+ else if (ent->flags & XML_DTD_ENT_TRIVIAL_STR)
{
TRACE(ctx, "Trivial entity &%s;", name);
bwrite(out, ent->text, ent->len);
a->elem = e;
a->name = name;
a->val = NULL;
+ a->user = NULL;
slist_add_tail(&e->attrs, &a->n);
}
slist_init(&e->attrs);
if (!e->parent)
{
- ctx->root = e;
+ ctx->dom = e;
if (ctx->doctype && strcmp(e->name, ctx->doctype))
xml_error(ctx, "The root element %s does not match the document type %s", e->name, ctx->doctype);
}
if (free)
{
if (!e->parent)
- ctx->root = NULL;
+ ctx->dom = NULL;
/* Restore hash table of attributes */
SLIST_FOR_EACH(struct xml_attr *, a, e->attrs)
xml_attrs_remove(ctx->tab_attrs, a);
xml_dtd_init(ctx);
if (ctx->h_dtd_start)
ctx->h_dtd_start(ctx);
- // FIXME: pu;; iface?
+ // FIXME: pull iface?
xml_parse_internal_subset(ctx);
// FIXME: external subset
if (ctx->h_dtd_end)
{
bputs(out, "PULL: eof\n");
if (want_dom)
- show_tree(ctx.root, 0);
+ show_tree(ctx.dom, 0);
}
xml_cleanup(&ctx);
#include "lib/mempool.h"
#include "lib/fastbuf.h"
+struct xml_context;
+struct xml_dtd_ent;
+
enum xml_error {
// FIXME
XML_ERR_OK = 0,
slist attrs; /* Link list of element attributes */
};
};
+ void *user; /* User-defined (initialized to NULL) */
};
struct xml_attr {
struct xml_node *elem; /* Parent element */
char *name; /* Attribute name */
char *val; /* Attribute value */
+ void *user; /* User-defined (initialized to NULL) */
};
struct xml_context {
void (*h_xml_decl)(struct xml_context *ctx); /* Called after the XML declaration */
void (*h_doctype_decl)(struct xml_context *ctx); /* Called in the doctype declaration (before optional internal subset) */
void (*h_comment)(struct xml_context *ctx); /* Called after a comment (only with XML_REPORT_COMMENTS) */
- void (*h_pi)(struct xml_context *ctx); /* Called after a processing instruction (only with XML_REPORT_PIS) */
+ void (*h_pi)(struct xml_context *ctx); /* Called after a processing instruction (only with XML_REPORT_PIS) */
void (*h_stag)(struct xml_context *ctx); /* Called after STag or EmptyElemTag (only with XML_REPORT_TAGS) */
void (*h_etag)(struct xml_context *ctx); /* Called before ETag or after EmptyElemTag (only with XML_REPORT_TAGS) */
void (*h_chars)(struct xml_context *ctx); /* Called after some characters (only with XML_REPORT_CHARS) */
void (*h_cdata)(struct xml_context *ctx); /* Called after a CDATA section (only with XML_REPORT_CHARS and XML_UNFOLD_CDATA) */
void (*h_dtd_start)(struct xml_context *ctx); /* Called just after the DTD structure is initialized */
void (*h_dtd_end)(struct xml_context *ctx); /* Called after DTD subsets subsets */
+ struct xml_dtd_ent *(*h_resolve_entity)(struct xml_context *ctx, char *name);
/* DOM */
- struct xml_node *root; /* DOM root */
+ struct xml_node *dom; /* DOM root */
struct xml_node *node; /* Current DOM node */
char *version_str;
void (*start_entity)(struct xml_context *ctx);
void (*end_entity)(struct xml_context *ctx);
- struct fastbuf *(*resolve_entity)(struct xml_context *ctx);
void (*notation_decl)(struct xml_context *ctx);
void (*unparsed_entity_decl)(struct xml_context *ctx);
};