Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
use std_regex_provider everywhere
  • Loading branch information
anonrig committed Jan 22, 2025
commit a790af38454fe42128afe8cad55471a0f1c60d55
6 changes: 2 additions & 4 deletions include/ada/url_pattern-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ std::string url_pattern_component<regex_provider>::to_string() const {
template <url_pattern_regex::regex_concept regex_provider>
url_pattern_component_result
url_pattern_component<regex_provider>::create_component_match_result(
std::string_view input, const std::smatch& exec_result) {
std::string_view input, const std::vector<std::string>& exec_result) {
// Let result be a new URLPatternComponentResult.
// Set result["input"] to input.
// Let groups be a record<USVString, (USVString or undefined)>.
Expand All @@ -60,11 +60,9 @@ url_pattern_component<regex_provider>::create_component_match_result(
// Let name be component’s group name list[index - 1].
// Let value be Get(execResult, ToString(index)).
// Set groups[name] to value.
auto exec = exec_result[index];
if (!exec.matched) continue;
result.groups.insert({
group_name_list[group_index],
exec.str(),
exec_result[index],
});

group_index++;
Expand Down
3 changes: 1 addition & 2 deletions include/ada/url_pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "ada/expected.h"
#include "ada/url_pattern_regex.h"

#include <regex>
#include <string>
#include <unordered_map>
#include <variant>
Expand Down Expand Up @@ -232,7 +231,7 @@ class url_pattern_component {

// @see https://urlpattern.spec.whatwg.org/#create-a-component-match-result
url_pattern_component_result create_component_match_result(
std::string_view input, const std::smatch& exec_result);
std::string_view input, const std::vector<std::string>& exec_result);

std::string to_string() const;

Expand Down
12 changes: 6 additions & 6 deletions include/ada/url_pattern_regex.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ concept regex_concept = requires(T t, std::string_view pattern,

// Function to perform regex search
{
t.regex_search(input, std::declval<typename T::regex_type&>())
} -> std::same_as<std::vector<std::string>>;
T::regex_search(input, std::declval<typename T::regex_type&>())
} -> std::same_as<std::optional<std::vector<std::string>>>;

// Function to match regex pattern
{
t.regex_match(input, std::declval<typename T::regex_type&>())
T::regex_match(input, std::declval<typename T::regex_type&>())
} -> std::same_as<bool>;

// Copy constructor
Expand All @@ -44,9 +44,9 @@ class std_regex_provider {
using regex_type = std::regex;
static std::optional<regex_type> create_instance(std::string_view pattern,
bool ignore_case);
std::vector<std::string> regex_search(std::string_view input,
const regex_type& pattern);
bool regex_match(std::string_view input, const regex_type& pattern);
static std::optional<std::vector<std::string>> regex_search(
std::string_view input, const regex_type& pattern);
static bool regex_match(std::string_view input, const regex_type& pattern);
};

} // namespace ada::url_pattern_regex
Expand Down
58 changes: 21 additions & 37 deletions src/url_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include <algorithm>
#include <optional>
#include <regex>
#include <string>

namespace ada {
Expand Down Expand Up @@ -678,60 +677,45 @@ result<std::optional<url_pattern_result>> url_pattern<regex_provider>::match(
}
}

auto regex_flags = std::regex_constants::match_any;

// Let protocolExecResult be RegExpBuiltinExec(urlPattern’s protocol
// component's regular expression, protocol).
std::smatch protocol_exec_result_value;
auto protocol_exec_result =
std::regex_search(protocol, protocol_exec_result_value,
protocol_component.regexp, regex_flags);
regex_provider::regex_search(protocol, protocol_component.regexp);

// Let usernameExecResult be RegExpBuiltinExec(urlPattern’s username
// component's regular expression, username).
std::smatch username_exec_result_value;
auto username_exec_result =
std::regex_search(username, username_exec_result_value,
username_component.regexp, regex_flags);
regex_provider::regex_search(username, username_component.regexp);

// Let passwordExecResult be RegExpBuiltinExec(urlPattern’s password
// component's regular expression, password).
std::smatch password_exec_result_value;
auto password_exec_result =
std::regex_search(password, password_exec_result_value,
password_component.regexp, regex_flags);
regex_provider::regex_search(password, password_component.regexp);

// Let hostnameExecResult be RegExpBuiltinExec(urlPattern’s hostname
// component's regular expression, hostname).
std::smatch hostname_exec_result_value;
auto hostname_exec_result =
std::regex_search(hostname, hostname_exec_result_value,
hostname_component.regexp, regex_flags);
regex_provider::regex_search(hostname, hostname_component.regexp);

// Let portExecResult be RegExpBuiltinExec(urlPattern’s port component's
// regular expression, port).
std::smatch port_exec_result_value;
auto port_exec_result = std::regex_search(port, port_exec_result_value,
port_component.regexp, regex_flags);
auto port_exec_result =
regex_provider::regex_search(port, port_component.regexp);

// Let pathnameExecResult be RegExpBuiltinExec(urlPattern’s pathname
// component's regular expression, pathname).
std::smatch pathname_exec_result_value;
auto pathname_exec_result =
std::regex_search(pathname, pathname_exec_result_value,
pathname_component.regexp, regex_flags);
regex_provider::regex_search(pathname, pathname_component.regexp);

// Let searchExecResult be RegExpBuiltinExec(urlPattern’s search component's
// regular expression, search).
std::smatch search_exec_result_value;
auto search_exec_result = std::regex_search(
search, search_exec_result_value, search_component.regexp, regex_flags);
auto search_exec_result =
regex_provider::regex_search(search, search_component.regexp);

// Let hashExecResult be RegExpBuiltinExec(urlPattern’s hash component's
// regular expression, hash).
std::smatch hash_exec_result_value;
auto hash_exec_result = std::regex_search(hash, hash_exec_result_value,
hash_component.regexp, regex_flags);
auto hash_exec_result =
regex_provider::regex_search(hash, hash_component.regexp);

// If protocolExecResult, usernameExecResult, passwordExecResult,
// hostnameExecResult, portExecResult, pathnameExecResult, searchExecResult,
Expand All @@ -749,42 +733,42 @@ result<std::optional<url_pattern_result>> url_pattern<regex_provider>::match(
// Set result["protocol"] to the result of creating a component match result
// given urlPattern’s protocol component, protocol, and protocolExecResult.
result.protocol = protocol_component.create_component_match_result(
protocol, protocol_exec_result_value);
protocol, *protocol_exec_result);

// Set result["username"] to the result of creating a component match result
// given urlPattern’s username component, username, and usernameExecResult.
result.username = username_component.create_component_match_result(
username, username_exec_result_value);
username, *username_exec_result);

// Set result["password"] to the result of creating a component match result
// given urlPattern’s password component, password, and passwordExecResult.
result.password = password_component.create_component_match_result(
password, password_exec_result_value);
password, *password_exec_result);

// Set result["hostname"] to the result of creating a component match result
// given urlPattern’s hostname component, hostname, and hostnameExecResult.
result.hostname = hostname_component.create_component_match_result(
hostname, hostname_exec_result_value);
hostname, *hostname_exec_result);

// Set result["port"] to the result of creating a component match result given
// urlPattern’s port component, port, and portExecResult.
result.port = port_component.create_component_match_result(
port, port_exec_result_value);
result.port =
port_component.create_component_match_result(port, *port_exec_result);

// Set result["pathname"] to the result of creating a component match result
// given urlPattern’s pathname component, pathname, and pathnameExecResult.
result.pathname = pathname_component.create_component_match_result(
pathname, pathname_exec_result_value);
pathname, *pathname_exec_result);

// Set result["search"] to the result of creating a component match result
// given urlPattern’s search component, search, and searchExecResult.
result.search = search_component.create_component_match_result(
search, search_exec_result_value);
search, *search_exec_result);

// Set result["hash"] to the result of creating a component match result given
// urlPattern’s hash component, hash, and hashExecResult.
result.hash = hash_component.create_component_match_result(
hash, hash_exec_result_value);
result.hash =
hash_component.create_component_match_result(hash, *hash_exec_result);

return result;
}
Expand Down
9 changes: 5 additions & 4 deletions src/url_pattern_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,11 @@ template <url_pattern_regex::regex_concept regex_provider>
bool protocol_component_matches_special_scheme(
url_pattern_component<regex_provider>& component) {
auto regex = component.regexp;
// TODO: Use provider.regex_match
return std::regex_match("http", regex) || std::regex_match("https", regex) ||
std::regex_match("ws", regex) || std::regex_match("wss", regex) ||
std::regex_match("ftp", regex);
return regex_provider::regex_match("http", regex) ||
regex_provider::regex_match("https", regex) ||
regex_provider::regex_match("ws", regex) ||
regex_provider::regex_match("wss", regex) ||
regex_provider::regex_match("ftp", regex);
}

template <url_pattern_regex::regex_concept regex_provider>
Expand Down
17 changes: 11 additions & 6 deletions src/url_pattern_regex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,22 @@ std::optional<std::regex> std_regex_provider::create_instance(
}
}

std::vector<std::string> std_regex_provider::regex_search(
std::optional<std::vector<std::string>> std_regex_provider::regex_search(
std::string_view input, const std::regex& pattern) {
std::vector<std::string> matches;
std::string input_str(
input.begin(),
input.end()); // Convert string_view to string for regex_search
std::smatch match_result;
while (std::regex_search(input_str, match_result, pattern,
std::regex_constants::match_any)) {
matches.push_back(match_result.str());
input_str = match_result.suffix().str();
if (!std::regex_search(input_str, match_result, pattern,
std::regex_constants::match_any)) {
return std::nullopt;
}
std::vector<std::string> matches;
matches.reserve(match_result.size() - 1);
for (const auto& match : match_result) {
if (match.matched) {
matches.push_back(match.str());
}
}
return matches;
}
Expand Down
Loading