forked from OSchip/llvm-project
[YAML] Support extended spellings when parsing bools.
Support all the spellings of boolean datatypes according to https://yaml.org/type/bool.html Reviewed By: silvas Differential Revision: https://reviews.llvm.org/D92755
This commit is contained in:
parent
f6e885ad2a
commit
0e5bfffb13
|
@ -78,6 +78,9 @@ bool scanTokens(StringRef Input);
|
|||
/// escaped, but emitted verbatim.
|
||||
std::string escape(StringRef Input, bool EscapePrintable = true);
|
||||
|
||||
/// Parse \p S as a bool according to https://yaml.org/type/bool.html.
|
||||
llvm::Optional<bool> parseBool(StringRef S);
|
||||
|
||||
/// This class represents a YAML stream potentially containing multiple
|
||||
/// documents.
|
||||
class Stream {
|
||||
|
|
|
@ -638,6 +638,7 @@ inline bool isNull(StringRef S) {
|
|||
}
|
||||
|
||||
inline bool isBool(StringRef S) {
|
||||
// FIXME: using parseBool is causing multiple tests to fail.
|
||||
return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
|
||||
S.equals("false") || S.equals("False") || S.equals("FALSE");
|
||||
}
|
||||
|
|
|
@ -746,6 +746,92 @@ std::string yaml::escape(StringRef Input, bool EscapePrintable) {
|
|||
return EscapedInput;
|
||||
}
|
||||
|
||||
llvm::Optional<bool> yaml::parseBool(StringRef S) {
|
||||
switch (S.size()) {
|
||||
case 1:
|
||||
switch (S.front()) {
|
||||
case 'y':
|
||||
case 'Y':
|
||||
return true;
|
||||
case 'n':
|
||||
case 'N':
|
||||
return false;
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
case 2:
|
||||
switch (S.front()) {
|
||||
case 'O':
|
||||
if (S[1] == 'N') // ON
|
||||
return true;
|
||||
LLVM_FALLTHROUGH;
|
||||
case 'o':
|
||||
if (S[1] == 'n') //[Oo]n
|
||||
return true;
|
||||
return None;
|
||||
case 'N':
|
||||
if (S[1] == 'O') // NO
|
||||
return false;
|
||||
LLVM_FALLTHROUGH;
|
||||
case 'n':
|
||||
if (S[1] == 'o') //[Nn]o
|
||||
return false;
|
||||
return None;
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
case 3:
|
||||
switch (S.front()) {
|
||||
case 'O':
|
||||
if (S.drop_front() == "FF") // OFF
|
||||
return false;
|
||||
LLVM_FALLTHROUGH;
|
||||
case 'o':
|
||||
if (S.drop_front() == "ff") //[Oo]ff
|
||||
return false;
|
||||
return None;
|
||||
case 'Y':
|
||||
if (S.drop_front() == "ES") // YES
|
||||
return true;
|
||||
LLVM_FALLTHROUGH;
|
||||
case 'y':
|
||||
if (S.drop_front() == "es") //[Yy]es
|
||||
return true;
|
||||
return None;
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
case 4:
|
||||
switch (S.front()) {
|
||||
case 'T':
|
||||
if (S.drop_front() == "RUE") // TRUE
|
||||
return true;
|
||||
LLVM_FALLTHROUGH;
|
||||
case 't':
|
||||
if (S.drop_front() == "rue") //[Tt]rue
|
||||
return true;
|
||||
return None;
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
case 5:
|
||||
switch (S.front()) {
|
||||
case 'F':
|
||||
if (S.drop_front() == "ALSE") // FALSE
|
||||
return false;
|
||||
LLVM_FALLTHROUGH;
|
||||
case 'f':
|
||||
if (S.drop_front() == "alse") //[Ff]alse
|
||||
return false;
|
||||
return None;
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Scanner::Scanner(StringRef Input, SourceMgr &sm, bool ShowColors,
|
||||
std::error_code *EC)
|
||||
: SM(sm), ShowColors(ShowColors), EC(EC) {
|
||||
|
|
|
@ -885,11 +885,8 @@ void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
|
|||
}
|
||||
|
||||
StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
|
||||
if (Scalar.equals("true")) {
|
||||
Val = true;
|
||||
return StringRef();
|
||||
} else if (Scalar.equals("false")) {
|
||||
Val = false;
|
||||
if (llvm::Optional<bool> Parsed = parseBool(Scalar)) {
|
||||
Val = *Parsed;
|
||||
return StringRef();
|
||||
}
|
||||
return "invalid boolean";
|
||||
|
|
|
@ -342,4 +342,44 @@ TEST(YAMLParser, FlowSequenceTokensOutsideFlowSequence) {
|
|||
}
|
||||
}
|
||||
|
||||
static void expectCanParseBool(StringRef S, bool Expected) {
|
||||
llvm::Optional<bool> Parsed = yaml::parseBool(S);
|
||||
EXPECT_TRUE(Parsed.hasValue());
|
||||
EXPECT_EQ(*Parsed, Expected);
|
||||
}
|
||||
|
||||
static void expectCannotParseBool(StringRef S) {
|
||||
EXPECT_FALSE(yaml::parseBool(S).hasValue());
|
||||
}
|
||||
|
||||
TEST(YAMLParser, ParsesBools) {
|
||||
// Test true values.
|
||||
expectCanParseBool("ON", true);
|
||||
expectCanParseBool("On", true);
|
||||
expectCanParseBool("on", true);
|
||||
expectCanParseBool("TRUE", true);
|
||||
expectCanParseBool("True", true);
|
||||
expectCanParseBool("true", true);
|
||||
expectCanParseBool("Y", true);
|
||||
expectCanParseBool("y", true);
|
||||
expectCanParseBool("YES", true);
|
||||
expectCanParseBool("Yes", true);
|
||||
expectCanParseBool("yes", true);
|
||||
expectCannotParseBool("1");
|
||||
|
||||
// Test false values.
|
||||
expectCanParseBool("FALSE", false);
|
||||
expectCanParseBool("False", false);
|
||||
expectCanParseBool("false", false);
|
||||
expectCanParseBool("N", false);
|
||||
expectCanParseBool("n", false);
|
||||
expectCanParseBool("NO", false);
|
||||
expectCanParseBool("No", false);
|
||||
expectCanParseBool("no", false);
|
||||
expectCanParseBool("OFF", false);
|
||||
expectCanParseBool("Off", false);
|
||||
expectCanParseBool("off", false);
|
||||
expectCannotParseBool("0");
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
|
Loading…
Reference in New Issue