File Coverage

src/panda/uri/parser.rl
Criterion Covered Total %
statement 28 34 82.3
branch 53 122 43.4
condition n/a
subroutine n/a
pod n/a
total 81 156 51.9


line stmt bran cond sub pod time code
1             #include "URI.h"
2              
3             namespace panda { namespace uri {
4              
5             // ============== RFC3986 compliant parser ===================
6              
7             %%{
8             machine uri_parser;
9            
10             action mark {
11 578           mark = p - ps;
12             }
13 505          
14             action digit {
15 2326 0         acc *= 10;
    100          
    50          
    0          
    100          
    50          
    100          
    50          
    100          
    100          
    100          
    50          
    100          
16 124           acc += *p - '0';
17             }
18 60          
19 123 50         action scheme { SAVE(_scheme); }
20 323 0         action host { SAVE(_host); }
    50          
    0          
    50          
    0          
    50          
    0          
    50          
    100          
    0          
    50          
    50          
    0          
    50          
21 29           action port { NSAVE(_port); }
22 134 50         action userinfo { SAVE(_user_info); }
    0          
    100          
23 149 0         action path { SAVE(_path); }
    0          
    50          
    0          
    50          
    0          
    50          
    0          
    50          
    0          
    50          
    50          
24 223 0         action query { SAVE(_qstr); }
    50          
    50          
    0          
25 79 50         action fragment { SAVE(_fragment); }
    50          
    0          
26 98 50        
    50          
27 0           action auth_pct { authority_has_pct = true; }
28 0          
29             sub_delim = "!" | "$" | "&" | "'" | "(" | ")" | "*" | "+" | "," | ";" | "=";
30 0 0         gen_delim = ":" | "/" | "?" | "#" | "[" | "]" | "@";
    0          
    0          
31 0           reserved = sub_delim | gen_delim;
32             unreserved = alnum | "-" | "." | "_" | "~";
33             pct_encoded = "%" xdigit{2};
34             pchar = unreserved | pct_encoded | sub_delim | ":" | "@";
35            
36             scheme = (alpha (alnum | "+" | "-" | "." )*) >mark %scheme;
37            
38             userinfo = ((unreserved | pct_encoded >auth_pct | sub_delim | ":" )*) >mark %userinfo;
39            
40             IPvFuture = "v" xdigit+ "." (unreserved | sub_delim | ":")+;
41              
42             dec_octet = digit # 0-9
43             | "1".."9" digit # 10-99
44             | "1" digit{2} # 100-199
45             | "2" "0".."4" digit # 200-240
46             | "25" "0".."5"; # 250-255
47             IPv4address = (dec_octet "."){3} dec_octet;
48              
49             h16 = xdigit{1,4}; # 16 bits of address represented in hexadecimal
50             ls32 = (h16 ":" h16) | IPv4address; # least-significant 32 bits of address
51             IPv6address = (h16 ":"){6} ls32
52             | "::" (h16 ":"){5} ls32
53             | ( h16)? "::" (h16 ":"){4} ls32
54             | ((h16 ":")? h16)? "::" (h16 ":"){3} ls32
55             | ((h16 ":"){0,2} h16)? "::" (h16 ":"){2} ls32
56             | ((h16 ":"){0,3} h16)? "::" (h16 ":"){1} ls32
57             | ((h16 ":"){0,4} h16)? "::" ls32
58             | ((h16 ":"){0,5} h16)? "::" h16
59             | ((h16 ":"){0,6} h16)? "::";
60            
61             IP_literal = "[" (IPv6address | IPvFuture) "]";
62             reg_name = (unreserved | pct_encoded >auth_pct | sub_delim)*;
63             host = (IP_literal | IPv4address | reg_name) >mark %host;
64             port = digit* $digit %port;
65             authority = (userinfo "@")? host (":" port)?;
66            
67             segment = pchar*;
68             segment_nz = pchar+;
69             segment_nz_nc = (unreserved | pct_encoded | sub_delim | "@")+; # non-zero-length segment without any colon ":"
70             path_abempty = ("/" segment)* >mark %path;
71             path_absolute = ("/" (segment_nz ("/" segment)*)?) >mark %path;
72             path_noscheme = (segment_nz_nc ("/" segment)*) >mark %path;
73             path_rootless = (segment_nz ("/" segment)*) >mark %path;
74             path_empty = ""; # zero characters
75             path = path_abempty # begins with "/" or is empty
76             | path_absolute # begins with "/" but not "//"
77             | path_noscheme # begins with a non-colon segment
78             | path_rootless # begins with a segment
79             | path_empty; # zero characters
80              
81             hier_part = "//" authority path_abempty | path_absolute | path_rootless | path_empty;
82              
83             query = (pchar | "/" | "?")* >mark %query;
84             fragment = (pchar | "/" | "?")* >mark %fragment;
85              
86             absolute_uri = scheme ":" hier_part ("?" query)? ("#" fragment)?;
87              
88             relative_part = "//" authority path_abempty | path_absolute | path_noscheme | path_empty;
89             relative_ref = relative_part ("?" query)? ("#" fragment)?;
90            
91             uri := absolute_uri | relative_ref;
92            
93             write data;
94             }%%
95              
96             #define SAVE(dest) dest = str.substr(mark, p - ps - mark);
97             #define NSAVE(dest) dest = acc; acc = 0
98              
99 145           void URI::parse (const string& str) {
100 145           const char* ps = str.data();
101 145           const char* p = ps;
102 145           const char* pe = p + str.length();
103 145           const char* eof = pe;
104 145           int cs = uri_parser_start;
105             size_t mark;
106 145           int acc = 0;
107 145           bool authority_has_pct = false;
108            
109             %% write exec;
110            
111 145 100         if (cs < uri_parser_first_final) {
112 7           clear();
113 7           return;
114             }
115            
116 138 50         if (authority_has_pct) {
117 0           decode_uri_component(_user_info, _user_info);
118 0           decode_uri_component(_host, _host);
119             }
120            
121 138 100         if (_qstr) ok_qstr();
122 138 100         if (_flags & Flags::allow_suffix_reference && !_host.length()) guess_suffix_reference();
    50          
    100          
123 145           sync_scheme_info();
124             }
125              
126             }}