@@ -225,6 +225,35 @@ node* node_nextChildBy(document* d, node* parent, node* prev, char* s, int slen)
225225}
226226
227227
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+
228257/////////////////////////////////////////////////////////////////////
229258// PARSER COMBINATORS
230259
@@ -238,8 +267,6 @@ void static inline skip(document* d, int i){d->cursor += i;}
238267char static inline peek(document* d){return peekAt(d, 0);}
239268char static inline get(document* d){char c = peek(d); skip(d, 1); return c;}
240269
241−bool static inline is_space(char c){ return c == ' ' || c == '\t' || c == '\r' || c == '\n';}
242−
243270// Remove whitespace characters from the cursor while they are still whitespace
244271void static inline trim(document* d)
245272{
@@ -286,15 +313,6 @@ void attr_alloc(attr_buffer* b, int ask)
286313 b->attrs = buf2;
287314}
288315
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−
298316// you now expect a name, perhaps preceeded by whitespace
299317// the name may be empty
300318str parse_name(document* d)
@@ -302,8 +320,11 @@ str parse_name(document* d)
302320 trim(d);
303321 str res;
304322 res.start = d->cursor;
305− while (isName(peek(d)))
306− get(d);
323+ if (!is_name1(peek(d)))
324+ return start_length(d->cursor, 0);
325+ skip(d, 1);
326+ while (is_name(peek(d)))
327+ skip(d, 1);
307328 res.length = d->cursor - res.start;
308329 return res;
309330}
@@ -443,6 +464,7 @@ str parse_content(document* d)
443464document* document_parse(char* s, int slen)
444465{
445466 if (slen == -1) slen = strlen(s);
467+ init_parse_table();
446468
447469 document* d = malloc(sizeof(document));
448470 d->body = s;