on master help sign in
Fix a lot of off-by-one errors in node
b26ca41Neil Mitchell
gen/test.c+11−10
@@ -229,7 +229,7 @@ static inline node* node_alloc(node_buffer* b)
229 b->alloc = buf2;
229 b->alloc = buf2;
230 }
230 }
231 b->used_back++;
231 b->used_back++;
232− return &b->nodes[b->size - b->used_back - 1];
232+ return &b->nodes[b->size - b->used_back];
233}
233}
234
234
235// buffer[from .. from+n] = reverse (buffer[from .. from+n])
235// buffer[from .. from+n] = reverse (buffer[from .. from+n])
@@ -321,41 +321,42 @@ static inline str gap(const char* ref, const char* start, const char* end)
321#define P_Abort(x) return x
321#define P_Abort(x) return x
322#define P_Tag \
322#define P_Tag \
323 printf("START: Tag %s\n", p); \
323 printf("START: Tag %s\n", p); \
324− me = node_alloc(&d->nodes); \
324+ tag_start = p;
325− me->outer = gap(d->body, p, p);
326#define P_NameStart name_start = p
325#define P_NameStart name_start = p
327#define P_NameEnd name_end = p
326#define P_NameEnd name_end = p
328#define P_AttribsStart \
327#define P_AttribsStart \
328+ me = node_alloc(&d->nodes); \
329 me->attrs.start = d->attrs.used; \
329 me->attrs.start = d->attrs.used; \
330 me->name = gap(d->body, name_start, name_end);
330 me->name = gap(d->body, name_start, name_end);
331#define P_AttribsEnd \
331#define P_AttribsEnd \
332 me->attrs = start_end(me->attrs.start, d->attrs.used);
332 me->attrs = start_end(me->attrs.start, d->attrs.used);
333#define P_QuoteStart quote_start = p
333#define P_QuoteStart quote_start = p
334#define P_QuoteEnd \
334#define P_QuoteEnd \
335− quote_end = p; \
336 attr* attr = attr_alloc(&d->attrs); \
335 attr* attr = attr_alloc(&d->attrs); \
337 attr->name = gap(d->body, name_start, name_end); \
336 attr->name = gap(d->body, name_start, name_end); \
338− attr->value = gap(d->body, quote_start, quote_end);
337+ attr->value = gap(d->body, quote_start, p);
339#define P_TagComment printf("MISSING: TagComment %s\n", p)
338#define P_TagComment printf("MISSING: TagComment %s\n", p)
340#define P_TagOpen \
339#define P_TagOpen \
341 me->nodes.length = -1; \
340 me->nodes.length = -1; \
342− me->inner = gap(d->body, p, p);
341+ me->inner = gap(d->body, p, p); \
342+ me->outer = gap(d->body, tag_start, tag_start);
343#define P_TagClose \
343#define P_TagClose \
344 str str = node_commit(&d->nodes); \
344 str str = node_commit(&d->nodes); \
345 me = &d->nodes.nodes[d->nodes.size - d->nodes.used_back]; \
345 me = &d->nodes.nodes[d->nodes.size - d->nodes.used_back]; \
346 me->nodes = str; \
346 me->nodes = str; \
347− me->inner.length = gap(d->body, p, p).length; \
347+ me->inner = gap(d->body, &d->body[me->inner.start], tag_start); \
348− me->outer.length = gap(d->body, p, p).length;
348+ me->outer = gap(d->body, &d->body[me->outer.start], p);
349#define P_TagOpenClose \
349#define P_TagOpenClose \
350 me->nodes = start_end(0, 0); \
350 me->nodes = start_end(0, 0); \
351 me->inner = gap(d->body, p, p); \
351 me->inner = gap(d->body, p, p); \
352− me->outer.length = gap(d->body, p, p).length;
352+ me->outer = gap(d->body, tag_start, p);
353
353
354// 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)
355static const char* parser(const char* p, document* d)
355static const char* parser(const char* p, document* d)
356{
356{
357+ const char *tag_start; // Where the tag starts [<foo
357 const char *name_start, *name_end; // Where a name is <[foo] or <foo [bar]=
358 const char *name_start, *name_end; // Where a name is <[foo] or <foo [bar]=
358− const char *quote_start, *quote_end; // Where an attribute quote is <foo bar='[123]'>
359+ const char *quote_start; // Where an attribute quote is <foo bar='[123'>
359 node* me; // The current node I'm working on
360 node* me; // The current node I'm working on
360# include "test.h"
361# include "test.h"
361 return NULL;
362 return NULL;