File Coverage

src/panda/uri/parser.rl
Criterion Covered Total %
statement 21 25 84.0
branch 43 110 39.0
condition n/a
subroutine n/a
pod n/a
total 64 135 47.4


line stmt bran cond sub pod time code
1             #include "parser.h"
2              
3             namespace panda { namespace uri {
4              
5             // ============== RFC3986 compliant parser ===================
6              
7             %%{
8             machine uri_parser_base;
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            
34             pct_encoded = "%" xdigit{2};
35             pchar = unreserved | pct_encoded | sub_delim | ":" | "@";
36            
37             scheme = (alpha (alnum | "+" | "-" | "." )*) >mark %scheme;
38            
39             userinfo = ((unreserved | pct_encoded >auth_pct | sub_delim | ":" )*) >mark %userinfo;
40            
41             IPvFuture = "v" xdigit+ "." (unreserved | sub_delim | ":")+;
42              
43             dec_octet = digit # 0-9
44             | "1".."9" digit # 10-99
45             | "1" digit{2} # 100-199
46             | "2" "0".."4" digit # 200-240
47             | "25" "0".."5"; # 250-255
48             IPv4address = (dec_octet "."){3} dec_octet;
49              
50             h16 = xdigit{1,4}; # 16 bits of address represented in hexadecimal
51             ls32 = (h16 ":" h16) | IPv4address; # least-significant 32 bits of address
52             IPv6address = (h16 ":"){6} ls32
53             | "::" (h16 ":"){5} ls32
54             | ( h16)? "::" (h16 ":"){4} ls32
55             | ((h16 ":")? h16)? "::" (h16 ":"){3} ls32
56             | ((h16 ":"){0,2} h16)? "::" (h16 ":"){2} ls32
57             | ((h16 ":"){0,3} h16)? "::" (h16 ":"){1} ls32
58             | ((h16 ":"){0,4} h16)? "::" ls32
59             | ((h16 ":"){0,5} h16)? "::" h16
60             | ((h16 ":"){0,6} h16)? "::";
61            
62             IP_literal = "[" (IPv6address | IPvFuture) "]";
63             reg_name = (unreserved | pct_encoded >auth_pct | sub_delim)*;
64             host = (IP_literal | IPv4address | reg_name) >mark %host;
65             port = digit* $digit %port;
66             authority = (userinfo "@")? host (":" port)?;
67            
68             segment = pchar*;
69             segment_nz = pchar+;
70             segment_nz_nc = (unreserved | pct_encoded | sub_delim | "@")+; # non-zero-length segment without any colon ":"
71             path_abempty = ("/" segment)* >mark %path;
72             path_absolute = ("/" (segment_nz ("/" segment)*)?) >mark %path;
73             path_noscheme = (segment_nz_nc ("/" segment)*) >mark %path;
74             path_rootless = (segment_nz ("/" segment)*) >mark %path;
75             path_empty = ""; # zero characters
76             path = path_abempty # begins with "/" or is empty
77             | path_absolute # begins with "/" but not "//"
78             | path_noscheme # begins with a non-colon segment
79             | path_rootless # begins with a segment
80             | path_empty; # zero characters
81              
82             hier_part = "//" authority path_abempty | path_absolute | path_rootless | path_empty;
83              
84             fragment = (pchar | "/" | "?")* >mark %fragment;
85              
86             relative_part = "//" authority path_abempty | path_absolute | path_noscheme | path_empty;
87             }%%
88              
89             %%{
90             machine uri_parser;
91             include uri_parser_base;
92              
93             query = (pchar | "/" | "?")* >mark %query;
94             absolute_uri = scheme ":" hier_part ("?" query)? ("#" fragment)?;
95             relative_ref = relative_part ("?" query)? ("#" fragment)?;
96            
97             uri := absolute_uri | relative_ref;
98            
99             write data;
100             }%%
101              
102             #define SAVE(dest) dest = str.substr(mark, p - ps - mark);
103             #define NSAVE(dest) dest = acc; acc = 0
104              
105 145           bool URI::_parse (const string& str, bool& authority_has_pct) {
106 145           const char* ps = str.data();
107 145           const char* p = ps;
108 145           const char* pe = p + str.length();
109 145           const char* eof = pe;
110 145           int cs = uri_parser_start;
111             size_t mark;
112 145           int acc = 0;
113            
114             %% write exec;
115            
116 145           return cs >= uri_parser_first_final;
117             }
118              
119             }}