Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
65 changes: 57 additions & 8 deletions src/support/string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,21 +82,70 @@ Split handleBracketingOperators(Split split) {
return ret;
}

bool wildcardMatch(const std::string& pattern, const std::string& value) {
for (size_t i = 0; i < pattern.size(); i++) {
bool wildcardMatch(const std::string& initialPattern,
const std::string& initialValue) {
// Avoid recursion, as strings can be very long.
struct Task {
std::string_view pattern;
std::string_view value;
size_t i;
// Whether we continue a task waiting on results of subtasks (see below).
bool continuation;
};
std::vector<Task> tasks;
std::vector<bool> results;
// We start with the initial data.
tasks.push_back({initialPattern, initialValue, 0, false});
while (!tasks.empty()) {
auto task = tasks.back();
tasks.pop_back();
auto& [pattern, value, i, continuation] = task;
if (continuation) {
// See below: We pushed two tasks, and must check if either matched.
auto num = results.size();
assert(num >= 2);
auto result = results[num - 1] || results[num - 2];
results.resize(num - 2);
results.push_back(result);
continue;
}
if (i == pattern.size()) {
// We reached the end.
results.push_back(value.size() == pattern.size());
continue;
}
if (pattern[i] == '*') {
return wildcardMatch(pattern.substr(i + 1), value.substr(i)) ||
(value.size() > 0 &&
wildcardMatch(pattern.substr(i), value.substr(i + 1)));
if (i >= value.size()) {
// A lone wildcard matches the empty string.
results.push_back(pattern.size() == (i + 1));
continue;
}
// Push a continuation of us, and then two child tasks. We need one of the
// child tasks to be true for us to match.
tasks.push_back({pattern, value, i, true});
// This child task matches if we can skip the '*' (we find what we want
// right after).
tasks.push_back({pattern.substr(i + 1), value.substr(i), 0, false});
// This child task matches if we can skip a character in the value (the
// '*' matches something arbitary, and later we find what we want).
tasks.push_back({pattern.substr(i), value.substr(i + 1), 0, false});
continue;
}
if (i >= value.size()) {
return false;
// We reached the end, and sizes do not match.
results.push_back(false);
continue;
}
if (pattern[i] != value[i]) {
return false;
// The data does not match.
results.push_back(false);
continue;
}
// Proceed onwards.
tasks.push_back({pattern, value, i + 1, false});
}
return value.size() == pattern.size();
assert(results.size() == 1);
return results[0];
}

std::string trim(const std::string& input) {
Expand Down
59 changes: 59 additions & 0 deletions test/lit/passes/no-inline.wast
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,26 @@
)
)

(func $very-long-name-we-should-not-error-on-even-though-it-is-very-very-long
;; Test a long name.
)

;; NO_FULL: (func $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long
;; NO_FULL-NEXT: )
;; NO_BOTH: (func $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long
;; NO_BOTH-NEXT: )
(func $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long
;; Test a long name with "maybe" in it.
)

;; NO_FULL: (func $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long
;; NO_FULL-NEXT: )
;; NO_BOTH: (func $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long
;; NO_BOTH-NEXT: )
(func $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long
;; Test a long name with "maybe" in it, and a partial match earlier ("may").
)

;; YES_ALL: (func $caller
;; YES_ALL-NEXT: (local $0 i32)
;; YES_ALL-NEXT: (local $1 i32)
Expand Down Expand Up @@ -741,6 +761,18 @@
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-even-though-it-is-very-very-long$4
;; YES_ALL-NEXT: (block
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long$5
;; YES_ALL-NEXT: (block
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: (block $__inlined_func$very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long$6
;; YES_ALL-NEXT: (block
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; NO_PART: (func $caller
;; NO_PART-NEXT: (call $maybe-partial-or-full-1
Expand All @@ -755,6 +787,18 @@
;; NO_PART-NEXT: (call $maybe-partial-or-full-2
;; NO_PART-NEXT: (i32.const 1)
;; NO_PART-NEXT: )
;; NO_PART-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-even-though-it-is-very-very-long
;; NO_PART-NEXT: (block
;; NO_PART-NEXT: )
;; NO_PART-NEXT: )
;; NO_PART-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long$1
;; NO_PART-NEXT: (block
;; NO_PART-NEXT: )
;; NO_PART-NEXT: )
;; NO_PART-NEXT: (block $__inlined_func$very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long$2
;; NO_PART-NEXT: (block
;; NO_PART-NEXT: )
;; NO_PART-NEXT: )
;; NO_PART-NEXT: )
;; NO_FULL: (func $caller
;; NO_FULL-NEXT: (local $0 i32)
Expand Down Expand Up @@ -817,6 +861,12 @@
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-even-though-it-is-very-very-long$4
;; NO_FULL-NEXT: (block
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: (call $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long)
;; NO_FULL-NEXT: (call $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long)
;; NO_FULL-NEXT: )
;; NO_BOTH: (func $caller
;; NO_BOTH-NEXT: (call $maybe-partial-or-full-1
Expand All @@ -831,6 +881,12 @@
;; NO_BOTH-NEXT: (call $maybe-partial-or-full-2
;; NO_BOTH-NEXT: (i32.const 1)
;; NO_BOTH-NEXT: )
;; NO_BOTH-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-even-though-it-is-very-very-long
;; NO_BOTH-NEXT: (block
;; NO_BOTH-NEXT: )
;; NO_BOTH-NEXT: )
;; NO_BOTH-NEXT: (call $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long)
;; NO_BOTH-NEXT: (call $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long)
;; NO_BOTH-NEXT: )
(func $caller
;; In YES_ALL we will fully inline all of these. In NO_FULL we will partially
Expand All @@ -851,6 +907,9 @@
(call $maybe-partial-or-full-2
(i32.const 1)
)
(call $very-long-name-we-should-not-error-on-even-though-it-is-very-very-long)
(call $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long)
(call $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long)
)
)
;; NO_FULL: (func $byn-split-outlined-B$maybe-partial-or-full-1 (param $x i32)
Expand Down
Loading