mongrel_esi 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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