@@ -93,8 +93,10 @@ static inline void bound_str(str s, int mn, int mx)
93static void render_str(render* r, str s)
93static void render_str(render* r, str s)
95 bound_str(s, 0, r->d->body_len);
95 bound_str(s, 0, r->d->body_len);
96 for (int i = 0; i < s.length; i++)
97 for (int i = 0; i < s.length; i++)
97 render_char(r, r->d->body[s.start + i]);
98 render_char(r, r->d->body[s.start + i]);
100static void render_tag(render* r, const node* n);
102static void render_tag(render* r, const node* n);
@@ -236,7 +238,6 @@ static inline void reverse(node* buffer, int from, int n)
237 int to = from + n - 1;
239 int to = from + n - 1;
238 for (int to = from + n - 1; to > from; from++, to--)
240 for (int to = from + n - 1; to > from; from++, to--)
241 node temp = buffer[to];
242 node temp = buffer[to];
242 buffer[to] = buffer[from];
243 buffer[to] = buffer[from];
@@ -257,8 +258,8 @@ static inline void memcpy_reverse(node* buffer, int from, int to, int n)
257// The ranges may overlap
258// The ranges may overlap
258static inline void memmove_reverse(node* buffer, int from, int to, int n)
259static inline void memmove_reverse(node* buffer, int from, int to, int n)
260− assert(from < to); // always the case in my usages
261+ assert(from >= to); // always the case in my usages
261− if (to - from >= n)
262+ if (to + n < from)
262 memcpy_reverse(buffer, from, to, n);
263 memcpy_reverse(buffer, from, to, n);
@@ -279,7 +280,7 @@ static inline str node_commit(node_buffer* b)
281 int n = open - (b->size - b->used_back);
282 int n = open - (b->size - b->used_back);
282− memmove_reverse(b->nodes, b->used_front, b->used_back, n);
283+ memmove_reverse(b->nodes, b->size - b->used_back - n + 1, b->used_front, n);
283 b->used_back -= n;
284 b->used_back -= n;
284 b->used_front += n;
285 b->used_front += n;
285 return start_length(b->used_front - n, n);
286 return start_length(b->used_front - n, n);
@@ -319,35 +320,43 @@ static inline str gap(const char* ref, const char* start, const char* end)
320#define P_Abort(x) return x
321#define P_Abort(x) return x
321#define P_Tag \
322#define P_Tag \
323+ printf("START: Tag %s\n", p); \
322− node = node_alloc(&d->nodes); \
324+ me = node_alloc(&d->nodes); \
323− node->outer = gap(d->body, p, p);
325+ me->outer = gap(d->body, p, p);
324#define P_NameStart name_start = p
326#define P_NameStart name_start = p
325#define P_NameEnd name_end = p
327#define P_NameEnd name_end = p
326#define P_AttribsStart \
328#define P_AttribsStart \
327− node->attrs.start = d->attrs.used; \
329+ me->attrs.start = d->attrs.used; \
328− node->name = gap(d->body, name_start, name_end);
330+ me->name = gap(d->body, name_start, name_end);
329#define P_AttribsEnd \
331#define P_AttribsEnd \
330− node->attrs = start_end(node->attrs.start, d->attrs.used);
332+ me->attrs = start_end(me->attrs.start, d->attrs.used);
331#define P_QuoteStart quote_start = p
333#define P_QuoteStart quote_start = p
332#define P_QuoteEnd \
334#define P_QuoteEnd \
333 quote_end = p; \
335 quote_end = p; \
334− attr = attr_alloc(&d->attrs); \
336+ attr* attr = attr_alloc(&d->attrs); \
335 attr->name = gap(d->body, name_start, name_end); \
337 attr->name = gap(d->body, name_start, name_end); \
336 attr->value = gap(d->body, quote_start, quote_end);
338 attr->value = gap(d->body, quote_start, quote_end);
337−#define P_TagComment printf("TagComment %s\n", p)
339+#define P_TagComment printf("MISSING: TagComment %s\n", p)
338−#define P_TagOpen printf("TagOpen - missed %s\n", p)
340+#define P_TagOpen \
341+ me->nodes.length = -1; \
342+ me->inner = gap(d->body, p, p);
339−#define P_TagClose printf("TagClose %s\n", p)
343+#define P_TagClose \
344+ str str = node_commit(&d->nodes); \
345+ me = &d->nodes.nodes[d->nodes.size - d->nodes.used_back]; \
347+ me->inner.length = gap(d->body, p, p).length; \
348+ me->outer.length = gap(d->body, p, p).length;
340#define P_TagOpenClose \
349#define P_TagOpenClose \
341− node->nodes = start_end(0, 0); \
350+ me->nodes = start_end(0, 0); \
351+ me->inner = gap(d->body, p, p); \
342− node->outer.length = gap(d->body, p, p).length;
352+ me->outer.length = gap(d->body, p, p).length;
344// Given the parsed string, return either NULL (success) or an error message (failure)
354// Given the parsed string, return either NULL (success) or an error message (failure)
345static const char* parser(const char* p, document* d)
355static const char* parser(const char* p, document* d)
347 const char *name_start, *name_end; // Where a name is <[foo] or <foo [bar]=
357 const char *name_start, *name_end; // Where a name is <[foo] or <foo [bar]=
348 const char *quote_start, *quote_end; // Where an attribute quote is <foo bar='[123]'>
358 const char *quote_start, *quote_end; // Where an attribute quote is <foo bar='[123]'>
349− attr* attr; // The current attribute I'm working on
350− node* node; // The current node I'm working on
359+ node* me; // The current node I'm working on
351# include "test.h"
360# include "test.h"
352 return NULL;
361 return NULL;
@@ -393,7 +402,11 @@ document* hexml_document_parse(const char* s, int slen)
393 if (res != NULL)
402 if (res != NULL)
394 d->error_message = strdup(res);
403 d->error_message = strdup(res);
396 d->nodes.nodes[0].nodes = node_commit(&d->nodes);
406 d->nodes.nodes[0].nodes = node_commit(&d->nodes);
407+ if (d->nodes.used_back != 0)
408+ d->error_message = strdup("used_back failure");
397 return d;
410 return d;
@@ -403,13 +416,18 @@ document* hexml_document_parse(const char* s, int slen)
403int main()
416int main()
405 setbuf(stdout, NULL);
418 setbuf(stdout, NULL);
406− const char* example = "<test foo = '123 xyz' bar = 't'><inner / > value< / test>";
419+ const char* example = "<test foo='123 xyz' bar='t'><inner /> value</test>";
407 document* d = hexml_document_parse(example, -1);
420 document* d = hexml_document_parse(example, -1);
421+ if (d->error_message != NULL)
422+ printf("Parse failure: %s\n", d->error_message);
408− char buf[1000];
425+ char buf[1000];
409− int len = hexml_node_render(d, hexml_document_node(d), buf, sizeof(buf));
426+ int len = hexml_node_render(d, hexml_document_node(d), buf, sizeof(buf));
410− buf[len] = 0;
427+ buf[len] = 0;
411− printf("Result = %s\n", buf);
428+ printf("Result = %s\n", buf);
412− printf("Used nodes = %i, attributes = %i\n", d->nodes.used_front, d->attrs.used);
429+ printf("Used nodes = %i, attributes = %i\n", d->nodes.used_front, d->attrs.used);
413 hexml_document_free(d);
431 hexml_document_free(d);
414 return 0;
432 return 0;