mirror of
https://github.com/boostorg/url.git
synced 2026-01-20 05:02:43 +00:00
This commit formats tables so that the content fits in the margins of the new UI template.
346 lines
9.4 KiB
C++
346 lines
9.4 KiB
C++
//
|
|
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
// Official repository: https://github.com/boostorg/url
|
|
//
|
|
|
|
#include <boost/url.hpp>
|
|
#include "test_suite.hpp"
|
|
|
|
#include <boost/core/ignore_unused.hpp>
|
|
#include <iostream>
|
|
|
|
namespace boost {
|
|
namespace urls {
|
|
namespace grammar {
|
|
|
|
namespace impl {
|
|
|
|
//[code_grammar_1_1
|
|
template< class Rule >
|
|
auto parse( core::string_view s, Rule const& r) -> system::result< typename Rule::value_type >;
|
|
|
|
template< class Rule >
|
|
auto parse( char const *& it, char const* end, Rule const& r) -> system::result< typename Rule::value_type >;
|
|
//]
|
|
|
|
} // impl
|
|
|
|
//------------------------------------------------
|
|
|
|
namespace {
|
|
|
|
//[code_grammar_2_2
|
|
struct ws_chars_t
|
|
{
|
|
constexpr bool operator()( char c ) const noexcept
|
|
{
|
|
return c == '\t' || c == ' ' || c == '\r' || c == '\n';
|
|
}
|
|
};
|
|
//]
|
|
|
|
//[code_grammar_2_3
|
|
static_assert( is_charset< ws_chars_t >::value, "CharSet requirements not met" );
|
|
//]
|
|
|
|
//[code_grammar_2_4
|
|
constexpr ws_chars_t ws_chars{};
|
|
//]
|
|
|
|
//[code_grammar_2_5
|
|
core::string_view get_token( core::string_view s ) noexcept
|
|
{
|
|
auto it0 = s.data();
|
|
auto const end = it0 + s.size();
|
|
|
|
// find the first non-whitespace character
|
|
it0 = find_if_not( it0, end, ws_chars );
|
|
|
|
if( it0 == end )
|
|
{
|
|
// all whitespace or empty string
|
|
return {};
|
|
}
|
|
|
|
// find the next whitespace character
|
|
auto it1 = find_if( it0, end, ws_chars );
|
|
|
|
// [it0, it1) is the part we want
|
|
return core::string_view( it0, it1 - it0 );
|
|
}
|
|
//]
|
|
|
|
//[code_grammar_2_9
|
|
struct is_visible
|
|
{
|
|
constexpr bool operator()( char ch ) const noexcept
|
|
{
|
|
return ch >= 33 && ch <= 126;
|
|
}
|
|
};
|
|
constexpr lut_chars visible_chars( is_visible{} ); // (since C++11)
|
|
//]
|
|
|
|
#if __cplusplus >= 201703L
|
|
namespace cpp17 {
|
|
//[code_grammar_2_10
|
|
constexpr lut_chars visible_chars( [](char ch) { return ch >= 33 && ch <= 126; } ); // (since C++17)
|
|
//]
|
|
} // cpp17
|
|
#endif
|
|
|
|
} // (anon)
|
|
|
|
struct doc_grammar_test
|
|
{
|
|
void snippets1()
|
|
{
|
|
//[code_grammar_1_2
|
|
struct comma_rule_t
|
|
{
|
|
// The type of value returned upon success
|
|
using value_type = core::string_view;
|
|
|
|
// The algorithm which checks for a match
|
|
system::result< value_type >
|
|
parse( char const*& it, char const* end ) const
|
|
{
|
|
if( it != end && *it == ',')
|
|
return core::string_view( it++, 1 );
|
|
|
|
return error::mismatch;
|
|
}
|
|
};
|
|
//]
|
|
|
|
//[code_grammar_1_3
|
|
constexpr comma_rule_t comma_rule{};
|
|
//]
|
|
|
|
{
|
|
//[code_grammar_1_4
|
|
system::result< core::string_view > rv = parse( ",", comma_rule );
|
|
|
|
assert( rv.has_value() && rv.value() == "," );
|
|
//]
|
|
}
|
|
{
|
|
//[code_grammar_1_5
|
|
system::result< unsigned short > rv =
|
|
parse( "16384", unsigned_rule< unsigned short >{} );
|
|
//]
|
|
ignore_unused(rv);
|
|
}
|
|
{
|
|
//[code_grammar_1_6
|
|
system::result< core::string_view > rv = parse( ",", delim_rule(',') );
|
|
//]
|
|
ignore_unused(rv);
|
|
}
|
|
}
|
|
//--------------------------------------------
|
|
|
|
void snippets2()
|
|
{
|
|
{
|
|
//[code_grammar_2_6
|
|
assert( get_token( " \t john-doe\r\n \t jane-doe\r\n") == "john-doe" );
|
|
//]
|
|
}
|
|
static
|
|
//[code_grammar_2_7
|
|
constexpr lut_chars vowels = "AEIOU" "aeiou";
|
|
//]
|
|
{
|
|
//[code_grammar_2_8
|
|
constexpr auto vowels_and_y = vowels + 'y' + 'Y';
|
|
//]
|
|
ignore_unused(vowels_and_y);
|
|
}
|
|
{
|
|
//[code_grammar_2_11
|
|
constexpr auto visible_non_vowels = visible_chars - vowels;
|
|
//]
|
|
ignore_unused(visible_non_vowels);
|
|
}
|
|
{
|
|
//[code_grammar_2_12
|
|
constexpr auto visible_non_vowels_or_y = visible_chars - vowels - 'y';
|
|
//]
|
|
ignore_unused(visible_non_vowels_or_y);
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------
|
|
|
|
void snippets3()
|
|
{
|
|
{
|
|
//[code_grammar_3_1
|
|
constexpr auto version_rule = tuple_rule( delim_rule( 'v' ), dec_octet_rule, delim_rule( '.' ), dec_octet_rule );
|
|
//]
|
|
|
|
//[code_grammar_3_2
|
|
system::result< std::tuple< core::string_view, unsigned char, core::string_view, unsigned char > > rv = parse( "v42.44800", version_rule );
|
|
//]
|
|
ignore_unused(rv);
|
|
}
|
|
{
|
|
//[code_grammar_3_3
|
|
constexpr auto version_rule = tuple_rule( squelch( delim_rule( 'v' ) ), dec_octet_rule, squelch( delim_rule( '.' ) ), dec_octet_rule );
|
|
|
|
system::result< std::tuple< unsigned char, unsigned char > > rv = parse( "v42.44800", version_rule );
|
|
//]
|
|
ignore_unused(rv);
|
|
}
|
|
{
|
|
//[code_grammar_3_4
|
|
// port = ":" unsigned-short
|
|
|
|
constexpr auto port_rule = tuple_rule( squelch( delim_rule( ':' ) ), unsigned_rule< unsigned short >{} );
|
|
|
|
system::result< unsigned short > rv = parse( ":443", port_rule );
|
|
//]
|
|
ignore_unused(rv);
|
|
}
|
|
{
|
|
//[code_grammar_3_5
|
|
// port = [ ":" unsigned-short ]
|
|
|
|
constexpr auto port_rule = optional_rule( tuple_rule( squelch( delim_rule( ':' ) ), unsigned_rule< unsigned short >{} ) );
|
|
|
|
system::result< boost::optional< unsigned short > > rv = parse( ":8080", port_rule );
|
|
|
|
assert( rv->has_value() && rv->value() == 8080 );
|
|
//]
|
|
}
|
|
{
|
|
//[code_grammar_3_6
|
|
// ipv4_address = dec-octet "." dec-octet "." dec-octet "." dec-octet
|
|
//
|
|
// port = ":" unsigned-short
|
|
//
|
|
// endpoint = ipv4_address [ port ]
|
|
|
|
constexpr auto endpoint_rule = tuple_rule(
|
|
tuple_rule(
|
|
dec_octet_rule, squelch( delim_rule( '.' ) ),
|
|
dec_octet_rule, squelch( delim_rule( '.' ) ),
|
|
dec_octet_rule, squelch( delim_rule( '.' ) ),
|
|
dec_octet_rule ),
|
|
optional_rule(
|
|
tuple_rule(
|
|
squelch( delim_rule( ':' ) ),
|
|
unsigned_rule< unsigned short >{} ) ) );
|
|
//]
|
|
ignore_unused(endpoint_rule);
|
|
}
|
|
{
|
|
//[code_grammar_3_7
|
|
constexpr auto endpoint_rule = tuple_rule(
|
|
ipv4_address_rule,
|
|
optional_rule(
|
|
tuple_rule(
|
|
squelch( delim_rule( ':' ) ),
|
|
unsigned_rule< unsigned short >{} ) ) );
|
|
|
|
system::result< std::tuple< ipv4_address, boost::optional< unsigned short > > > rv = parse( "192.168.0.1:443", endpoint_rule );
|
|
//]
|
|
ignore_unused(rv);
|
|
}
|
|
{
|
|
//[code_grammar_3_8
|
|
constexpr auto request_target_rule = variant_rule(
|
|
origin_form_rule,
|
|
absolute_uri_rule,
|
|
authority_rule,
|
|
delim_rule('*') );
|
|
|
|
system::result< variant2::variant< url_view, url_view, authority_view, core::string_view > > rv = parse( "/results.htm?page=4", request_target_rule );
|
|
//]
|
|
}
|
|
}
|
|
|
|
void snippets4()
|
|
{
|
|
{
|
|
//[code_grammar_4_1
|
|
constexpr auto chunk_ext_rule = range_rule(
|
|
tuple_rule( squelch( delim_rule( ';' ) ), token_rule( alnum_chars ) ) );
|
|
//]
|
|
//[code_grammar_4_2
|
|
system::result< range< core::string_view > > rv = parse( ";johndoe;janedoe;end", chunk_ext_rule );
|
|
|
|
for( auto s : rv.value() )
|
|
std::cout << s << "\n";
|
|
//]
|
|
}
|
|
{
|
|
//[code_grammar_4_3
|
|
constexpr auto token_list_rule = range_rule(
|
|
token_rule( alnum_chars ),
|
|
tuple_rule( squelch( delim_rule( ',' ) ), token_rule( alnum_chars ) ),
|
|
1 );
|
|
//]
|
|
//[code_grammar_4_4
|
|
system::result< range< core::string_view > > rv = parse( "johndoe,janedoe,end", token_list_rule );
|
|
|
|
for( auto s : rv.value() )
|
|
std::cout << s << "\n";
|
|
//]
|
|
}
|
|
}
|
|
|
|
void
|
|
snippets5()
|
|
{
|
|
{
|
|
core::string_view s;
|
|
//[code_grammar_5_1
|
|
system::result< pct_string_view > rv = parse( s, pct_encoded_rule( pchars ) );
|
|
//]
|
|
ignore_unused(rv);
|
|
}
|
|
{
|
|
//[code_grammar_5_2
|
|
// request-line = method SP request-target SP HTTP-version CRLF
|
|
|
|
constexpr auto request_line_rule = tuple_rule(
|
|
not_empty_rule( token_rule( alpha_chars ) ), // method
|
|
squelch( delim_rule( ' ' ) ), // SP
|
|
variant_rule(
|
|
absolute_uri_rule, // absolute-uri or
|
|
relative_ref_rule), // relative-ref
|
|
squelch( delim_rule( ' ' ) ),
|
|
squelch( literal_rule( "HTTP/" ) ), // "HTTP/"
|
|
delim_rule( digit_chars ), // DIGIT
|
|
squelch( delim_rule( '.' ) ), // "."
|
|
delim_rule( digit_chars ), // DIGIT
|
|
squelch( literal_rule( "\r\n" ) ) ); // CRLF
|
|
//]
|
|
ignore_unused(request_line_rule);
|
|
}
|
|
}
|
|
|
|
void
|
|
run()
|
|
{
|
|
snippets1();
|
|
snippets2();
|
|
snippets3();
|
|
snippets4();
|
|
}
|
|
};
|
|
|
|
TEST_SUITE(
|
|
doc_grammar_test,
|
|
"boost.url.doc.grammar");
|
|
|
|
} // grammar
|
|
} // urls
|
|
} // boost
|