/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2015 Danny Robson */ #include #include #include #include // We generate some really old style C code via ragel here, so we have to // disable some noisy warnings (doubly so given -Werror) #pragma GCC diagnostic ignored "-Wold-style-cast" using cruft::uri; /////////////////////////////////////////////////////////////////////////////// %%{ machine impl; action trace { if (0) std::cerr << *p; } action success {__success = true; } action failure {__success = false; } action scheme_begin { starts[SCHEME] = p; } action scheme_end { record_component (SCHEME); } action hier_begin { ; } action hier_end { ; } action user_begin { starts[USER] = p; } action user_end { record_component (USER); } action host_begin { starts[HOST] = p; } action host_end { record_component (HOST); } action port_begin { starts[PORT] = p; } action port_end { record_component (PORT); } action authority_begin { ; } action authority_end { ; } action path_begin { starts[PATH] = p; } action path_end { record_component (PATH); } action query_begin { starts[QUERY] = p; } action query_end { record_component (QUERY); } action fragment_begin { starts[FRAGMENT] = p; } action fragment_end { record_component (FRAGMENT); } action uri_begin {} action uri_end {} include rfc3986 'rfc3986.rl'; impl := URI >uri_begin %uri_end %success $!failure $trace; write data; }%% /////////////////////////////////////////////////////////////////////////////// #include //----------------------------------------------------------------------------- void cruft::uri::parse (void) { char const *starts[NUM_COMPONENTS] = {}; const char *str = m_value.data (); const char *p = m_value.data (); const char *pe = m_value.data () + m_value.size (); const char *eof = pe; m_offsets = {}; auto record_component = [&] (int const idx) { // CHECK (m_offsets[idx].first == 0); // CHECK (m_offsets[idx].second == 0); CHECK (starts[idx]); m_offsets[idx].first = cruft::cast::narrow (starts[idx] - str); m_offsets[idx].second = cruft::cast::narrow ( p - str); }; bool __success = false; int cs; %%write init; %%write exec; if constexpr (debug_enabled) { if (!m_value.empty ()) CHECK (std::any_of ( m_offsets.begin (), m_offsets.end (), [] (auto const &i) { return !!i.second; })); } if (!__success) throw parse_error (fmt::format ("invalid uri '{}'", m_value)); }