2 * Sherlock Library -- A simple XML parser
4 * (c) 2007--2008 Pavel Charvat <pchar@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
10 #ifndef _SHERLOCK_XML_INTERNALS_H
11 #define _SHERLOCK_XML_INTERNALS_H
19 #define TRACE(c, f, p...) do { DBG("XML %u: " f, xml_row(c), ##p); } while(0)
21 #define TRACE(c, f, p...) do {} while(0)
24 /*** Error handling ***/
26 void NONRET xml_throw(struct xml_context *ctx);
28 /*** Memory management ***/
31 struct xml_stack *next;
32 struct mempool_state state;
37 xml_do_push(struct xml_context *ctx, uns size)
39 /* Saves ctx->stack and ctx->flags state */
40 struct mempool_state state;
41 mp_save(ctx->stack, &state);
42 struct xml_stack *s = mp_alloc(ctx->stack, size);
44 s->flags = ctx->flags;
45 s->next = ctx->stack_list;
51 xml_do_pop(struct xml_context *ctx, struct xml_stack *s)
53 /* Restore ctx->stack and ctx->flags state */
54 ctx->stack_list = s->next;
55 ctx->flags = s->flags;
56 mp_restore(ctx->stack, &s->state);
60 xml_push(struct xml_context *ctx)
63 xml_do_push(ctx, sizeof(struct xml_stack));
67 xml_pop(struct xml_context *ctx)
70 ASSERT(ctx->stack_list);
71 xml_do_pop(ctx, ctx->stack_list);
74 struct xml_dom_stack {
75 struct xml_stack stack;
76 struct mempool_state state;
79 static inline struct xml_node *
80 xml_push_dom(struct xml_context *ctx, struct mempool_state *state)
82 /* Create a new DOM node */
83 TRACE(ctx, "push_dom");
84 struct xml_dom_stack *s = xml_do_push(ctx, sizeof(*s));
88 mp_save(ctx->pool, &s->state);
89 struct xml_node *n = mp_alloc(ctx->pool, sizeof(*n));
91 if (n->parent = ctx->node)
92 clist_add_tail(&n->parent->sons, &n->n);
97 xml_pop_dom(struct xml_context *ctx, uns free)
99 /* Leave DOM subtree */
100 TRACE(ctx, "pop_dom");
102 struct xml_node *p = ctx->node->parent;
103 struct xml_dom_stack *s = (void *)ctx->stack_list;
106 /* See xml_pop_element() for cleanup of attribute hash table */
108 clist_remove(&ctx->node->n);
109 mp_restore(ctx->pool, &s->state);
112 xml_do_pop(ctx, &s->stack);
115 #define XML_HASH_HDR_SIZE ALIGN_TO(sizeof(void *), CPU_STRUCT_ALIGN)
116 #define XML_HASH_GIVE_ALLOC struct HASH_PREFIX(table); \
117 static inline void *HASH_PREFIX(alloc)(struct HASH_PREFIX(table) *t, uns size) \
118 { return mp_alloc(*(void **)((void *)t - XML_HASH_HDR_SIZE), size); } \
119 static inline void HASH_PREFIX(free)(struct HASH_PREFIX(table) *t UNUSED, void *p UNUSED) {}
121 void *xml_hash_new(struct mempool *pool, uns size);
123 void xml_spout_chars(struct fastbuf *fb);
125 /*** Reading of document/external entities ***/
127 void NONRET xml_fatal_nested(struct xml_context *ctx);
130 xml_inc(struct xml_context *ctx)
132 /* Called after the first character of a block */
138 xml_dec(struct xml_context *ctx)
140 /* Called after the last character of a block */
142 if (unlikely(!ctx->depth--))
143 xml_fatal_nested(ctx);
146 #include "obj/xml/unicat.h"
152 return 1U << xml_char_tab1[(c & 0xff) + xml_char_tab2[c >> 8]];
153 else if (likely(c < 0x110000))
154 return 1U << xml_char_tab3[c >> 16];
162 return xml_char_tab1[c];
165 struct xml_source *xml_push_source(struct xml_context *ctx);
166 void xml_push_entity(struct xml_context *ctx, struct xml_dtd_entity *ent);
168 void xml_refill(struct xml_context *ctx);
171 xml_peek_char(struct xml_context *ctx)
173 if (ctx->bptr == ctx->bstop)
179 xml_peek_cat(struct xml_context *ctx)
181 if (ctx->bptr == ctx->bstop)
187 xml_get_char(struct xml_context *ctx)
189 uns c = xml_peek_char(ctx);
195 xml_get_cat(struct xml_context *ctx)
197 uns c = xml_peek_cat(ctx);
203 xml_last_char(struct xml_context *ctx)
205 return ctx->bptr[-2];
209 xml_last_cat(struct xml_context *ctx)
211 return ctx->bptr[-1];
215 xml_skip_char(struct xml_context *ctx)
217 uns c = ctx->bptr[0];
223 xml_unget_char(struct xml_context *ctx)
225 return *(ctx->bptr -= 2);
228 void xml_sources_cleanup(struct xml_context *ctx);
232 void NONRET xml_fatal_expected(struct xml_context *ctx, uns c);
233 void NONRET xml_fatal_expected_white(struct xml_context *ctx);
234 void NONRET xml_fatal_expected_quot(struct xml_context *ctx);
237 xml_parse_white(struct xml_context *ctx, uns mandatory)
239 /* mandatory=1 -> S ::= (#x20 | #x9 | #xD | #xA)+
240 * mandatory=0 -> S? */
242 while (xml_peek_cat(ctx) & XML_CHAR_WHITE)
247 if (unlikely(mandatory && !cnt))
248 xml_fatal_expected_white(ctx);
253 xml_parse_char(struct xml_context *ctx, uns c)
255 /* Consumes a given Unicode character */
256 if (unlikely(c != xml_get_char(ctx)))
257 xml_fatal_expected(ctx, c);
261 xml_parse_seq(struct xml_context *ctx, const char *seq)
263 /* Consumes a given sequence of ASCII characters */
265 xml_parse_char(ctx, *seq++);
268 void xml_parse_eq(struct xml_context *ctx);
271 xml_parse_quote(struct xml_context *ctx)
274 uns c = xml_get_char(ctx);
275 if (unlikely(c != '\'' && c != '\"'))
276 xml_fatal_expected_quot(ctx);
280 char *xml_parse_name(struct xml_context *ctx, struct mempool *pool);
281 void xml_skip_name(struct xml_context *ctx);
282 char *xml_parse_nmtoken(struct xml_context *ctx, struct mempool *pool);
284 char *xml_parse_system_literal(struct xml_context *ctx, struct mempool *pool);
285 char *xml_parse_pubid_literal(struct xml_context *ctx, struct mempool *pool);
287 uns xml_parse_char_ref(struct xml_context *ctx);
288 void xml_parse_pe_ref(struct xml_context *ctx);
290 char *xml_parse_attr_value(struct xml_context *ctx, struct xml_dtd_attr *attr);
292 void xml_skip_internal_subset(struct xml_context *ctx);
293 void xml_parse_notation_decl(struct xml_context *ctx);
294 void xml_parse_entity_decl(struct xml_context *ctx);
295 void xml_parse_element_decl(struct xml_context *ctx);
296 void xml_parse_attr_list_decl(struct xml_context *ctx);
298 void xml_push_comment(struct xml_context *ctx);
299 void xml_pop_comment(struct xml_context *ctx);
300 void xml_skip_comment(struct xml_context *ctx);
302 void xml_push_pi(struct xml_context *ctx);
303 void xml_pop_pi(struct xml_context *ctx);
304 void xml_skip_pi(struct xml_context *ctx);
306 void xml_attrs_table_init(struct xml_context *ctx);
307 void xml_attrs_table_cleanup(struct xml_context *ctx);
309 void xml_validate_attr(struct xml_context *ctx, struct xml_dtd_attr *dtd, char *value);