on master help sign in
Redo node_alloc to return a suitable node
0f72a82Neil Mitchell
gen/test.c+29−21
@@ -211,19 +211,29 @@ node* hexml_node_child(const document* d, const node* parent, const node* prev,
211/////////////////////////////////////////////////////////////////////
211/////////////////////////////////////////////////////////////////////
212// PARSING CODE
212// PARSING CODE
213
213
214−static inline void node_alloc(node_buffer* b, int ask)
214+static inline node* node_alloc(node_buffer* b)
215{
215{
216+ // Invariant: node_commit requires at least one spare spot
216 int space = b->size - b->used_back - b->used_front;
217 int space = b->size - b->used_back - b->used_front;
217− if (space >= ask) return;
218+ if (space < 2)
219+ {
218− int size2 = (b->size + 1000 + ask) * 2;
220+ int size2 = (b->size + 1000) * 2;
219− node* buf2 = malloc(size2 * sizeof(node));
221+ node* buf2 = malloc(size2 * sizeof(node));
220− assert(buf2);
222+ assert(buf2);
221− memcpy(buf2, b->nodes, b->used_front * sizeof(node));
223+ memcpy(buf2, b->nodes, b->used_front * sizeof(node));
222− memcpy(&buf2[size2 - b->used_back], &b->nodes[b->size - b->used_back], b->used_back * sizeof(node));
224+ memcpy(&buf2[size2 - b->used_back], &b->nodes[b->size - b->used_back], b->used_back * sizeof(node));
223− free(b->alloc);
225+ free(b->alloc);
224− b->size = size2;
226+ b->size = size2;
225− b->nodes = buf2;
227+ b->nodes = buf2;
226− b->alloc = buf2;
228+ b->alloc = buf2;
229+ }
230+ b->used_back++;
231+ return &b->nodes[b->size - b->used_back - 1];
232+}
233+
234+static inline void node_commit(node_buffer* b)
235+{
236+
227}
237}
228
238
229static inline attr* attr_alloc(attr_buffer* b)
239static inline attr* attr_alloc(attr_buffer* b)
@@ -260,17 +270,15 @@ static inline str gap(const char* ref, const char* start, const char* end)
260
270
261#define P_Abort(x) return x
271#define P_Abort(x) return x
262#define P_Tag \
272#define P_Tag \
263− node_alloc(&d->nodes, 1); \
273+ node = node_alloc(&d->nodes); \
264− d->nodes.used_back++; \
265− me = &d->nodes.nodes[d->nodes.size - d->nodes.used_back]; \
266− me->outer = gap(d->body, p, p);
274+ node->outer = gap(d->body, p, p);
267#define P_NameStart name_start = p
275#define P_NameStart name_start = p
268#define P_NameEnd name_end = p
276#define P_NameEnd name_end = p
269#define P_AttribsStart \
277#define P_AttribsStart \
270− me->attrs.start = d->attrs.used; \
278+ node->attrs.start = d->attrs.used; \
271− me->name = gap(d->body, name_start, name_end);
279+ node->name = gap(d->body, name_start, name_end);
272#define P_AttribsEnd \
280#define P_AttribsEnd \
273− me->attrs = start_end(me->attrs.start, d->attrs.used);
281+ node->attrs = start_end(node->attrs.start, d->attrs.used);
274#define P_QuoteStart quote_start = p
282#define P_QuoteStart quote_start = p
275#define P_QuoteEnd \
283#define P_QuoteEnd \
276 quote_end = p; \
284 quote_end = p; \
@@ -281,8 +289,8 @@ static inline str gap(const char* ref, const char* start, const char* end)
281#define P_TagOpen printf("TagOpen %s\n", p)
289#define P_TagOpen printf("TagOpen %s\n", p)
282#define P_TagClose printf("TagClose %s\n", p)
290#define P_TagClose printf("TagClose %s\n", p)
283#define P_TagOpenClose \
291#define P_TagOpenClose \
284− me->nodes = start_end(0, 0); \
292+ node->nodes = start_end(0, 0); \
285− me->outer.length = gap(d->body, p, p).length;
293+ node->outer.length = gap(d->body, p, p).length;
286
294
287// Given the parsed string, return either NULL (success) or an error message (failure)
295// Given the parsed string, return either NULL (success) or an error message (failure)
288static const char* parser(const char* p, document* d)
296static const char* parser(const char* p, document* d)
@@ -290,7 +298,7 @@ static const char* parser(const char* p, document* d)
290 const char *name_start, *name_end; // Where a name is <[foo] or <foo [bar]=
298 const char *name_start, *name_end; // Where a name is <[foo] or <foo [bar]=
291 const char *quote_start, *quote_end; // Where an attribute quote is <foo bar='[123]'>
299 const char *quote_start, *quote_end; // Where an attribute quote is <foo bar='[123]'>
292 attr* attr; // The current attribute I'm working on
300 attr* attr; // The current attribute I'm working on
293− node* me; // The current node I'm working on
301+ node* node; // The current node I'm working on
294# include "test.h"
302# include "test.h"
295 return NULL;
303 return NULL;
296}
304}