waitress-core 0.2.2 → 0.2.3
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.
- checksums.yaml +4 -4
 - data/Gemfile +4 -4
 - data/LICENSE +21 -21
 - data/Rakefile +13 -13
 - data/bin/waitress +22 -22
 - data/ext/Thanks.md +1 -1
 - data/ext/waitress_http11/ext_help.h +15 -15
 - data/ext/waitress_http11/extconf.rb +6 -6
 - data/ext/waitress_http11/http11.c +532 -532
 - data/ext/waitress_http11/http11_parser.c +1216 -1216
 - data/ext/waitress_http11/http11_parser.h +49 -49
 - data/ext/waitress_http11/http11_parser.java.rl +171 -171
 - data/ext/waitress_http11/http11_parser.rl +165 -165
 - data/ext/waitress_http11/http11_parser_common.rl +55 -55
 - data/ext/waitress_http11/http11_wrb_parser.h +91 -91
 - data/lib/waitress/chef.rb +113 -113
 - data/lib/waitress/configure.rb +121 -121
 - data/lib/waitress/evalbind.rb +9 -9
 - data/lib/waitress/handlers/dirhandler.rb +39 -39
 - data/lib/waitress/handlers/handler.rb +57 -57
 - data/lib/waitress/handlers/handler404.rb +25 -25
 - data/lib/waitress/handlers/libhandler.rb +58 -58
 - data/lib/waitress/kernel.rb +182 -182
 - data/lib/waitress/parse/query.rb +60 -60
 - data/lib/waitress/request.rb +45 -45
 - data/lib/waitress/resources/default_config.rb +52 -52
 - data/lib/waitress/resources/http/404.html +18 -18
 - data/lib/waitress/resources/http/css/hack.css +37 -37
 - data/lib/waitress/resources/http/css/waitress.css +57 -57
 - data/lib/waitress/resources/http/fonts/svg/latin/hack-bold-latin-webfont.svg +240 -240
 - data/lib/waitress/resources/http/fonts/svg/latin/hack-bolditalic-latin-webfont.svg +240 -240
 - data/lib/waitress/resources/http/fonts/svg/latin/hack-italic-latin-webfont.svg +240 -240
 - data/lib/waitress/resources/http/fonts/svg/latin/hack-regular-latin-webfont.svg +240 -240
 - data/lib/waitress/resources/http/index.html +15 -15
 - data/lib/waitress/response.rb +105 -105
 - data/lib/waitress/server.rb +160 -161
 - data/lib/waitress/util.rb +707 -707
 - data/lib/waitress/version.rb +3 -3
 - data/lib/waitress/vhost.rb +217 -217
 - data/lib/waitress.rb +99 -106
 - data/lib/waitress_http11.bundle +0 -0
 - data/waitress-core.gemspec +29 -29
 - metadata +4 -4
 - data/lib/waitress_http11.so +0 -0
 
| 
         @@ -1,165 +1,165 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            /**
         
     | 
| 
       2 
     | 
    
         
            -
             * Copyright (c) 2005 Zed A. Shaw
         
     | 
| 
       3 
     | 
    
         
            -
             * You can redistribute it and/or modify it under the same terms as Ruby.
         
     | 
| 
       4 
     | 
    
         
            -
             */
         
     | 
| 
       5 
     | 
    
         
            -
            #include "http11_parser.h"
         
     | 
| 
       6 
     | 
    
         
            -
            #include <stdio.h>
         
     | 
| 
       7 
     | 
    
         
            -
            #include <assert.h>
         
     | 
| 
       8 
     | 
    
         
            -
            #include <stdlib.h>
         
     | 
| 
       9 
     | 
    
         
            -
            #include <ctype.h>
         
     | 
| 
       10 
     | 
    
         
            -
            #include <string.h>
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            /*
         
     | 
| 
       13 
     | 
    
         
            -
             * capitalizes all lower-case ASCII characters,
         
     | 
| 
       14 
     | 
    
         
            -
             * converts dashes to underscores.
         
     | 
| 
       15 
     | 
    
         
            -
             */
         
     | 
| 
       16 
     | 
    
         
            -
            static void snake_upcase_char(char *c)
         
     | 
| 
       17 
     | 
    
         
            -
            {
         
     | 
| 
       18 
     | 
    
         
            -
                if (*c >= 'a' && *c <= 'z')
         
     | 
| 
       19 
     | 
    
         
            -
                  *c &= ~0x20;
         
     | 
| 
       20 
     | 
    
         
            -
                else if (*c == '-')
         
     | 
| 
       21 
     | 
    
         
            -
                  *c = '_';
         
     | 
| 
       22 
     | 
    
         
            -
            }
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            #define LEN(AT, FPC) (FPC - buffer - parser->AT)
         
     | 
| 
       25 
     | 
    
         
            -
            #define MARK(M,FPC) (parser->M = (FPC) - buffer)
         
     | 
| 
       26 
     | 
    
         
            -
            #define PTR_TO(F) (buffer + parser->F)
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
            /** Machine **/
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            %%{
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
              machine http_parser;
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
              action mark {MARK(mark, fpc); }
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
              action start_field { MARK(field_start, fpc); }
         
     | 
| 
       38 
     | 
    
         
            -
              action snake_upcase_field { snake_upcase_char((char *)fpc); }
         
     | 
| 
       39 
     | 
    
         
            -
              action write_field {
         
     | 
| 
       40 
     | 
    
         
            -
                parser->field_len = LEN(field_start, fpc);
         
     | 
| 
       41 
     | 
    
         
            -
              }
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
              action start_value { MARK(mark, fpc); }
         
     | 
| 
       44 
     | 
    
         
            -
              action write_value {
         
     | 
| 
       45 
     | 
    
         
            -
                if(parser->http_field != NULL) {
         
     | 
| 
       46 
     | 
    
         
            -
                  parser->http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, fpc));
         
     | 
| 
       47 
     | 
    
         
            -
                }
         
     | 
| 
       48 
     | 
    
         
            -
              }
         
     | 
| 
       49 
     | 
    
         
            -
              action request_method {
         
     | 
| 
       50 
     | 
    
         
            -
                if(parser->request_method != NULL)
         
     | 
| 
       51 
     | 
    
         
            -
                  parser->request_method(parser->data, PTR_TO(mark), LEN(mark, fpc));
         
     | 
| 
       52 
     | 
    
         
            -
              }
         
     | 
| 
       53 
     | 
    
         
            -
              action request_uri {
         
     | 
| 
       54 
     | 
    
         
            -
                if(parser->request_uri != NULL)
         
     | 
| 
       55 
     | 
    
         
            -
                  parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, fpc));
         
     | 
| 
       56 
     | 
    
         
            -
              }
         
     | 
| 
       57 
     | 
    
         
            -
              action fragment {
         
     | 
| 
       58 
     | 
    
         
            -
                if(parser->fragment != NULL)
         
     | 
| 
       59 
     | 
    
         
            -
                  parser->fragment(parser->data, PTR_TO(mark), LEN(mark, fpc));
         
     | 
| 
       60 
     | 
    
         
            -
              }
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
              action start_query {MARK(query_start, fpc); }
         
     | 
| 
       63 
     | 
    
         
            -
              action query_string {
         
     | 
| 
       64 
     | 
    
         
            -
                if(parser->query_string != NULL)
         
     | 
| 
       65 
     | 
    
         
            -
                  parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, fpc));
         
     | 
| 
       66 
     | 
    
         
            -
              }
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
              action http_version {
         
     | 
| 
       69 
     | 
    
         
            -
                if(parser->http_version != NULL)
         
     | 
| 
       70 
     | 
    
         
            -
                  parser->http_version(parser->data, PTR_TO(mark), LEN(mark, fpc));
         
     | 
| 
       71 
     | 
    
         
            -
              }
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
              action request_path {
         
     | 
| 
       74 
     | 
    
         
            -
                if(parser->request_path != NULL)
         
     | 
| 
       75 
     | 
    
         
            -
                  parser->request_path(parser->data, PTR_TO(mark), LEN(mark,fpc));
         
     | 
| 
       76 
     | 
    
         
            -
              }
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
              action done {
         
     | 
| 
       79 
     | 
    
         
            -
                parser->body_start = fpc - buffer + 1;
         
     | 
| 
       80 
     | 
    
         
            -
                if(parser->header_done != NULL)
         
     | 
| 
       81 
     | 
    
         
            -
                  parser->header_done(parser->data, fpc + 1, pe - fpc - 1);
         
     | 
| 
       82 
     | 
    
         
            -
                fbreak;
         
     | 
| 
       83 
     | 
    
         
            -
              }
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
              include http_parser_common "http11_parser_common.rl";
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
            }%%
         
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
            /** Data **/
         
     | 
| 
       90 
     | 
    
         
            -
            %% write data;
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
            int http_parser_init(http_parser *parser)  {
         
     | 
| 
       93 
     | 
    
         
            -
              int cs = 0;
         
     | 
| 
       94 
     | 
    
         
            -
              %% write init;
         
     | 
| 
       95 
     | 
    
         
            -
              parser->cs = cs;
         
     | 
| 
       96 
     | 
    
         
            -
              parser->body_start = 0;
         
     | 
| 
       97 
     | 
    
         
            -
              parser->content_len = 0;
         
     | 
| 
       98 
     | 
    
         
            -
              parser->mark = 0;
         
     | 
| 
       99 
     | 
    
         
            -
              parser->nread = 0;
         
     | 
| 
       100 
     | 
    
         
            -
              parser->field_len = 0;
         
     | 
| 
       101 
     | 
    
         
            -
              parser->field_start = 0;
         
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
              return(1);
         
     | 
| 
       104 
     | 
    
         
            -
            }
         
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
            /** exec **/
         
     | 
| 
       108 
     | 
    
         
            -
            size_t http_parser_execute(http_parser *parser, const char *buffer, size_t len, size_t off)  {
         
     | 
| 
       109 
     | 
    
         
            -
              const char *p, *pe;
         
     | 
| 
       110 
     | 
    
         
            -
              int cs = parser->cs;
         
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
              assert(off <= len && "offset past end of buffer");
         
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
              p = buffer+off;
         
     | 
| 
       115 
     | 
    
         
            -
              pe = buffer+len;
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
              assert(*pe == '\0' && "pointer does not end on NUL");
         
     | 
| 
       118 
     | 
    
         
            -
              assert(pe - p == len - off && "pointers aren't same distance");
         
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
              %% write exec;
         
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
              parser->cs = cs;
         
     | 
| 
       124 
     | 
    
         
            -
              parser->nread += p - (buffer + off);
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
              assert(p <= pe && "buffer overflow after parsing execute");
         
     | 
| 
       127 
     | 
    
         
            -
              assert(parser->nread <= len && "nread longer than length");
         
     | 
| 
       128 
     | 
    
         
            -
              assert(parser->body_start <= len && "body starts after buffer end");
         
     | 
| 
       129 
     | 
    
         
            -
              assert(parser->mark < len && "mark is after buffer end");
         
     | 
| 
       130 
     | 
    
         
            -
              assert(parser->field_len <= len && "field has length longer than whole buffer");
         
     | 
| 
       131 
     | 
    
         
            -
              assert(parser->field_start < len && "field starts after buffer end");
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
              if(parser->body_start) {
         
     | 
| 
       134 
     | 
    
         
            -
                /* final \r\n combo encountered so stop right here */
         
     | 
| 
       135 
     | 
    
         
            -
                %%write eof;
         
     | 
| 
       136 
     | 
    
         
            -
                parser->nread++;
         
     | 
| 
       137 
     | 
    
         
            -
              }
         
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
              return(parser->nread);
         
     | 
| 
       140 
     | 
    
         
            -
            }
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
            int http_parser_finish(http_parser *parser)
         
     | 
| 
       143 
     | 
    
         
            -
            {
         
     | 
| 
       144 
     | 
    
         
            -
              int cs = parser->cs;
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
              %%write eof;
         
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
              parser->cs = cs;
         
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
     | 
    
         
            -
              if (http_parser_has_error(parser) ) {
         
     | 
| 
       151 
     | 
    
         
            -
                return -1;
         
     | 
| 
       152 
     | 
    
         
            -
              } else if (http_parser_is_finished(parser) ) {
         
     | 
| 
       153 
     | 
    
         
            -
                return 1;
         
     | 
| 
       154 
     | 
    
         
            -
              } else {
         
     | 
| 
       155 
     | 
    
         
            -
                return 0;
         
     | 
| 
       156 
     | 
    
         
            -
              }
         
     | 
| 
       157 
     | 
    
         
            -
            }
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
            int http_parser_has_error(http_parser *parser) {
         
     | 
| 
       160 
     | 
    
         
            -
              return parser->cs == http_parser_error;
         
     | 
| 
       161 
     | 
    
         
            -
            }
         
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
            int http_parser_is_finished(http_parser *parser) {
         
     | 
| 
       164 
     | 
    
         
            -
              return parser->cs == http_parser_first_final;
         
     | 
| 
       165 
     | 
    
         
            -
            }
         
     | 
| 
      
 1 
     | 
    
         
            +
            /**
         
     | 
| 
      
 2 
     | 
    
         
            +
             * Copyright (c) 2005 Zed A. Shaw
         
     | 
| 
      
 3 
     | 
    
         
            +
             * You can redistribute it and/or modify it under the same terms as Ruby.
         
     | 
| 
      
 4 
     | 
    
         
            +
             */
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include "http11_parser.h"
         
     | 
| 
      
 6 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 7 
     | 
    
         
            +
            #include <assert.h>
         
     | 
| 
      
 8 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 9 
     | 
    
         
            +
            #include <ctype.h>
         
     | 
| 
      
 10 
     | 
    
         
            +
            #include <string.h>
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            /*
         
     | 
| 
      
 13 
     | 
    
         
            +
             * capitalizes all lower-case ASCII characters,
         
     | 
| 
      
 14 
     | 
    
         
            +
             * converts dashes to underscores.
         
     | 
| 
      
 15 
     | 
    
         
            +
             */
         
     | 
| 
      
 16 
     | 
    
         
            +
            static void snake_upcase_char(char *c)
         
     | 
| 
      
 17 
     | 
    
         
            +
            {
         
     | 
| 
      
 18 
     | 
    
         
            +
                if (*c >= 'a' && *c <= 'z')
         
     | 
| 
      
 19 
     | 
    
         
            +
                  *c &= ~0x20;
         
     | 
| 
      
 20 
     | 
    
         
            +
                else if (*c == '-')
         
     | 
| 
      
 21 
     | 
    
         
            +
                  *c = '_';
         
     | 
| 
      
 22 
     | 
    
         
            +
            }
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            #define LEN(AT, FPC) (FPC - buffer - parser->AT)
         
     | 
| 
      
 25 
     | 
    
         
            +
            #define MARK(M,FPC) (parser->M = (FPC) - buffer)
         
     | 
| 
      
 26 
     | 
    
         
            +
            #define PTR_TO(F) (buffer + parser->F)
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            /** Machine **/
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            %%{
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              machine http_parser;
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              action mark {MARK(mark, fpc); }
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              action start_field { MARK(field_start, fpc); }
         
     | 
| 
      
 38 
     | 
    
         
            +
              action snake_upcase_field { snake_upcase_char((char *)fpc); }
         
     | 
| 
      
 39 
     | 
    
         
            +
              action write_field {
         
     | 
| 
      
 40 
     | 
    
         
            +
                parser->field_len = LEN(field_start, fpc);
         
     | 
| 
      
 41 
     | 
    
         
            +
              }
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              action start_value { MARK(mark, fpc); }
         
     | 
| 
      
 44 
     | 
    
         
            +
              action write_value {
         
     | 
| 
      
 45 
     | 
    
         
            +
                if(parser->http_field != NULL) {
         
     | 
| 
      
 46 
     | 
    
         
            +
                  parser->http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, fpc));
         
     | 
| 
      
 47 
     | 
    
         
            +
                }
         
     | 
| 
      
 48 
     | 
    
         
            +
              }
         
     | 
| 
      
 49 
     | 
    
         
            +
              action request_method {
         
     | 
| 
      
 50 
     | 
    
         
            +
                if(parser->request_method != NULL)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  parser->request_method(parser->data, PTR_TO(mark), LEN(mark, fpc));
         
     | 
| 
      
 52 
     | 
    
         
            +
              }
         
     | 
| 
      
 53 
     | 
    
         
            +
              action request_uri {
         
     | 
| 
      
 54 
     | 
    
         
            +
                if(parser->request_uri != NULL)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, fpc));
         
     | 
| 
      
 56 
     | 
    
         
            +
              }
         
     | 
| 
      
 57 
     | 
    
         
            +
              action fragment {
         
     | 
| 
      
 58 
     | 
    
         
            +
                if(parser->fragment != NULL)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  parser->fragment(parser->data, PTR_TO(mark), LEN(mark, fpc));
         
     | 
| 
      
 60 
     | 
    
         
            +
              }
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
              action start_query {MARK(query_start, fpc); }
         
     | 
| 
      
 63 
     | 
    
         
            +
              action query_string {
         
     | 
| 
      
 64 
     | 
    
         
            +
                if(parser->query_string != NULL)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, fpc));
         
     | 
| 
      
 66 
     | 
    
         
            +
              }
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              action http_version {
         
     | 
| 
      
 69 
     | 
    
         
            +
                if(parser->http_version != NULL)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  parser->http_version(parser->data, PTR_TO(mark), LEN(mark, fpc));
         
     | 
| 
      
 71 
     | 
    
         
            +
              }
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              action request_path {
         
     | 
| 
      
 74 
     | 
    
         
            +
                if(parser->request_path != NULL)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  parser->request_path(parser->data, PTR_TO(mark), LEN(mark,fpc));
         
     | 
| 
      
 76 
     | 
    
         
            +
              }
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
              action done {
         
     | 
| 
      
 79 
     | 
    
         
            +
                parser->body_start = fpc - buffer + 1;
         
     | 
| 
      
 80 
     | 
    
         
            +
                if(parser->header_done != NULL)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  parser->header_done(parser->data, fpc + 1, pe - fpc - 1);
         
     | 
| 
      
 82 
     | 
    
         
            +
                fbreak;
         
     | 
| 
      
 83 
     | 
    
         
            +
              }
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
              include http_parser_common "http11_parser_common.rl";
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            }%%
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            /** Data **/
         
     | 
| 
      
 90 
     | 
    
         
            +
            %% write data;
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            int http_parser_init(http_parser *parser)  {
         
     | 
| 
      
 93 
     | 
    
         
            +
              int cs = 0;
         
     | 
| 
      
 94 
     | 
    
         
            +
              %% write init;
         
     | 
| 
      
 95 
     | 
    
         
            +
              parser->cs = cs;
         
     | 
| 
      
 96 
     | 
    
         
            +
              parser->body_start = 0;
         
     | 
| 
      
 97 
     | 
    
         
            +
              parser->content_len = 0;
         
     | 
| 
      
 98 
     | 
    
         
            +
              parser->mark = 0;
         
     | 
| 
      
 99 
     | 
    
         
            +
              parser->nread = 0;
         
     | 
| 
      
 100 
     | 
    
         
            +
              parser->field_len = 0;
         
     | 
| 
      
 101 
     | 
    
         
            +
              parser->field_start = 0;
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
              return(1);
         
     | 
| 
      
 104 
     | 
    
         
            +
            }
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            /** exec **/
         
     | 
| 
      
 108 
     | 
    
         
            +
            size_t http_parser_execute(http_parser *parser, const char *buffer, size_t len, size_t off)  {
         
     | 
| 
      
 109 
     | 
    
         
            +
              const char *p, *pe;
         
     | 
| 
      
 110 
     | 
    
         
            +
              int cs = parser->cs;
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
              assert(off <= len && "offset past end of buffer");
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
              p = buffer+off;
         
     | 
| 
      
 115 
     | 
    
         
            +
              pe = buffer+len;
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
              assert(*pe == '\0' && "pointer does not end on NUL");
         
     | 
| 
      
 118 
     | 
    
         
            +
              assert(pe - p == len - off && "pointers aren't same distance");
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
              %% write exec;
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
              parser->cs = cs;
         
     | 
| 
      
 124 
     | 
    
         
            +
              parser->nread += p - (buffer + off);
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
              assert(p <= pe && "buffer overflow after parsing execute");
         
     | 
| 
      
 127 
     | 
    
         
            +
              assert(parser->nread <= len && "nread longer than length");
         
     | 
| 
      
 128 
     | 
    
         
            +
              assert(parser->body_start <= len && "body starts after buffer end");
         
     | 
| 
      
 129 
     | 
    
         
            +
              assert(parser->mark < len && "mark is after buffer end");
         
     | 
| 
      
 130 
     | 
    
         
            +
              assert(parser->field_len <= len && "field has length longer than whole buffer");
         
     | 
| 
      
 131 
     | 
    
         
            +
              assert(parser->field_start < len && "field starts after buffer end");
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
              if(parser->body_start) {
         
     | 
| 
      
 134 
     | 
    
         
            +
                /* final \r\n combo encountered so stop right here */
         
     | 
| 
      
 135 
     | 
    
         
            +
                %%write eof;
         
     | 
| 
      
 136 
     | 
    
         
            +
                parser->nread++;
         
     | 
| 
      
 137 
     | 
    
         
            +
              }
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
              return(parser->nread);
         
     | 
| 
      
 140 
     | 
    
         
            +
            }
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            int http_parser_finish(http_parser *parser)
         
     | 
| 
      
 143 
     | 
    
         
            +
            {
         
     | 
| 
      
 144 
     | 
    
         
            +
              int cs = parser->cs;
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
              %%write eof;
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
              parser->cs = cs;
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
              if (http_parser_has_error(parser) ) {
         
     | 
| 
      
 151 
     | 
    
         
            +
                return -1;
         
     | 
| 
      
 152 
     | 
    
         
            +
              } else if (http_parser_is_finished(parser) ) {
         
     | 
| 
      
 153 
     | 
    
         
            +
                return 1;
         
     | 
| 
      
 154 
     | 
    
         
            +
              } else {
         
     | 
| 
      
 155 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 156 
     | 
    
         
            +
              }
         
     | 
| 
      
 157 
     | 
    
         
            +
            }
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
            int http_parser_has_error(http_parser *parser) {
         
     | 
| 
      
 160 
     | 
    
         
            +
              return parser->cs == http_parser_error;
         
     | 
| 
      
 161 
     | 
    
         
            +
            }
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
            int http_parser_is_finished(http_parser *parser) {
         
     | 
| 
      
 164 
     | 
    
         
            +
              return parser->cs == http_parser_first_final;
         
     | 
| 
      
 165 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -1,55 +1,55 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            %%{
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
              machine http_parser_common;
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            #### HTTP PROTOCOL GRAMMAR
         
     | 
| 
       6 
     | 
    
         
            -
            # line endings
         
     | 
| 
       7 
     | 
    
         
            -
              CRLF = "\r\n";
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            # character types
         
     | 
| 
       10 
     | 
    
         
            -
              CTL = (cntrl | 127);
         
     | 
| 
       11 
     | 
    
         
            -
              safe = ("$" | "-" | "_" | ".");
         
     | 
| 
       12 
     | 
    
         
            -
              extra = ("!" | "*" | "'" | "(" | ")" | ",");
         
     | 
| 
       13 
     | 
    
         
            -
              reserved = (";" | "/" | "?" | ":" | "@" | "&" | "=" | "+");
         
     | 
| 
       14 
     | 
    
         
            -
              sorta_safe = ("\"" | "<" | ">");
         
     | 
| 
       15 
     | 
    
         
            -
              unsafe = (CTL | " " | "#" | "%" | sorta_safe);
         
     | 
| 
       16 
     | 
    
         
            -
              national = any -- (alpha | digit | reserved | extra | safe | unsafe);
         
     | 
| 
       17 
     | 
    
         
            -
              unreserved = (alpha | digit | safe | extra | national);
         
     | 
| 
       18 
     | 
    
         
            -
              escape = ("%" xdigit xdigit);
         
     | 
| 
       19 
     | 
    
         
            -
              uchar = (unreserved | escape | sorta_safe);
         
     | 
| 
       20 
     | 
    
         
            -
              pchar = (uchar | ":" | "@" | "&" | "=" | "+");
         
     | 
| 
       21 
     | 
    
         
            -
              tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t");
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
            # elements
         
     | 
| 
       24 
     | 
    
         
            -
              token = (ascii -- (CTL | tspecials));
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            # URI schemes and absolute paths
         
     | 
| 
       27 
     | 
    
         
            -
              scheme = ( alpha | digit | "+" | "-" | "." )* ;
         
     | 
| 
       28 
     | 
    
         
            -
              absolute_uri = (scheme ":" (uchar | reserved )*);
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
              path = ( pchar+ ( "/" pchar* )* ) ;
         
     | 
| 
       31 
     | 
    
         
            -
              query = ( uchar | reserved )* %query_string ;
         
     | 
| 
       32 
     | 
    
         
            -
              param = ( pchar | "/" )* ;
         
     | 
| 
       33 
     | 
    
         
            -
              params = ( param ( ";" param )* ) ;
         
     | 
| 
       34 
     | 
    
         
            -
              rel_path = ( path? %request_path (";" params)? ) ("?" %start_query query)?;
         
     | 
| 
       35 
     | 
    
         
            -
              absolute_path = ( "/"+ rel_path );
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
              Request_URI = ( "*" | absolute_uri | absolute_path ) >mark %request_uri;
         
     | 
| 
       38 
     | 
    
         
            -
              Fragment = ( uchar | reserved )* >mark %fragment;
         
     | 
| 
       39 
     | 
    
         
            -
              Method = ( upper | digit | safe ){1,20} >mark %request_method;
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
              http_number = ( digit+ "." digit+ ) ;
         
     | 
| 
       42 
     | 
    
         
            -
              HTTP_Version = ( "HTTP/" http_number ) >mark %http_version ;
         
     | 
| 
       43 
     | 
    
         
            -
              Request_Line = ( Method " " Request_URI ("#" Fragment){0,1} " " HTTP_Version CRLF ) ;
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
              field_name = ( token -- ":" )+ >start_field $snake_upcase_field %write_field;
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
              field_value = any* >start_value %write_value;
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
              message_header = field_name ":" " "* field_value :> CRLF;
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
              Request = Request_Line ( message_header )* ( CRLF @done );
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
            main := Request;
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
            }%%
         
     | 
| 
      
 1 
     | 
    
         
            +
            %%{
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              machine http_parser_common;
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            #### HTTP PROTOCOL GRAMMAR
         
     | 
| 
      
 6 
     | 
    
         
            +
            # line endings
         
     | 
| 
      
 7 
     | 
    
         
            +
              CRLF = "\r\n";
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            # character types
         
     | 
| 
      
 10 
     | 
    
         
            +
              CTL = (cntrl | 127);
         
     | 
| 
      
 11 
     | 
    
         
            +
              safe = ("$" | "-" | "_" | ".");
         
     | 
| 
      
 12 
     | 
    
         
            +
              extra = ("!" | "*" | "'" | "(" | ")" | ",");
         
     | 
| 
      
 13 
     | 
    
         
            +
              reserved = (";" | "/" | "?" | ":" | "@" | "&" | "=" | "+");
         
     | 
| 
      
 14 
     | 
    
         
            +
              sorta_safe = ("\"" | "<" | ">");
         
     | 
| 
      
 15 
     | 
    
         
            +
              unsafe = (CTL | " " | "#" | "%" | sorta_safe);
         
     | 
| 
      
 16 
     | 
    
         
            +
              national = any -- (alpha | digit | reserved | extra | safe | unsafe);
         
     | 
| 
      
 17 
     | 
    
         
            +
              unreserved = (alpha | digit | safe | extra | national);
         
     | 
| 
      
 18 
     | 
    
         
            +
              escape = ("%" xdigit xdigit);
         
     | 
| 
      
 19 
     | 
    
         
            +
              uchar = (unreserved | escape | sorta_safe);
         
     | 
| 
      
 20 
     | 
    
         
            +
              pchar = (uchar | ":" | "@" | "&" | "=" | "+");
         
     | 
| 
      
 21 
     | 
    
         
            +
              tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t");
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            # elements
         
     | 
| 
      
 24 
     | 
    
         
            +
              token = (ascii -- (CTL | tspecials));
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            # URI schemes and absolute paths
         
     | 
| 
      
 27 
     | 
    
         
            +
              scheme = ( alpha | digit | "+" | "-" | "." )* ;
         
     | 
| 
      
 28 
     | 
    
         
            +
              absolute_uri = (scheme ":" (uchar | reserved )*);
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              path = ( pchar+ ( "/" pchar* )* ) ;
         
     | 
| 
      
 31 
     | 
    
         
            +
              query = ( uchar | reserved )* %query_string ;
         
     | 
| 
      
 32 
     | 
    
         
            +
              param = ( pchar | "/" )* ;
         
     | 
| 
      
 33 
     | 
    
         
            +
              params = ( param ( ";" param )* ) ;
         
     | 
| 
      
 34 
     | 
    
         
            +
              rel_path = ( path? %request_path (";" params)? ) ("?" %start_query query)?;
         
     | 
| 
      
 35 
     | 
    
         
            +
              absolute_path = ( "/"+ rel_path );
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              Request_URI = ( "*" | absolute_uri | absolute_path ) >mark %request_uri;
         
     | 
| 
      
 38 
     | 
    
         
            +
              Fragment = ( uchar | reserved )* >mark %fragment;
         
     | 
| 
      
 39 
     | 
    
         
            +
              Method = ( upper | digit | safe ){1,20} >mark %request_method;
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              http_number = ( digit+ "." digit+ ) ;
         
     | 
| 
      
 42 
     | 
    
         
            +
              HTTP_Version = ( "HTTP/" http_number ) >mark %http_version ;
         
     | 
| 
      
 43 
     | 
    
         
            +
              Request_Line = ( Method " " Request_URI ("#" Fragment){0,1} " " HTTP_Version CRLF ) ;
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              field_name = ( token -- ":" )+ >start_field $snake_upcase_field %write_field;
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              field_value = any* >start_value %write_value;
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              message_header = field_name ":" " "* field_value :> CRLF;
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              Request = Request_Line ( message_header )* ( CRLF @done );
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            main := Request;
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            }%%
         
     | 
| 
         @@ -1,91 +1,91 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #ifndef RSTRING_PTR
         
     | 
| 
       2 
     | 
    
         
            -
            #define RSTRING_PTR(s) (RSTRING(s)->ptr)
         
     | 
| 
       3 
     | 
    
         
            -
            #endif
         
     | 
| 
       4 
     | 
    
         
            -
            #ifndef RSTRING_LEN
         
     | 
| 
       5 
     | 
    
         
            -
            #define RSTRING_LEN(s) (RSTRING(s)->len)
         
     | 
| 
       6 
     | 
    
         
            -
            #endif
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            char *substr(const char *buff, int start, int len) {
         
     | 
| 
       9 
     | 
    
         
            -
                char subbuff[len + 1];
         
     | 
| 
       10 
     | 
    
         
            -
                memcpy(subbuff, &buff[start], len);
         
     | 
| 
       11 
     | 
    
         
            -
                subbuff[len] = '\0';
         
     | 
| 
       12 
     | 
    
         
            -
                return strdup(subbuff);
         
     | 
| 
       13 
     | 
    
         
            -
            }
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            int mat(char *str1, char *str2) {
         
     | 
| 
       16 
     | 
    
         
            -
                return strcmp(str1, str2) == 0;
         
     | 
| 
       17 
     | 
    
         
            -
            }
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
            VALUE WRB_Parse(VALUE self, VALUE string, VALUE buffer) {
         
     | 
| 
       20 
     | 
    
         
            -
              char *sptr = RSTRING_PTR(string);
         
     | 
| 
       21 
     | 
    
         
            -
              long slen = RSTRING_LEN(string);
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
              char *tar = "<?ruby";
         
     | 
| 
       24 
     | 
    
         
            -
              char tarlen = 6;
         
     | 
| 
       25 
     | 
    
         
            -
              char *end = "?>";
         
     | 
| 
       26 
     | 
    
         
            -
              char endlen = 2;
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
              int i = 0;
         
     | 
| 
       29 
     | 
    
         
            -
              char pc = NULL;
         
     | 
| 
       30 
     | 
    
         
            -
              int line_cur = 1;
         
     | 
| 
       31 
     | 
    
         
            -
              int line = 1;
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
              while (i < slen) {
         
     | 
| 
       34 
     | 
    
         
            -
                char c = sptr[i];
         
     | 
| 
       35 
     | 
    
         
            -
                if (c == '\n') line_cur += 1;
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                int open_e = i + tarlen;
         
     | 
| 
       38 
     | 
    
         
            -
                char *open_s = substr(sptr, i, tarlen);
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                if (mat(open_s, tar) && pc != '\\') {
         
     | 
| 
       41 
     | 
    
         
            -
                  line = line_cur;
         
     | 
| 
       42 
     | 
    
         
            -
                  int j = open_e;
         
     | 
| 
       43 
     | 
    
         
            -
                  int search = 1;
         
     | 
| 
       44 
     | 
    
         
            -
                  int q1 = 0; int q2 = 0;
         
     | 
| 
       45 
     | 
    
         
            -
                  while (j < slen && search) {
         
     | 
| 
       46 
     | 
    
         
            -
                    char cc = sptr[j];
         
     | 
| 
       47 
     | 
    
         
            -
                    if (cc == '\n') line_cur += 1;
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
                    int close_e = j + endlen;
         
     | 
| 
       50 
     | 
    
         
            -
                    char *close_s = substr(sptr, j, endlen);
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                    if (sptr[j-1] != '\\') {
         
     | 
| 
       53 
     | 
    
         
            -
                      if (cc == '\"') q1 = (q1 == 0 ? 1 : 0);
         
     | 
| 
       54 
     | 
    
         
            -
                      if (cc == '\'') q2 = (q2 == 0 ? 1 : 0);
         
     | 
| 
       55 
     | 
    
         
            -
                      if (mat(close_s, end) && !q1 && !q2) {
         
     | 
| 
       56 
     | 
    
         
            -
                        i = close_e - 1;
         
     | 
| 
       57 
     | 
    
         
            -
                        search = 0;
         
     | 
| 
       58 
     | 
    
         
            -
                        char *rb_ev = substr(sptr, open_e, j - open_e);
         
     | 
| 
       59 
     | 
    
         
            -
                        rb_yield_values(2, rb_str_new2(rb_ev), INT2NUM(line));
         
     | 
| 
       60 
     | 
    
         
            -
                      }
         
     | 
| 
       61 
     | 
    
         
            -
                    }
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                    j+=1;
         
     | 
| 
       64 
     | 
    
         
            -
                  }
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                  if (j == slen && search) {
         
     | 
| 
       67 
     | 
    
         
            -
                    char *rb_ev = substr(sptr, open_e, j);
         
     | 
| 
       68 
     | 
    
         
            -
                    i = slen;
         
     | 
| 
       69 
     | 
    
         
            -
                    rb_eval_string(rb_ev);
         
     | 
| 
       70 
     | 
    
         
            -
                  }
         
     | 
| 
       71 
     | 
    
         
            -
                } else if (c == '\\') {
         
     | 
| 
       72 
     | 
    
         
            -
                  if (!mat(substr(sptr, i+1, tarlen), tar)) {
         
     | 
| 
       73 
     | 
    
         
            -
                    char strbuf[2] = "\0";
         
     | 
| 
       74 
     | 
    
         
            -
                    strbuf[0] = c;
         
     | 
| 
       75 
     | 
    
         
            -
                    rb_funcall(buffer, rb_intern("write"), 1, rb_str_new2(strbuf));
         
     | 
| 
       76 
     | 
    
         
            -
                  }
         
     | 
| 
       77 
     | 
    
         
            -
                } else {
         
     | 
| 
       78 
     | 
    
         
            -
                  char strbuf[2] = "\0";
         
     | 
| 
       79 
     | 
    
         
            -
                  strbuf[0] = c;
         
     | 
| 
       80 
     | 
    
         
            -
                  rb_funcall(buffer, rb_intern("write"), 1, rb_str_new2(strbuf));
         
     | 
| 
       81 
     | 
    
         
            -
                }
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
                pc = c;
         
     | 
| 
       84 
     | 
    
         
            -
                i += 1;
         
     | 
| 
       85 
     | 
    
         
            -
              }
         
     | 
| 
       86 
     | 
    
         
            -
            }
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
            void init_parse(VALUE rubyModule) {
         
     | 
| 
       89 
     | 
    
         
            -
              VALUE cWaParse = rb_define_class_under(rubyModule, "WRBParser", rb_cObject);
         
     | 
| 
       90 
     | 
    
         
            -
              rb_define_module_function(cWaParse, "parse!", WRB_Parse, 2);
         
     | 
| 
       91 
     | 
    
         
            -
            }
         
     | 
| 
      
 1 
     | 
    
         
            +
            #ifndef RSTRING_PTR
         
     | 
| 
      
 2 
     | 
    
         
            +
            #define RSTRING_PTR(s) (RSTRING(s)->ptr)
         
     | 
| 
      
 3 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 4 
     | 
    
         
            +
            #ifndef RSTRING_LEN
         
     | 
| 
      
 5 
     | 
    
         
            +
            #define RSTRING_LEN(s) (RSTRING(s)->len)
         
     | 
| 
      
 6 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            char *substr(const char *buff, int start, int len) {
         
     | 
| 
      
 9 
     | 
    
         
            +
                char subbuff[len + 1];
         
     | 
| 
      
 10 
     | 
    
         
            +
                memcpy(subbuff, &buff[start], len);
         
     | 
| 
      
 11 
     | 
    
         
            +
                subbuff[len] = '\0';
         
     | 
| 
      
 12 
     | 
    
         
            +
                return strdup(subbuff);
         
     | 
| 
      
 13 
     | 
    
         
            +
            }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            int mat(char *str1, char *str2) {
         
     | 
| 
      
 16 
     | 
    
         
            +
                return strcmp(str1, str2) == 0;
         
     | 
| 
      
 17 
     | 
    
         
            +
            }
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            VALUE WRB_Parse(VALUE self, VALUE string, VALUE buffer) {
         
     | 
| 
      
 20 
     | 
    
         
            +
              char *sptr = RSTRING_PTR(string);
         
     | 
| 
      
 21 
     | 
    
         
            +
              long slen = RSTRING_LEN(string);
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              char *tar = "<?ruby";
         
     | 
| 
      
 24 
     | 
    
         
            +
              char tarlen = 6;
         
     | 
| 
      
 25 
     | 
    
         
            +
              char *end = "?>";
         
     | 
| 
      
 26 
     | 
    
         
            +
              char endlen = 2;
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              int i = 0;
         
     | 
| 
      
 29 
     | 
    
         
            +
              char pc = NULL;
         
     | 
| 
      
 30 
     | 
    
         
            +
              int line_cur = 1;
         
     | 
| 
      
 31 
     | 
    
         
            +
              int line = 1;
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              while (i < slen) {
         
     | 
| 
      
 34 
     | 
    
         
            +
                char c = sptr[i];
         
     | 
| 
      
 35 
     | 
    
         
            +
                if (c == '\n') line_cur += 1;
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                int open_e = i + tarlen;
         
     | 
| 
      
 38 
     | 
    
         
            +
                char *open_s = substr(sptr, i, tarlen);
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                if (mat(open_s, tar) && pc != '\\') {
         
     | 
| 
      
 41 
     | 
    
         
            +
                  line = line_cur;
         
     | 
| 
      
 42 
     | 
    
         
            +
                  int j = open_e;
         
     | 
| 
      
 43 
     | 
    
         
            +
                  int search = 1;
         
     | 
| 
      
 44 
     | 
    
         
            +
                  int q1 = 0; int q2 = 0;
         
     | 
| 
      
 45 
     | 
    
         
            +
                  while (j < slen && search) {
         
     | 
| 
      
 46 
     | 
    
         
            +
                    char cc = sptr[j];
         
     | 
| 
      
 47 
     | 
    
         
            +
                    if (cc == '\n') line_cur += 1;
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    int close_e = j + endlen;
         
     | 
| 
      
 50 
     | 
    
         
            +
                    char *close_s = substr(sptr, j, endlen);
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                    if (sptr[j-1] != '\\') {
         
     | 
| 
      
 53 
     | 
    
         
            +
                      if (cc == '\"') q1 = (q1 == 0 ? 1 : 0);
         
     | 
| 
      
 54 
     | 
    
         
            +
                      if (cc == '\'') q2 = (q2 == 0 ? 1 : 0);
         
     | 
| 
      
 55 
     | 
    
         
            +
                      if (mat(close_s, end) && !q1 && !q2) {
         
     | 
| 
      
 56 
     | 
    
         
            +
                        i = close_e - 1;
         
     | 
| 
      
 57 
     | 
    
         
            +
                        search = 0;
         
     | 
| 
      
 58 
     | 
    
         
            +
                        char *rb_ev = substr(sptr, open_e, j - open_e);
         
     | 
| 
      
 59 
     | 
    
         
            +
                        rb_yield_values(2, rb_str_new2(rb_ev), INT2NUM(line));
         
     | 
| 
      
 60 
     | 
    
         
            +
                      }
         
     | 
| 
      
 61 
     | 
    
         
            +
                    }
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                    j+=1;
         
     | 
| 
      
 64 
     | 
    
         
            +
                  }
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  if (j == slen && search) {
         
     | 
| 
      
 67 
     | 
    
         
            +
                    char *rb_ev = substr(sptr, open_e, j);
         
     | 
| 
      
 68 
     | 
    
         
            +
                    i = slen;
         
     | 
| 
      
 69 
     | 
    
         
            +
                    rb_eval_string(rb_ev);
         
     | 
| 
      
 70 
     | 
    
         
            +
                  }
         
     | 
| 
      
 71 
     | 
    
         
            +
                } else if (c == '\\') {
         
     | 
| 
      
 72 
     | 
    
         
            +
                  if (!mat(substr(sptr, i+1, tarlen), tar)) {
         
     | 
| 
      
 73 
     | 
    
         
            +
                    char strbuf[2] = "\0";
         
     | 
| 
      
 74 
     | 
    
         
            +
                    strbuf[0] = c;
         
     | 
| 
      
 75 
     | 
    
         
            +
                    rb_funcall(buffer, rb_intern("write"), 1, rb_str_new2(strbuf));
         
     | 
| 
      
 76 
     | 
    
         
            +
                  }
         
     | 
| 
      
 77 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 78 
     | 
    
         
            +
                  char strbuf[2] = "\0";
         
     | 
| 
      
 79 
     | 
    
         
            +
                  strbuf[0] = c;
         
     | 
| 
      
 80 
     | 
    
         
            +
                  rb_funcall(buffer, rb_intern("write"), 1, rb_str_new2(strbuf));
         
     | 
| 
      
 81 
     | 
    
         
            +
                }
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                pc = c;
         
     | 
| 
      
 84 
     | 
    
         
            +
                i += 1;
         
     | 
| 
      
 85 
     | 
    
         
            +
              }
         
     | 
| 
      
 86 
     | 
    
         
            +
            }
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            void init_parse(VALUE rubyModule) {
         
     | 
| 
      
 89 
     | 
    
         
            +
              VALUE cWaParse = rb_define_class_under(rubyModule, "WRBParser", rb_cObject);
         
     | 
| 
      
 90 
     | 
    
         
            +
              rb_define_module_function(cWaParse, "parse!", WRB_Parse, 2);
         
     | 
| 
      
 91 
     | 
    
         
            +
            }
         
     |