Skip to content

Commit 7d5a0ab

Browse files
authored
Manifest: allow comma & space in flags (#1182)
1 parent c437584 commit 7d5a0ab

File tree

1 file changed

+37
-12
lines changed

1 file changed

+37
-12
lines changed

src/Manifest.cc

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <cstdlib>
1313
#include <fmt/core.h>
1414
#include <optional>
15+
#include <ranges>
1516
#include <spdlog/spdlog.h>
1617
#include <string>
1718
#include <string_view>
@@ -72,22 +73,27 @@ validateOptLevel(const std::uint8_t optLevel) noexcept {
7273

7374
static Result<void>
7475
validateFlag(const char* type, const std::string_view flag) noexcept {
75-
// cxxflag must start with `-`
76-
if (flag.empty() || flag[0] != '-') {
77-
Bail("{} must start with `-`", type);
78-
}
76+
Ensure(!flag.empty() && flag[0] == '-', "{} must start with `-`", type);
7977

80-
// cxxflag only contains alphanumeric characters, `-`, `_`, `=`, `+`, `:`,
81-
// or `.`.
78+
static const std::unordered_set<char> allowed{
79+
'-', '_', '=', '+', ':', '.', ',' // `-fsanitize=address,undefined`
80+
};
81+
std::unordered_map<char, bool> allowedOnce{
82+
{ ' ', false }, // `-framework Metal`
83+
};
8284
for (const char c : flag) {
83-
if (!std::isalnum(c) && c != '-' && c != '_' && c != '=' && c != '+'
84-
&& c != ':' && c != '.') {
85-
Bail(
86-
"{} must only contain alphanumeric characters, `-`, `_`, `=`, "
87-
"`+`, `:`, or `.`",
88-
type
85+
if (allowedOnce.contains(c)) {
86+
Ensure(
87+
!allowedOnce[c], "{} must only contain {} once", type,
88+
allowedOnce | std::views::keys
8989
);
90+
allowedOnce[c] = true;
91+
continue;
9092
}
93+
Ensure(
94+
std::isalnum(c) || allowed.contains(c),
95+
"{} must only contain {} or alphanumeric characters", type, allowed
96+
);
9197
}
9298

9399
return Ok();
@@ -990,6 +996,24 @@ testValidateDepName() {
990996
pass();
991997
}
992998

999+
static void
1000+
testValidateFlag() {
1001+
assertTrue(validateFlag("cxxflags", "-fsanitize=address,undefined").is_ok());
1002+
1003+
// issue #1183
1004+
assertTrue(validateFlag("ldflags", "-framework Metal").is_ok());
1005+
assertEq(
1006+
validateFlag("ldflags", "-framework Metal").unwrap_err()->what(),
1007+
"ldflags must only contain [' '] once"
1008+
);
1009+
assertEq(
1010+
validateFlag("ldflags", "-framework Metal && bash").unwrap_err()->what(),
1011+
"ldflags must only contain [' '] once"
1012+
);
1013+
1014+
pass();
1015+
}
1016+
9931017
} // namespace tests
9941018

9951019
int
@@ -1002,6 +1026,7 @@ main() {
10021026
tests::testParseProfiles();
10031027
tests::testLintTryFromToml();
10041028
tests::testValidateDepName();
1029+
tests::testValidateFlag();
10051030
}
10061031

10071032
#endif

0 commit comments

Comments
 (0)