Line data Source code
1 : // 2 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com) 3 : // 4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 : // 7 : // Official repository: https://github.com/boostorg/url 8 : // 9 : 10 : 11 : #include <boost/url/detail/config.hpp> 12 : #include "boost/url/detail/replacement_field_rule.hpp" 13 : #include <boost/url/grammar/alnum_chars.hpp> 14 : #include <boost/url/grammar/alpha_chars.hpp> 15 : #include <boost/url/grammar/delim_rule.hpp> 16 : #include <boost/url/grammar/lut_chars.hpp> 17 : #include <boost/url/grammar/optional_rule.hpp> 18 : #include <boost/url/grammar/parse.hpp> 19 : #include <boost/url/grammar/token_rule.hpp> 20 : #include <boost/url/grammar/tuple_rule.hpp> 21 : #include <boost/url/grammar/vchars.hpp> 22 : 23 : namespace boost { 24 : namespace urls { 25 : namespace detail { 26 : 27 : auto 28 673 : replacement_field_rule_t:: 29 : parse( 30 : char const*& it, 31 : char const* const end) const noexcept -> 32 : system::result<value_type> 33 : { 34 : static constexpr auto replacement_field_rules = 35 : grammar::tuple_rule( 36 : // open 37 : grammar::squelch( 38 : grammar::delim_rule('{')), 39 : // id 40 : grammar::optional_rule(arg_id_rule), 41 : // format options 42 : grammar::optional_rule( 43 : grammar::tuple_rule( 44 : grammar::squelch( 45 : grammar::delim_rule(':')), 46 : format_spec_rule)), 47 : // close 48 : grammar::squelch( 49 : grammar::delim_rule('}'))); 50 673 : auto it0 = it; 51 1346 : auto rv = grammar::parse(it, end, replacement_field_rules); 52 673 : if (!rv) 53 : { 54 328 : BOOST_URL_RETURN_EC( 55 : grammar::error::mismatch); 56 : } 57 345 : return core::string_view(it0, it); 58 : } 59 : 60 : auto 61 720 : identifier_rule_t:: 62 : parse( 63 : char const*& it, 64 : char const* const end) const noexcept 65 : -> system::result<value_type> 66 : { 67 : static constexpr auto identifier_rules = 68 : grammar::tuple_rule( 69 : grammar::delim_rule( 70 : grammar::alpha_chars + 71 : grammar::lut_chars('_')), 72 : grammar::optional_rule( 73 : grammar::token_rule( 74 : grammar::alnum_chars + 75 : grammar::lut_chars('_')))); 76 720 : char const* it0 = it; 77 1440 : auto rv = grammar::parse(it, end, identifier_rules); 78 720 : if (!rv) 79 : { 80 349 : BOOST_URL_RETURN_EC( 81 : grammar::error::mismatch); 82 : } 83 371 : return core::string_view(it0, it); 84 : } 85 : 86 : auto 87 86 : format_spec_rule_t:: 88 : parse( 89 : char const*& it, 90 : char const* const end) const noexcept 91 : -> system::result<value_type> 92 : { 93 86 : if (it == end) 94 2 : return {}; 95 : 96 : // any tokens allowed in fmt specs 97 : static constexpr auto fmt_specs_token_rule = 98 : grammar::optional_rule( 99 : grammar::token_rule( 100 : grammar::vchars + 101 : grammar::lut_chars(' ') 102 : - "{}")); 103 : 104 : // internal ids in the fmt specs 105 : // "{" [arg_id] "}" 106 : static constexpr auto internal_id_rule = 107 : grammar::tuple_rule( 108 : grammar::squelch( 109 : grammar::delim_rule('{')), 110 : grammar::optional_rule( 111 : arg_id_rule), 112 : grammar::squelch( 113 : grammar::delim_rule('}'))); 114 : 115 84 : auto start = it; 116 : // consume fmt_spec chars 117 112 : while (grammar::parse(it, end, fmt_specs_token_rule)) 118 : { 119 112 : auto it0 = it; 120 : // consume internal id 121 112 : if (!grammar::parse(it, end, internal_id_rule)) 122 : { 123 : // rewind 124 84 : it = it0; 125 84 : break; 126 : } 127 : } 128 : 129 84 : return core::string_view(start, it); 130 : } 131 : 132 : } // detail 133 : } // urls 134 : } // boost 135 :