]> mj.ucw.cz Git - libucw.git/blob - ucw-xml/internals.h
Released as 6.5.16.
[libucw.git] / ucw-xml / internals.h
1 /*
2  *      UCW Library -- A simple XML parser
3  *
4  *      (c) 2007--2008 Pavel Charvat <pchar@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #ifndef _UCW_XML_INTERNALS_H
11 #define _UCW_XML_INTERNALS_H
12
13 #include <ucw-xml/xml.h>
14 #include <ucw-xml/dtd.h>
15
16 #ifdef CONFIG_UCW_CLEAN_ABI
17 #define xml_do_pop ucw_xml_do_pop
18 #define xml_do_push ucw_xml_do_push
19 #define xml_fatal_expected ucw_xml_fatal_expected
20 #define xml_fatal_expected_quot ucw_xml_fatal_expected_quot
21 #define xml_fatal_expected_white ucw_xml_fatal_expected_white
22 #define xml_fatal_nested ucw_xml_fatal_nested
23 #define xml_hash_new ucw_xml_hash_new
24 #define xml_ns_cleanup ucw_xml_ns_cleanup
25 #define xml_ns_pop_element ucw_xml_ns_pop_element
26 #define xml_ns_push_element ucw_xml_ns_push_element
27 #define xml_ns_reset ucw_xml_ns_reset
28 #define xml_parse_attr_list_decl ucw_xml_parse_attr_list_decl
29 #define xml_parse_attr_value ucw_xml_parse_attr_value
30 #define xml_parse_char_ref ucw_xml_parse_char_ref
31 #define xml_parse_element_decl ucw_xml_parse_element_decl
32 #define xml_parse_entity_decl ucw_xml_parse_entity_decl
33 #define xml_parse_eq ucw_xml_parse_eq
34 #define xml_parse_name ucw_xml_parse_name
35 #define xml_parse_nmtoken ucw_xml_parse_nmtoken
36 #define xml_parse_notation_decl ucw_xml_parse_notation_decl
37 #define xml_parse_pe_ref ucw_xml_parse_pe_ref
38 #define xml_parse_pubid_literal ucw_xml_parse_pubid_literal
39 #define xml_parse_system_literal ucw_xml_parse_system_literal
40 #define xml_parse_white ucw_xml_parse_white
41 #define xml_pop_comment ucw_xml_pop_comment
42 #define xml_pop_dom ucw_xml_pop_dom
43 #define xml_pop_pi ucw_xml_pop_pi
44 #define xml_push_comment ucw_xml_push_comment
45 #define xml_push_dom ucw_xml_push_dom
46 #define xml_push_entity ucw_xml_push_entity
47 #define xml_push_pi ucw_xml_push_pi
48 #define xml_push_source ucw_xml_push_source
49 #define xml_refill ucw_xml_refill
50 #define xml_skip_comment ucw_xml_skip_comment
51 #define xml_skip_internal_subset ucw_xml_skip_internal_subset
52 #define xml_skip_name ucw_xml_skip_name
53 #define xml_skip_pi ucw_xml_skip_pi
54 #define xml_sources_cleanup ucw_xml_sources_cleanup
55 #define xml_spout_chars ucw_xml_spout_chars
56 #define xml_throw ucw_xml_throw
57 #define xml_validate_attr ucw_xml_validate_attr
58 #endif
59
60 /*** Debugging ***/
61
62 #ifdef LOCAL_DEBUG
63 #define TRACE(c, f, p...) do { DBG("XML %u: " f, xml_row(c), ##p); } while(0)
64 #else
65 #define TRACE(c, f, p...) do {} while(0)
66 #endif
67
68 /*** Error handling ***/
69
70 void NONRET xml_throw(struct xml_context *ctx);
71
72 /*** Memory management ***/
73
74 struct xml_stack {
75   struct xml_stack *next;
76   struct mempool_state state;
77   uint flags;
78 };
79
80 void *xml_do_push(struct xml_context *ctx, uint size);
81 void xml_do_pop(struct xml_context *ctx, struct xml_stack *s);
82
83 static inline void xml_push(struct xml_context *ctx)
84 {
85   TRACE(ctx, "push");
86   xml_do_push(ctx, sizeof(struct xml_stack));
87 }
88
89 static inline void xml_pop(struct xml_context *ctx)
90 {
91   TRACE(ctx, "pop");
92   ASSERT(ctx->stack_list);
93   xml_do_pop(ctx, ctx->stack_list);
94 }
95
96 struct xml_dom_stack {
97   struct xml_stack stack;
98   struct mempool_state state;
99 };
100
101 struct xml_node *xml_push_dom(struct xml_context *ctx, struct mempool_state *state);
102 void xml_pop_dom(struct xml_context *ctx, uint free);
103
104 #define XML_HASH_HDR_SIZE ALIGN_TO(sizeof(void *), CPU_STRUCT_ALIGN)
105 #define XML_HASH_GIVE_ALLOC struct HASH_PREFIX(table); \
106   static inline void *HASH_PREFIX(alloc)(struct HASH_PREFIX(table) *t, uint size) \
107   { return mp_alloc(*(void **)((void *)t - XML_HASH_HDR_SIZE), size); } \
108   static inline void HASH_PREFIX(free)(struct HASH_PREFIX(table) *t UNUSED, void *p UNUSED) {}
109
110 void *xml_hash_new(struct mempool *pool, uint size);
111
112 void xml_spout_chars(struct fastbuf *fb);
113
114 /*** Reading of document/external entities ***/
115
116 void NONRET xml_fatal_nested(struct xml_context *ctx);
117
118 static inline void xml_inc(struct xml_context *ctx)
119 {
120   /* Called after the first character of a block */
121   TRACE(ctx, "inc");
122   ctx->depth++;
123 }
124
125 static inline void xml_dec(struct xml_context *ctx)
126 {
127   /* Called after the last character of a block */
128   TRACE(ctx, "dec");
129   if (unlikely(!ctx->depth--))
130     xml_fatal_nested(ctx);
131 }
132
133 #include "obj/ucw-xml/unicat.h"
134
135 static inline uint xml_char_cat(uint c)
136 {
137   if (c < 0x10000)
138     return 1U << ucw_xml_char_tab1[(c & 0xff) + ucw_xml_char_tab2[c >> 8]];
139   else if (likely(c < 0x110000))
140     return 1U << ucw_xml_char_tab3[c >> 16];
141   else
142     return 1;
143 }
144
145 static inline uint xml_ascii_cat(uint c)
146 {
147   return ucw_xml_char_tab1[c];
148 }
149
150 struct xml_source *xml_push_source(struct xml_context *ctx);
151 void xml_push_entity(struct xml_context *ctx, struct xml_dtd_entity *ent);
152
153 void xml_refill(struct xml_context *ctx);
154
155 static inline uint xml_peek_char(struct xml_context *ctx)
156 {
157   if (ctx->bptr == ctx->bstop)
158     xml_refill(ctx);
159   return ctx->bptr[0];
160 }
161
162 static inline uint xml_peek_cat(struct xml_context *ctx)
163 {
164   if (ctx->bptr == ctx->bstop)
165     xml_refill(ctx);
166   return ctx->bptr[1];
167 }
168
169 static inline uint xml_get_char(struct xml_context *ctx)
170 {
171   uint c = xml_peek_char(ctx);
172   ctx->bptr += 2;
173   return c;
174 }
175
176 static inline uint xml_get_cat(struct xml_context *ctx)
177 {
178   uint c = xml_peek_cat(ctx);
179   ctx->bptr += 2;
180   return c;
181 }
182
183 static inline uint xml_last_char(struct xml_context *ctx)
184 {
185   return ctx->bptr[-2];
186 }
187
188 static inline uint xml_last_cat(struct xml_context *ctx)
189 {
190   return ctx->bptr[-1];
191 }
192
193 static inline uint xml_skip_char(struct xml_context *ctx)
194 {
195   uint c = ctx->bptr[0];
196   ctx->bptr += 2;
197   return c;
198 }
199
200 static inline uint xml_unget_char(struct xml_context *ctx)
201 {
202   return *(ctx->bptr -= 2);
203 }
204
205 void xml_sources_cleanup(struct xml_context *ctx);
206
207 /*** Parsing ***/
208
209 void NONRET xml_fatal_expected(struct xml_context *ctx, uint c);
210 void NONRET xml_fatal_expected_white(struct xml_context *ctx);
211 void NONRET xml_fatal_expected_quot(struct xml_context *ctx);
212
213 uint xml_parse_white(struct xml_context *ctx, uint mandatory);
214
215 static inline void xml_parse_char(struct xml_context *ctx, uint c)
216 {
217   /* Consumes a given Unicode character */
218   if (unlikely(c != xml_get_char(ctx)))
219     xml_fatal_expected(ctx, c);
220 }
221
222 static inline void xml_parse_seq(struct xml_context *ctx, const char *seq)
223 {
224   /* Consumes a given sequence of ASCII characters */
225   while (*seq)
226     xml_parse_char(ctx, *seq++);
227 }
228
229 void xml_parse_eq(struct xml_context *ctx);
230
231 static inline uint xml_parse_quote(struct xml_context *ctx)
232 {
233   /* "'" | '"' */
234   uint c = xml_get_char(ctx);
235   if (unlikely(c != '\'' && c != '\"'))
236     xml_fatal_expected_quot(ctx);
237   return c;
238 }
239
240 char *xml_parse_name(struct xml_context *ctx, struct mempool *pool);
241 void xml_skip_name(struct xml_context *ctx);
242 char *xml_parse_nmtoken(struct xml_context *ctx, struct mempool *pool);
243
244 char *xml_parse_system_literal(struct xml_context *ctx, struct mempool *pool);
245 char *xml_parse_pubid_literal(struct xml_context *ctx, struct mempool *pool);
246
247 uint xml_parse_char_ref(struct xml_context *ctx);
248 void xml_parse_pe_ref(struct xml_context *ctx);
249
250 char *xml_parse_attr_value(struct xml_context *ctx, struct xml_dtd_attr *attr);
251
252 void xml_skip_internal_subset(struct xml_context *ctx);
253 void xml_parse_notation_decl(struct xml_context *ctx);
254 void xml_parse_entity_decl(struct xml_context *ctx);
255 void xml_parse_element_decl(struct xml_context *ctx);
256 void xml_parse_attr_list_decl(struct xml_context *ctx);
257
258 void xml_push_comment(struct xml_context *ctx);
259 void xml_pop_comment(struct xml_context *ctx);
260 void xml_skip_comment(struct xml_context *ctx);
261
262 void xml_push_pi(struct xml_context *ctx);
263 void xml_pop_pi(struct xml_context *ctx);
264 void xml_skip_pi(struct xml_context *ctx);
265
266 void xml_validate_attr(struct xml_context *ctx, struct xml_dtd_attr *dtd, char *value);
267
268 /*** Namespaces ***/
269
270 void xml_ns_cleanup(struct xml_context *ctx);
271 void xml_ns_reset(struct xml_context *ctx);
272 void xml_ns_push_element(struct xml_context *ctx);
273 void xml_ns_pop_element(struct xml_context *ctx);
274
275 #endif