]> mj.ucw.cz Git - libucw.git/blob - sherlock/xml/common.c
XML: The great reorganization... several improvements in the iface,
[libucw.git] / sherlock / xml / common.c
1 /*
2  *      Sherlock Library -- A simple XML parser
3  *
4  *      (c) 2007 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 #undef LOCAL_DEBUG
11
12 #include "sherlock/sherlock.h"
13 #include "sherlock/xml/xml.h"
14 #include "sherlock/xml/dtd.h"
15 #include "sherlock/xml/common.h"
16 #include "lib/stkstring.h"
17 #include "lib/ff-unicode.h"
18
19 #include <setjmp.h>
20
21 /*** Error handling ***/
22
23 void NONRET
24 xml_throw(struct xml_context *ctx)
25 {
26   ASSERT(ctx->err_code && ctx->throw_buf);
27   longjmp(*(jmp_buf *)ctx->throw_buf, ctx->err_code);
28 }
29
30 void
31 xml_warn(struct xml_context *ctx, const char *format, ...)
32 {
33   if (ctx->h_warn)
34     {
35       va_list args;
36       va_start(args, format);
37       ctx->err_msg = stk_vprintf(format, args);
38       ctx->err_code = XML_ERR_WARN;
39       va_end(args);
40       ctx->h_warn(ctx);
41       ctx->err_msg = NULL;
42       ctx->err_code = XML_ERR_OK;
43     }
44 }
45
46 void
47 xml_error(struct xml_context *ctx, const char *format, ...)
48 {
49   if (ctx->h_error)
50     {
51       va_list args;
52       va_start(args, format);
53       ctx->err_msg = stk_vprintf(format, args);
54       ctx->err_code = XML_ERR_ERROR;
55       va_end(args);
56       ctx->h_error(ctx);
57       ctx->err_msg = NULL;
58       ctx->err_code = XML_ERR_OK;
59     }
60 }
61
62 void NONRET
63 xml_fatal(struct xml_context *ctx, const char *format, ...)
64 {
65   va_list args;
66   va_start(args, format);
67   ctx->err_msg = mp_vprintf(ctx->stack, format, args);
68   ctx->err_code = XML_ERR_FATAL;
69   ctx->state = XML_STATE_EOF;
70   va_end(args);
71   if (ctx->h_fatal)
72     ctx->h_fatal(ctx);
73   xml_throw(ctx);
74 }
75
76 /*** Memory management ***/
77
78 void *
79 xml_hash_new(struct mempool *pool, uns size)
80 {
81   void *tab = mp_alloc_zero(pool, size + XML_HASH_HDR_SIZE);
82   *(void **)tab = pool;
83   return tab + XML_HASH_HDR_SIZE;
84 }
85
86 static void
87 xml_chars_spout(struct fastbuf *fb)
88 {
89   if (fb->bptr >= fb->bufend)
90     {
91       struct xml_context *ctx = SKIP_BACK(struct xml_context, chars, fb);
92       struct mempool *pool = ctx->pool;
93       if (fb->bufend != fb->buffer)
94         {
95           uns len = fb->bufend - fb->buffer;
96           TRACE(ctx, "grow_chars");
97           fb->buffer = mp_expand(pool);
98           fb->bufend = fb->buffer + mp_avail(pool);
99           fb->bstop = fb->buffer;
100           fb->bptr = fb->buffer + len;
101         }
102       else
103         {
104           TRACE(ctx, "push_chars");
105           struct xml_node *n = xml_push_dom(ctx);
106           n->type = XML_NODE_CHARS;
107           xml_start_chars(ctx);
108         }
109     }
110 }
111
112 static void
113 xml_init_chars(struct xml_context *ctx)
114 {
115   struct fastbuf *fb = &ctx->chars;
116   fb->name = "<xml-chars>";
117   fb->spout = xml_chars_spout;
118   fb->can_overwrite_buffer = 1;
119   fb->bptr = fb->bstop = fb->buffer = fb->bufend = NULL;
120 }
121
122 /*** Initialization ***/
123
124 static void
125 xml_do_init(struct xml_context *ctx)
126 {
127   ctx->flags = XML_REPORT_ALL;
128   xml_init_chars(ctx);
129   xml_attrs_table_init(ctx);
130 }
131
132 void
133 xml_init(struct xml_context *ctx)
134 {
135   bzero(ctx, sizeof(*ctx));
136   ctx->pool = mp_new(65536);
137   ctx->stack = mp_new(65536);
138   xml_do_init(ctx);
139   TRACE(ctx, "init");
140 }
141
142 void
143 xml_cleanup(struct xml_context *ctx)
144 {
145   TRACE(ctx, "cleanup");
146   xml_attrs_table_cleanup(ctx);
147   xml_dtd_cleanup(ctx);
148   xml_sources_cleanup(ctx);
149   mp_delete(ctx->pool);
150   mp_delete(ctx->stack);
151 }
152
153 void
154 xml_reset(struct xml_context *ctx)
155 {
156   TRACE(ctx, "reset");
157   struct mempool *pool = ctx->pool, *stack = ctx->stack;
158   xml_attrs_table_cleanup(ctx);
159   xml_dtd_cleanup(ctx);
160   xml_sources_cleanup(ctx);
161   mp_flush(pool);
162   mp_flush(stack);
163   bzero(ctx, sizeof(*ctx));
164   xml_do_init(ctx);
165 }