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 673 : 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 673 : }
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 720 : 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 720 : }
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 :
|