mongrel_esi 0.5.0 → 0.5.1

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 (202) hide show
  1. data/Rakefile +14 -6
  2. data/doc/rdoc/classes/ESI/CParser.html +122 -0
  3. data/doc/rdoc/classes/ESI/Cache.html +178 -0
  4. data/doc/rdoc/classes/ESI/Cache.src/M000085.html +17 -0
  5. data/doc/rdoc/classes/ESI/Cache.src/M000086.html +20 -0
  6. data/doc/rdoc/classes/ESI/Config.html +333 -0
  7. data/doc/rdoc/classes/ESI/Config.src/M000052.html +18 -0
  8. data/doc/rdoc/classes/ESI/Config.src/M000053.html +18 -0
  9. data/doc/rdoc/classes/ESI/Config.src/M000054.html +35 -0
  10. data/doc/rdoc/classes/ESI/Config.src/M000055.html +38 -0
  11. data/doc/rdoc/classes/ESI/Config.src/M000056.html +23 -0
  12. data/doc/rdoc/classes/ESI/Config.src/M000057.html +18 -0
  13. data/doc/rdoc/classes/ESI/Config.src/M000058.html +20 -0
  14. data/doc/rdoc/classes/ESI/Config.src/M000059.html +18 -0
  15. data/doc/rdoc/classes/ESI/Config.src/M000060.html +24 -0
  16. data/doc/rdoc/classes/ESI/Config/CacheConfig.html +212 -0
  17. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000064.html +19 -0
  18. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000065.html +19 -0
  19. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000066.html +18 -0
  20. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000067.html +18 -0
  21. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000068.html +18 -0
  22. data/doc/rdoc/classes/ESI/Config/ConfigRouter.html +187 -0
  23. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000061.html +19 -0
  24. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000062.html +21 -0
  25. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000063.html +21 -0
  26. data/doc/rdoc/classes/ESI/Dispatcher.html +172 -0
  27. data/doc/rdoc/classes/ESI/Dispatcher.src/M000087.html +22 -0
  28. data/doc/rdoc/classes/ESI/Dispatcher.src/M000088.html +18 -0
  29. data/doc/rdoc/classes/ESI/Fragment.html +218 -0
  30. data/doc/rdoc/classes/ESI/Fragment.src/M000100.html +20 -0
  31. data/doc/rdoc/classes/ESI/Fragment.src/M000101.html +18 -0
  32. data/doc/rdoc/classes/ESI/Fragment.src/M000102.html +18 -0
  33. data/doc/rdoc/classes/ESI/Invalidator.html +131 -0
  34. data/doc/rdoc/classes/ESI/Invalidator.src/M000004.html +41 -0
  35. data/doc/rdoc/classes/ESI/Log.html +221 -0
  36. data/doc/rdoc/classes/ESI/Log.src/M000030.html +18 -0
  37. data/doc/rdoc/classes/ESI/Log.src/M000031.html +18 -0
  38. data/doc/rdoc/classes/ESI/Log.src/M000032.html +18 -0
  39. data/doc/rdoc/classes/ESI/Log.src/M000033.html +18 -0
  40. data/doc/rdoc/classes/ESI/Log.src/M000034.html +18 -0
  41. data/doc/rdoc/classes/ESI/Log.src/M000035.html +18 -0
  42. data/doc/rdoc/classes/ESI/Log.src/M000036.html +18 -0
  43. data/doc/rdoc/classes/ESI/MemcachedCache.html +314 -0
  44. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000040.html +24 -0
  45. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000041.html +22 -0
  46. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000042.html +19 -0
  47. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000043.html +23 -0
  48. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000044.html +18 -0
  49. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000045.html +19 -0
  50. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000046.html +18 -0
  51. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000047.html +18 -0
  52. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000048.html +17 -0
  53. data/doc/rdoc/classes/ESI/Parser.html +184 -0
  54. data/doc/rdoc/classes/ESI/Parser.src/M000049.html +51 -0
  55. data/doc/rdoc/classes/ESI/Parser.src/M000050.html +39 -0
  56. data/doc/rdoc/classes/ESI/Parser.src/M000051.html +19 -0
  57. data/doc/rdoc/classes/ESI/Processor.html +194 -0
  58. data/doc/rdoc/classes/ESI/Processor.src/M000037.html +26 -0
  59. data/doc/rdoc/classes/ESI/Processor.src/M000038.html +44 -0
  60. data/doc/rdoc/classes/ESI/Processor.src/M000039.html +26 -0
  61. data/doc/rdoc/classes/ESI/Proxy.html +304 -0
  62. data/doc/rdoc/classes/ESI/Proxy.src/M000069.html +20 -0
  63. data/doc/rdoc/classes/ESI/Proxy.src/M000070.html +55 -0
  64. data/doc/rdoc/classes/ESI/Proxy.src/M000071.html +53 -0
  65. data/doc/rdoc/classes/ESI/Proxy.src/M000072.html +25 -0
  66. data/doc/rdoc/classes/ESI/Proxy.src/M000073.html +19 -0
  67. data/doc/rdoc/classes/ESI/Proxy.src/M000074.html +27 -0
  68. data/doc/rdoc/classes/ESI/Proxy.src/M000075.html +18 -0
  69. data/doc/rdoc/classes/ESI/Proxy.src/M000076.html +28 -0
  70. data/doc/rdoc/classes/ESI/Proxy.src/M000077.html +29 -0
  71. data/doc/rdoc/classes/ESI/Response.html +250 -0
  72. data/doc/rdoc/classes/ESI/Response.src/M000078.html +23 -0
  73. data/doc/rdoc/classes/ESI/Response.src/M000079.html +18 -0
  74. data/doc/rdoc/classes/ESI/Response.src/M000080.html +21 -0
  75. data/doc/rdoc/classes/ESI/Response.src/M000081.html +20 -0
  76. data/doc/rdoc/classes/ESI/Response.src/M000082.html +25 -0
  77. data/doc/rdoc/classes/ESI/Response.src/M000083.html +18 -0
  78. data/doc/rdoc/classes/ESI/Response.src/M000084.html +33 -0
  79. data/doc/rdoc/classes/ESI/Router.html +212 -0
  80. data/doc/rdoc/classes/ESI/Router.src/M000098.html +36 -0
  81. data/doc/rdoc/classes/ESI/Router.src/M000099.html +25 -0
  82. data/doc/rdoc/classes/ESI/RubyCache.html +278 -0
  83. data/doc/rdoc/classes/ESI/RubyCache.src/M000089.html +20 -0
  84. data/doc/rdoc/classes/ESI/RubyCache.src/M000090.html +20 -0
  85. data/doc/rdoc/classes/ESI/RubyCache.src/M000091.html +20 -0
  86. data/doc/rdoc/classes/ESI/RubyCache.src/M000092.html +22 -0
  87. data/doc/rdoc/classes/ESI/RubyCache.src/M000093.html +18 -0
  88. data/doc/rdoc/classes/ESI/RubyCache.src/M000094.html +22 -0
  89. data/doc/rdoc/classes/ESI/RubyCache.src/M000095.html +18 -0
  90. data/doc/rdoc/classes/ESI/RubyCache.src/M000096.html +18 -0
  91. data/doc/rdoc/classes/ESI/RubyCache.src/M000097.html +18 -0
  92. data/doc/rdoc/classes/ESI/Tag.html +141 -0
  93. data/doc/rdoc/classes/ESI/Tag/Attempt.html +113 -0
  94. data/doc/rdoc/classes/ESI/Tag/Base.html +237 -0
  95. data/doc/rdoc/classes/ESI/Tag/Base.src/M000026.html +23 -0
  96. data/doc/rdoc/classes/ESI/Tag/Base.src/M000027.html +22 -0
  97. data/doc/rdoc/classes/ESI/Tag/Base.src/M000028.html +22 -0
  98. data/doc/rdoc/classes/ESI/Tag/Base.src/M000029.html +17 -0
  99. data/doc/rdoc/classes/ESI/Tag/Container.html +206 -0
  100. data/doc/rdoc/classes/ESI/Tag/Container.src/M000015.html +20 -0
  101. data/doc/rdoc/classes/ESI/Tag/Container.src/M000016.html +22 -0
  102. data/doc/rdoc/classes/ESI/Tag/Container.src/M000017.html +25 -0
  103. data/doc/rdoc/classes/ESI/Tag/Except.html +184 -0
  104. data/doc/rdoc/classes/ESI/Tag/Except.src/M000018.html +21 -0
  105. data/doc/rdoc/classes/ESI/Tag/Except.src/M000019.html +20 -0
  106. data/doc/rdoc/classes/ESI/Tag/Except.src/M000020.html +18 -0
  107. data/doc/rdoc/classes/ESI/Tag/Include.html +257 -0
  108. data/doc/rdoc/classes/ESI/Tag/Include.src/M000005.html +20 -0
  109. data/doc/rdoc/classes/ESI/Tag/Include.src/M000006.html +18 -0
  110. data/doc/rdoc/classes/ESI/Tag/Include.src/M000007.html +34 -0
  111. data/doc/rdoc/classes/ESI/Tag/Include.src/M000008.html +22 -0
  112. data/doc/rdoc/classes/ESI/Tag/Include.src/M000009.html +27 -0
  113. data/doc/rdoc/classes/ESI/Tag/Include.src/M000010.html +30 -0
  114. data/doc/rdoc/classes/ESI/Tag/Include.src/M000011.html +51 -0
  115. data/doc/rdoc/classes/ESI/Tag/Include/Request.html +199 -0
  116. data/doc/rdoc/classes/ESI/Tag/Include/Request.src/M000012.html +18 -0
  117. data/doc/rdoc/classes/ESI/Tag/Include/Request.src/M000013.html +44 -0
  118. data/doc/rdoc/classes/ESI/Tag/Include/Request/Error.html +155 -0
  119. data/doc/rdoc/classes/ESI/Tag/Include/Request/Error.src/M000014.html +19 -0
  120. data/doc/rdoc/classes/ESI/Tag/Invalidate.html +171 -0
  121. data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000023.html +19 -0
  122. data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000024.html +51 -0
  123. data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000025.html +19 -0
  124. data/doc/rdoc/classes/ESI/Tag/Try.html +154 -0
  125. data/doc/rdoc/classes/ESI/Tag/Try.src/M000021.html +38 -0
  126. data/doc/rdoc/classes/ESI/Tag/Try.src/M000022.html +18 -0
  127. data/doc/rdoc/classes/MultiDirHandler.html +198 -0
  128. data/doc/rdoc/classes/MultiDirHandler.src/M000001.html +20 -0
  129. data/doc/rdoc/classes/MultiDirHandler.src/M000002.html +28 -0
  130. data/doc/rdoc/classes/MultiDirHandler.src/M000003.html +22 -0
  131. data/doc/rdoc/created.rid +1 -0
  132. data/doc/rdoc/files/COPYING.html +167 -0
  133. data/doc/rdoc/files/LICENSE.html +605 -0
  134. data/doc/rdoc/files/README.html +359 -0
  135. data/doc/rdoc/files/ext/esi/common_rl.html +160 -0
  136. data/doc/rdoc/files/ext/esi/esi_parser_c.html +101 -0
  137. data/doc/rdoc/files/ext/esi/parser_c.html +101 -0
  138. data/doc/rdoc/files/ext/esi/parser_h.html +101 -0
  139. data/doc/rdoc/files/ext/esi/parser_rl.html +827 -0
  140. data/doc/rdoc/files/ext/esi/test/common_rl.html +160 -0
  141. data/doc/rdoc/files/ext/esi/test/parser_c.html +101 -0
  142. data/doc/rdoc/files/ext/esi/test/parser_h.html +101 -0
  143. data/doc/rdoc/files/ext/esi/test/parser_rl.html +827 -0
  144. data/doc/rdoc/files/ext/esi/test/sp_c.html +101 -0
  145. data/doc/rdoc/files/ext/esi/test/test_c.html +101 -0
  146. data/doc/rdoc/files/lib/esi/cache_rb.html +119 -0
  147. data/doc/rdoc/files/lib/esi/config_rb.html +114 -0
  148. data/doc/rdoc/files/lib/esi/dispatcher_rb.html +108 -0
  149. data/doc/rdoc/files/lib/esi/invalidator_rb.html +114 -0
  150. data/doc/rdoc/files/lib/esi/logger_rb.html +108 -0
  151. data/doc/rdoc/files/lib/esi/parser_rb.html +120 -0
  152. data/doc/rdoc/files/lib/esi/processor_rb.html +115 -0
  153. data/doc/rdoc/files/lib/esi/proxy_rb.html +123 -0
  154. data/doc/rdoc/files/lib/esi/response_rb.html +116 -0
  155. data/doc/rdoc/files/lib/esi/router_rb.html +107 -0
  156. data/doc/rdoc/files/lib/esi/tag/attempt_rb.html +114 -0
  157. data/doc/rdoc/files/lib/esi/tag/base_rb.html +114 -0
  158. data/doc/rdoc/files/lib/esi/tag/container_rb.html +115 -0
  159. data/doc/rdoc/files/lib/esi/tag/except_rb.html +114 -0
  160. data/doc/rdoc/files/lib/esi/tag/include_rb.html +116 -0
  161. data/doc/rdoc/files/lib/esi/tag/invalidate_rb.html +115 -0
  162. data/doc/rdoc/files/lib/esi/tag/try_rb.html +115 -0
  163. data/doc/rdoc/files/lib/esi/version_rb.html +101 -0
  164. data/doc/rdoc/files/lib/multi_dirhandler_rb.html +109 -0
  165. data/doc/rdoc/fr_class_index.html +53 -0
  166. data/doc/rdoc/fr_file_index.html +59 -0
  167. data/doc/rdoc/fr_method_index.html +128 -0
  168. data/doc/rdoc/index.html +24 -0
  169. data/doc/rdoc/rdoc-style.css +208 -0
  170. data/ext/esi/esi_parser.c +12 -1
  171. data/ext/esi/parser.c +492 -3927
  172. data/ext/esi/parser.rl +83 -14
  173. data/ext/esi/test/parser.c +1587 -367
  174. data/ext/esi/test/parser.rl +83 -14
  175. data/ext/esi/test/sp.c +125 -0
  176. data/ext/esi/test/test.c +198 -6
  177. data/lib/esi/cache.rb +5 -8
  178. data/lib/esi/config.rb +3 -3
  179. data/lib/esi/dispatcher.rb +2 -4
  180. data/lib/esi/parser.rb +26 -13
  181. data/lib/esi/processor.rb +13 -35
  182. data/lib/esi/proxy.rb +113 -44
  183. data/lib/esi/response.rb +23 -55
  184. data/lib/esi/router.rb +0 -11
  185. data/lib/esi/tag/attempt.rb +2 -1
  186. data/lib/esi/tag/base.rb +1 -24
  187. data/lib/esi/tag/container.rb +40 -0
  188. data/lib/esi/tag/except.rb +3 -1
  189. data/lib/esi/tag/include.rb +53 -62
  190. data/lib/esi/tag/try.rb +16 -18
  191. data/lib/esi/version.rb +9 -0
  192. data/test/integration/handler_test.rb +49 -12
  193. data/test/integration/help.rb +12 -0
  194. data/test/load_test.rb +8 -4
  195. data/test/load_test_ab.rb +8 -0
  196. data/test/sample.html +31 -0
  197. data/test/unit/help.rb +12 -8
  198. data/test/unit/include_request_test.rb +14 -21
  199. data/test/unit/parser_test.rb +2 -1
  200. data/test/unit/response_test.rb +4 -8
  201. data/tools/rakehelp.rb +1 -1
  202. metadata +216 -5
data/ext/esi/parser.rl CHANGED
@@ -15,6 +15,8 @@ static void debug_string( const char *msg, const char *str, size_t len )
15
15
  printf( "%s :'%s'\n", msg, pstr );
16
16
  free( pstr );
17
17
  }
18
+ #else
19
+ #define debug_string(m,s,l)
18
20
  #endif
19
21
 
20
22
  /* define default callbacks */
@@ -93,7 +95,7 @@ static void esi_parser_concat_to_echobuffer( ESIParser *parser, char ch )
93
95
  {
94
96
  parser->echobuffer_index++;
95
97
 
96
- if( parser->echobuffer_allocated <= parser->echobuffer_index ){
98
+ if( parser->echobuffer_allocated <= parser->echobuffer_index ) {
97
99
  /* double the echobuffer size
98
100
  * we're getting some crazy input if this case ever happens
99
101
  */
@@ -114,7 +116,7 @@ static void ltrim_pointer( const char **ptr, const char *bounds, size_t *len )
114
116
  **ptr == '=' ||
115
117
  **ptr == '"' ||
116
118
  **ptr == '<' ||
117
- **ptr == '\'' ) && (*len > 0) && (*ptr != bounds) ){
119
+ **ptr == '\'' ) && (*len > 0) && (*ptr != bounds) ) {
118
120
  (*ptr)++;
119
121
  (*len)--;
120
122
  }
@@ -229,11 +231,11 @@ static void rtrim_pointer( const char **ptr, const char *bounds, size_t *len )
229
231
  parser->attr_value, parser->attr_value_length );
230
232
 
231
233
  /* add the new attribute to the list of attributes */
232
- if( parser->attributes ){
234
+ if( parser->attributes ) {
233
235
  parser->last->next = attr;
234
236
  parser->last = attr;
235
237
  }
236
- else{
238
+ else {
237
239
  parser->last = parser->attributes = attr;
238
240
  }
239
241
  }
@@ -277,7 +279,7 @@ static void rtrim_pointer( const char **ptr, const char *bounds, size_t *len )
277
279
  # process each character in the input stream for output
278
280
  action echo {
279
281
  //printf( "[%c:%d],", *p, cs );
280
- switch( cs ){
282
+ switch( cs ) {
281
283
  case 0: /* non matching state */
282
284
  if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
283
285
  if( parser->echobuffer && parser->echobuffer_index != -1 ){
@@ -363,11 +365,14 @@ ESIParser *esi_parser_new()
363
365
  ESIParser *parser = (ESIParser*)malloc(sizeof(ESIParser));
364
366
  parser->cs = esi_start;
365
367
  parser->mark = NULL;
368
+ parser->tag_text = NULL;
369
+ parser->attr_key = NULL;
370
+ parser->attr_value = NULL;
366
371
  parser->overflow_data_size = 0;
367
372
  parser->overflow_data = NULL;
368
373
 
369
- /* allocate 1024 bytes for the echobuffer */
370
- parser->echobuffer_allocated = ESI_OUTPUT_BUFFER_SIZE; /* NOTE: change this value, to reduce memory consumtion or allocations */
374
+ /* allocate ESI_OUTPUT_BUFFER_SIZE bytes for the echobuffer */
375
+ parser->echobuffer_allocated = ESI_OUTPUT_BUFFER_SIZE;
371
376
  parser->echobuffer_index = -1;
372
377
  parser->echobuffer = (char*)malloc(sizeof(char)*parser->echobuffer_allocated);
373
378
 
@@ -408,12 +413,58 @@ int esi_parser_init( ESIParser *parser )
408
413
 
409
414
  static int compute_offset( const char *mark, const char *data )
410
415
  {
411
- if( mark ){
416
+ if( mark ) {
412
417
  return mark - data;
413
418
  }
414
419
  return -1;
415
420
  }
416
421
 
422
+ /*
423
+ * scans the data buffer for a start sequence /<$/, /<e$/, /<es$/, /<esi$/, /<esi:$/
424
+ * returns index of if start sequence found else returns -1
425
+ */
426
+ static int
427
+ esi_parser_scan_for_start( ESIParser *parser, const char *data, size_t length )
428
+ {
429
+ size_t i, f = -2, s = -2;
430
+ char ch;
431
+
432
+ for( i = 0; i < length; ++i ) {
433
+ ch = data[i];
434
+ switch( ch ) {
435
+ case '<':
436
+ f = s = i;
437
+ break;
438
+ case '/':
439
+ if( s == (i-1) && f != -2 ) { s = i; }
440
+ break;
441
+ case 'e':
442
+ if( s == (i-1) && f != -2 ) { s = i; }
443
+ break;
444
+ case 's':
445
+ if( s == (i-1) && f != -2 ) { s = i; }
446
+ break;
447
+ case 'i':
448
+ if( s == (i-1) && f != -2 ) { s = i; }
449
+ break;
450
+ case ':':
451
+ if( s == (i-1) && f != -2 ) { s = i; return f; }
452
+ break;
453
+ default:
454
+ f = s = -2;
455
+ break;
456
+ }
457
+ }
458
+
459
+ // if s and f are still valid at end of input return f
460
+ if( f != -2 && s != -2 ) {
461
+ return f;
462
+ }
463
+ else {
464
+ return -1;
465
+ }
466
+ }
467
+
417
468
  /* accept an arbitrary length string buffer
418
469
  * when this methods exits it determines if an end state was reached
419
470
  * if no end state was reached it saves the full input into an internal buffer
@@ -426,11 +477,23 @@ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
426
477
  const char *p = data;
427
478
  const char *eof = NULL; // ragel 6.x compat
428
479
  const char *pe = data + length;
480
+ int pindex;
429
481
 
430
482
  if( length == 0 ){ return cs; }
431
483
 
484
+ /* scan data for any '<esi:' start sequences, /<$/, /<e$/, /<es$/, /<esi$/, /<esi:$/ */
485
+ if( cs == esi_start ) {
486
+ pindex = esi_parser_scan_for_start( parser, data, length );
487
+ if( pindex == -1 ) {
488
+ for( pindex = 0; pindex < length; ++pindex ) {
489
+ esi_parser_echo_char( parser, data[pindex] );
490
+ }
491
+ return cs;
492
+ }
493
+ }
494
+
432
495
  /* there's an existing overflow buffer data append the new data to the existing data */
433
- if( parser->overflow_data && parser->overflow_data_size > 0 ){
496
+ if( parser->overflow_data && parser->overflow_data_size > 0 ) {
434
497
 
435
498
  // recompute mark, tag_text, attr_key, and attr_value since they all exist within overflow_data
436
499
  int mark_offset = compute_offset( parser->mark, parser->overflow_data );
@@ -456,7 +519,7 @@ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
456
519
 
457
520
  }
458
521
 
459
- if( !parser->mark ){
522
+ if( !parser->mark ) {
460
523
  parser->mark = p;
461
524
  }
462
525
 
@@ -466,7 +529,7 @@ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
466
529
 
467
530
  parser->cs = cs;
468
531
 
469
- if( cs != esi_start && cs != 0 ){
532
+ if( cs != esi_start && cs != 0 ) {
470
533
 
471
534
  /* reached the end and we're not at a termination point save the buffer as overflow */
472
535
  if( !parser->overflow_data ){
@@ -477,10 +540,16 @@ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
477
540
  int attr_value_offset = compute_offset( parser->attr_value, data );
478
541
  //debug_string( "mark before move", parser->mark, 1 );
479
542
 
480
- parser->overflow_data = (char*)malloc( sizeof( char ) * length );
543
+ if( ESI_OUTPUT_BUFFER_SIZE > length ) {
544
+ parser->echobuffer_allocated = ESI_OUTPUT_BUFFER_SIZE;
545
+ }
546
+ else {
547
+ parser->echobuffer_allocated = length;
548
+ }
549
+ parser->overflow_data = (char*)malloc( sizeof( char ) * parser->echobuffer_allocated );
481
550
  memcpy( parser->overflow_data, data, length );
482
551
  parser->overflow_data_size = length;
483
- // printf( "allocate overflow data: %ld\n", parser->overflow_data_size );
552
+ //printf( "allocate overflow data: %ld\n", parser->echobuffer_allocated );
484
553
 
485
554
  // in our new memory space mark will now be
486
555
  parser->mark = ( mark_offset >= 0 ) ? parser->overflow_data + mark_offset : NULL;
@@ -490,7 +559,7 @@ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
490
559
  //if( parser->mark ){ debug_string( "mark after move", parser->mark, 1 ); } else { printf( "mark is now empty\n" ); }
491
560
  }
492
561
 
493
- }else if( parser->overflow_data ){
562
+ }else if( parser->overflow_data ) {
494
563
  /* dump the overflow buffer execution ended at a final state */
495
564
  free( parser->overflow_data );
496
565
  parser->overflow_data = NULL;
@@ -1,10 +1,25 @@
1
1
  #line 1 "parser.rl"
2
+ /**
3
+ * Copyright (c) 2008 Todd A. Fisher
4
+ * see LICENSE
5
+ */
2
6
  #include <stdio.h>
3
7
  #include <stdlib.h>
4
8
  #include <string.h>
5
- #include <unistd.h>
9
+ #include <ctype.h>
6
10
  #include "parser.h"
7
11
 
12
+ #ifdef DEBUG
13
+ static void debug_string( const char *msg, const char *str, size_t len )
14
+ {
15
+ char *pstr = esi_strndup( str, len );
16
+ printf( "%s :'%s'\n", msg, pstr );
17
+ free( pstr );
18
+ }
19
+ #else
20
+ #define debug_string(m,s,l)
21
+ #endif
22
+
8
23
  /* define default callbacks */
9
24
  static void
10
25
  esi_parser_default_start_cb( const void *data,
@@ -28,258 +43,129 @@ esi_parser_default_output_cp(const void *data,
28
43
  {
29
44
  }
30
45
 
31
- #if defined(DEBUG)
32
- static void debug_string( const char *msg, const char *str, size_t len )
46
+ /*
47
+ * flush output buffer
48
+ */
49
+ static void esi_parser_flush_output( ESIParser *parser )
33
50
  {
34
- char *pstr = esi_strndup( str, len );
35
- printf( "%s :'%s'\n", msg, pstr );
36
- free( pstr );
51
+ if( parser->output_buffer_size > 0 ) {
52
+ //debug_string( "esi_parser_flush_output:", parser->output_buffer, parser->output_buffer_size );
53
+ parser->output_handler( (void*)parser->output_buffer, parser->output_buffer_size, parser->user_data );
54
+ parser->output_buffer_size = 0;
55
+ }
37
56
  }
38
- #endif
39
-
57
+ /* send the character to the output handler marking it
58
+ * as ready for consumption, e.g. not an esi tag
59
+ */
40
60
  static void esi_parser_echo_char( ESIParser *parser, char ch )
41
61
  {
42
- parser->output_handler( (void*)&ch, 1, parser->user_data );
62
+ parser->output_buffer[parser->output_buffer_size++] = ch;
63
+ if( parser->output_buffer_size == ESI_OUTPUT_BUFFER_SIZE ) {
64
+ // flush the buffer to the consumer
65
+ esi_parser_flush_output( parser );
66
+ }
43
67
  }
44
-
68
+ /* send any buffered characters to the output handler.
69
+ * This happens when we enter a case such as <em> where the
70
+ * first two characters < and e match the <esi: expression
71
+ */
45
72
  static void esi_parser_echo_buffer( ESIParser *parser )
46
73
  {
47
- // debug_string( "echobuffer", parser->echobuffer, parser->echobuffer_index+1 );
48
- parser->output_handler( parser->echobuffer, parser->echobuffer_index+1, parser->user_data );
74
+ size_t i = 0, len = parser->echobuffer_index + 1;;
75
+ //debug_string( "echobuffer", parser->echobuffer, parser->echobuffer_index+1 );
76
+ //parser->output_handler( parser->echobuffer, parser->echobuffer_index+1, parser->user_data );
77
+ for( ; i < len; ++i ) {
78
+ esi_parser_echo_char( parser, parser->echobuffer[i] );
79
+ }
49
80
  }
50
-
81
+ /*
82
+ * clear the buffer, no buffered characters should be emitted .
83
+ * e.g. we matched an esi tag completely and all buffered characters can be tossed out
84
+ */
51
85
  static void esi_parser_echobuffer_clear( ESIParser *parser )
52
86
  {
53
87
  parser->echobuffer_index = -1;
54
88
  }
55
89
 
90
+ /*
91
+ * add a character to the echobuffer.
92
+ * this happens when we can't determine if the character is allowed to be sent to the client device
93
+ * e.g. matching <e it's not yet determined if these characters are safe to send or not
94
+ */
56
95
  static void esi_parser_concat_to_echobuffer( ESIParser *parser, char ch )
57
96
  {
58
97
  parser->echobuffer_index++;
59
98
 
60
- if( parser->echobuffer_allocated <= parser->echobuffer_index ){
61
- // double the echobuffer size
99
+ if( parser->echobuffer_allocated <= parser->echobuffer_index ) {
100
+ /* double the echobuffer size
101
+ * we're getting some crazy input if this case ever happens
102
+ */
62
103
  parser->echobuffer_allocated *= 2;
63
104
  parser->echobuffer = (char*)realloc( parser->echobuffer, parser->echobuffer_allocated );
64
105
  }
65
106
  parser->echobuffer[parser->echobuffer_index] = ch;
66
107
  // debug_string( "echo buffer", parser->echobuffer, parser->echobuffer_index+1 );
67
108
  }
109
+ /*
110
+ * the mark boundary is not always going to be exactly on the attribute or tag name boundary
111
+ * this trims characters from the left to right, advancing *ptr and reducing *len
112
+ */
113
+ static void ltrim_pointer( const char **ptr, const char *bounds, size_t *len )
114
+ {
115
+ // remove any spaces or = at the before the value
116
+ while( (isspace( **ptr ) ||
117
+ **ptr == '=' ||
118
+ **ptr == '"' ||
119
+ **ptr == '<' ||
120
+ **ptr == '\'' ) && (*len > 0) && (*ptr != bounds) ) {
121
+ (*ptr)++;
122
+ (*len)--;
123
+ }
124
+ }
125
+ /*
126
+ * similar to ltrim_pointer, this walks from bounds to *ptr, reducing *len
127
+ */
128
+ static void rtrim_pointer( const char **ptr, const char *bounds, size_t *len )
129
+ {
130
+ bounds = (*ptr+(*len-1));
131
+ // remove any spaces or = at the before the value
132
+ while( (isspace( *bounds ) ||
133
+ *bounds == '=' ||
134
+ *bounds == '"' ||
135
+ *bounds == '>' ||
136
+ *bounds == '\'') && (*len > 0) && (*ptr != bounds) ){
137
+ bounds--;
138
+ (*len)--;
139
+ }
140
+ }
68
141
 
69
- #line 164 "parser.rl"
70
-
71
-
72
-
73
- #line 74 "parser.c"
74
- static const char _esi_actions[] = {
75
- 0, 1, 9, 2, 9, 0, 2, 9,
76
- 1, 2, 9, 2, 2, 9, 3, 2,
77
- 9, 4, 2, 9, 5, 2, 9, 6,
78
- 2, 9, 7, 2, 9, 8, 3, 9,
79
- 0, 1, 3, 9, 3, 1, 4, 9,
80
- 0, 3, 1, 4, 9, 3, 6, 1
81
-
82
- };
83
-
84
- static const short _esi_key_offsets[] = {
85
- 0, 1, 4, 6, 8, 10, 12, 15,
86
- 19, 21, 23, 25, 28, 36, 48, 59,
87
- 69, 75, 85, 94, 106, 117, 119, 130,
88
- 140, 150, 160, 170, 180, 191, 201, 211,
89
- 221, 231, 246, 256, 265, 277, 288, 298,
90
- 304, 314, 325, 335, 345, 355, 365, 375,
91
- 386, 396, 406, 416, 426, 441, 451, 453,
92
- 455, 456, 457, 466, 475
93
- };
94
-
95
- static const char _esi_trans_keys[] = {
96
- 60, 47, 60, 101, 60, 101, 60, 115,
97
- 60, 105, 58, 60, 60, 97, 122, 60,
98
- 62, 97, 122, 60, 115, 60, 105, 58,
99
- 60, 60, 97, 122, 32, 47, 60, 62,
100
- 9, 13, 97, 122, 32, 45, 47, 60,
101
- 62, 95, 9, 13, 65, 90, 97, 122,
102
- 32, 45, 47, 60, 95, 9, 13, 65,
103
- 90, 97, 122, 45, 60, 61, 95, 48,
104
- 57, 65, 90, 97, 122, 32, 34, 39,
105
- 60, 9, 13, 33, 60, 95, 125, 35,
106
- 38, 40, 90, 97, 123, 34, 39, 60,
107
- 95, 125, 33, 90, 97, 123, 32, 45,
108
- 47, 60, 62, 95, 9, 13, 65, 90,
109
- 97, 122, 32, 45, 47, 60, 95, 9,
110
- 13, 65, 90, 97, 122, 60, 62, 34,
111
- 39, 47, 60, 95, 101, 125, 33, 90,
112
- 97, 123, 34, 39, 60, 95, 101, 125,
113
- 33, 90, 97, 123, 34, 39, 60, 95,
114
- 115, 125, 33, 90, 97, 123, 34, 39,
115
- 60, 95, 105, 125, 33, 90, 97, 123,
116
- 34, 39, 58, 60, 95, 125, 33, 90,
117
- 97, 123, 34, 39, 60, 95, 123, 125,
118
- 33, 90, 97, 122, 34, 39, 60, 62,
119
- 95, 123, 125, 33, 90, 97, 122, 34,
120
- 39, 60, 95, 115, 125, 33, 90, 97,
121
- 123, 34, 39, 60, 95, 105, 125, 33,
122
- 90, 97, 123, 34, 39, 58, 60, 95,
123
- 125, 33, 90, 97, 123, 34, 39, 60,
124
- 95, 123, 125, 33, 90, 97, 122, 32,
125
- 34, 39, 47, 60, 62, 95, 123, 125,
126
- 9, 13, 33, 90, 97, 122, 34, 39,
127
- 60, 62, 95, 125, 33, 90, 97, 123,
128
- 34, 39, 60, 95, 125, 33, 90, 97,
129
- 123, 32, 45, 47, 60, 62, 95, 9,
130
- 13, 65, 90, 97, 122, 32, 45, 47,
131
- 60, 95, 9, 13, 65, 90, 97, 122,
132
- 45, 60, 61, 95, 48, 57, 65, 90,
133
- 97, 122, 32, 34, 39, 60, 9, 13,
134
- 33, 60, 95, 125, 35, 38, 40, 90,
135
- 97, 123, 34, 39, 47, 60, 95, 101,
136
- 125, 33, 90, 97, 123, 34, 39, 60,
137
- 95, 101, 125, 33, 90, 97, 123, 34,
138
- 39, 60, 95, 115, 125, 33, 90, 97,
139
- 123, 34, 39, 60, 95, 105, 125, 33,
140
- 90, 97, 123, 34, 39, 58, 60, 95,
141
- 125, 33, 90, 97, 123, 34, 39, 60,
142
- 95, 123, 125, 33, 90, 97, 122, 34,
143
- 39, 60, 62, 95, 123, 125, 33, 90,
144
- 97, 122, 34, 39, 60, 95, 115, 125,
145
- 33, 90, 97, 123, 34, 39, 60, 95,
146
- 105, 125, 33, 90, 97, 123, 34, 39,
147
- 58, 60, 95, 125, 33, 90, 97, 123,
148
- 34, 39, 60, 95, 123, 125, 33, 90,
149
- 97, 122, 32, 34, 39, 47, 60, 62,
150
- 95, 123, 125, 9, 13, 33, 90, 97,
151
- 122, 34, 39, 60, 62, 95, 125, 33,
152
- 90, 97, 123, 60, 62, 60, 62, 60,
153
- 60, 34, 39, 60, 95, 125, 33, 90,
154
- 97, 123, 34, 39, 60, 95, 125, 33,
155
- 90, 97, 123, 60, 0
156
- };
157
-
158
- static const char _esi_single_lengths[] = {
159
- 1, 3, 2, 2, 2, 2, 1, 2,
160
- 2, 2, 2, 1, 4, 6, 5, 4,
161
- 4, 4, 5, 6, 5, 2, 7, 6,
162
- 6, 6, 6, 6, 7, 6, 6, 6,
163
- 6, 9, 6, 5, 6, 5, 4, 4,
164
- 4, 7, 6, 6, 6, 6, 6, 7,
165
- 6, 6, 6, 6, 9, 6, 2, 2,
166
- 1, 1, 5, 5, 1
167
- };
168
-
169
- static const char _esi_range_lengths[] = {
170
- 0, 0, 0, 0, 0, 0, 1, 1,
171
- 0, 0, 0, 1, 2, 3, 3, 3,
172
- 1, 3, 2, 3, 3, 0, 2, 2,
173
- 2, 2, 2, 2, 2, 2, 2, 2,
174
- 2, 3, 2, 2, 3, 3, 3, 1,
175
- 3, 2, 2, 2, 2, 2, 2, 2,
176
- 2, 2, 2, 2, 3, 2, 0, 0,
177
- 0, 0, 2, 2, 0
178
- };
179
-
180
- static const short _esi_index_offsets[] = {
181
- 0, 2, 6, 9, 12, 15, 18, 21,
182
- 25, 28, 31, 34, 37, 44, 54, 63,
183
- 71, 77, 85, 93, 103, 112, 115, 125,
184
- 134, 143, 152, 161, 170, 180, 189, 198,
185
- 207, 216, 229, 238, 246, 256, 265, 273,
186
- 279, 287, 297, 306, 315, 324, 333, 342,
187
- 352, 361, 370, 379, 388, 401, 410, 413,
188
- 416, 418, 420, 428, 436
189
- };
142
+ #line 306 "parser.rl"
190
143
 
191
- static const char _esi_indicies[] = {
192
- 1, 0, 2, 1, 3, 0, 1, 4,
193
- 0, 1, 5, 0, 1, 6, 0, 7,
194
- 1, 0, 1, 8, 0, 1, 9, 8,
195
- 0, 1, 10, 0, 1, 11, 0, 12,
196
- 1, 0, 1, 13, 0, 14, 15, 1,
197
- 16, 14, 13, 0, 17, 18, 19, 1,
198
- 20, 18, 17, 18, 18, 0, 17, 18,
199
- 19, 1, 18, 17, 18, 18, 0, 18,
200
- 1, 21, 18, 18, 18, 18, 0, 22,
201
- 23, 23, 1, 22, 0, 24, 25, 24,
202
- 24, 24, 24, 24, 0, 26, 26, 25,
203
- 24, 24, 24, 24, 0, 27, 18, 28,
204
- 1, 20, 18, 27, 18, 18, 0, 27,
205
- 18, 28, 1, 18, 27, 18, 18, 0,
206
- 1, 29, 0, 26, 26, 30, 25, 24,
207
- 31, 24, 24, 24, 0, 26, 26, 25,
208
- 24, 32, 24, 24, 24, 0, 26, 26,
209
- 25, 24, 33, 24, 24, 24, 0, 26,
210
- 26, 25, 24, 34, 24, 24, 24, 0,
211
- 26, 26, 35, 25, 24, 24, 24, 24,
212
- 0, 26, 26, 25, 24, 24, 24, 24,
213
- 36, 0, 26, 26, 25, 37, 24, 24,
214
- 24, 24, 36, 0, 26, 26, 25, 24,
215
- 38, 24, 24, 24, 0, 26, 26, 25,
216
- 24, 39, 24, 24, 24, 0, 26, 26,
217
- 40, 25, 24, 24, 24, 24, 0, 26,
218
- 26, 25, 24, 24, 24, 24, 41, 0,
219
- 14, 26, 26, 42, 25, 43, 24, 24,
220
- 24, 14, 24, 41, 0, 26, 26, 25,
221
- 44, 24, 24, 24, 24, 0, 46, 46,
222
- 47, 45, 45, 45, 45, 0, 48, 49,
223
- 28, 1, 20, 49, 48, 49, 49, 0,
224
- 48, 49, 28, 1, 49, 48, 49, 49,
225
- 0, 49, 1, 50, 49, 49, 49, 49,
226
- 0, 51, 52, 52, 1, 51, 0, 45,
227
- 47, 45, 45, 45, 45, 45, 0, 46,
228
- 46, 53, 47, 45, 54, 45, 45, 45,
229
- 0, 46, 46, 47, 45, 55, 45, 45,
230
- 45, 0, 46, 46, 47, 45, 56, 45,
231
- 45, 45, 0, 46, 46, 47, 45, 57,
232
- 45, 45, 45, 0, 46, 46, 58, 47,
233
- 45, 45, 45, 45, 0, 46, 46, 47,
234
- 45, 45, 45, 45, 59, 0, 46, 46,
235
- 47, 60, 45, 45, 45, 45, 59, 0,
236
- 46, 46, 47, 45, 61, 45, 45, 45,
237
- 0, 46, 46, 47, 45, 62, 45, 45,
238
- 45, 0, 46, 46, 63, 47, 45, 45,
239
- 45, 45, 0, 46, 46, 47, 45, 45,
240
- 45, 45, 64, 0, 14, 46, 46, 65,
241
- 47, 66, 45, 45, 45, 14, 45, 64,
242
- 0, 46, 46, 47, 67, 45, 45, 45,
243
- 45, 0, 1, 68, 0, 1, 69, 0,
244
- 1, 0, 71, 70, 74, 74, 75, 73,
245
- 73, 73, 73, 72, 74, 74, 75, 73,
246
- 73, 73, 73, 72, 76, 72, 0
247
- };
248
144
 
249
- static const char _esi_trans_targs_wi[] = {
250
- 0, 1, 2, 8, 3, 4, 5, 6,
251
- 7, 0, 9, 10, 11, 12, 13, 55,
252
- 0, 14, 15, 54, 57, 16, 16, 17,
253
- 18, 22, 19, 20, 21, 57, 23, 29,
254
- 24, 25, 26, 27, 28, 18, 30, 31,
255
- 32, 33, 34, 18, 58, 35, 36, 41,
256
- 37, 38, 39, 39, 40, 42, 48, 43,
257
- 44, 45, 46, 47, 35, 49, 50, 51,
258
- 52, 53, 35, 59, 60, 60, 0, 1,
259
- 0, 35, 36, 41, 1
260
- };
261
145
 
262
- static const char _esi_trans_actions_wi[] = {
263
- 1, 3, 1, 1, 1, 1, 1, 1,
264
- 1, 27, 1, 1, 1, 1, 9, 9,
265
- 24, 1, 1, 9, 15, 18, 1, 1,
266
- 1, 3, 21, 1, 1, 12, 1, 1,
267
- 1, 1, 1, 1, 1, 27, 1, 1,
268
- 1, 1, 9, 24, 1, 1, 21, 3,
269
- 1, 1, 18, 1, 1, 1, 1, 1,
270
- 1, 1, 1, 1, 27, 1, 1, 1,
271
- 1, 9, 24, 1, 12, 1, 6, 30,
272
- 34, 34, 43, 38, 38
146
+ #line 147 "parser.c"
147
+ static const char _esi_eof_actions[] = {
148
+ 0, 0, 0, 0, 0, 0, 0, 0,
149
+ 0, 0, 0, 0, 0, 0, 0, 0,
150
+ 0, 0, 0, 0, 0, 0, 0, 0,
151
+ 0, 0, 0, 0, 0, 0, 0, 0,
152
+ 0, 0, 0, 0, 0, 0, 0, 0,
153
+ 0, 0, 0, 0, 0, 0, 0, 0,
154
+ 0, 0, 0, 0, 0, 0, 0, 0,
155
+ 0, 0, 0, 0, 0, 0, 0, 0,
156
+ 0, 0, 0, 0, 0, 0, 0, 0,
157
+ 0, 0, 0, 0, 10, 10, 10, 10
273
158
  };
274
159
 
275
- static const int esi_start = 56;
276
- static const int esi_first_final = 56;
160
+ static const int esi_start = 75;
161
+ static const int esi_first_final = 75;
277
162
  static const int esi_error = -1;
278
163
 
279
- static const int esi_en_main = 56;
164
+ static const int esi_en_main = 75;
280
165
 
281
- #line 167 "parser.rl"
166
+ #line 309 "parser.rl"
282
167
 
168
+ /* dup the string up to len */
283
169
  char *esi_strndup( const char *str, size_t len )
284
170
  {
285
171
  char *s = (char*)malloc(sizeof(char)*(len+1));
@@ -297,6 +183,29 @@ ESIAttribute *esi_attribute_new( const char *name, size_t name_length, const cha
297
183
  return attr;
298
184
  }
299
185
 
186
+ ESIAttribute *esi_attribute_copy( ESIAttribute *attribute )
187
+ {
188
+ ESIAttribute *head, *nattr;
189
+ if( !attribute ){ return NULL; }
190
+
191
+ // copy the first attribute
192
+ nattr = esi_attribute_new( attribute->name, strlen( attribute->name ),
193
+ attribute->value, strlen( attribute->value ) );
194
+ // save a pointer for return
195
+ head = nattr;
196
+ // copy next attributes
197
+ attribute = attribute->next;
198
+ while( attribute ) {
199
+ // set the next attribute
200
+ nattr->next = esi_attribute_new( attribute->name, strlen( attribute->name ),
201
+ attribute->value, strlen( attribute->value ) );
202
+ // next attribute
203
+ nattr = nattr->next;
204
+ attribute = attribute->next;
205
+ }
206
+ return head;
207
+ }
208
+
300
209
  void esi_attribute_free( ESIAttribute *attribute )
301
210
  {
302
211
  ESIAttribute *ptr;
@@ -314,11 +223,14 @@ ESIParser *esi_parser_new()
314
223
  ESIParser *parser = (ESIParser*)malloc(sizeof(ESIParser));
315
224
  parser->cs = esi_start;
316
225
  parser->mark = NULL;
226
+ parser->tag_text = NULL;
227
+ parser->attr_key = NULL;
228
+ parser->attr_value = NULL;
317
229
  parser->overflow_data_size = 0;
318
230
  parser->overflow_data = NULL;
319
231
 
320
- /* allocate 1024 bytes for the echobuffer */
321
- parser->echobuffer_allocated = 1024;
232
+ /* allocate ESI_OUTPUT_BUFFER_SIZE bytes for the echobuffer */
233
+ parser->echobuffer_allocated = ESI_OUTPUT_BUFFER_SIZE;
322
234
  parser->echobuffer_index = -1;
323
235
  parser->echobuffer = (char*)malloc(sizeof(char)*parser->echobuffer_allocated);
324
236
 
@@ -329,6 +241,9 @@ ESIParser *esi_parser_new()
329
241
  parser->end_tag_handler = esi_parser_default_end_cb;
330
242
  parser->output_handler = esi_parser_default_output_cp;
331
243
 
244
+ parser->output_buffer_size = 0;
245
+ memset( parser->output_buffer, 0, ESI_OUTPUT_BUFFER_SIZE );
246
+
332
247
  return parser;
333
248
  }
334
249
  void esi_parser_free( ESIParser *parser )
@@ -350,32 +265,98 @@ int esi_parser_init( ESIParser *parser )
350
265
  {
351
266
  int cs;
352
267
 
353
- #line 354 "parser.c"
268
+ #line 269 "parser.c"
354
269
  {
355
270
  cs = esi_start;
356
271
  }
357
- #line 238 "parser.rl"
272
+ #line 410 "parser.rl"
358
273
  parser->prev_state = parser->cs = cs;
359
274
  return 0;
360
275
  }
361
276
 
362
277
  static int compute_offset( const char *mark, const char *data )
363
278
  {
364
- if( mark ){
279
+ if( mark ) {
365
280
  return mark - data;
366
281
  }
367
282
  return -1;
368
283
  }
369
284
 
285
+ /*
286
+ * scans the data buffer for a start sequence /<$/, /<e$/, /<es$/, /<esi$/, /<esi:$/
287
+ * returns index of if start sequence found else returns -1
288
+ */
289
+ static int
290
+ esi_parser_scan_for_start( ESIParser *parser, const char *data, size_t length )
291
+ {
292
+ size_t i, f = -2, s = -2;
293
+ char ch;
294
+
295
+ for( i = 0; i < length; ++i ) {
296
+ ch = data[i];
297
+ switch( ch ) {
298
+ case '<':
299
+ f = s = i;
300
+ break;
301
+ case '/':
302
+ if( s == (i-1) && f != -2 ) { s = i; }
303
+ break;
304
+ case 'e':
305
+ if( s == (i-1) && f != -2 ) { s = i; }
306
+ break;
307
+ case 's':
308
+ if( s == (i-1) && f != -2 ) { s = i; }
309
+ break;
310
+ case 'i':
311
+ if( s == (i-1) && f != -2 ) { s = i; }
312
+ break;
313
+ case ':':
314
+ if( s == (i-1) && f != -2 ) { s = i; return f; }
315
+ break;
316
+ default:
317
+ f = s = -2;
318
+ break;
319
+ }
320
+ }
321
+
322
+ // if s and f are still valid at end of input return f
323
+ if( f != -2 && s != -2 ) {
324
+ return f;
325
+ }
326
+ else {
327
+ return -1;
328
+ }
329
+ }
330
+
331
+ /* accept an arbitrary length string buffer
332
+ * when this methods exits it determines if an end state was reached
333
+ * if no end state was reached it saves the full input into an internal buffer
334
+ * when invoked next, it reuses that internable buffer copying all pointers into the
335
+ * newly allocated buffer. if it exits in a terminal state, e.g. 0 then it will dump these buffers
336
+ */
370
337
  int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
371
338
  {
372
339
  int cs = parser->cs;
373
340
  const char *p = data;
341
+ const char *eof = NULL; // ragel 6.x compat
374
342
  const char *pe = data + length;
343
+ int pindex;
375
344
 
376
345
  if( length == 0 ){ return cs; }
377
346
 
378
- if( parser->overflow_data && parser->overflow_data_size > 0 ){
347
+ /* scan data for any '<esi:' start sequences, /<$/, /<e$/, /<es$/, /<esi$/, /<esi:$/ */
348
+ if( cs == esi_start ) {
349
+ pindex = esi_parser_scan_for_start( parser, data, length );
350
+ if( pindex == -1 ) {
351
+ for( pindex = 0; pindex < length; ++pindex ) {
352
+ esi_parser_echo_char( parser, data[pindex] );
353
+ }
354
+ return cs;
355
+ }
356
+ }
357
+
358
+ /* there's an existing overflow buffer data append the new data to the existing data */
359
+ if( parser->overflow_data && parser->overflow_data_size > 0 ) {
379
360
 
380
361
  // recompute mark, tag_text, attr_key, and attr_value since they all exist within overflow_data
381
362
  int mark_offset = compute_offset( parser->mark, parser->overflow_data );
@@ -383,252 +364,1493 @@ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
383
364
  int attr_key_offset = compute_offset( parser->attr_key, parser->overflow_data );
384
365
  int attr_value_offset = compute_offset( parser->attr_value, parser->overflow_data );
385
366
 
386
- // debug_string("grow overflow buffer", parser->overflow_data, parser->overflow_data_size );
387
-
388
367
  parser->overflow_data = (char*)realloc( parser->overflow_data, sizeof(char)*(parser->overflow_data_size+length) );
389
368
  memcpy( parser->overflow_data+parser->overflow_data_size, data, length );
390
369
 
391
370
  p = parser->overflow_data + parser->overflow_data_size;
392
-
371
+
393
372
  // in our new memory space mark will now be
394
- parser->mark = ( mark_offset > 0 ) ? parser->overflow_data + mark_offset : NULL;
395
- parser->tag_text = ( tag_text_offset > 0 ) ? parser->overflow_data + tag_text_offset : NULL;
396
- parser->attr_key = ( attr_key_offset > 0 ) ? parser->overflow_data + attr_key_offset : NULL;
397
- parser->attr_value = ( attr_value_offset > 0 ) ? parser->overflow_data + attr_value_offset : NULL;
373
+ parser->mark = ( mark_offset >= 0 ) ? parser->overflow_data + mark_offset : NULL;
374
+ parser->tag_text = ( tag_text_offset >= 0 ) ? parser->overflow_data + tag_text_offset : NULL;
375
+ parser->attr_key = ( attr_key_offset >= 0 ) ? parser->overflow_data + attr_key_offset : NULL;
376
+ parser->attr_value = ( attr_value_offset >= 0 ) ? parser->overflow_data + attr_value_offset : NULL;
398
377
 
399
378
  data = parser->overflow_data;
400
379
  parser->overflow_data_size = length = length + parser->overflow_data_size;
380
+ // printf( "grow overflow data: %ld\n", parser->overflow_data_size );
401
381
  pe = data + length;
402
382
 
403
- // debug_string( "overflow", parser->overflow_data, parser->overflow_data_size );
404
383
  }
405
384
 
406
- if( !parser->mark ){
385
+ if( !parser->mark ) {
407
386
  parser->mark = p;
408
387
  }
409
388
 
410
389
  // printf( "cs: %d, ", cs );
411
- // debug_string( "data", data, length );
412
390
 
413
391
 
414
- #line 415 "parser.c"
392
+ #line 393 "parser.c"
415
393
  {
416
- int _klen;
417
- unsigned int _trans;
418
- const char *_acts;
419
- unsigned int _nacts;
420
- const char *_keys;
421
-
422
394
  if ( p == pe )
423
- goto _out;
395
+ goto _test_eof;
424
396
  _resume:
425
- _keys = _esi_trans_keys + _esi_key_offsets[cs];
426
- _trans = _esi_index_offsets[cs];
427
-
428
- _klen = _esi_single_lengths[cs];
429
- if ( _klen > 0 ) {
430
- const char *_lower = _keys;
431
- const char *_mid;
432
- const char *_upper = _keys + _klen - 1;
433
- while (1) {
434
- if ( _upper < _lower )
435
- break;
436
-
437
- _mid = _lower + ((_upper-_lower) >> 1);
438
- if ( (*p) < *_mid )
439
- _upper = _mid - 1;
440
- else if ( (*p) > *_mid )
441
- _lower = _mid + 1;
442
- else {
443
- _trans += (_mid - _keys);
444
- goto _match;
445
- }
446
- }
447
- _keys += _klen;
448
- _trans += _klen;
449
- }
450
-
451
- _klen = _esi_range_lengths[cs];
452
- if ( _klen > 0 ) {
453
- const char *_lower = _keys;
454
- const char *_mid;
455
- const char *_upper = _keys + (_klen<<1) - 2;
456
- while (1) {
457
- if ( _upper < _lower )
458
- break;
459
-
460
- _mid = _lower + (((_upper-_lower) >> 1) & ~1);
461
- if ( (*p) < _mid[0] )
462
- _upper = _mid - 2;
463
- else if ( (*p) > _mid[1] )
464
- _lower = _mid + 2;
465
- else {
466
- _trans += ((_mid - _keys)>>1);
467
- goto _match;
468
- }
469
- }
470
- _trans += _klen;
471
- }
472
-
473
- _match:
474
- _trans = _esi_indicies[_trans];
475
- cs = _esi_trans_targs_wi[_trans];
476
-
477
- if ( _esi_trans_actions_wi[_trans] == 0 )
478
- goto _again;
479
-
480
- _acts = _esi_actions + _esi_trans_actions_wi[_trans];
481
- _nacts = (unsigned int) *_acts++;
482
- while ( _nacts-- > 0 )
397
+ switch ( cs ) {
398
+ case 75:
399
+ if ( (*p) == 60 )
400
+ goto tr1;
401
+ goto tr0;
402
+ case 0:
403
+ if ( (*p) == 60 )
404
+ goto tr1;
405
+ goto tr0;
406
+ case 1:
407
+ switch( (*p) ) {
408
+ case 47: goto tr2;
409
+ case 60: goto tr1;
410
+ case 101: goto tr3;
411
+ }
412
+ goto tr0;
413
+ case 2:
414
+ switch( (*p) ) {
415
+ case 60: goto tr1;
416
+ case 101: goto tr4;
417
+ }
418
+ goto tr0;
419
+ case 3:
420
+ switch( (*p) ) {
421
+ case 60: goto tr1;
422
+ case 115: goto tr5;
423
+ }
424
+ goto tr0;
425
+ case 4:
426
+ switch( (*p) ) {
427
+ case 60: goto tr1;
428
+ case 105: goto tr6;
429
+ }
430
+ goto tr0;
431
+ case 5:
432
+ switch( (*p) ) {
433
+ case 58: goto tr7;
434
+ case 60: goto tr1;
435
+ }
436
+ goto tr0;
437
+ case 6:
438
+ if ( (*p) == 60 )
439
+ goto tr1;
440
+ if ( 97 <= (*p) && (*p) <= 122 )
441
+ goto tr8;
442
+ goto tr0;
443
+ case 7:
444
+ switch( (*p) ) {
445
+ case 60: goto tr1;
446
+ case 62: goto tr9;
447
+ }
448
+ if ( 97 <= (*p) && (*p) <= 122 )
449
+ goto tr8;
450
+ goto tr0;
451
+ case 8:
452
+ switch( (*p) ) {
453
+ case 60: goto tr1;
454
+ case 115: goto tr10;
455
+ }
456
+ goto tr0;
457
+ case 9:
458
+ switch( (*p) ) {
459
+ case 60: goto tr1;
460
+ case 105: goto tr11;
461
+ }
462
+ goto tr0;
463
+ case 10:
464
+ switch( (*p) ) {
465
+ case 58: goto tr12;
466
+ case 60: goto tr1;
467
+ }
468
+ goto tr0;
469
+ case 11:
470
+ if ( (*p) == 60 )
471
+ goto tr1;
472
+ if ( 97 <= (*p) && (*p) <= 122 )
473
+ goto tr13;
474
+ goto tr0;
475
+ case 12:
476
+ switch( (*p) ) {
477
+ case 32: goto tr14;
478
+ case 60: goto tr1;
479
+ case 62: goto tr15;
480
+ }
481
+ if ( (*p) > 13 ) {
482
+ if ( 97 <= (*p) && (*p) <= 122 )
483
+ goto tr13;
484
+ } else if ( (*p) >= 9 )
485
+ goto tr14;
486
+ goto tr0;
487
+ case 13:
488
+ switch( (*p) ) {
489
+ case 32: goto tr16;
490
+ case 45: goto tr17;
491
+ case 47: goto tr18;
492
+ case 60: goto tr1;
493
+ case 62: goto tr19;
494
+ case 95: goto tr17;
495
+ }
496
+ if ( (*p) < 65 ) {
497
+ if ( 9 <= (*p) && (*p) <= 13 )
498
+ goto tr16;
499
+ } else if ( (*p) > 90 ) {
500
+ if ( 97 <= (*p) && (*p) <= 122 )
501
+ goto tr17;
502
+ } else
503
+ goto tr17;
504
+ goto tr0;
505
+ case 14:
506
+ switch( (*p) ) {
507
+ case 32: goto tr16;
508
+ case 45: goto tr17;
509
+ case 47: goto tr18;
510
+ case 60: goto tr1;
511
+ case 95: goto tr17;
512
+ }
513
+ if ( (*p) < 65 ) {
514
+ if ( 9 <= (*p) && (*p) <= 13 )
515
+ goto tr16;
516
+ } else if ( (*p) > 90 ) {
517
+ if ( 97 <= (*p) && (*p) <= 122 )
518
+ goto tr17;
519
+ } else
520
+ goto tr17;
521
+ goto tr0;
522
+ case 15:
523
+ switch( (*p) ) {
524
+ case 45: goto tr17;
525
+ case 60: goto tr1;
526
+ case 61: goto tr20;
527
+ case 95: goto tr17;
528
+ }
529
+ if ( (*p) < 65 ) {
530
+ if ( 48 <= (*p) && (*p) <= 57 )
531
+ goto tr17;
532
+ } else if ( (*p) > 90 ) {
533
+ if ( 97 <= (*p) && (*p) <= 122 )
534
+ goto tr17;
535
+ } else
536
+ goto tr17;
537
+ goto tr0;
538
+ case 16:
539
+ switch( (*p) ) {
540
+ case 32: goto tr21;
541
+ case 34: goto tr22;
542
+ case 39: goto tr23;
543
+ case 60: goto tr1;
544
+ }
545
+ if ( 9 <= (*p) && (*p) <= 13 )
546
+ goto tr21;
547
+ goto tr0;
548
+ case 17:
549
+ switch( (*p) ) {
550
+ case 34: goto tr24;
551
+ case 60: goto tr25;
552
+ case 92: goto tr26;
553
+ }
554
+ goto tr22;
555
+ case 18:
556
+ switch( (*p) ) {
557
+ case 34: goto tr24;
558
+ case 47: goto tr27;
559
+ case 60: goto tr25;
560
+ case 92: goto tr26;
561
+ case 101: goto tr28;
562
+ }
563
+ goto tr22;
564
+ case 19:
565
+ switch( (*p) ) {
566
+ case 34: goto tr24;
567
+ case 60: goto tr25;
568
+ case 92: goto tr26;
569
+ case 101: goto tr29;
570
+ }
571
+ goto tr22;
572
+ case 20:
573
+ switch( (*p) ) {
574
+ case 34: goto tr30;
575
+ case 60: goto tr25;
576
+ case 92: goto tr26;
577
+ }
578
+ goto tr22;
579
+ case 21:
580
+ switch( (*p) ) {
581
+ case 32: goto tr31;
582
+ case 34: goto tr24;
583
+ case 45: goto tr32;
584
+ case 47: goto tr33;
585
+ case 60: goto tr25;
586
+ case 62: goto tr34;
587
+ case 92: goto tr26;
588
+ case 95: goto tr32;
589
+ }
590
+ if ( (*p) < 65 ) {
591
+ if ( 9 <= (*p) && (*p) <= 13 )
592
+ goto tr31;
593
+ } else if ( (*p) > 90 ) {
594
+ if ( 97 <= (*p) && (*p) <= 122 )
595
+ goto tr32;
596
+ } else
597
+ goto tr32;
598
+ goto tr22;
599
+ case 22:
600
+ switch( (*p) ) {
601
+ case 32: goto tr31;
602
+ case 34: goto tr24;
603
+ case 45: goto tr32;
604
+ case 47: goto tr33;
605
+ case 60: goto tr25;
606
+ case 92: goto tr26;
607
+ case 95: goto tr32;
608
+ }
609
+ if ( (*p) < 65 ) {
610
+ if ( 9 <= (*p) && (*p) <= 13 )
611
+ goto tr31;
612
+ } else if ( (*p) > 90 ) {
613
+ if ( 97 <= (*p) && (*p) <= 122 )
614
+ goto tr32;
615
+ } else
616
+ goto tr32;
617
+ goto tr22;
618
+ case 23:
619
+ switch( (*p) ) {
620
+ case 34: goto tr24;
621
+ case 45: goto tr32;
622
+ case 60: goto tr25;
623
+ case 61: goto tr35;
624
+ case 92: goto tr26;
625
+ case 95: goto tr32;
626
+ }
627
+ if ( (*p) < 65 ) {
628
+ if ( 48 <= (*p) && (*p) <= 57 )
629
+ goto tr32;
630
+ } else if ( (*p) > 90 ) {
631
+ if ( 97 <= (*p) && (*p) <= 122 )
632
+ goto tr32;
633
+ } else
634
+ goto tr32;
635
+ goto tr22;
636
+ case 24:
637
+ switch( (*p) ) {
638
+ case 32: goto tr36;
639
+ case 34: goto tr30;
640
+ case 39: goto tr37;
641
+ case 60: goto tr25;
642
+ case 92: goto tr26;
643
+ }
644
+ if ( 9 <= (*p) && (*p) <= 13 )
645
+ goto tr36;
646
+ goto tr22;
647
+ case 25:
648
+ switch( (*p) ) {
649
+ case 34: goto tr38;
650
+ case 39: goto tr30;
651
+ case 60: goto tr39;
652
+ case 92: goto tr40;
653
+ }
654
+ goto tr37;
655
+ case 26:
656
+ switch( (*p) ) {
657
+ case 32: goto tr41;
658
+ case 39: goto tr24;
659
+ case 45: goto tr42;
660
+ case 47: goto tr43;
661
+ case 60: goto tr44;
662
+ case 62: goto tr45;
663
+ case 92: goto tr46;
664
+ case 95: goto tr42;
665
+ }
666
+ if ( (*p) < 65 ) {
667
+ if ( 9 <= (*p) && (*p) <= 13 )
668
+ goto tr41;
669
+ } else if ( (*p) > 90 ) {
670
+ if ( 97 <= (*p) && (*p) <= 122 )
671
+ goto tr42;
672
+ } else
673
+ goto tr42;
674
+ goto tr23;
675
+ case 27:
676
+ switch( (*p) ) {
677
+ case 39: goto tr24;
678
+ case 60: goto tr44;
679
+ case 92: goto tr46;
680
+ }
681
+ goto tr23;
682
+ case 28:
683
+ switch( (*p) ) {
684
+ case 39: goto tr24;
685
+ case 47: goto tr47;
686
+ case 60: goto tr44;
687
+ case 92: goto tr46;
688
+ case 101: goto tr48;
689
+ }
690
+ goto tr23;
691
+ case 29:
692
+ switch( (*p) ) {
693
+ case 39: goto tr24;
694
+ case 60: goto tr44;
695
+ case 92: goto tr46;
696
+ case 101: goto tr49;
697
+ }
698
+ goto tr23;
699
+ case 30:
700
+ switch( (*p) ) {
701
+ case 39: goto tr38;
702
+ case 60: goto tr44;
703
+ case 92: goto tr46;
704
+ }
705
+ goto tr23;
706
+ case 31:
707
+ switch( (*p) ) {
708
+ case 39: goto tr24;
709
+ case 60: goto tr44;
710
+ case 92: goto tr46;
711
+ case 115: goto tr50;
712
+ }
713
+ goto tr23;
714
+ case 32:
715
+ switch( (*p) ) {
716
+ case 39: goto tr24;
717
+ case 60: goto tr44;
718
+ case 92: goto tr46;
719
+ case 105: goto tr51;
720
+ }
721
+ goto tr23;
722
+ case 33:
723
+ switch( (*p) ) {
724
+ case 39: goto tr24;
725
+ case 58: goto tr52;
726
+ case 60: goto tr44;
727
+ case 92: goto tr46;
728
+ }
729
+ goto tr23;
730
+ case 34:
731
+ switch( (*p) ) {
732
+ case 39: goto tr24;
733
+ case 60: goto tr44;
734
+ case 92: goto tr46;
735
+ }
736
+ if ( 97 <= (*p) && (*p) <= 122 )
737
+ goto tr53;
738
+ goto tr23;
739
+ case 35:
740
+ switch( (*p) ) {
741
+ case 39: goto tr24;
742
+ case 60: goto tr44;
743
+ case 62: goto tr54;
744
+ case 92: goto tr46;
745
+ }
746
+ if ( 97 <= (*p) && (*p) <= 122 )
747
+ goto tr53;
748
+ goto tr23;
749
+ case 36:
750
+ switch( (*p) ) {
751
+ case 39: goto tr24;
752
+ case 60: goto tr44;
753
+ case 92: goto tr46;
754
+ case 115: goto tr55;
755
+ }
756
+ goto tr23;
757
+ case 37:
758
+ switch( (*p) ) {
759
+ case 39: goto tr24;
760
+ case 60: goto tr44;
761
+ case 92: goto tr46;
762
+ case 105: goto tr56;
763
+ }
764
+ goto tr23;
765
+ case 38:
766
+ switch( (*p) ) {
767
+ case 39: goto tr24;
768
+ case 58: goto tr57;
769
+ case 60: goto tr44;
770
+ case 92: goto tr46;
771
+ }
772
+ goto tr23;
773
+ case 39:
774
+ switch( (*p) ) {
775
+ case 39: goto tr24;
776
+ case 60: goto tr44;
777
+ case 92: goto tr46;
778
+ }
779
+ if ( 97 <= (*p) && (*p) <= 122 )
780
+ goto tr58;
781
+ goto tr23;
782
+ case 40:
783
+ switch( (*p) ) {
784
+ case 32: goto tr59;
785
+ case 39: goto tr24;
786
+ case 60: goto tr44;
787
+ case 62: goto tr60;
788
+ case 92: goto tr46;
789
+ }
790
+ if ( (*p) > 13 ) {
791
+ if ( 97 <= (*p) && (*p) <= 122 )
792
+ goto tr58;
793
+ } else if ( (*p) >= 9 )
794
+ goto tr59;
795
+ goto tr23;
796
+ case 76:
797
+ switch( (*p) ) {
798
+ case 39: goto tr100;
799
+ case 60: goto tr101;
800
+ case 92: goto tr102;
801
+ }
802
+ goto tr99;
803
+ case 41:
804
+ switch( (*p) ) {
805
+ case 32: goto tr41;
806
+ case 39: goto tr24;
807
+ case 45: goto tr42;
808
+ case 47: goto tr43;
809
+ case 60: goto tr44;
810
+ case 92: goto tr46;
811
+ case 95: goto tr42;
812
+ }
813
+ if ( (*p) < 65 ) {
814
+ if ( 9 <= (*p) && (*p) <= 13 )
815
+ goto tr41;
816
+ } else if ( (*p) > 90 ) {
817
+ if ( 97 <= (*p) && (*p) <= 122 )
818
+ goto tr42;
819
+ } else
820
+ goto tr42;
821
+ goto tr23;
822
+ case 42:
823
+ switch( (*p) ) {
824
+ case 39: goto tr24;
825
+ case 45: goto tr42;
826
+ case 60: goto tr44;
827
+ case 61: goto tr61;
828
+ case 92: goto tr46;
829
+ case 95: goto tr42;
830
+ }
831
+ if ( (*p) < 65 ) {
832
+ if ( 48 <= (*p) && (*p) <= 57 )
833
+ goto tr42;
834
+ } else if ( (*p) > 90 ) {
835
+ if ( 97 <= (*p) && (*p) <= 122 )
836
+ goto tr42;
837
+ } else
838
+ goto tr42;
839
+ goto tr23;
840
+ case 43:
841
+ switch( (*p) ) {
842
+ case 32: goto tr62;
843
+ case 34: goto tr37;
844
+ case 39: goto tr38;
845
+ case 60: goto tr44;
846
+ case 92: goto tr46;
847
+ }
848
+ if ( 9 <= (*p) && (*p) <= 13 )
849
+ goto tr62;
850
+ goto tr23;
851
+ case 44:
852
+ switch( (*p) ) {
853
+ case 39: goto tr24;
854
+ case 60: goto tr44;
855
+ case 62: goto tr63;
856
+ case 92: goto tr46;
857
+ }
858
+ goto tr23;
859
+ case 45:
860
+ switch( (*p) ) {
861
+ case 34: goto tr38;
862
+ case 39: goto tr30;
863
+ case 47: goto tr64;
864
+ case 60: goto tr39;
865
+ case 92: goto tr40;
866
+ case 101: goto tr65;
867
+ }
868
+ goto tr37;
869
+ case 46:
870
+ switch( (*p) ) {
871
+ case 34: goto tr38;
872
+ case 39: goto tr30;
873
+ case 60: goto tr39;
874
+ case 92: goto tr40;
875
+ case 101: goto tr66;
876
+ }
877
+ goto tr37;
878
+ case 47:
879
+ switch( (*p) ) {
880
+ case 34: goto tr67;
881
+ case 39: goto tr67;
882
+ case 60: goto tr39;
883
+ case 92: goto tr40;
884
+ }
885
+ goto tr37;
886
+ case 48:
887
+ switch( (*p) ) {
888
+ case 32: goto tr68;
889
+ case 34: goto tr38;
890
+ case 39: goto tr30;
891
+ case 45: goto tr69;
892
+ case 47: goto tr70;
893
+ case 60: goto tr39;
894
+ case 62: goto tr71;
895
+ case 92: goto tr40;
896
+ case 95: goto tr69;
897
+ }
898
+ if ( (*p) < 65 ) {
899
+ if ( 9 <= (*p) && (*p) <= 13 )
900
+ goto tr68;
901
+ } else if ( (*p) > 90 ) {
902
+ if ( 97 <= (*p) && (*p) <= 122 )
903
+ goto tr69;
904
+ } else
905
+ goto tr69;
906
+ goto tr37;
907
+ case 49:
908
+ switch( (*p) ) {
909
+ case 32: goto tr68;
910
+ case 34: goto tr38;
911
+ case 39: goto tr30;
912
+ case 45: goto tr69;
913
+ case 47: goto tr70;
914
+ case 60: goto tr39;
915
+ case 92: goto tr40;
916
+ case 95: goto tr69;
917
+ }
918
+ if ( (*p) < 65 ) {
919
+ if ( 9 <= (*p) && (*p) <= 13 )
920
+ goto tr68;
921
+ } else if ( (*p) > 90 ) {
922
+ if ( 97 <= (*p) && (*p) <= 122 )
923
+ goto tr69;
924
+ } else
925
+ goto tr69;
926
+ goto tr37;
927
+ case 50:
928
+ switch( (*p) ) {
929
+ case 34: goto tr38;
930
+ case 39: goto tr30;
931
+ case 45: goto tr69;
932
+ case 60: goto tr39;
933
+ case 61: goto tr72;
934
+ case 92: goto tr40;
935
+ case 95: goto tr69;
936
+ }
937
+ if ( (*p) < 65 ) {
938
+ if ( 48 <= (*p) && (*p) <= 57 )
939
+ goto tr69;
940
+ } else if ( (*p) > 90 ) {
941
+ if ( 97 <= (*p) && (*p) <= 122 )
942
+ goto tr69;
943
+ } else
944
+ goto tr69;
945
+ goto tr37;
946
+ case 51:
947
+ switch( (*p) ) {
948
+ case 32: goto tr73;
949
+ case 34: goto tr67;
950
+ case 39: goto tr67;
951
+ case 60: goto tr39;
952
+ case 92: goto tr40;
953
+ }
954
+ if ( 9 <= (*p) && (*p) <= 13 )
955
+ goto tr73;
956
+ goto tr37;
957
+ case 52:
958
+ switch( (*p) ) {
959
+ case 34: goto tr38;
960
+ case 39: goto tr30;
961
+ case 60: goto tr39;
962
+ case 62: goto tr74;
963
+ case 92: goto tr40;
964
+ }
965
+ goto tr37;
966
+ case 77:
967
+ switch( (*p) ) {
968
+ case 34: goto tr104;
969
+ case 39: goto tr105;
970
+ case 60: goto tr106;
971
+ case 92: goto tr107;
972
+ }
973
+ goto tr103;
974
+ case 53:
975
+ switch( (*p) ) {
976
+ case 34: goto tr38;
977
+ case 39: goto tr30;
978
+ case 60: goto tr39;
979
+ case 92: goto tr40;
980
+ case 115: goto tr75;
981
+ }
982
+ goto tr37;
983
+ case 54:
984
+ switch( (*p) ) {
985
+ case 34: goto tr38;
986
+ case 39: goto tr30;
987
+ case 60: goto tr39;
988
+ case 92: goto tr40;
989
+ case 105: goto tr76;
990
+ }
991
+ goto tr37;
992
+ case 55:
993
+ switch( (*p) ) {
994
+ case 34: goto tr38;
995
+ case 39: goto tr30;
996
+ case 58: goto tr77;
997
+ case 60: goto tr39;
998
+ case 92: goto tr40;
999
+ }
1000
+ goto tr37;
1001
+ case 56:
1002
+ switch( (*p) ) {
1003
+ case 34: goto tr38;
1004
+ case 39: goto tr30;
1005
+ case 60: goto tr39;
1006
+ case 92: goto tr40;
1007
+ }
1008
+ if ( 97 <= (*p) && (*p) <= 122 )
1009
+ goto tr78;
1010
+ goto tr37;
1011
+ case 57:
1012
+ switch( (*p) ) {
1013
+ case 34: goto tr38;
1014
+ case 39: goto tr30;
1015
+ case 60: goto tr39;
1016
+ case 62: goto tr79;
1017
+ case 92: goto tr40;
1018
+ }
1019
+ if ( 97 <= (*p) && (*p) <= 122 )
1020
+ goto tr78;
1021
+ goto tr37;
1022
+ case 58:
1023
+ switch( (*p) ) {
1024
+ case 34: goto tr38;
1025
+ case 39: goto tr30;
1026
+ case 60: goto tr39;
1027
+ case 92: goto tr40;
1028
+ case 115: goto tr80;
1029
+ }
1030
+ goto tr37;
1031
+ case 59:
1032
+ switch( (*p) ) {
1033
+ case 34: goto tr38;
1034
+ case 39: goto tr30;
1035
+ case 60: goto tr39;
1036
+ case 92: goto tr40;
1037
+ case 105: goto tr81;
1038
+ }
1039
+ goto tr37;
1040
+ case 60:
1041
+ switch( (*p) ) {
1042
+ case 34: goto tr38;
1043
+ case 39: goto tr30;
1044
+ case 58: goto tr82;
1045
+ case 60: goto tr39;
1046
+ case 92: goto tr40;
1047
+ }
1048
+ goto tr37;
1049
+ case 61:
1050
+ switch( (*p) ) {
1051
+ case 34: goto tr38;
1052
+ case 39: goto tr30;
1053
+ case 60: goto tr39;
1054
+ case 92: goto tr40;
1055
+ }
1056
+ if ( 97 <= (*p) && (*p) <= 122 )
1057
+ goto tr83;
1058
+ goto tr37;
1059
+ case 62:
1060
+ switch( (*p) ) {
1061
+ case 32: goto tr84;
1062
+ case 34: goto tr38;
1063
+ case 39: goto tr30;
1064
+ case 60: goto tr39;
1065
+ case 62: goto tr85;
1066
+ case 92: goto tr40;
1067
+ }
1068
+ if ( (*p) > 13 ) {
1069
+ if ( 97 <= (*p) && (*p) <= 122 )
1070
+ goto tr83;
1071
+ } else if ( (*p) >= 9 )
1072
+ goto tr84;
1073
+ goto tr37;
1074
+ case 63:
1075
+ switch( (*p) ) {
1076
+ case 34: goto tr24;
1077
+ case 60: goto tr25;
1078
+ case 62: goto tr86;
1079
+ case 92: goto tr26;
1080
+ }
1081
+ goto tr22;
1082
+ case 78:
1083
+ switch( (*p) ) {
1084
+ case 34: goto tr100;
1085
+ case 60: goto tr109;
1086
+ case 92: goto tr110;
1087
+ }
1088
+ goto tr108;
1089
+ case 64:
1090
+ switch( (*p) ) {
1091
+ case 34: goto tr24;
1092
+ case 60: goto tr25;
1093
+ case 92: goto tr26;
1094
+ case 115: goto tr87;
1095
+ }
1096
+ goto tr22;
1097
+ case 65:
1098
+ switch( (*p) ) {
1099
+ case 34: goto tr24;
1100
+ case 60: goto tr25;
1101
+ case 92: goto tr26;
1102
+ case 105: goto tr88;
1103
+ }
1104
+ goto tr22;
1105
+ case 66:
1106
+ switch( (*p) ) {
1107
+ case 34: goto tr24;
1108
+ case 58: goto tr89;
1109
+ case 60: goto tr25;
1110
+ case 92: goto tr26;
1111
+ }
1112
+ goto tr22;
1113
+ case 67:
1114
+ switch( (*p) ) {
1115
+ case 34: goto tr24;
1116
+ case 60: goto tr25;
1117
+ case 92: goto tr26;
1118
+ }
1119
+ if ( 97 <= (*p) && (*p) <= 122 )
1120
+ goto tr90;
1121
+ goto tr22;
1122
+ case 68:
1123
+ switch( (*p) ) {
1124
+ case 34: goto tr24;
1125
+ case 60: goto tr25;
1126
+ case 62: goto tr91;
1127
+ case 92: goto tr26;
1128
+ }
1129
+ if ( 97 <= (*p) && (*p) <= 122 )
1130
+ goto tr90;
1131
+ goto tr22;
1132
+ case 69:
1133
+ switch( (*p) ) {
1134
+ case 34: goto tr24;
1135
+ case 60: goto tr25;
1136
+ case 92: goto tr26;
1137
+ case 115: goto tr92;
1138
+ }
1139
+ goto tr22;
1140
+ case 70:
1141
+ switch( (*p) ) {
1142
+ case 34: goto tr24;
1143
+ case 60: goto tr25;
1144
+ case 92: goto tr26;
1145
+ case 105: goto tr93;
1146
+ }
1147
+ goto tr22;
1148
+ case 71:
1149
+ switch( (*p) ) {
1150
+ case 34: goto tr24;
1151
+ case 58: goto tr94;
1152
+ case 60: goto tr25;
1153
+ case 92: goto tr26;
1154
+ }
1155
+ goto tr22;
1156
+ case 72:
1157
+ switch( (*p) ) {
1158
+ case 34: goto tr24;
1159
+ case 60: goto tr25;
1160
+ case 92: goto tr26;
1161
+ }
1162
+ if ( 97 <= (*p) && (*p) <= 122 )
1163
+ goto tr95;
1164
+ goto tr22;
1165
+ case 73:
1166
+ switch( (*p) ) {
1167
+ case 32: goto tr96;
1168
+ case 34: goto tr24;
1169
+ case 60: goto tr25;
1170
+ case 62: goto tr97;
1171
+ case 92: goto tr26;
1172
+ }
1173
+ if ( (*p) > 13 ) {
1174
+ if ( 97 <= (*p) && (*p) <= 122 )
1175
+ goto tr95;
1176
+ } else if ( (*p) >= 9 )
1177
+ goto tr96;
1178
+ goto tr22;
1179
+ case 74:
1180
+ switch( (*p) ) {
1181
+ case 60: goto tr1;
1182
+ case 62: goto tr98;
1183
+ }
1184
+ goto tr0;
1185
+ case 79:
1186
+ if ( (*p) == 60 )
1187
+ goto tr112;
1188
+ goto tr111;
1189
+ }
1190
+
1191
+ tr0: cs = 0; goto f0;
1192
+ tr9: cs = 0; goto f2;
1193
+ tr111: cs = 0; goto f10;
1194
+ tr1: cs = 1; goto f1;
1195
+ tr112: cs = 1; goto f12;
1196
+ tr2: cs = 2; goto f0;
1197
+ tr4: cs = 3; goto f0;
1198
+ tr5: cs = 4; goto f0;
1199
+ tr6: cs = 5; goto f0;
1200
+ tr7: cs = 6; goto f0;
1201
+ tr8: cs = 7; goto f0;
1202
+ tr3: cs = 8; goto f0;
1203
+ tr10: cs = 9; goto f0;
1204
+ tr11: cs = 10; goto f0;
1205
+ tr12: cs = 11; goto f0;
1206
+ tr13: cs = 12; goto f0;
1207
+ tr14: cs = 13; goto f3;
1208
+ tr24: cs = 13; goto f7;
1209
+ tr100: cs = 13; goto f11;
1210
+ tr16: cs = 14; goto f0;
1211
+ tr17: cs = 15; goto f0;
1212
+ tr21: cs = 16; goto f0;
1213
+ tr20: cs = 16; goto f6;
1214
+ tr22: cs = 17; goto f0;
1215
+ tr91: cs = 17; goto f2;
1216
+ tr108: cs = 17; goto f10;
1217
+ tr25: cs = 18; goto f1;
1218
+ tr109: cs = 18; goto f12;
1219
+ tr27: cs = 19; goto f0;
1220
+ tr26: cs = 20; goto f0;
1221
+ tr110: cs = 20; goto f10;
1222
+ tr96: cs = 21; goto f3;
1223
+ tr30: cs = 21; goto f7;
1224
+ tr105: cs = 21; goto f11;
1225
+ tr31: cs = 22; goto f0;
1226
+ tr32: cs = 23; goto f0;
1227
+ tr36: cs = 24; goto f0;
1228
+ tr35: cs = 24; goto f6;
1229
+ tr37: cs = 25; goto f0;
1230
+ tr79: cs = 25; goto f2;
1231
+ tr103: cs = 25; goto f10;
1232
+ tr59: cs = 26; goto f3;
1233
+ tr38: cs = 26; goto f7;
1234
+ tr104: cs = 26; goto f11;
1235
+ tr23: cs = 27; goto f0;
1236
+ tr54: cs = 27; goto f2;
1237
+ tr99: cs = 27; goto f10;
1238
+ tr44: cs = 28; goto f1;
1239
+ tr101: cs = 28; goto f12;
1240
+ tr47: cs = 29; goto f0;
1241
+ tr46: cs = 30; goto f0;
1242
+ tr102: cs = 30; goto f10;
1243
+ tr49: cs = 31; goto f0;
1244
+ tr50: cs = 32; goto f0;
1245
+ tr51: cs = 33; goto f0;
1246
+ tr52: cs = 34; goto f0;
1247
+ tr53: cs = 35; goto f0;
1248
+ tr48: cs = 36; goto f0;
1249
+ tr55: cs = 37; goto f0;
1250
+ tr56: cs = 38; goto f0;
1251
+ tr57: cs = 39; goto f0;
1252
+ tr58: cs = 40; goto f0;
1253
+ tr41: cs = 41; goto f0;
1254
+ tr42: cs = 42; goto f0;
1255
+ tr62: cs = 43; goto f0;
1256
+ tr61: cs = 43; goto f6;
1257
+ tr43: cs = 44; goto f0;
1258
+ tr39: cs = 45; goto f1;
1259
+ tr106: cs = 45; goto f12;
1260
+ tr64: cs = 46; goto f0;
1261
+ tr40: cs = 47; goto f0;
1262
+ tr107: cs = 47; goto f10;
1263
+ tr84: cs = 48; goto f3;
1264
+ tr67: cs = 48; goto f7;
1265
+ tr68: cs = 49; goto f0;
1266
+ tr69: cs = 50; goto f0;
1267
+ tr73: cs = 51; goto f0;
1268
+ tr72: cs = 51; goto f6;
1269
+ tr70: cs = 52; goto f0;
1270
+ tr66: cs = 53; goto f0;
1271
+ tr75: cs = 54; goto f0;
1272
+ tr76: cs = 55; goto f0;
1273
+ tr77: cs = 56; goto f0;
1274
+ tr78: cs = 57; goto f0;
1275
+ tr65: cs = 58; goto f0;
1276
+ tr80: cs = 59; goto f0;
1277
+ tr81: cs = 60; goto f0;
1278
+ tr82: cs = 61; goto f0;
1279
+ tr83: cs = 62; goto f0;
1280
+ tr33: cs = 63; goto f0;
1281
+ tr29: cs = 64; goto f0;
1282
+ tr87: cs = 65; goto f0;
1283
+ tr88: cs = 66; goto f0;
1284
+ tr89: cs = 67; goto f0;
1285
+ tr90: cs = 68; goto f0;
1286
+ tr28: cs = 69; goto f0;
1287
+ tr92: cs = 70; goto f0;
1288
+ tr93: cs = 71; goto f0;
1289
+ tr94: cs = 72; goto f0;
1290
+ tr95: cs = 73; goto f0;
1291
+ tr18: cs = 74; goto f0;
1292
+ tr60: cs = 76; goto f4;
1293
+ tr45: cs = 76; goto f5;
1294
+ tr63: cs = 76; goto f8;
1295
+ tr85: cs = 77; goto f4;
1296
+ tr71: cs = 77; goto f5;
1297
+ tr74: cs = 77; goto f8;
1298
+ tr97: cs = 78; goto f4;
1299
+ tr34: cs = 78; goto f5;
1300
+ tr86: cs = 78; goto f8;
1301
+ tr15: cs = 79; goto f4;
1302
+ tr19: cs = 79; goto f5;
1303
+ tr98: cs = 79; goto f8;
1304
+
1305
+ f0:
1306
+ #line 280 "parser.rl"
483
1307
  {
484
- switch ( *_acts++ )
485
- {
486
- case 0:
487
- #line 71 "parser.rl"
1308
+ //printf( "[%c:%d],", *p, cs );
1309
+ switch( cs ) {
1310
+ case 0: /* non matching state */
1311
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1312
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1313
+ /* send the echo buffer */
1314
+ esi_parser_echo_buffer( parser );
1315
+ }
1316
+ /* send the current character */
1317
+ esi_parser_echo_char( parser, *p );
1318
+ }
1319
+ /* clear the echo buffer */
1320
+ esi_parser_echobuffer_clear( parser );
1321
+ break;
1322
+ default:
1323
+ /* append to the echo buffer */
1324
+ esi_parser_concat_to_echobuffer( parser, *p );
1325
+ }
1326
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1327
+ is state 12 and 7
1328
+ */
1329
+ parser->prev_state = cs;
1330
+ }
1331
+ goto _again;
1332
+ f1:
1333
+ #line 280 "parser.rl"
1334
+ {
1335
+ //printf( "[%c:%d],", *p, cs );
1336
+ switch( cs ) {
1337
+ case 0: /* non matching state */
1338
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1339
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1340
+ /* send the echo buffer */
1341
+ esi_parser_echo_buffer( parser );
1342
+ }
1343
+ /* send the current character */
1344
+ esi_parser_echo_char( parser, *p );
1345
+ }
1346
+ /* clear the echo buffer */
1347
+ esi_parser_echobuffer_clear( parser );
1348
+ break;
1349
+ default:
1350
+ /* append to the echo buffer */
1351
+ esi_parser_concat_to_echobuffer( parser, *p );
1352
+ }
1353
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1354
+ is state 12 and 7
1355
+ */
1356
+ parser->prev_state = cs;
1357
+ }
1358
+ #line 144 "parser.rl"
488
1359
  {
489
1360
  parser->mark = p;
490
- // printf( "begin\n" );
1361
+ //debug_string( "begin", p, 1 );
491
1362
  }
492
- break;
493
- case 1:
494
- #line 75 "parser.rl"
1363
+ goto _again;
1364
+ f10:
1365
+ #line 280 "parser.rl"
1366
+ {
1367
+ //printf( "[%c:%d],", *p, cs );
1368
+ switch( cs ) {
1369
+ case 0: /* non matching state */
1370
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1371
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1372
+ /* send the echo buffer */
1373
+ esi_parser_echo_buffer( parser );
1374
+ }
1375
+ /* send the current character */
1376
+ esi_parser_echo_char( parser, *p );
1377
+ }
1378
+ /* clear the echo buffer */
1379
+ esi_parser_echobuffer_clear( parser );
1380
+ break;
1381
+ default:
1382
+ /* append to the echo buffer */
1383
+ esi_parser_concat_to_echobuffer( parser, *p );
1384
+ }
1385
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1386
+ is state 12 and 7
1387
+ */
1388
+ parser->prev_state = cs;
1389
+ }
1390
+ #line 148 "parser.rl"
495
1391
  {
496
1392
  // printf( "finish\n" );
497
1393
  }
498
- break;
499
- case 2:
500
- #line 80 "parser.rl"
1394
+ goto _again;
1395
+ f3:
1396
+ #line 280 "parser.rl"
1397
+ {
1398
+ //printf( "[%c:%d],", *p, cs );
1399
+ switch( cs ) {
1400
+ case 0: /* non matching state */
1401
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1402
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1403
+ /* send the echo buffer */
1404
+ esi_parser_echo_buffer( parser );
1405
+ }
1406
+ /* send the current character */
1407
+ esi_parser_echo_char( parser, *p );
1408
+ }
1409
+ /* clear the echo buffer */
1410
+ esi_parser_echobuffer_clear( parser );
1411
+ break;
1412
+ default:
1413
+ /* append to the echo buffer */
1414
+ esi_parser_concat_to_echobuffer( parser, *p );
1415
+ }
1416
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1417
+ is state 12 and 7
1418
+ */
1419
+ parser->prev_state = cs;
1420
+ }
1421
+ #line 153 "parser.rl"
501
1422
  {
502
1423
  parser->tag_text = parser->mark+1;
503
1424
  parser->tag_text_length = p - (parser->mark+1);
504
- // debug_string( "have esi start", parser->tag_text, parser->tag_text_length );
505
1425
  parser->mark = p;
506
1426
  }
507
- break;
508
- case 3:
509
- #line 87 "parser.rl"
1427
+ goto _again;
1428
+ f8:
1429
+ #line 280 "parser.rl"
1430
+ {
1431
+ //printf( "[%c:%d],", *p, cs );
1432
+ switch( cs ) {
1433
+ case 0: /* non matching state */
1434
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1435
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1436
+ /* send the echo buffer */
1437
+ esi_parser_echo_buffer( parser );
1438
+ }
1439
+ /* send the current character */
1440
+ esi_parser_echo_char( parser, *p );
1441
+ }
1442
+ /* clear the echo buffer */
1443
+ esi_parser_echobuffer_clear( parser );
1444
+ break;
1445
+ default:
1446
+ /* append to the echo buffer */
1447
+ esi_parser_concat_to_echobuffer( parser, *p );
1448
+ }
1449
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1450
+ is state 12 and 7
1451
+ */
1452
+ parser->prev_state = cs;
1453
+ }
1454
+ #line 160 "parser.rl"
510
1455
  {
511
- // debug_string( "parsed esi tag", parser->tag_text, parser->tag_text_length );
1456
+ /* trim the tag text */
1457
+ ltrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1458
+ rtrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1459
+
1460
+ /* send the start tag and end tag message */
1461
+ esi_parser_flush_output( parser );
512
1462
  parser->start_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->attributes, parser->user_data );
1463
+ esi_parser_flush_output( parser );
513
1464
  parser->end_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->user_data );
1465
+ esi_parser_flush_output( parser );
1466
+
1467
+ /* mark the position */
514
1468
  parser->tag_text = NULL;
515
1469
  parser->tag_text_length = 0;
1470
+ parser->mark = p;
1471
+
1472
+ /* clear out the echo buffer */
1473
+ esi_parser_echobuffer_clear( parser );
516
1474
  }
517
- break;
518
- case 4:
519
- #line 95 "parser.rl"
1475
+ goto _again;
1476
+ f5:
1477
+ #line 280 "parser.rl"
520
1478
  {
521
- // debug_string( "parsed esi tag", parser->tag_text, parser->tag_text_length );
1479
+ //printf( "[%c:%d],", *p, cs );
1480
+ switch( cs ) {
1481
+ case 0: /* non matching state */
1482
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1483
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1484
+ /* send the echo buffer */
1485
+ esi_parser_echo_buffer( parser );
1486
+ }
1487
+ /* send the current character */
1488
+ esi_parser_echo_char( parser, *p );
1489
+ }
1490
+ /* clear the echo buffer */
1491
+ esi_parser_echobuffer_clear( parser );
1492
+ break;
1493
+ default:
1494
+ /* append to the echo buffer */
1495
+ esi_parser_concat_to_echobuffer( parser, *p );
1496
+ }
1497
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1498
+ is state 12 and 7
1499
+ */
1500
+ parser->prev_state = cs;
1501
+ }
1502
+ #line 182 "parser.rl"
1503
+ {
1504
+ /* trim tag text */
1505
+ ltrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1506
+ rtrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1507
+
1508
+ /* send the start and end tag message */
1509
+ esi_parser_flush_output( parser );
522
1510
  parser->start_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->attributes, parser->user_data );
1511
+ esi_parser_flush_output( parser );
1512
+
523
1513
  parser->tag_text = NULL;
524
1514
  parser->tag_text_length = 0;
1515
+ parser->mark = p;
1516
+
1517
+ /* clear out the echo buffer */
1518
+ esi_parser_echobuffer_clear( parser );
525
1519
  }
526
- break;
527
- case 5:
528
- #line 102 "parser.rl"
1520
+ goto _again;
1521
+ f6:
1522
+ #line 280 "parser.rl"
529
1523
  {
1524
+ //printf( "[%c:%d],", *p, cs );
1525
+ switch( cs ) {
1526
+ case 0: /* non matching state */
1527
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1528
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1529
+ /* send the echo buffer */
1530
+ esi_parser_echo_buffer( parser );
1531
+ }
1532
+ /* send the current character */
1533
+ esi_parser_echo_char( parser, *p );
1534
+ }
1535
+ /* clear the echo buffer */
1536
+ esi_parser_echobuffer_clear( parser );
1537
+ break;
1538
+ default:
1539
+ /* append to the echo buffer */
1540
+ esi_parser_concat_to_echobuffer( parser, *p );
1541
+ }
1542
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1543
+ is state 12 and 7
1544
+ */
1545
+ parser->prev_state = cs;
1546
+ }
1547
+ #line 201 "parser.rl"
1548
+ {
1549
+ /* save the attribute key start */
530
1550
  parser->attr_key = parser->mark;
1551
+ /* compute the length of the key */
531
1552
  parser->attr_key_length = p - parser->mark;
1553
+ /* save the position following the key */
532
1554
  parser->mark = p;
533
- // debug_string( "\tattribute key", parser->attr_key, parser->attr_key_length );
1555
+
1556
+ /* trim the attribute key */
1557
+ ltrim_pointer( &(parser->attr_key), p, &(parser->attr_key_length) );
1558
+ rtrim_pointer( &(parser->attr_key), p, &(parser->attr_key_length) );
534
1559
  }
535
- break;
536
- case 6:
537
- #line 109 "parser.rl"
1560
+ goto _again;
1561
+ f7:
1562
+ #line 280 "parser.rl"
1563
+ {
1564
+ //printf( "[%c:%d],", *p, cs );
1565
+ switch( cs ) {
1566
+ case 0: /* non matching state */
1567
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1568
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1569
+ /* send the echo buffer */
1570
+ esi_parser_echo_buffer( parser );
1571
+ }
1572
+ /* send the current character */
1573
+ esi_parser_echo_char( parser, *p );
1574
+ }
1575
+ /* clear the echo buffer */
1576
+ esi_parser_echobuffer_clear( parser );
1577
+ break;
1578
+ default:
1579
+ /* append to the echo buffer */
1580
+ esi_parser_concat_to_echobuffer( parser, *p );
1581
+ }
1582
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1583
+ is state 12 and 7
1584
+ */
1585
+ parser->prev_state = cs;
1586
+ }
1587
+ #line 215 "parser.rl"
538
1588
  {
539
1589
  ESIAttribute *attr;
1590
+
1591
+ /* save the attribute value start */
540
1592
  parser->attr_value = parser->mark;
1593
+ /* compute the length of the value */
541
1594
  parser->attr_value_length = p - parser->mark;
1595
+ /* svae the position following the value */
542
1596
  parser->mark = p;
543
- // allocate a new attribute
1597
+
1598
+ /* trim the attribute value */
1599
+ ltrim_pointer( &(parser->attr_value), p, &(parser->attr_value_length) );
1600
+ rtrim_pointer( &(parser->attr_value), p, &(parser->attr_value_length) );
1601
+
1602
+ /* using the attr_key and attr_value, allocate a new attribute object */
544
1603
  attr = esi_attribute_new( parser->attr_key, parser->attr_key_length,
545
1604
  parser->attr_value, parser->attr_value_length );
546
- if( parser->attributes ){
1605
+
1606
+ /* add the new attribute to the list of attributes */
1607
+ if( parser->attributes ) {
547
1608
  parser->last->next = attr;
548
1609
  parser->last = attr;
549
1610
  }
550
- else{
1611
+ else {
551
1612
  parser->last = parser->attributes = attr;
552
1613
  }
553
- // debug_string( "\tattribute value", parser->attr_value, parser->attr_value_length );
554
1614
  }
555
- break;
556
- case 7:
557
- #line 127 "parser.rl"
1615
+ goto _again;
1616
+ f4:
1617
+ #line 280 "parser.rl"
1618
+ {
1619
+ //printf( "[%c:%d],", *p, cs );
1620
+ switch( cs ) {
1621
+ case 0: /* non matching state */
1622
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1623
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1624
+ /* send the echo buffer */
1625
+ esi_parser_echo_buffer( parser );
1626
+ }
1627
+ /* send the current character */
1628
+ esi_parser_echo_char( parser, *p );
1629
+ }
1630
+ /* clear the echo buffer */
1631
+ esi_parser_echobuffer_clear( parser );
1632
+ break;
1633
+ default:
1634
+ /* append to the echo buffer */
1635
+ esi_parser_concat_to_echobuffer( parser, *p );
1636
+ }
1637
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1638
+ is state 12 and 7
1639
+ */
1640
+ parser->prev_state = cs;
1641
+ }
1642
+ #line 244 "parser.rl"
558
1643
  {
1644
+
559
1645
  parser->tag_text = parser->mark;
560
1646
  parser->tag_text_length = p - parser->mark;
1647
+
561
1648
  parser->mark = p;
1649
+
1650
+ ltrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1651
+ rtrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1652
+
1653
+ esi_parser_flush_output( parser );
562
1654
  parser->start_tag_handler( data, parser->tag_text, parser->tag_text_length, NULL, parser->user_data );
1655
+ esi_parser_flush_output( parser );
1656
+
1657
+ esi_parser_echobuffer_clear( parser );
563
1658
  }
564
- break;
565
- case 8:
566
- #line 134 "parser.rl"
1659
+ goto _again;
1660
+ f2:
1661
+ #line 280 "parser.rl"
1662
+ {
1663
+ //printf( "[%c:%d],", *p, cs );
1664
+ switch( cs ) {
1665
+ case 0: /* non matching state */
1666
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1667
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1668
+ /* send the echo buffer */
1669
+ esi_parser_echo_buffer( parser );
1670
+ }
1671
+ /* send the current character */
1672
+ esi_parser_echo_char( parser, *p );
1673
+ }
1674
+ /* clear the echo buffer */
1675
+ esi_parser_echobuffer_clear( parser );
1676
+ break;
1677
+ default:
1678
+ /* append to the echo buffer */
1679
+ esi_parser_concat_to_echobuffer( parser, *p );
1680
+ }
1681
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1682
+ is state 12 and 7
1683
+ */
1684
+ parser->prev_state = cs;
1685
+ }
1686
+ #line 262 "parser.rl"
567
1687
  {
1688
+ /* offset by 2 to account for the </ characters */
568
1689
  parser->tag_text = parser->mark+2;
569
1690
  parser->tag_text_length = p - (parser->mark+2);
1691
+
570
1692
  parser->mark = p;
1693
+
1694
+ ltrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1695
+ rtrim_pointer( &(parser->tag_text), p, &(parser->tag_text_length) );
1696
+
1697
+ esi_parser_flush_output( parser );
571
1698
  parser->end_tag_handler( data, parser->tag_text, parser->tag_text_length, parser->user_data );
1699
+ esi_parser_flush_output( parser );
1700
+
1701
+ esi_parser_echobuffer_clear( parser );
572
1702
  }
573
- break;
574
- case 9:
575
- #line 141 "parser.rl"
1703
+ goto _again;
1704
+ f12:
1705
+ #line 280 "parser.rl"
576
1706
  {
577
- switch( cs ){
578
- case 0:
579
- if( parser->prev_state != 12 && parser->prev_state != 7 ){
580
- if( parser->echobuffer && (parser->prev_state != (esi_en_main +1)) && parser->prev_state != 60 ){
581
- // stream echobuffer
1707
+ //printf( "[%c:%d],", *p, cs );
1708
+ switch( cs ) {
1709
+ case 0: /* non matching state */
1710
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1711
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1712
+ /* send the echo buffer */
582
1713
  esi_parser_echo_buffer( parser );
583
1714
  }
584
- // printf( "[%d: %c]", cs, *p );
585
- // stream the current character
1715
+ /* send the current character */
586
1716
  esi_parser_echo_char( parser, *p );
587
1717
  }
588
- // clear the echobuffer
1718
+ /* clear the echo buffer */
589
1719
  esi_parser_echobuffer_clear( parser );
590
1720
  break;
591
1721
  default:
592
- // append characters to echobuffer
1722
+ /* append to the echo buffer */
593
1723
  esi_parser_concat_to_echobuffer( parser, *p );
594
1724
  }
1725
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1726
+ is state 12 and 7
1727
+ */
595
1728
  parser->prev_state = cs;
596
1729
  }
597
- break;
598
- #line 599 "parser.c"
599
- }
600
- }
1730
+ #line 144 "parser.rl"
1731
+ {
1732
+ parser->mark = p;
1733
+ //debug_string( "begin", p, 1 );
1734
+ }
1735
+ #line 148 "parser.rl"
1736
+ {
1737
+ // printf( "finish\n" );
1738
+ }
1739
+ goto _again;
1740
+ f11:
1741
+ #line 280 "parser.rl"
1742
+ {
1743
+ //printf( "[%c:%d],", *p, cs );
1744
+ switch( cs ) {
1745
+ case 0: /* non matching state */
1746
+ if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
1747
+ if( parser->echobuffer && parser->echobuffer_index != -1 ){
1748
+ /* send the echo buffer */
1749
+ esi_parser_echo_buffer( parser );
1750
+ }
1751
+ /* send the current character */
1752
+ esi_parser_echo_char( parser, *p );
1753
+ }
1754
+ /* clear the echo buffer */
1755
+ esi_parser_echobuffer_clear( parser );
1756
+ break;
1757
+ default:
1758
+ /* append to the echo buffer */
1759
+ esi_parser_concat_to_echobuffer( parser, *p );
1760
+ }
1761
+ /* save the previous state, necessary for end case detection such as /> and </esi:try> the trailing > character
1762
+ is state 12 and 7
1763
+ */
1764
+ parser->prev_state = cs;
1765
+ }
1766
+ #line 215 "parser.rl"
1767
+ {
1768
+ ESIAttribute *attr;
1769
+
1770
+ /* save the attribute value start */
1771
+ parser->attr_value = parser->mark;
1772
+ /* compute the length of the value */
1773
+ parser->attr_value_length = p - parser->mark;
1774
+ /* svae the position following the value */
1775
+ parser->mark = p;
1776
+
1777
+ /* trim the attribute value */
1778
+ ltrim_pointer( &(parser->attr_value), p, &(parser->attr_value_length) );
1779
+ rtrim_pointer( &(parser->attr_value), p, &(parser->attr_value_length) );
1780
+
1781
+ /* using the attr_key and attr_value, allocate a new attribute object */
1782
+ attr = esi_attribute_new( parser->attr_key, parser->attr_key_length,
1783
+ parser->attr_value, parser->attr_value_length );
1784
+
1785
+ /* add the new attribute to the list of attributes */
1786
+ if( parser->attributes ) {
1787
+ parser->last->next = attr;
1788
+ parser->last = attr;
1789
+ }
1790
+ else {
1791
+ parser->last = parser->attributes = attr;
1792
+ }
1793
+ }
1794
+ #line 148 "parser.rl"
1795
+ {
1796
+ // printf( "finish\n" );
1797
+ }
1798
+ goto _again;
601
1799
 
602
1800
  _again:
603
1801
  if ( ++p != pe )
604
1802
  goto _resume;
605
- _out: {}
1803
+ _test_eof: {}
1804
+ if ( p == eof )
1805
+ {
1806
+ switch ( _esi_eof_actions[cs] ) {
1807
+ case 10:
1808
+ #line 148 "parser.rl"
1809
+ {
1810
+ // printf( "finish\n" );
1811
+ }
1812
+ break;
1813
+ #line 1814 "parser.c"
1814
+ }
606
1815
  }
607
- #line 294 "parser.rl"
1816
+
1817
+ }
1818
+ #line 529 "parser.rl"
608
1819
 
609
1820
  parser->cs = cs;
610
1821
 
611
- if( cs != esi_start && cs != 0 ){
1822
+ if( cs != esi_start && cs != 0 ) {
612
1823
 
1824
+ /* reached the end and we're not at a termination point save the buffer as overflow */
613
1825
  if( !parser->overflow_data ){
614
1826
  // recompute mark, tag_text, attr_key, and attr_value since they all exist within overflow_data
615
1827
  int mark_offset = compute_offset( parser->mark, data );
616
1828
  int tag_text_offset = compute_offset( parser->tag_text, data );
617
1829
  int attr_key_offset = compute_offset( parser->attr_key, data );
618
1830
  int attr_value_offset = compute_offset( parser->attr_value, data );
1831
+ //debug_string( "mark before move", parser->mark, 1 );
619
1832
 
620
- parser->overflow_data = (char*)malloc( sizeof( char ) * length );
1833
+ if( ESI_OUTPUT_BUFFER_SIZE > length ) {
1834
+ parser->echobuffer_allocated = ESI_OUTPUT_BUFFER_SIZE;
1835
+ }
1836
+ else {
1837
+ parser->echobuffer_allocated = length;
1838
+ }
1839
+ parser->overflow_data = (char*)malloc( sizeof( char ) * parser->echobuffer_allocated );
621
1840
  memcpy( parser->overflow_data, data, length );
622
1841
  parser->overflow_data_size = length;
1842
+ //printf( "allocate overflow data: %ld\n", parser->echobuffer_allocated );
623
1843
 
624
1844
  // in our new memory space mark will now be
625
- parser->mark = ( mark_offset > 0 ) ? parser->overflow_data + mark_offset : NULL;
626
- parser->tag_text = ( tag_text_offset > 0 ) ? parser->overflow_data + tag_text_offset : NULL;
627
- parser->attr_key = ( attr_key_offset > 0 ) ? parser->overflow_data + attr_key_offset : NULL;
628
- parser->attr_value = ( attr_value_offset > 0 ) ? parser->overflow_data + attr_value_offset : NULL;
1845
+ parser->mark = ( mark_offset >= 0 ) ? parser->overflow_data + mark_offset : NULL;
1846
+ parser->tag_text = ( tag_text_offset >= 0 ) ? parser->overflow_data + tag_text_offset : NULL;
1847
+ parser->attr_key = ( attr_key_offset >= 0 ) ? parser->overflow_data + attr_key_offset : NULL;
1848
+ parser->attr_value = ( attr_value_offset >= 0 ) ? parser->overflow_data + attr_value_offset : NULL;
1849
+ //if( parser->mark ){ debug_string( "mark after move", parser->mark, 1 ); } else { printf( "mark is now empty\n" ); }
629
1850
  }
630
1851
 
631
- }else if( parser->overflow_data ){
1852
+ }else if( parser->overflow_data ) {
1853
+ /* dump the overflow buffer execution ended at a final state */
632
1854
  free( parser->overflow_data );
633
1855
  parser->overflow_data = NULL;
634
1856
  parser->overflow_data_size = 0;
@@ -638,9 +1860,7 @@ _again:
638
1860
  }
639
1861
  int esi_parser_finish( ESIParser *parser )
640
1862
  {
641
-
642
- #line 643 "parser.c"
643
- #line 328 "parser.rl"
1863
+ esi_parser_flush_output( parser );
644
1864
  return 0;
645
1865
  }
646
1866