@@ -139,6 +139,16 @@ void render_tag(render* r, node* n)
140 render_char(r, '<');
140 render_char(r, '<');
141 render_str(r, n->name);
141 render_str(r, n->name);
142+ for (int i = 0; i < n->attrs.length; i++)
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, '\"');
142 render_char(r, '>');
152 render_char(r, '>');
143 render_content(r, n);
153 render_content(r, n);
144 render_char(r, '<');
154 render_char(r, '<');
@@ -270,7 +280,11 @@ void attr_alloc(attr_buffer* b, int ask)
271 int space = b->size - b->used;
281 int space = b->size - b->used;
272 if (space >= ask) return;
282 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));
276void lexeme(char* msg, document* d, str s)
290void lexeme(char* msg, document* d, str s)
@@ -302,18 +316,42 @@ str parse_attrval(document* d)
304 if (peek(d) != '=') return start_length(0,0);
318 if (peek(d) != '=') return start_length(0,0);
322+ if (c == '\"' || c == '\'')
325+ int start = d->cursor;
328+ d->error_message = _strdup("Couldn't find closing attribute bit");
329+ return start_length(0, 0);
332+ return start_end(start, d->cursor - 1);
306− return parse_name(d);
335+ return parse_name(d);
310// seen a tag name, now looking for attributes terminated by >
340// seen a tag name, now looking for attributes terminated by >
311// puts the attributes it finds in the attribute buffer
341// puts the attributes it finds in the attribute buffer
312str parse_attributes(document* d)
342str parse_attributes(document* d)
315 res.start = d->attrs.used;
345 res.start = d->attrs.used;
316− // do attribute parsing here
346+ for (int i = 0; ; i++)
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);
317 res.length = d->attrs.used - res.start;
355 res.length = d->attrs.used - res.start;
318 return res;
356 return res;
@@ -328,22 +366,27 @@ void parse_tag(document* d)
328 d->nodes.used_back++;
366 d->nodes.used_back++;
329 int me = d->nodes.size - d->nodes.used_back;
367 int me = d->nodes.size - d->nodes.used_back;
369+ d->nodes.nodes[me].outer.start = d->cursor;
331 char c = get(d);
370 char c = get(d);
332 assert(c == '<');
371 assert(c == '<');
333−
372+ if (peek(d) == '?') skip(d, 1);
334− d->nodes.nodes[me].outer.start = d->cursor;
335 d->nodes.nodes[me].name = parse_name(d);
373 d->nodes.nodes[me].name = parse_name(d);
336 d->nodes.nodes[me].attrs = parse_attributes(d);
374 d->nodes.nodes[me].attrs = parse_attributes(d);
338− c = peek(d);
376+ c = get(d);
339− if ((c == '/' || c == '?') && peekAt(d, 1) == '>')
377+ if ((c == '/' || c == '?') && peek(d) == '>')
341− skip(d, 2);
379+ skip(d, 1);
342 d->nodes.nodes[me].nodes = start_length(0, 0);
380 d->nodes.nodes[me].nodes = start_length(0, 0);
343 d->nodes.nodes[me].outer.length = start_end(d->nodes.nodes[me].outer.start, d->cursor).length;
381 d->nodes.nodes[me].outer.length = start_end(d->nodes.nodes[me].outer.start, d->cursor).length;
344 d->nodes.nodes[me].inner = start_length(d->cursor, 0);
382 d->nodes.nodes[me].inner = start_length(d->cursor, 0);
387+ d->error_message = _strdup("Gunk at the end of the tag");
347 d->nodes.nodes[me].inner.start = d->cursor;
390 d->nodes.nodes[me].inner.start = d->cursor;
348 d->nodes.nodes[me].nodes = parse_content(d);
391 d->nodes.nodes[me].nodes = parse_content(d);
349 d->nodes.nodes[me].inner.length = start_end(d->nodes.nodes[me].inner.start, d->cursor).length;
392 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)
359 d->nodes.nodes[me].outer.length = start_end(d->nodes.nodes[me].outer.start, d->cursor).length;
402 d->nodes.nodes[me].outer.length = start_end(d->nodes.nodes[me].outer.start, d->cursor).length;
360 if (close.length == d->nodes.nodes[me].name.length &&
403 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 &&
363 d->error_message = _strdup("Mismatch in closing tags");
407 d->error_message = _strdup("Mismatch in closing tags");
@@ -423,14 +467,6 @@ document* document_parse(char* s, int slen)
423 d->nodes.nodes[0].attrs = start_length(0, 0);
467 d->nodes.nodes[0].attrs = start_length(0, 0);
424 d->nodes.nodes[0].nodes = parse_content(d);
468 d->nodes.nodes[0].nodes = parse_content(d);
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);
430− me = &d->nodes.nodes[1];
431−// printf("Got %i %i\n", me->nodes.start, me->nodes.length);
432− assert(me->nodes.length == 0);
434 if (d->cursor < d->length && d->error_message == NULL)
470 if (d->cursor < d->length && d->error_message == NULL)
436 printf("%i vs %i\n", d->cursor, d->length);
472 printf("%i vs %i\n", d->cursor, d->length);