on master help sign in
Improve the parsing in various ways, clean up lots of details
commit78bf30bbfd3d21b8baa8ee13ddf2b250b6418e01 authorNeil Mitchell <ndmitchell@gmail.com> dateSun 27 Nov 2016, 21:43 (10 years ago) parent5f4ef78
1 file changed+53−17
hexml.c+53−17
hexml.c+53−17
@@ -139,6 +139,16 @@ void render_tag(render* r, node* n)
139139{
140140 render_char(r, '<');
141141 render_str(r, n->name);
142+ for (int i = 0; i < n->attrs.length; i++)
143+ {
144+ attr* x = &r->d->attrs.attrs[n->attrs.start + i];
145+ render_char(r, ' ');
146+ render_str(r, x->name);
147+ render_char(r, '=');
148+ render_char(r, '\"');
149+ render_str(r, x->value);
150+ render_char(r, '\"');
151+ }
142152 render_char(r, '>');
143153 render_content(r, n);
144154 render_char(r, '<');
@@ -270,7 +280,11 @@ void attr_alloc(attr_buffer* b, int ask)
270280{
271281 int space = b->size - b->used;
272282 if (space >= ask) return;
273− assert(0);
283+ int size2 = (b->size + 1000 + ask) * 2;
284+ attr* buf2 = malloc(size2 * sizeof(attr));
285+ memcpy(buf2, b->attrs, b->used * sizeof(attr));
286+ free(b->attrs);
287+ b->attrs = buf2;
274288}
275289
276290void lexeme(char* msg, document* d, str s)
@@ -302,18 +316,42 @@ str parse_attrval(document* d)
302316{
303317 trim(d);
304318 if (peek(d) != '=') return start_length(0,0);
319+ skip(d, 1);
305320 trim(d);
306− return parse_name(d);
321+ char c = peek(d);
322+ if (c == '\"' || c == '\'')
323+ {
324+ skip(d, 1);
325+ int start = d->cursor;
326+ if (!find(d, c))
327+ {
328+ d->error_message = _strdup("Couldn't find closing attribute bit");
329+ return start_length(0, 0);
330+ }
331+ skip(d, 1);
332+ return start_end(start, d->cursor - 1);
333+ }
334+ else
335+ return parse_name(d);
307336}
308337
309338
339+
310340// seen a tag name, now looking for attributes terminated by >
311341// puts the attributes it finds in the attribute buffer
312342str parse_attributes(document* d)
313343{
314344 str res;
315345 res.start = d->attrs.used;
316− // do attribute parsing here
346+ for (int i = 0; ; i++)
347+ {
348+ str name = parse_name(d);
349+ if (name.length == 0) break;
350+ attr_alloc(&d->attrs, 1);
351+ d->attrs.attrs[d->attrs.used].name = name;
352+ d->attrs.attrs[d->attrs.used].value = parse_attrval(d);
353+ d->attrs.used++;
354+ }
317355 res.length = d->attrs.used - res.start;
318356 return res;
319357}
@@ -328,22 +366,27 @@ void parse_tag(document* d)
328366 d->nodes.used_back++;
329367 int me = d->nodes.size - d->nodes.used_back;
330368
369+ d->nodes.nodes[me].outer.start = d->cursor;
331370 char c = get(d);
332371 assert(c == '<');
333−
334− d->nodes.nodes[me].outer.start = d->cursor;
372+ if (peek(d) == '?') skip(d, 1);
335373 d->nodes.nodes[me].name = parse_name(d);
336374 d->nodes.nodes[me].attrs = parse_attributes(d);
337375
338− c = peek(d);
339− if ((c == '/' || c == '?') && peekAt(d, 1) == '>')
376+ c = get(d);
377+ if ((c == '/' || c == '?') && peek(d) == '>')
340378 {
341− skip(d, 2);
379+ skip(d, 1);
342380 d->nodes.nodes[me].nodes = start_length(0, 0);
343381 d->nodes.nodes[me].outer.length = start_end(d->nodes.nodes[me].outer.start, d->cursor).length;
344382 d->nodes.nodes[me].inner = start_length(d->cursor, 0);
345383 return;
346384 }
385+ else if (c != '>')
386+ {
387+ d->error_message = _strdup("Gunk at the end of the tag");
388+ return;
389+ }
347390 d->nodes.nodes[me].inner.start = d->cursor;
348391 d->nodes.nodes[me].nodes = parse_content(d);
349392 d->nodes.nodes[me].inner.length = start_end(d->nodes.nodes[me].inner.start, d->cursor).length;
@@ -358,7 +401,8 @@ void parse_tag(document* d)
358401 trim(d);
359402 d->nodes.nodes[me].outer.length = start_end(d->nodes.nodes[me].outer.start, d->cursor).length;
360403 if (close.length == d->nodes.nodes[me].name.length &&
361− memcmp(&d->body[close.start], &d->body[d->nodes.nodes[me].name.start], close.length) == 0)
404+ memcmp(&d->body[close.start], &d->body[d->nodes.nodes[me].name.start], close.length) == 0 &&
405+ get(d) == '>');
362406 return;
363407 d->error_message = _strdup("Mismatch in closing tags");
364408 return;
@@ -423,14 +467,6 @@ document* document_parse(char* s, int slen)
423467 d->nodes.nodes[0].attrs = start_length(0, 0);
424468 d->nodes.nodes[0].nodes = parse_content(d);
425469
426− node* me = &d->nodes.nodes[0];
427−// printf("Got %i %i\n", me->nodes.start, me->nodes.length);
428− assert(me->nodes.start == 1 && me->nodes.length == 1);
429−
430− me = &d->nodes.nodes[1];
431−// printf("Got %i %i\n", me->nodes.start, me->nodes.length);
432− assert(me->nodes.length == 0);
433−
434470 if (d->cursor < d->length && d->error_message == NULL)
435471 {
436472 printf("%i vs %i\n", d->cursor, d->length);