mongrel_esi 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. data/COPYING +53 -0
  2. data/LICENSE +471 -0
  3. data/README +186 -0
  4. data/Rakefile +141 -0
  5. data/bin/mongrel_esi +271 -0
  6. data/ext/esi/common.rl +41 -0
  7. data/ext/esi/esi_parser.c +387 -0
  8. data/ext/esi/extconf.rb +6 -0
  9. data/ext/esi/machine.rb +499 -0
  10. data/ext/esi/parser.c +1675 -0
  11. data/ext/esi/parser.h +113 -0
  12. data/ext/esi/parser.rb +49 -0
  13. data/ext/esi/parser.rl +398 -0
  14. data/ext/esi/ruby_esi.rl +135 -0
  15. data/ext/esi/run-test.rb +3 -0
  16. data/ext/esi/test/common.rl +41 -0
  17. data/ext/esi/test/parser.c +1676 -0
  18. data/ext/esi/test/parser.h +113 -0
  19. data/ext/esi/test/parser.rl +398 -0
  20. data/ext/esi/test/test.c +373 -0
  21. data/ext/esi/test1.rb +56 -0
  22. data/ext/esi/test2.rb +45 -0
  23. data/lib/esi/cache.rb +207 -0
  24. data/lib/esi/config.rb +154 -0
  25. data/lib/esi/dispatcher.rb +27 -0
  26. data/lib/esi/handler.rb +236 -0
  27. data/lib/esi/invalidator.rb +40 -0
  28. data/lib/esi/logger.rb +46 -0
  29. data/lib/esi/router.rb +84 -0
  30. data/lib/esi/tag/attempt.rb +6 -0
  31. data/lib/esi/tag/base.rb +85 -0
  32. data/lib/esi/tag/except.rb +24 -0
  33. data/lib/esi/tag/include.rb +190 -0
  34. data/lib/esi/tag/invalidate.rb +54 -0
  35. data/lib/esi/tag/try.rb +40 -0
  36. data/lib/multi_dirhandler.rb +70 -0
  37. data/setup.rb +1585 -0
  38. data/test/integration/basic_test.rb +39 -0
  39. data/test/integration/cache_test.rb +37 -0
  40. data/test/integration/docs/content/500.html +16 -0
  41. data/test/integration/docs/content/500_with_failover.html +16 -0
  42. data/test/integration/docs/content/500_with_failover_to_alt.html +8 -0
  43. data/test/integration/docs/content/ajax_test_page.html +15 -0
  44. data/test/integration/docs/content/cookie_variable.html +3 -0
  45. data/test/integration/docs/content/foo.html +15 -0
  46. data/test/integration/docs/content/include_in_include.html +15 -0
  47. data/test/integration/docs/content/malformed_transforms.html +16 -0
  48. data/test/integration/docs/content/malformed_transforms.html-correct +11 -0
  49. data/test/integration/docs/content/static-failover.html +20 -0
  50. data/test/integration/docs/content/test2.html +1 -0
  51. data/test/integration/docs/content/test3.html +17 -0
  52. data/test/integration/docs/esi_invalidate.html +6 -0
  53. data/test/integration/docs/esi_mixed_content.html +15 -0
  54. data/test/integration/docs/esi_test_content.html +27 -0
  55. data/test/integration/docs/index.html +688 -0
  56. data/test/integration/docs/test1.html +1 -0
  57. data/test/integration/docs/test3.html +9 -0
  58. data/test/integration/docs/test_failover.html +1 -0
  59. data/test/integration/handler_test.rb +270 -0
  60. data/test/integration/help.rb +234 -0
  61. data/test/net/get_test.rb +197 -0
  62. data/test/net/net_helper.rb +16 -0
  63. data/test/net/server_test.rb +249 -0
  64. data/test/unit/base_tag_test.rb +44 -0
  65. data/test/unit/esi-sample.html +56 -0
  66. data/test/unit/help.rb +77 -0
  67. data/test/unit/include_request_test.rb +69 -0
  68. data/test/unit/include_tag_test.rb +14 -0
  69. data/test/unit/parser_test.rb +478 -0
  70. data/test/unit/router_test.rb +34 -0
  71. data/test/unit/sample.html +21 -0
  72. data/tools/rakehelp.rb +119 -0
  73. metadata +182 -0
@@ -0,0 +1,135 @@
1
+ module ESI
2
+ class ParserMachine
3
+
4
+ %%{
5
+ machine esi;
6
+
7
+ action begin {
8
+ @mark = p
9
+ }
10
+ action finish {
11
+ }
12
+
13
+ # record the position of the start tag
14
+ action see_start_tag {
15
+ @tag_text = data[@mark,p-@mark]
16
+ @tag_info = {} # store the tag attributes
17
+ @tag_info[:name] = @tag_text.sub('<','').strip
18
+ @tag_info[:attributes] = {}
19
+ # puts "have esi tag at #{p}=>#{@mark}:#{data[p,1].inspect} with data #{@tag_text.inspect}"
20
+ @mark = p
21
+ }
22
+
23
+ action see_end_tag {
24
+ # puts "parsed esi tag at #{p}=>#{@mark}:#{data[p,1].inspect} with data #{@tag_text.inspect}"
25
+ @start_tag.call @tag_info[:name], @tag_info[:attributes] if @start_tag
26
+ @end_tag.call @tag_info[:name] if @end_tag
27
+ @attr_key = nil
28
+ @attr_value = nil
29
+ @tag_text = nil
30
+ @tag_info = nil
31
+ }
32
+
33
+ action see_block_start_with_attributes {
34
+ # puts "parsed esi tag at #{p}=>#{@mark}:#{data[p,1].inspect} with data #{@tag_text.inspect}"
35
+ @start_tag.call @tag_info[:name], @tag_info[:attributes] if @start_tag
36
+ @attr_key = nil
37
+ @attr_value = nil
38
+ @tag_text = nil
39
+ @tag_info = nil
40
+ }
41
+
42
+ action see_attribute_key {
43
+ @attr_key = data[@mark,p-@mark]
44
+ @mark += (@attr_key.size)
45
+ @attr_key.gsub!(/^['"]/,'')
46
+ @attr_key.strip!
47
+ # puts "SeeAttributeKey: #{data[@mark,1].inspect}: #{data[p,1].inspect} #{@attr_key.inspect}"
48
+ }
49
+
50
+ action see_attribute_value {
51
+ @attr_value = data[@mark,p-@mark]
52
+ @attr_value.strip!
53
+ @attr_value.gsub!(/^=?\s*['"]/,'')
54
+ @attr_value.gsub!(/['"]$/,'')
55
+
56
+ @tag_info[:attributes][@attr_key] = @attr_value
57
+ # puts "SeeAttributeValue: #{p} #{data[@mark,1].inspect}: #{data[p,1].inspect} #{@attr_key.inspect} => #{@attr_value.inspect}"
58
+ @mark = p
59
+ }
60
+
61
+ action block_start_tag {
62
+ tag_text = data[@mark+1,p-@mark-1]
63
+ @start_tag.call tag_text, {} if @start_tag
64
+ # puts "Block start: #{p} #{tag_text}"
65
+ }
66
+
67
+ action block_end_tag {
68
+ tag_text = data[@mark+2,p-@mark-2]
69
+ @end_tag.call tag_text if @end_tag
70
+ # puts "Block end: #{p} #{tag_text}"
71
+ }
72
+
73
+ action echo {
74
+ # print " [#{data[p,1].inspect}:#{cs}] " if $debug
75
+
76
+ case cs
77
+ when 0
78
+ # NOTE: state 12 is the character state before <esi:try>, state 7 is the character before </esi:try>
79
+ # | |
80
+ # - state 12 - state 7
81
+ # state 60 is for empty inline tags e.g.
82
+ # <esi:include/>
83
+ # |
84
+ # - 60
85
+
86
+ if @prev_state != 12 and @prev_state != 7
87
+ if !@prev_buffer.empty? and (@prev_state != (esi_en_main + 1)) and @prev_state != 60
88
+ stream_buffer @prev_buffer
89
+ end
90
+ stream_buffer data[p,1]
91
+ end
92
+ @prev_buffer = ""
93
+ else
94
+ @prev_buffer << data[p,1]
95
+ end
96
+ @prev_state = cs
97
+ }
98
+
99
+ include esi_common_parser "common.rl";
100
+ }%%
101
+
102
+ def initialize
103
+ %% write data;
104
+ end
105
+
106
+ # process a block of esi tags
107
+ def process(data)
108
+ if @data
109
+ # puts "append : #{@mark} : #{p}"
110
+ data = @data + data
111
+ p = @data.length
112
+ end
113
+ @mark ||= 0
114
+ p ||= 0
115
+ pe ||= data.length
116
+ @cs ||= esi_start
117
+ cs = @cs
118
+ # puts "process: #{cs.inspect} :start #{data.inspect}, #{p}"
119
+ %% write exec;
120
+ @cs = cs
121
+ if( @cs != esi_start && @cs != 0 )
122
+ # puts "append process: #{@cs.inspect}"
123
+ @data = data
124
+ else
125
+ @data = nil
126
+ end
127
+ end
128
+
129
+ def finish
130
+ %% write eof;
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ exec valgrind --leak-check=full --suppressions=valgrind-ruby.supp ruby test2.rb
@@ -0,0 +1,41 @@
1
+ %%{
2
+ machine esi_common_parser;
3
+
4
+ # inline tags e.g. <esi:comment text='some useless text'/> or <esi:include src='/foo/'/>, etc...
5
+ esi_inline_tag = (
6
+ start: (
7
+ '<esi:' [a-z]+ space @see_start_tag -> start_attribute |
8
+ '<esi:' [a-z]+ space* '/>' >see_start_tag %see_end_tag -> final
9
+ ),
10
+ start_attribute: (
11
+ space* [a-zA-Z_\-]+ [a-zA-Z_\-0-9]* '=' @see_attribute_key -> end_attribute |
12
+ space* '/>' @see_end_tag -> final
13
+ ),
14
+ end_attribute: (
15
+ space* ['"][!{}#-&(-/:-@a-zA-Z0-9+_\-]+['"] @see_attribute_value -> start_attribute
16
+ )
17
+ ) >begin %finish;
18
+
19
+ # block tags e.g. <esi:try> <esi:attempt>, etc..
20
+ esi_block_tag = (
21
+ start: (
22
+ '<esi:' [a-z]+ '>' @block_start_tag -> start |
23
+ '<esi:' [a-z]+ space @see_start_tag -> start_attribute |
24
+ '</esi:' [a-z]+ '>' @block_end_tag
25
+ ),
26
+ start_attribute: (
27
+ space* [a-zA-Z_\-]+ [a-zA-Z_\-0-9]* '=' @see_attribute_key -> end_attribute | '>' @see_block_start_with_attributes -> final
28
+ ),
29
+ end_attribute: (
30
+ space* ['"][!{}#-&(-/:-@a-zA-Z0-9+_\-]+['"] @see_attribute_value -> start_attribute
31
+ )
32
+ ) >begin %finish;
33
+
34
+ echo_state = (
35
+ start: (
36
+ /./ @echo
37
+ )
38
+ );
39
+
40
+ main := ((/.*/)? @echo (esi_inline_tag|esi_block_tag) )*;
41
+ }%%
@@ -0,0 +1,1676 @@
1
+ #line 1 "parser.rl"
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+ #include <string.h>
5
+ #include <ctype.h>
6
+ #include <unistd.h>
7
+ #include "parser.h"
8
+
9
+ /* define default callbacks */
10
+ static void
11
+ esi_parser_default_start_cb( const void *data,
12
+ const char *name_start,
13
+ size_t name_length,
14
+ ESIAttribute *attributes,
15
+ void *user_data )
16
+ {
17
+ }
18
+ static void
19
+ esi_parser_default_end_cb( const void *data,
20
+ const char *name_start,
21
+ size_t name_length,
22
+ void *user_data )
23
+ {
24
+ }
25
+ static void
26
+ esi_parser_default_output_cp(const void *data,
27
+ size_t length,
28
+ void *user_data)
29
+ {
30
+ }
31
+ #ifdef DEBUG
32
+ static void debug_string( const char *msg, const char *str, size_t len )
33
+ {
34
+ char *pstr = esi_strndup( str, len );
35
+ printf( "%s :'%s'\n", msg, pstr );
36
+ free( pstr );
37
+ }
38
+ #endif
39
+
40
+ static void esi_parser_echo_char( ESIParser *parser, char ch )
41
+ {
42
+ parser->output_handler( (void*)&ch, 1, parser->user_data );
43
+ }
44
+
45
+ static void esi_parser_echo_buffer( ESIParser *parser )
46
+ {
47
+ // debug_string( "echobuffer", parser->echobuffer, parser->echobuffer_index+1 );
48
+ parser->output_handler( parser->echobuffer, parser->echobuffer_index+1, parser->user_data );
49
+ }
50
+
51
+ static void esi_parser_echobuffer_clear( ESIParser *parser )
52
+ {
53
+ parser->echobuffer_index = -1;
54
+ }
55
+
56
+ static void esi_parser_concat_to_echobuffer( ESIParser *parser, char ch )
57
+ {
58
+ parser->echobuffer_index++;
59
+
60
+ if( parser->echobuffer_allocated <= parser->echobuffer_index ){
61
+ // double the echobuffer size
62
+ parser->echobuffer_allocated *= 2;
63
+ parser->echobuffer = (char*)realloc( parser->echobuffer, parser->echobuffer_allocated );
64
+ }
65
+ parser->echobuffer[parser->echobuffer_index] = ch;
66
+ // debug_string( "echo buffer", parser->echobuffer, parser->echobuffer_index+1 );
67
+ }
68
+
69
+ static void ltrim_pointer( const char **ptr, const char *bounds, size_t *len )
70
+ {
71
+ // remove any spaces or = at the before the value
72
+ while( isspace( **ptr ) ||
73
+ **ptr == '=' ||
74
+ **ptr == '"' ||
75
+ **ptr == '<' ||
76
+ **ptr == '\'' &&
77
+ *len > 0 &&
78
+ (*ptr != bounds) ){
79
+ (*ptr)++;
80
+ (*len)--;
81
+ }
82
+ }
83
+
84
+ #line 199 "parser.rl"
85
+
86
+
87
+
88
+ #line 89 "parser.c"
89
+ static const int esi_start = 56;
90
+ static const int esi_first_final = 56;
91
+ static const int esi_error = -1;
92
+
93
+ static const int esi_en_main = 56;
94
+
95
+ #line 202 "parser.rl"
96
+
97
+ char *esi_strndup( const char *str, size_t len )
98
+ {
99
+ char *s = (char*)malloc(sizeof(char)*(len+1));
100
+ memcpy( s, str, len );
101
+ s[len] = '\0';
102
+ return s;
103
+ }
104
+
105
+ ESIAttribute *esi_attribute_new( const char *name, size_t name_length, const char *value, size_t value_length )
106
+ {
107
+ ESIAttribute *attr = (ESIAttribute*)malloc(sizeof(ESIAttribute));
108
+ attr->name = esi_strndup(name, name_length);
109
+ attr->value = esi_strndup(value, value_length);
110
+ attr->next = NULL;
111
+ return attr;
112
+ }
113
+
114
+ ESIAttribute *esi_attribute_copy( ESIAttribute *attribute )
115
+ {
116
+ ESIAttribute *head, *nattr;
117
+ if( !attribute ){ return NULL; }
118
+
119
+ // copy the first attribute
120
+ nattr = esi_attribute_new( attribute->name, strlen( attribute->name ),
121
+ attribute->value, strlen( attribute->value ) );
122
+ // save a pointer for return
123
+ head = nattr;
124
+ // copy next attributes
125
+ attribute = attribute->next;
126
+ while( attribute ) {
127
+ // set the next attribute
128
+ nattr->next = esi_attribute_new( attribute->name, strlen( attribute->name ),
129
+ attribute->value, strlen( attribute->value ) );
130
+ // next attribute
131
+ nattr = nattr->next;
132
+ attribute = attribute->next;
133
+ }
134
+ return head;
135
+ }
136
+
137
+ void esi_attribute_free( ESIAttribute *attribute )
138
+ {
139
+ ESIAttribute *ptr;
140
+ while( attribute ){
141
+ free( attribute->name );
142
+ free( attribute->value );
143
+ ptr = attribute->next;
144
+ free( attribute );
145
+ attribute = ptr;
146
+ }
147
+ }
148
+
149
+ ESIParser *esi_parser_new()
150
+ {
151
+ ESIParser *parser = (ESIParser*)malloc(sizeof(ESIParser));
152
+ parser->cs = esi_start;
153
+ parser->mark = NULL;
154
+ parser->overflow_data_size = 0;
155
+ parser->overflow_data = NULL;
156
+
157
+ /* allocate 1024 bytes for the echobuffer */
158
+ parser->echobuffer_allocated = 1024;
159
+ parser->echobuffer_index = -1;
160
+ parser->echobuffer = (char*)malloc(sizeof(char)*parser->echobuffer_allocated);
161
+
162
+ parser->attributes = NULL;
163
+ parser->last = NULL;
164
+
165
+ parser->start_tag_handler = esi_parser_default_start_cb;
166
+ parser->end_tag_handler = esi_parser_default_end_cb;
167
+ parser->output_handler = esi_parser_default_output_cp;
168
+
169
+ return parser;
170
+ }
171
+ void esi_parser_free( ESIParser *parser )
172
+ {
173
+ if( parser->overflow_data ){ free( parser->overflow_data ); }
174
+
175
+ free( parser->echobuffer );
176
+ esi_attribute_free( parser->attributes );
177
+
178
+ free( parser );
179
+ }
180
+
181
+ void esi_parser_output_handler( ESIParser *parser, output_cb output_handler )
182
+ {
183
+ parser->output_handler = output_handler;
184
+ }
185
+
186
+ int esi_parser_init( ESIParser *parser )
187
+ {
188
+ int cs;
189
+
190
+ #line 191 "parser.c"
191
+ {
192
+ cs = esi_start;
193
+ }
194
+ #line 296 "parser.rl"
195
+ parser->prev_state = parser->cs = cs;
196
+ return 0;
197
+ }
198
+
199
+ static int compute_offset( const char *mark, const char *data )
200
+ {
201
+ if( mark ){
202
+ return mark - data;
203
+ }
204
+ return -1;
205
+ }
206
+
207
+ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
208
+ {
209
+ int cs = parser->cs;
210
+ const char *p = data;
211
+ const char *pe = data + length;
212
+
213
+ if( length == 0 ){ return cs; }
214
+
215
+ if( parser->overflow_data && parser->overflow_data_size > 0 ){
216
+
217
+ // recompute mark, tag_text, attr_key, and attr_value since they all exist within overflow_data
218
+ int mark_offset = compute_offset( parser->mark, parser->overflow_data );
219
+ int tag_text_offset = compute_offset( parser->tag_text, parser->overflow_data );
220
+ int attr_key_offset = compute_offset( parser->attr_key, parser->overflow_data );
221
+ int attr_value_offset = compute_offset( parser->attr_value, parser->overflow_data );
222
+
223
+ // debug_string("grow overflow buffer", parser->overflow_data, parser->overflow_data_size );
224
+
225
+ parser->overflow_data = (char*)realloc( parser->overflow_data, sizeof(char)*(parser->overflow_data_size+length) );
226
+ memcpy( parser->overflow_data+parser->overflow_data_size, data, length );
227
+
228
+ p = parser->overflow_data + parser->overflow_data_size;
229
+
230
+ // in our new memory space mark will now be
231
+ parser->mark = ( mark_offset >= 0 ) ? parser->overflow_data + mark_offset : NULL;
232
+ parser->tag_text = ( tag_text_offset >= 0 ) ? parser->overflow_data + tag_text_offset : NULL;
233
+ parser->attr_key = ( attr_key_offset >= 0 ) ? parser->overflow_data + attr_key_offset : NULL;
234
+ parser->attr_value = ( attr_value_offset >= 0 ) ? parser->overflow_data + attr_value_offset : NULL;
235
+
236
+ data = parser->overflow_data;
237
+ parser->overflow_data_size = length = length + parser->overflow_data_size;
238
+ pe = data + length;
239
+
240
+ // debug_string( "overflow", parser->overflow_data, parser->overflow_data_size );
241
+ }
242
+
243
+ if( !parser->mark ){
244
+ parser->mark = p;
245
+ }
246
+
247
+ // printf( "cs: %d, ", cs );
248
+ // debug_string( "data", data, length );
249
+
250
+
251
+ #line 252 "parser.c"
252
+ {
253
+ if ( p == pe )
254
+ goto _out;
255
+ _resume:
256
+ switch ( cs ) {
257
+ case 56:
258
+ if ( (*p) == 60 )
259
+ goto tr1;
260
+ goto tr0;
261
+ case 0:
262
+ if ( (*p) == 60 )
263
+ goto tr1;
264
+ goto tr0;
265
+ case 1:
266
+ switch( (*p) ) {
267
+ case 47: goto tr2;
268
+ case 60: goto tr1;
269
+ case 101: goto tr3;
270
+ }
271
+ goto tr0;
272
+ case 2:
273
+ switch( (*p) ) {
274
+ case 60: goto tr1;
275
+ case 101: goto tr4;
276
+ }
277
+ goto tr0;
278
+ case 3:
279
+ switch( (*p) ) {
280
+ case 60: goto tr1;
281
+ case 115: goto tr5;
282
+ }
283
+ goto tr0;
284
+ case 4:
285
+ switch( (*p) ) {
286
+ case 60: goto tr1;
287
+ case 105: goto tr6;
288
+ }
289
+ goto tr0;
290
+ case 5:
291
+ switch( (*p) ) {
292
+ case 58: goto tr7;
293
+ case 60: goto tr1;
294
+ }
295
+ goto tr0;
296
+ case 6:
297
+ if ( (*p) == 60 )
298
+ goto tr1;
299
+ if ( 97 <= (*p) && (*p) <= 122 )
300
+ goto tr8;
301
+ goto tr0;
302
+ case 7:
303
+ switch( (*p) ) {
304
+ case 60: goto tr1;
305
+ case 62: goto tr9;
306
+ }
307
+ if ( 97 <= (*p) && (*p) <= 122 )
308
+ goto tr8;
309
+ goto tr0;
310
+ case 8:
311
+ switch( (*p) ) {
312
+ case 60: goto tr1;
313
+ case 115: goto tr10;
314
+ }
315
+ goto tr0;
316
+ case 9:
317
+ switch( (*p) ) {
318
+ case 60: goto tr1;
319
+ case 105: goto tr11;
320
+ }
321
+ goto tr0;
322
+ case 10:
323
+ switch( (*p) ) {
324
+ case 58: goto tr12;
325
+ case 60: goto tr1;
326
+ }
327
+ goto tr0;
328
+ case 11:
329
+ if ( (*p) == 60 )
330
+ goto tr1;
331
+ if ( 97 <= (*p) && (*p) <= 122 )
332
+ goto tr13;
333
+ goto tr0;
334
+ case 12:
335
+ switch( (*p) ) {
336
+ case 32: goto tr14;
337
+ case 47: goto tr15;
338
+ case 60: goto tr1;
339
+ case 62: goto tr16;
340
+ }
341
+ if ( (*p) > 13 ) {
342
+ if ( 97 <= (*p) && (*p) <= 122 )
343
+ goto tr13;
344
+ } else if ( (*p) >= 9 )
345
+ goto tr14;
346
+ goto tr0;
347
+ case 13:
348
+ switch( (*p) ) {
349
+ case 32: goto tr17;
350
+ case 45: goto tr18;
351
+ case 47: goto tr19;
352
+ case 60: goto tr1;
353
+ case 62: goto tr20;
354
+ case 95: goto tr18;
355
+ }
356
+ if ( (*p) < 65 ) {
357
+ if ( 9 <= (*p) && (*p) <= 13 )
358
+ goto tr17;
359
+ } else if ( (*p) > 90 ) {
360
+ if ( 97 <= (*p) && (*p) <= 122 )
361
+ goto tr18;
362
+ } else
363
+ goto tr18;
364
+ goto tr0;
365
+ case 14:
366
+ switch( (*p) ) {
367
+ case 32: goto tr17;
368
+ case 45: goto tr18;
369
+ case 47: goto tr19;
370
+ case 60: goto tr1;
371
+ case 95: goto tr18;
372
+ }
373
+ if ( (*p) < 65 ) {
374
+ if ( 9 <= (*p) && (*p) <= 13 )
375
+ goto tr17;
376
+ } else if ( (*p) > 90 ) {
377
+ if ( 97 <= (*p) && (*p) <= 122 )
378
+ goto tr18;
379
+ } else
380
+ goto tr18;
381
+ goto tr0;
382
+ case 15:
383
+ switch( (*p) ) {
384
+ case 45: goto tr18;
385
+ case 60: goto tr1;
386
+ case 61: goto tr21;
387
+ case 95: goto tr18;
388
+ }
389
+ if ( (*p) < 65 ) {
390
+ if ( 48 <= (*p) && (*p) <= 57 )
391
+ goto tr18;
392
+ } else if ( (*p) > 90 ) {
393
+ if ( 97 <= (*p) && (*p) <= 122 )
394
+ goto tr18;
395
+ } else
396
+ goto tr18;
397
+ goto tr0;
398
+ case 16:
399
+ switch( (*p) ) {
400
+ case 32: goto tr22;
401
+ case 34: goto tr23;
402
+ case 39: goto tr23;
403
+ case 60: goto tr1;
404
+ }
405
+ if ( 9 <= (*p) && (*p) <= 13 )
406
+ goto tr22;
407
+ goto tr0;
408
+ case 17:
409
+ switch( (*p) ) {
410
+ case 33: goto tr24;
411
+ case 60: goto tr25;
412
+ case 95: goto tr24;
413
+ case 125: goto tr24;
414
+ }
415
+ if ( (*p) < 40 ) {
416
+ if ( 35 <= (*p) && (*p) <= 38 )
417
+ goto tr24;
418
+ } else if ( (*p) > 90 ) {
419
+ if ( 97 <= (*p) && (*p) <= 123 )
420
+ goto tr24;
421
+ } else
422
+ goto tr24;
423
+ goto tr0;
424
+ case 18:
425
+ switch( (*p) ) {
426
+ case 34: goto tr26;
427
+ case 39: goto tr26;
428
+ case 60: goto tr25;
429
+ case 95: goto tr24;
430
+ case 125: goto tr24;
431
+ }
432
+ if ( (*p) > 90 ) {
433
+ if ( 97 <= (*p) && (*p) <= 123 )
434
+ goto tr24;
435
+ } else if ( (*p) >= 33 )
436
+ goto tr24;
437
+ goto tr0;
438
+ case 19:
439
+ switch( (*p) ) {
440
+ case 32: goto tr27;
441
+ case 45: goto tr18;
442
+ case 47: goto tr28;
443
+ case 60: goto tr1;
444
+ case 62: goto tr20;
445
+ case 95: goto tr18;
446
+ }
447
+ if ( (*p) < 65 ) {
448
+ if ( 9 <= (*p) && (*p) <= 13 )
449
+ goto tr27;
450
+ } else if ( (*p) > 90 ) {
451
+ if ( 97 <= (*p) && (*p) <= 122 )
452
+ goto tr18;
453
+ } else
454
+ goto tr18;
455
+ goto tr0;
456
+ case 20:
457
+ switch( (*p) ) {
458
+ case 32: goto tr27;
459
+ case 45: goto tr18;
460
+ case 47: goto tr28;
461
+ case 60: goto tr1;
462
+ case 95: goto tr18;
463
+ }
464
+ if ( (*p) < 65 ) {
465
+ if ( 9 <= (*p) && (*p) <= 13 )
466
+ goto tr27;
467
+ } else if ( (*p) > 90 ) {
468
+ if ( 97 <= (*p) && (*p) <= 122 )
469
+ goto tr18;
470
+ } else
471
+ goto tr18;
472
+ goto tr0;
473
+ case 21:
474
+ switch( (*p) ) {
475
+ case 60: goto tr1;
476
+ case 62: goto tr29;
477
+ }
478
+ goto tr0;
479
+ case 57:
480
+ if ( (*p) == 60 )
481
+ goto tr71;
482
+ goto tr70;
483
+ case 22:
484
+ switch( (*p) ) {
485
+ case 34: goto tr26;
486
+ case 39: goto tr26;
487
+ case 47: goto tr30;
488
+ case 60: goto tr25;
489
+ case 95: goto tr24;
490
+ case 101: goto tr31;
491
+ case 125: goto tr24;
492
+ }
493
+ if ( (*p) > 90 ) {
494
+ if ( 97 <= (*p) && (*p) <= 123 )
495
+ goto tr24;
496
+ } else if ( (*p) >= 33 )
497
+ goto tr24;
498
+ goto tr0;
499
+ case 23:
500
+ switch( (*p) ) {
501
+ case 34: goto tr26;
502
+ case 39: goto tr26;
503
+ case 60: goto tr25;
504
+ case 95: goto tr24;
505
+ case 101: goto tr32;
506
+ case 125: goto tr24;
507
+ }
508
+ if ( (*p) > 90 ) {
509
+ if ( 97 <= (*p) && (*p) <= 123 )
510
+ goto tr24;
511
+ } else if ( (*p) >= 33 )
512
+ goto tr24;
513
+ goto tr0;
514
+ case 24:
515
+ switch( (*p) ) {
516
+ case 34: goto tr26;
517
+ case 39: goto tr26;
518
+ case 60: goto tr25;
519
+ case 95: goto tr24;
520
+ case 115: goto tr33;
521
+ case 125: goto tr24;
522
+ }
523
+ if ( (*p) > 90 ) {
524
+ if ( 97 <= (*p) && (*p) <= 123 )
525
+ goto tr24;
526
+ } else if ( (*p) >= 33 )
527
+ goto tr24;
528
+ goto tr0;
529
+ case 25:
530
+ switch( (*p) ) {
531
+ case 34: goto tr26;
532
+ case 39: goto tr26;
533
+ case 60: goto tr25;
534
+ case 95: goto tr24;
535
+ case 105: goto tr34;
536
+ case 125: goto tr24;
537
+ }
538
+ if ( (*p) > 90 ) {
539
+ if ( 97 <= (*p) && (*p) <= 123 )
540
+ goto tr24;
541
+ } else if ( (*p) >= 33 )
542
+ goto tr24;
543
+ goto tr0;
544
+ case 26:
545
+ switch( (*p) ) {
546
+ case 34: goto tr26;
547
+ case 39: goto tr26;
548
+ case 58: goto tr35;
549
+ case 60: goto tr25;
550
+ case 95: goto tr24;
551
+ case 125: goto tr24;
552
+ }
553
+ if ( (*p) > 90 ) {
554
+ if ( 97 <= (*p) && (*p) <= 123 )
555
+ goto tr24;
556
+ } else if ( (*p) >= 33 )
557
+ goto tr24;
558
+ goto tr0;
559
+ case 27:
560
+ switch( (*p) ) {
561
+ case 34: goto tr26;
562
+ case 39: goto tr26;
563
+ case 60: goto tr25;
564
+ case 95: goto tr24;
565
+ case 123: goto tr24;
566
+ case 125: goto tr24;
567
+ }
568
+ if ( (*p) > 90 ) {
569
+ if ( 97 <= (*p) && (*p) <= 122 )
570
+ goto tr36;
571
+ } else if ( (*p) >= 33 )
572
+ goto tr24;
573
+ goto tr0;
574
+ case 28:
575
+ switch( (*p) ) {
576
+ case 34: goto tr26;
577
+ case 39: goto tr26;
578
+ case 60: goto tr25;
579
+ case 62: goto tr37;
580
+ case 95: goto tr24;
581
+ case 123: goto tr24;
582
+ case 125: goto tr24;
583
+ }
584
+ if ( (*p) > 90 ) {
585
+ if ( 97 <= (*p) && (*p) <= 122 )
586
+ goto tr36;
587
+ } else if ( (*p) >= 33 )
588
+ goto tr24;
589
+ goto tr0;
590
+ case 29:
591
+ switch( (*p) ) {
592
+ case 34: goto tr26;
593
+ case 39: goto tr26;
594
+ case 60: goto tr25;
595
+ case 95: goto tr24;
596
+ case 115: goto tr38;
597
+ case 125: goto tr24;
598
+ }
599
+ if ( (*p) > 90 ) {
600
+ if ( 97 <= (*p) && (*p) <= 123 )
601
+ goto tr24;
602
+ } else if ( (*p) >= 33 )
603
+ goto tr24;
604
+ goto tr0;
605
+ case 30:
606
+ switch( (*p) ) {
607
+ case 34: goto tr26;
608
+ case 39: goto tr26;
609
+ case 60: goto tr25;
610
+ case 95: goto tr24;
611
+ case 105: goto tr39;
612
+ case 125: goto tr24;
613
+ }
614
+ if ( (*p) > 90 ) {
615
+ if ( 97 <= (*p) && (*p) <= 123 )
616
+ goto tr24;
617
+ } else if ( (*p) >= 33 )
618
+ goto tr24;
619
+ goto tr0;
620
+ case 31:
621
+ switch( (*p) ) {
622
+ case 34: goto tr26;
623
+ case 39: goto tr26;
624
+ case 58: goto tr40;
625
+ case 60: goto tr25;
626
+ case 95: goto tr24;
627
+ case 125: goto tr24;
628
+ }
629
+ if ( (*p) > 90 ) {
630
+ if ( 97 <= (*p) && (*p) <= 123 )
631
+ goto tr24;
632
+ } else if ( (*p) >= 33 )
633
+ goto tr24;
634
+ goto tr0;
635
+ case 32:
636
+ switch( (*p) ) {
637
+ case 34: goto tr26;
638
+ case 39: goto tr26;
639
+ case 60: goto tr25;
640
+ case 95: goto tr24;
641
+ case 123: goto tr24;
642
+ case 125: goto tr24;
643
+ }
644
+ if ( (*p) > 90 ) {
645
+ if ( 97 <= (*p) && (*p) <= 122 )
646
+ goto tr41;
647
+ } else if ( (*p) >= 33 )
648
+ goto tr24;
649
+ goto tr0;
650
+ case 33:
651
+ switch( (*p) ) {
652
+ case 32: goto tr14;
653
+ case 34: goto tr26;
654
+ case 39: goto tr26;
655
+ case 47: goto tr42;
656
+ case 60: goto tr25;
657
+ case 62: goto tr43;
658
+ case 95: goto tr24;
659
+ case 123: goto tr24;
660
+ case 125: goto tr24;
661
+ }
662
+ if ( (*p) < 33 ) {
663
+ if ( 9 <= (*p) && (*p) <= 13 )
664
+ goto tr14;
665
+ } else if ( (*p) > 90 ) {
666
+ if ( 97 <= (*p) && (*p) <= 122 )
667
+ goto tr41;
668
+ } else
669
+ goto tr24;
670
+ goto tr0;
671
+ case 34:
672
+ switch( (*p) ) {
673
+ case 34: goto tr26;
674
+ case 39: goto tr26;
675
+ case 60: goto tr25;
676
+ case 62: goto tr44;
677
+ case 95: goto tr24;
678
+ case 125: goto tr24;
679
+ }
680
+ if ( (*p) > 90 ) {
681
+ if ( 97 <= (*p) && (*p) <= 123 )
682
+ goto tr24;
683
+ } else if ( (*p) >= 33 )
684
+ goto tr24;
685
+ goto tr0;
686
+ case 58:
687
+ switch( (*p) ) {
688
+ case 34: goto tr74;
689
+ case 39: goto tr74;
690
+ case 60: goto tr75;
691
+ case 95: goto tr73;
692
+ case 125: goto tr73;
693
+ }
694
+ if ( (*p) > 90 ) {
695
+ if ( 97 <= (*p) && (*p) <= 123 )
696
+ goto tr73;
697
+ } else if ( (*p) >= 33 )
698
+ goto tr73;
699
+ goto tr72;
700
+ case 35:
701
+ switch( (*p) ) {
702
+ case 34: goto tr46;
703
+ case 39: goto tr46;
704
+ case 60: goto tr47;
705
+ case 95: goto tr45;
706
+ case 125: goto tr45;
707
+ }
708
+ if ( (*p) > 90 ) {
709
+ if ( 97 <= (*p) && (*p) <= 123 )
710
+ goto tr45;
711
+ } else if ( (*p) >= 33 )
712
+ goto tr45;
713
+ goto tr0;
714
+ case 36:
715
+ switch( (*p) ) {
716
+ case 32: goto tr48;
717
+ case 45: goto tr49;
718
+ case 47: goto tr28;
719
+ case 60: goto tr1;
720
+ case 62: goto tr20;
721
+ case 95: goto tr49;
722
+ }
723
+ if ( (*p) < 65 ) {
724
+ if ( 9 <= (*p) && (*p) <= 13 )
725
+ goto tr48;
726
+ } else if ( (*p) > 90 ) {
727
+ if ( 97 <= (*p) && (*p) <= 122 )
728
+ goto tr49;
729
+ } else
730
+ goto tr49;
731
+ goto tr0;
732
+ case 37:
733
+ switch( (*p) ) {
734
+ case 32: goto tr48;
735
+ case 45: goto tr49;
736
+ case 47: goto tr28;
737
+ case 60: goto tr1;
738
+ case 95: goto tr49;
739
+ }
740
+ if ( (*p) < 65 ) {
741
+ if ( 9 <= (*p) && (*p) <= 13 )
742
+ goto tr48;
743
+ } else if ( (*p) > 90 ) {
744
+ if ( 97 <= (*p) && (*p) <= 122 )
745
+ goto tr49;
746
+ } else
747
+ goto tr49;
748
+ goto tr0;
749
+ case 38:
750
+ switch( (*p) ) {
751
+ case 45: goto tr49;
752
+ case 60: goto tr1;
753
+ case 61: goto tr50;
754
+ case 95: goto tr49;
755
+ }
756
+ if ( (*p) < 65 ) {
757
+ if ( 48 <= (*p) && (*p) <= 57 )
758
+ goto tr49;
759
+ } else if ( (*p) > 90 ) {
760
+ if ( 97 <= (*p) && (*p) <= 122 )
761
+ goto tr49;
762
+ } else
763
+ goto tr49;
764
+ goto tr0;
765
+ case 39:
766
+ switch( (*p) ) {
767
+ case 32: goto tr51;
768
+ case 34: goto tr52;
769
+ case 39: goto tr52;
770
+ case 60: goto tr1;
771
+ }
772
+ if ( 9 <= (*p) && (*p) <= 13 )
773
+ goto tr51;
774
+ goto tr0;
775
+ case 40:
776
+ switch( (*p) ) {
777
+ case 33: goto tr45;
778
+ case 60: goto tr47;
779
+ case 95: goto tr45;
780
+ case 125: goto tr45;
781
+ }
782
+ if ( (*p) < 40 ) {
783
+ if ( 35 <= (*p) && (*p) <= 38 )
784
+ goto tr45;
785
+ } else if ( (*p) > 90 ) {
786
+ if ( 97 <= (*p) && (*p) <= 123 )
787
+ goto tr45;
788
+ } else
789
+ goto tr45;
790
+ goto tr0;
791
+ case 41:
792
+ switch( (*p) ) {
793
+ case 34: goto tr46;
794
+ case 39: goto tr46;
795
+ case 47: goto tr53;
796
+ case 60: goto tr47;
797
+ case 95: goto tr45;
798
+ case 101: goto tr54;
799
+ case 125: goto tr45;
800
+ }
801
+ if ( (*p) > 90 ) {
802
+ if ( 97 <= (*p) && (*p) <= 123 )
803
+ goto tr45;
804
+ } else if ( (*p) >= 33 )
805
+ goto tr45;
806
+ goto tr0;
807
+ case 42:
808
+ switch( (*p) ) {
809
+ case 34: goto tr46;
810
+ case 39: goto tr46;
811
+ case 60: goto tr47;
812
+ case 95: goto tr45;
813
+ case 101: goto tr55;
814
+ case 125: goto tr45;
815
+ }
816
+ if ( (*p) > 90 ) {
817
+ if ( 97 <= (*p) && (*p) <= 123 )
818
+ goto tr45;
819
+ } else if ( (*p) >= 33 )
820
+ goto tr45;
821
+ goto tr0;
822
+ case 43:
823
+ switch( (*p) ) {
824
+ case 34: goto tr46;
825
+ case 39: goto tr46;
826
+ case 60: goto tr47;
827
+ case 95: goto tr45;
828
+ case 115: goto tr56;
829
+ case 125: goto tr45;
830
+ }
831
+ if ( (*p) > 90 ) {
832
+ if ( 97 <= (*p) && (*p) <= 123 )
833
+ goto tr45;
834
+ } else if ( (*p) >= 33 )
835
+ goto tr45;
836
+ goto tr0;
837
+ case 44:
838
+ switch( (*p) ) {
839
+ case 34: goto tr46;
840
+ case 39: goto tr46;
841
+ case 60: goto tr47;
842
+ case 95: goto tr45;
843
+ case 105: goto tr57;
844
+ case 125: goto tr45;
845
+ }
846
+ if ( (*p) > 90 ) {
847
+ if ( 97 <= (*p) && (*p) <= 123 )
848
+ goto tr45;
849
+ } else if ( (*p) >= 33 )
850
+ goto tr45;
851
+ goto tr0;
852
+ case 45:
853
+ switch( (*p) ) {
854
+ case 34: goto tr46;
855
+ case 39: goto tr46;
856
+ case 58: goto tr58;
857
+ case 60: goto tr47;
858
+ case 95: goto tr45;
859
+ case 125: goto tr45;
860
+ }
861
+ if ( (*p) > 90 ) {
862
+ if ( 97 <= (*p) && (*p) <= 123 )
863
+ goto tr45;
864
+ } else if ( (*p) >= 33 )
865
+ goto tr45;
866
+ goto tr0;
867
+ case 46:
868
+ switch( (*p) ) {
869
+ case 34: goto tr46;
870
+ case 39: goto tr46;
871
+ case 60: goto tr47;
872
+ case 95: goto tr45;
873
+ case 123: goto tr45;
874
+ case 125: goto tr45;
875
+ }
876
+ if ( (*p) > 90 ) {
877
+ if ( 97 <= (*p) && (*p) <= 122 )
878
+ goto tr59;
879
+ } else if ( (*p) >= 33 )
880
+ goto tr45;
881
+ goto tr0;
882
+ case 47:
883
+ switch( (*p) ) {
884
+ case 34: goto tr46;
885
+ case 39: goto tr46;
886
+ case 60: goto tr47;
887
+ case 62: goto tr60;
888
+ case 95: goto tr45;
889
+ case 123: goto tr45;
890
+ case 125: goto tr45;
891
+ }
892
+ if ( (*p) > 90 ) {
893
+ if ( 97 <= (*p) && (*p) <= 122 )
894
+ goto tr59;
895
+ } else if ( (*p) >= 33 )
896
+ goto tr45;
897
+ goto tr0;
898
+ case 48:
899
+ switch( (*p) ) {
900
+ case 34: goto tr46;
901
+ case 39: goto tr46;
902
+ case 60: goto tr47;
903
+ case 95: goto tr45;
904
+ case 115: goto tr61;
905
+ case 125: goto tr45;
906
+ }
907
+ if ( (*p) > 90 ) {
908
+ if ( 97 <= (*p) && (*p) <= 123 )
909
+ goto tr45;
910
+ } else if ( (*p) >= 33 )
911
+ goto tr45;
912
+ goto tr0;
913
+ case 49:
914
+ switch( (*p) ) {
915
+ case 34: goto tr46;
916
+ case 39: goto tr46;
917
+ case 60: goto tr47;
918
+ case 95: goto tr45;
919
+ case 105: goto tr62;
920
+ case 125: goto tr45;
921
+ }
922
+ if ( (*p) > 90 ) {
923
+ if ( 97 <= (*p) && (*p) <= 123 )
924
+ goto tr45;
925
+ } else if ( (*p) >= 33 )
926
+ goto tr45;
927
+ goto tr0;
928
+ case 50:
929
+ switch( (*p) ) {
930
+ case 34: goto tr46;
931
+ case 39: goto tr46;
932
+ case 58: goto tr63;
933
+ case 60: goto tr47;
934
+ case 95: goto tr45;
935
+ case 125: goto tr45;
936
+ }
937
+ if ( (*p) > 90 ) {
938
+ if ( 97 <= (*p) && (*p) <= 123 )
939
+ goto tr45;
940
+ } else if ( (*p) >= 33 )
941
+ goto tr45;
942
+ goto tr0;
943
+ case 51:
944
+ switch( (*p) ) {
945
+ case 34: goto tr46;
946
+ case 39: goto tr46;
947
+ case 60: goto tr47;
948
+ case 95: goto tr45;
949
+ case 123: goto tr45;
950
+ case 125: goto tr45;
951
+ }
952
+ if ( (*p) > 90 ) {
953
+ if ( 97 <= (*p) && (*p) <= 122 )
954
+ goto tr64;
955
+ } else if ( (*p) >= 33 )
956
+ goto tr45;
957
+ goto tr0;
958
+ case 52:
959
+ switch( (*p) ) {
960
+ case 32: goto tr14;
961
+ case 34: goto tr46;
962
+ case 39: goto tr46;
963
+ case 47: goto tr65;
964
+ case 60: goto tr47;
965
+ case 62: goto tr66;
966
+ case 95: goto tr45;
967
+ case 123: goto tr45;
968
+ case 125: goto tr45;
969
+ }
970
+ if ( (*p) < 33 ) {
971
+ if ( 9 <= (*p) && (*p) <= 13 )
972
+ goto tr14;
973
+ } else if ( (*p) > 90 ) {
974
+ if ( 97 <= (*p) && (*p) <= 122 )
975
+ goto tr64;
976
+ } else
977
+ goto tr45;
978
+ goto tr0;
979
+ case 53:
980
+ switch( (*p) ) {
981
+ case 34: goto tr46;
982
+ case 39: goto tr46;
983
+ case 60: goto tr47;
984
+ case 62: goto tr67;
985
+ case 95: goto tr45;
986
+ case 125: goto tr45;
987
+ }
988
+ if ( (*p) > 90 ) {
989
+ if ( 97 <= (*p) && (*p) <= 123 )
990
+ goto tr45;
991
+ } else if ( (*p) >= 33 )
992
+ goto tr45;
993
+ goto tr0;
994
+ case 59:
995
+ switch( (*p) ) {
996
+ case 34: goto tr74;
997
+ case 39: goto tr74;
998
+ case 60: goto tr75;
999
+ case 95: goto tr73;
1000
+ case 125: goto tr73;
1001
+ }
1002
+ if ( (*p) > 90 ) {
1003
+ if ( 97 <= (*p) && (*p) <= 123 )
1004
+ goto tr73;
1005
+ } else if ( (*p) >= 33 )
1006
+ goto tr73;
1007
+ goto tr72;
1008
+ case 54:
1009
+ switch( (*p) ) {
1010
+ case 60: goto tr1;
1011
+ case 62: goto tr68;
1012
+ }
1013
+ goto tr0;
1014
+ case 60:
1015
+ if ( (*p) == 60 )
1016
+ goto tr76;
1017
+ goto tr72;
1018
+ case 55:
1019
+ switch( (*p) ) {
1020
+ case 60: goto tr1;
1021
+ case 62: goto tr69;
1022
+ }
1023
+ goto tr0;
1024
+ }
1025
+
1026
+ tr0: cs = 0; goto f0;
1027
+ tr9: cs = 0; goto f2;
1028
+ tr16: cs = 0; goto f4;
1029
+ tr70: cs = 0; goto f9;
1030
+ tr72: cs = 0; goto f11;
1031
+ tr1: cs = 1; goto f1;
1032
+ tr71: cs = 1; goto f10;
1033
+ tr76: cs = 1; goto f13;
1034
+ tr2: cs = 2; goto f0;
1035
+ tr4: cs = 3; goto f0;
1036
+ tr5: cs = 4; goto f0;
1037
+ tr6: cs = 5; goto f0;
1038
+ tr7: cs = 6; goto f0;
1039
+ tr8: cs = 7; goto f0;
1040
+ tr3: cs = 8; goto f0;
1041
+ tr10: cs = 9; goto f0;
1042
+ tr11: cs = 10; goto f0;
1043
+ tr12: cs = 11; goto f0;
1044
+ tr13: cs = 12; goto f0;
1045
+ tr14: cs = 13; goto f3;
1046
+ tr17: cs = 14; goto f0;
1047
+ tr18: cs = 15; goto f0;
1048
+ tr22: cs = 16; goto f0;
1049
+ tr21: cs = 16; goto f6;
1050
+ tr23: cs = 17; goto f0;
1051
+ tr24: cs = 18; goto f0;
1052
+ tr37: cs = 18; goto f2;
1053
+ tr43: cs = 18; goto f4;
1054
+ tr26: cs = 19; goto f7;
1055
+ tr27: cs = 20; goto f0;
1056
+ tr28: cs = 21; goto f0;
1057
+ tr25: cs = 22; goto f1;
1058
+ tr30: cs = 23; goto f0;
1059
+ tr32: cs = 24; goto f0;
1060
+ tr33: cs = 25; goto f0;
1061
+ tr34: cs = 26; goto f0;
1062
+ tr35: cs = 27; goto f0;
1063
+ tr36: cs = 28; goto f0;
1064
+ tr31: cs = 29; goto f0;
1065
+ tr38: cs = 30; goto f0;
1066
+ tr39: cs = 31; goto f0;
1067
+ tr40: cs = 32; goto f0;
1068
+ tr41: cs = 33; goto f0;
1069
+ tr42: cs = 34; goto f3;
1070
+ tr45: cs = 35; goto f0;
1071
+ tr60: cs = 35; goto f2;
1072
+ tr66: cs = 35; goto f4;
1073
+ tr73: cs = 35; goto f11;
1074
+ tr46: cs = 36; goto f7;
1075
+ tr74: cs = 36; goto f12;
1076
+ tr48: cs = 37; goto f0;
1077
+ tr49: cs = 38; goto f0;
1078
+ tr51: cs = 39; goto f0;
1079
+ tr50: cs = 39; goto f6;
1080
+ tr52: cs = 40; goto f0;
1081
+ tr47: cs = 41; goto f1;
1082
+ tr75: cs = 41; goto f13;
1083
+ tr53: cs = 42; goto f0;
1084
+ tr55: cs = 43; goto f0;
1085
+ tr56: cs = 44; goto f0;
1086
+ tr57: cs = 45; goto f0;
1087
+ tr58: cs = 46; goto f0;
1088
+ tr59: cs = 47; goto f0;
1089
+ tr54: cs = 48; goto f0;
1090
+ tr61: cs = 49; goto f0;
1091
+ tr62: cs = 50; goto f0;
1092
+ tr63: cs = 51; goto f0;
1093
+ tr64: cs = 52; goto f0;
1094
+ tr65: cs = 53; goto f3;
1095
+ tr19: cs = 54; goto f3;
1096
+ tr15: cs = 55; goto f3;
1097
+ tr20: cs = 57; goto f5;
1098
+ tr29: cs = 57; goto f8;
1099
+ tr44: cs = 58; goto f0;
1100
+ tr67: cs = 59; goto f0;
1101
+ tr69: cs = 60; goto f0;
1102
+ tr68: cs = 60; goto f8;
1103
+
1104
+ f0:
1105
+ #line 176 "parser.rl"
1106
+ {
1107
+ switch( cs ){
1108
+ case 0:
1109
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1110
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1111
+ // stream echobuffer
1112
+ esi_parser_echo_buffer( parser );
1113
+ }
1114
+ // printf( "[%d: %c]", cs, *p );
1115
+ // stream the current character
1116
+ esi_parser_echo_char( parser, *p );
1117
+ }
1118
+ // clear the echobuffer
1119
+ esi_parser_echobuffer_clear( parser );
1120
+ break;
1121
+ default:
1122
+ // append characters to echobuffer
1123
+ esi_parser_concat_to_echobuffer( parser, *p );
1124
+ }
1125
+ parser->prev_state = cs;
1126
+ }
1127
+ goto _again;
1128
+ f1:
1129
+ #line 176 "parser.rl"
1130
+ {
1131
+ switch( cs ){
1132
+ case 0:
1133
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1134
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1135
+ // stream echobuffer
1136
+ esi_parser_echo_buffer( parser );
1137
+ }
1138
+ // printf( "[%d: %c]", cs, *p );
1139
+ // stream the current character
1140
+ esi_parser_echo_char( parser, *p );
1141
+ }
1142
+ // clear the echobuffer
1143
+ esi_parser_echobuffer_clear( parser );
1144
+ break;
1145
+ default:
1146
+ // append characters to echobuffer
1147
+ esi_parser_concat_to_echobuffer( parser, *p );
1148
+ }
1149
+ parser->prev_state = cs;
1150
+ }
1151
+ #line 86 "parser.rl"
1152
+ {
1153
+ parser->mark = p;
1154
+ //debug_string( "begin", p, 1 );
1155
+ }
1156
+ goto _again;
1157
+ f9:
1158
+ #line 176 "parser.rl"
1159
+ {
1160
+ switch( cs ){
1161
+ case 0:
1162
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1163
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1164
+ // stream echobuffer
1165
+ esi_parser_echo_buffer( parser );
1166
+ }
1167
+ // printf( "[%d: %c]", cs, *p );
1168
+ // stream the current character
1169
+ esi_parser_echo_char( parser, *p );
1170
+ }
1171
+ // clear the echobuffer
1172
+ esi_parser_echobuffer_clear( parser );
1173
+ break;
1174
+ default:
1175
+ // append characters to echobuffer
1176
+ esi_parser_concat_to_echobuffer( parser, *p );
1177
+ }
1178
+ parser->prev_state = cs;
1179
+ }
1180
+ #line 90 "parser.rl"
1181
+ {
1182
+ // printf( "finish\n" );
1183
+ }
1184
+ goto _again;
1185
+ f3:
1186
+ #line 176 "parser.rl"
1187
+ {
1188
+ switch( cs ){
1189
+ case 0:
1190
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1191
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1192
+ // stream echobuffer
1193
+ esi_parser_echo_buffer( parser );
1194
+ }
1195
+ // printf( "[%d: %c]", cs, *p );
1196
+ // stream the current character
1197
+ esi_parser_echo_char( parser, *p );
1198
+ }
1199
+ // clear the echobuffer
1200
+ esi_parser_echobuffer_clear( parser );
1201
+ break;
1202
+ default:
1203
+ // append characters to echobuffer
1204
+ esi_parser_concat_to_echobuffer( parser, *p );
1205
+ }
1206
+ parser->prev_state = cs;
1207
+ }
1208
+ #line 95 "parser.rl"
1209
+ {
1210
+ parser->tag_text = parser->mark+1;
1211
+ parser->tag_text_length = p - (parser->mark+1);
1212
+ // debug_string( "have esi start", parser->tag_text, parser->tag_text_length );
1213
+ parser->mark = p;
1214
+ //debug_string( "see_start_tag", p, 1 );
1215
+ }
1216
+ goto _again;
1217
+ f8:
1218
+ #line 176 "parser.rl"
1219
+ {
1220
+ switch( cs ){
1221
+ case 0:
1222
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1223
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1224
+ // stream echobuffer
1225
+ esi_parser_echo_buffer( parser );
1226
+ }
1227
+ // printf( "[%d: %c]", cs, *p );
1228
+ // stream the current character
1229
+ esi_parser_echo_char( parser, *p );
1230
+ }
1231
+ // clear the echobuffer
1232
+ esi_parser_echobuffer_clear( parser );
1233
+ break;
1234
+ default:
1235
+ // append characters to echobuffer
1236
+ esi_parser_concat_to_echobuffer( parser, *p );
1237
+ }
1238
+ parser->prev_state = cs;
1239
+ }
1240
+ #line 103 "parser.rl"
1241
+ {
1242
+ //debug_string( "see_end_tag: before parsed esi tag", parser->tag_text, parser->tag_text_length );
1243
+ ltrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1244
+ //debug_string( "see_end_tag: after parsed esi tag", parser->tag_text, parser->tag_text_length );
1245
+ parser->start_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->attributes, parser->user_data );
1246
+ //debug_string( "see_end_tag: after start parsed esi tag", parser->tag_text, parser->tag_text_length );
1247
+ parser->end_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->user_data );
1248
+ //debug_string( "see_end_tag: after end parsed esi tag", parser->tag_text, parser->tag_text_length );
1249
+ parser->tag_text = NULL;
1250
+ parser->tag_text_length = 0;
1251
+ parser->mark = p;
1252
+ //debug_string( "see_end_tag", p, 1 );
1253
+ }
1254
+ goto _again;
1255
+ f5:
1256
+ #line 176 "parser.rl"
1257
+ {
1258
+ switch( cs ){
1259
+ case 0:
1260
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1261
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1262
+ // stream echobuffer
1263
+ esi_parser_echo_buffer( parser );
1264
+ }
1265
+ // printf( "[%d: %c]", cs, *p );
1266
+ // stream the current character
1267
+ esi_parser_echo_char( parser, *p );
1268
+ }
1269
+ // clear the echobuffer
1270
+ esi_parser_echobuffer_clear( parser );
1271
+ break;
1272
+ default:
1273
+ // append characters to echobuffer
1274
+ esi_parser_concat_to_echobuffer( parser, *p );
1275
+ }
1276
+ parser->prev_state = cs;
1277
+ }
1278
+ #line 117 "parser.rl"
1279
+ {
1280
+ // debug_string( "parsed esi tag", parser->tag_text, parser->tag_text_length );
1281
+ ltrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1282
+ parser->start_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->attributes, parser->user_data );
1283
+ parser->tag_text = NULL;
1284
+ parser->tag_text_length = 0;
1285
+ }
1286
+ goto _again;
1287
+ f6:
1288
+ #line 176 "parser.rl"
1289
+ {
1290
+ switch( cs ){
1291
+ case 0:
1292
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1293
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1294
+ // stream echobuffer
1295
+ esi_parser_echo_buffer( parser );
1296
+ }
1297
+ // printf( "[%d: %c]", cs, *p );
1298
+ // stream the current character
1299
+ esi_parser_echo_char( parser, *p );
1300
+ }
1301
+ // clear the echobuffer
1302
+ esi_parser_echobuffer_clear( parser );
1303
+ break;
1304
+ default:
1305
+ // append characters to echobuffer
1306
+ esi_parser_concat_to_echobuffer( parser, *p );
1307
+ }
1308
+ parser->prev_state = cs;
1309
+ }
1310
+ #line 125 "parser.rl"
1311
+ {
1312
+ parser->attr_key = parser->mark;
1313
+ parser->attr_key_length = p - parser->mark;
1314
+ parser->mark = p;
1315
+ ltrim_pointer( &(parser->attr_key), p, &(parser->attr_key_length) );
1316
+ // debug_string( "\tattribute key", parser->attr_key, parser->attr_key_length );
1317
+ //debug_string( "see_attribute_key", p, 1 );
1318
+ }
1319
+ goto _again;
1320
+ f7:
1321
+ #line 176 "parser.rl"
1322
+ {
1323
+ switch( cs ){
1324
+ case 0:
1325
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1326
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1327
+ // stream echobuffer
1328
+ esi_parser_echo_buffer( parser );
1329
+ }
1330
+ // printf( "[%d: %c]", cs, *p );
1331
+ // stream the current character
1332
+ esi_parser_echo_char( parser, *p );
1333
+ }
1334
+ // clear the echobuffer
1335
+ esi_parser_echobuffer_clear( parser );
1336
+ break;
1337
+ default:
1338
+ // append characters to echobuffer
1339
+ esi_parser_concat_to_echobuffer( parser, *p );
1340
+ }
1341
+ parser->prev_state = cs;
1342
+ }
1343
+ #line 134 "parser.rl"
1344
+ {
1345
+ ESIAttribute *attr;
1346
+ parser->attr_value = parser->mark;
1347
+ parser->attr_value_length = p - parser->mark;
1348
+ parser->mark = p;
1349
+
1350
+ ltrim_pointer( &(parser->attr_value), p, &(parser->attr_value_length) );
1351
+
1352
+ // allocate a new attribute
1353
+ attr = esi_attribute_new( parser->attr_key, parser->attr_key_length,
1354
+ parser->attr_value, parser->attr_value_length );
1355
+ if( parser->attributes ){
1356
+ parser->last->next = attr;
1357
+ parser->last = attr;
1358
+ }
1359
+ else{
1360
+ parser->last = parser->attributes = attr;
1361
+ }
1362
+ // debug_string( "\tattribute value", parser->attr_value, parser->attr_value_length );
1363
+ //debug_string( "see_attribute_value", p, 1 );
1364
+ }
1365
+ goto _again;
1366
+ f4:
1367
+ #line 176 "parser.rl"
1368
+ {
1369
+ switch( cs ){
1370
+ case 0:
1371
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1372
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1373
+ // stream echobuffer
1374
+ esi_parser_echo_buffer( parser );
1375
+ }
1376
+ // printf( "[%d: %c]", cs, *p );
1377
+ // stream the current character
1378
+ esi_parser_echo_char( parser, *p );
1379
+ }
1380
+ // clear the echobuffer
1381
+ esi_parser_echobuffer_clear( parser );
1382
+ break;
1383
+ default:
1384
+ // append characters to echobuffer
1385
+ esi_parser_concat_to_echobuffer( parser, *p );
1386
+ }
1387
+ parser->prev_state = cs;
1388
+ }
1389
+ #line 156 "parser.rl"
1390
+ {
1391
+ parser->tag_text = parser->mark;
1392
+ parser->tag_text_length = p - parser->mark;
1393
+ parser->mark = p;
1394
+ ltrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1395
+ parser->start_tag_handler( data, parser->tag_text, parser->tag_text_length, NULL, parser->user_data );
1396
+ //debug_string( "block_start_tag", p, 1 );
1397
+ }
1398
+ goto _again;
1399
+ f2:
1400
+ #line 176 "parser.rl"
1401
+ {
1402
+ switch( cs ){
1403
+ case 0:
1404
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1405
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1406
+ // stream echobuffer
1407
+ esi_parser_echo_buffer( parser );
1408
+ }
1409
+ // printf( "[%d: %c]", cs, *p );
1410
+ // stream the current character
1411
+ esi_parser_echo_char( parser, *p );
1412
+ }
1413
+ // clear the echobuffer
1414
+ esi_parser_echobuffer_clear( parser );
1415
+ break;
1416
+ default:
1417
+ // append characters to echobuffer
1418
+ esi_parser_concat_to_echobuffer( parser, *p );
1419
+ }
1420
+ parser->prev_state = cs;
1421
+ }
1422
+ #line 165 "parser.rl"
1423
+ {
1424
+ parser->tag_text = parser->mark+2;
1425
+ parser->tag_text_length = p - (parser->mark+2);
1426
+ //printf( "mark: [%s], p: [%s], length: %d\n", parser->mark, p, parser->tag_text_length );
1427
+ parser->mark = p;
1428
+ //debug_string( "block_end_tag: before parsed esi tag", parser->tag_text, parser->tag_text_length );
1429
+ ltrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1430
+ //debug_string( "block_end_tag: after parsed esi tag", parser->tag_text, parser->tag_text_length );
1431
+ parser->end_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->user_data );
1432
+ }
1433
+ goto _again;
1434
+ f10:
1435
+ #line 176 "parser.rl"
1436
+ {
1437
+ switch( cs ){
1438
+ case 0:
1439
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1440
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1441
+ // stream echobuffer
1442
+ esi_parser_echo_buffer( parser );
1443
+ }
1444
+ // printf( "[%d: %c]", cs, *p );
1445
+ // stream the current character
1446
+ esi_parser_echo_char( parser, *p );
1447
+ }
1448
+ // clear the echobuffer
1449
+ esi_parser_echobuffer_clear( parser );
1450
+ break;
1451
+ default:
1452
+ // append characters to echobuffer
1453
+ esi_parser_concat_to_echobuffer( parser, *p );
1454
+ }
1455
+ parser->prev_state = cs;
1456
+ }
1457
+ #line 86 "parser.rl"
1458
+ {
1459
+ parser->mark = p;
1460
+ //debug_string( "begin", p, 1 );
1461
+ }
1462
+ #line 90 "parser.rl"
1463
+ {
1464
+ // printf( "finish\n" );
1465
+ }
1466
+ goto _again;
1467
+ f11:
1468
+ #line 176 "parser.rl"
1469
+ {
1470
+ switch( cs ){
1471
+ case 0:
1472
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1473
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1474
+ // stream echobuffer
1475
+ esi_parser_echo_buffer( parser );
1476
+ }
1477
+ // printf( "[%d: %c]", cs, *p );
1478
+ // stream the current character
1479
+ esi_parser_echo_char( parser, *p );
1480
+ }
1481
+ // clear the echobuffer
1482
+ esi_parser_echobuffer_clear( parser );
1483
+ break;
1484
+ default:
1485
+ // append characters to echobuffer
1486
+ esi_parser_concat_to_echobuffer( parser, *p );
1487
+ }
1488
+ parser->prev_state = cs;
1489
+ }
1490
+ #line 103 "parser.rl"
1491
+ {
1492
+ //debug_string( "see_end_tag: before parsed esi tag", parser->tag_text, parser->tag_text_length );
1493
+ ltrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1494
+ //debug_string( "see_end_tag: after parsed esi tag", parser->tag_text, parser->tag_text_length );
1495
+ parser->start_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->attributes, parser->user_data );
1496
+ //debug_string( "see_end_tag: after start parsed esi tag", parser->tag_text, parser->tag_text_length );
1497
+ parser->end_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->user_data );
1498
+ //debug_string( "see_end_tag: after end parsed esi tag", parser->tag_text, parser->tag_text_length );
1499
+ parser->tag_text = NULL;
1500
+ parser->tag_text_length = 0;
1501
+ parser->mark = p;
1502
+ //debug_string( "see_end_tag", p, 1 );
1503
+ }
1504
+ #line 90 "parser.rl"
1505
+ {
1506
+ // printf( "finish\n" );
1507
+ }
1508
+ goto _again;
1509
+ f13:
1510
+ #line 176 "parser.rl"
1511
+ {
1512
+ switch( cs ){
1513
+ case 0:
1514
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1515
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1516
+ // stream echobuffer
1517
+ esi_parser_echo_buffer( parser );
1518
+ }
1519
+ // printf( "[%d: %c]", cs, *p );
1520
+ // stream the current character
1521
+ esi_parser_echo_char( parser, *p );
1522
+ }
1523
+ // clear the echobuffer
1524
+ esi_parser_echobuffer_clear( parser );
1525
+ break;
1526
+ default:
1527
+ // append characters to echobuffer
1528
+ esi_parser_concat_to_echobuffer( parser, *p );
1529
+ }
1530
+ parser->prev_state = cs;
1531
+ }
1532
+ #line 86 "parser.rl"
1533
+ {
1534
+ parser->mark = p;
1535
+ //debug_string( "begin", p, 1 );
1536
+ }
1537
+ #line 103 "parser.rl"
1538
+ {
1539
+ //debug_string( "see_end_tag: before parsed esi tag", parser->tag_text, parser->tag_text_length );
1540
+ ltrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1541
+ //debug_string( "see_end_tag: after parsed esi tag", parser->tag_text, parser->tag_text_length );
1542
+ parser->start_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->attributes, parser->user_data );
1543
+ //debug_string( "see_end_tag: after start parsed esi tag", parser->tag_text, parser->tag_text_length );
1544
+ parser->end_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->user_data );
1545
+ //debug_string( "see_end_tag: after end parsed esi tag", parser->tag_text, parser->tag_text_length );
1546
+ parser->tag_text = NULL;
1547
+ parser->tag_text_length = 0;
1548
+ parser->mark = p;
1549
+ //debug_string( "see_end_tag", p, 1 );
1550
+ }
1551
+ #line 90 "parser.rl"
1552
+ {
1553
+ // printf( "finish\n" );
1554
+ }
1555
+ goto _again;
1556
+ f12:
1557
+ #line 176 "parser.rl"
1558
+ {
1559
+ switch( cs ){
1560
+ case 0:
1561
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){
1562
+ if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
1563
+ // stream echobuffer
1564
+ esi_parser_echo_buffer( parser );
1565
+ }
1566
+ // printf( "[%d: %c]", cs, *p );
1567
+ // stream the current character
1568
+ esi_parser_echo_char( parser, *p );
1569
+ }
1570
+ // clear the echobuffer
1571
+ esi_parser_echobuffer_clear( parser );
1572
+ break;
1573
+ default:
1574
+ // append characters to echobuffer
1575
+ esi_parser_concat_to_echobuffer( parser, *p );
1576
+ }
1577
+ parser->prev_state = cs;
1578
+ }
1579
+ #line 103 "parser.rl"
1580
+ {
1581
+ //debug_string( "see_end_tag: before parsed esi tag", parser->tag_text, parser->tag_text_length );
1582
+ ltrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1583
+ //debug_string( "see_end_tag: after parsed esi tag", parser->tag_text, parser->tag_text_length );
1584
+ parser->start_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->attributes, parser->user_data );
1585
+ //debug_string( "see_end_tag: after start parsed esi tag", parser->tag_text, parser->tag_text_length );
1586
+ parser->end_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->user_data );
1587
+ //debug_string( "see_end_tag: after end parsed esi tag", parser->tag_text, parser->tag_text_length );
1588
+ parser->tag_text = NULL;
1589
+ parser->tag_text_length = 0;
1590
+ parser->mark = p;
1591
+ //debug_string( "see_end_tag", p, 1 );
1592
+ }
1593
+ #line 134 "parser.rl"
1594
+ {
1595
+ ESIAttribute *attr;
1596
+ parser->attr_value = parser->mark;
1597
+ parser->attr_value_length = p - parser->mark;
1598
+ parser->mark = p;
1599
+
1600
+ ltrim_pointer( &(parser->attr_value), p, &(parser->attr_value_length) );
1601
+
1602
+ // allocate a new attribute
1603
+ attr = esi_attribute_new( parser->attr_key, parser->attr_key_length,
1604
+ parser->attr_value, parser->attr_value_length );
1605
+ if( parser->attributes ){
1606
+ parser->last->next = attr;
1607
+ parser->last = attr;
1608
+ }
1609
+ else{
1610
+ parser->last = parser->attributes = attr;
1611
+ }
1612
+ // debug_string( "\tattribute value", parser->attr_value, parser->attr_value_length );
1613
+ //debug_string( "see_attribute_value", p, 1 );
1614
+ }
1615
+ #line 90 "parser.rl"
1616
+ {
1617
+ // printf( "finish\n" );
1618
+ }
1619
+ goto _again;
1620
+
1621
+ _again:
1622
+ if ( ++p != pe )
1623
+ goto _resume;
1624
+ _out: {}
1625
+ }
1626
+ #line 352 "parser.rl"
1627
+
1628
+ parser->cs = cs;
1629
+
1630
+ if( cs != esi_start && cs != 0 ){
1631
+
1632
+ if( !parser->overflow_data ){
1633
+ // recompute mark, tag_text, attr_key, and attr_value since they all exist within overflow_data
1634
+ int mark_offset = compute_offset( parser->mark, data );
1635
+ int tag_text_offset = compute_offset( parser->tag_text, data );
1636
+ int attr_key_offset = compute_offset( parser->attr_key, data );
1637
+ int attr_value_offset = compute_offset( parser->attr_value, data );
1638
+ //debug_string( "mark before move", parser->mark, 1 );
1639
+
1640
+ parser->overflow_data = (char*)malloc( sizeof( char ) * length );
1641
+ memcpy( parser->overflow_data, data, length );
1642
+ parser->overflow_data_size = length;
1643
+
1644
+ // in our new memory space mark will now be
1645
+ parser->mark = ( mark_offset >= 0 ) ? parser->overflow_data + mark_offset : NULL;
1646
+ parser->tag_text = ( tag_text_offset >= 0 ) ? parser->overflow_data + tag_text_offset : NULL;
1647
+ parser->attr_key = ( attr_key_offset >= 0 ) ? parser->overflow_data + attr_key_offset : NULL;
1648
+ parser->attr_value = ( attr_value_offset >= 0 ) ? parser->overflow_data + attr_value_offset : NULL;
1649
+ //if( parser->mark ){ debug_string( "mark after move", parser->mark, 1 ); } else { printf( "mark is now empty\n" ); }
1650
+ }
1651
+
1652
+ }else if( parser->overflow_data ){
1653
+ free( parser->overflow_data );
1654
+ parser->overflow_data = NULL;
1655
+ parser->overflow_data_size = 0;
1656
+ }
1657
+
1658
+ return cs;
1659
+ }
1660
+ int esi_parser_finish( ESIParser *parser )
1661
+ {
1662
+
1663
+ #line 1664 "parser.c"
1664
+ #line 388 "parser.rl"
1665
+ return 0;
1666
+ }
1667
+
1668
+ void esi_parser_start_tag_handler( ESIParser *parser, start_tag_cb callback )
1669
+ {
1670
+ parser->start_tag_handler = callback;
1671
+ }
1672
+
1673
+ void esi_parser_end_tag_handler( ESIParser *parser, end_tag_cb callback )
1674
+ {
1675
+ parser->end_tag_handler = callback;
1676
+ }