on master help sign in
Switch to a parse table for looking up flags, very slight performance improvement
44005f1Neil Mitchell
hexml.c+35−13
@@ -225,6 +225,35 @@ node* node_nextChildBy(document* d, node* parent, node* prev, char* s, int slen)
225}
225}
226
226
227
227
228+/////////////////////////////////////////////////////////////////////
229+// PARSE TABLE
230+
231+const char tag_name1 = 0x1;
232+const char tag_name = 0x2;
233+const char tag_space = 0x4;
234+
235+char parse_table[256];
236+
237+void init_parse_table()
238+{
239+ static bool done = 0;
240+ if (done) return;
241+ for (int i = 0; i < 256; i++)
242+ {
243+ bool name1 = i == ':' || i == '_' || (i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z');
244+ bool name = name1 || i == '-' || (i >= '0' && i <= '9');
245+ bool space = i == ' ' || i == '\t' || i == '\r' || i == '\n';
246+ parse_table[i] = (name1 ? tag_name1 : 0) | (name ? tag_name : 0) | (space ? tag_space : 0);
247+ }
248+ done = 1;
249+}
250+
251+bool static inline is(char c, char tag) { return parse_table[c] & tag; }
252+bool static inline is_name1(char c) { return is(c, tag_name1); }
253+bool static inline is_name(char c) { return is(c, tag_name); }
254+bool static inline is_space(char c) { return is(c, tag_space); }
255+
256+
228/////////////////////////////////////////////////////////////////////
257/////////////////////////////////////////////////////////////////////
229// PARSER COMBINATORS
258// PARSER COMBINATORS
230
259
@@ -238,8 +267,6 @@ void static inline skip(document* d, int i){d->cursor += i;}
238char static inline peek(document* d){return peekAt(d, 0);}
267char static inline peek(document* d){return peekAt(d, 0);}
239char static inline get(document* d){char c = peek(d); skip(d, 1); return c;}
268char static inline get(document* d){char c = peek(d); skip(d, 1); return c;}
240
269
241−bool static inline is_space(char c){ return c == ' ' || c == '\t' || c == '\r' || c == '\n';}
242−
243// Remove whitespace characters from the cursor while they are still whitespace
270// Remove whitespace characters from the cursor while they are still whitespace
244void static inline trim(document* d)
271void static inline trim(document* d)
245{
272{
@@ -286,15 +313,6 @@ void attr_alloc(attr_buffer* b, int ask)
286 b->attrs = buf2;
313 b->attrs = buf2;
287}
314}
288
315
289−int static inline isName(char c)
290−{
291− return
292− (c >= 'a' && c <= 'z') ||
293− (c >= 'A' && c <= 'Z') ||
294− (c >= '0' && c <= '9') ||
295− c == '_' || c == '-';
296−}
297−
298// you now expect a name, perhaps preceeded by whitespace
316// you now expect a name, perhaps preceeded by whitespace
299// the name may be empty
317// the name may be empty
300str parse_name(document* d)
318str parse_name(document* d)
@@ -302,8 +320,11 @@ str parse_name(document* d)
302 trim(d);
320 trim(d);
303 str res;
321 str res;
304 res.start = d->cursor;
322 res.start = d->cursor;
323+ if (!is_name1(peek(d)))
324+ return start_length(d->cursor, 0);
325+ skip(d, 1);
305− while (isName(peek(d)))
326+ while (is_name(peek(d)))
306− get(d);
327+ skip(d, 1);
307 res.length = d->cursor - res.start;
328 res.length = d->cursor - res.start;
308 return res;
329 return res;
309}
330}
@@ -443,6 +464,7 @@ str parse_content(document* d)
443document* document_parse(char* s, int slen)
464document* document_parse(char* s, int slen)
444{
465{
445 if (slen == -1) slen = strlen(s);
466 if (slen == -1) slen = strlen(s);
467+ init_parse_table();
446
468
447 document* d = malloc(sizeof(document));
469 document* d = malloc(sizeof(document));
448 d->body = s;
470 d->body = s;