| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/developer/debug/zxdb/expr/parse_special_identifier.h" |
| |
| #include <gtest/gtest.h> |
| |
| namespace zxdb { |
| |
| TEST(ParseSpecialIdentifier, NoName) { |
| size_t cur = 0; |
| SpecialIdentifier si; |
| std::string contents; |
| size_t error_location = 0; |
| |
| // Followed by end of input. |
| Err err = ParseSpecialIdentifier("$", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.has_error()); |
| EXPECT_EQ("Expected special name or '(' for escaped input.", err.msg()); |
| EXPECT_EQ(1u, error_location); |
| |
| // Followed by invalid character. |
| cur = 1; |
| error_location = 0; |
| err = ParseSpecialIdentifier(" $ something", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.has_error()); |
| EXPECT_EQ("Expected special name or '(' for escaped input.", err.msg()); |
| EXPECT_EQ(2u, error_location); |
| |
| // Followed by (). |
| cur = 0; |
| error_location = 0; |
| err = ParseSpecialIdentifier("$()", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.ok()) << err.msg(); |
| EXPECT_EQ(3u, cur); |
| EXPECT_EQ(SpecialIdentifier::kEscaped, si); |
| EXPECT_TRUE(contents.empty()); |
| |
| // Followed by (something). |
| cur = 0; |
| error_location = 0; |
| err = ParseSpecialIdentifier("$(something)", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.ok()) << err.msg(); |
| EXPECT_EQ(12u, cur); |
| EXPECT_EQ(SpecialIdentifier::kEscaped, si); |
| EXPECT_EQ("something", contents); |
| } |
| |
| TEST(ParseSpecialIdentifier, Name) { |
| size_t cur = 0; |
| SpecialIdentifier si; |
| std::string contents; |
| size_t error_location = 0; |
| |
| // Space terminates the name. |
| Err err = ParseSpecialIdentifier("$main ", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.ok()) << err.msg(); |
| EXPECT_EQ(5u, cur); |
| EXPECT_EQ(SpecialIdentifier::kMain, si); |
| EXPECT_EQ("", contents); |
| |
| // End of input terminates the name. |
| cur = 0; |
| err = ParseSpecialIdentifier("$anon", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.ok()) << err.msg(); |
| EXPECT_EQ(5u, cur); |
| EXPECT_EQ(SpecialIdentifier::kAnon, si); |
| EXPECT_EQ("", contents); |
| |
| // Name with empty contents. |
| cur = 0; |
| err = ParseSpecialIdentifier("$reg()", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.ok()) << err.msg(); |
| EXPECT_EQ(6u, cur); |
| EXPECT_EQ(SpecialIdentifier::kRegister, si); |
| EXPECT_EQ("", contents); |
| |
| // Name with nonempty contents. |
| cur = 0; |
| err = ParseSpecialIdentifier("$reg(foo)", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.ok()) << err.msg(); |
| EXPECT_EQ(9u, cur); |
| EXPECT_EQ(SpecialIdentifier::kRegister, si); |
| EXPECT_EQ("foo", contents); |
| |
| // Invalid name. |
| cur = 0; |
| err = ParseSpecialIdentifier("$invalid", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.has_error()); |
| EXPECT_EQ(8u, cur); |
| EXPECT_EQ(SpecialIdentifier::kNone, si); |
| EXPECT_TRUE(contents.empty()); |
| } |
| |
| TEST(ParseSpecialIdentifier, ContentsEscaping) { |
| size_t cur = 0; |
| SpecialIdentifier si; |
| std::string contents; |
| size_t error_location = 0; |
| |
| // Unterminated paren. |
| Err err = ParseSpecialIdentifier("$(unterm", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.has_error()); |
| EXPECT_EQ("Unexpected end of input in special identifier to match.", err.msg()); |
| EXPECT_EQ(1u, error_location); |
| |
| // Mismatched paren. |
| cur = 0; |
| err = ParseSpecialIdentifier("$(unt(erm)", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.has_error()); |
| EXPECT_EQ("Unexpected end of input in special identifier to match.", err.msg()); |
| EXPECT_EQ(1u, error_location); |
| |
| // Escaped the opening and closing parens. |
| cur = 0; |
| err = ParseSpecialIdentifier("$(ab\\)c\\(de)", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.ok()); |
| EXPECT_EQ(12u, cur); |
| EXPECT_EQ(SpecialIdentifier::kEscaped, si); |
| EXPECT_EQ("ab)c(de", contents); |
| |
| // Escaped backslash. |
| cur = 0; |
| err = ParseSpecialIdentifier("$(\\\\)", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.ok()); |
| EXPECT_EQ(5u, cur); |
| EXPECT_EQ(SpecialIdentifier::kEscaped, si); |
| EXPECT_EQ("\\", contents); |
| |
| // Backslash at end of input. |
| cur = 0; |
| err = ParseSpecialIdentifier("$(\\", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.has_error()); |
| EXPECT_EQ("Unexpected end of input in special identifier to match.", err.msg()); |
| EXPECT_EQ(1u, error_location); |
| |
| // Invalid escaped thing. |
| cur = 0; |
| err = ParseSpecialIdentifier("$(\\ab)", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.has_error()); |
| EXPECT_EQ(SpecialIdentifier::kEscaped, si); |
| EXPECT_EQ("Invalid backslash-escaped character in special identifier.", err.msg()); |
| EXPECT_EQ(3u, error_location); |
| |
| // Valid nested parens. |
| cur = 0; |
| err = ParseSpecialIdentifier("$((foo(bar)))", &cur, &si, &contents, &error_location); |
| EXPECT_TRUE(err.ok()); |
| EXPECT_EQ(13u, cur); |
| EXPECT_EQ(SpecialIdentifier::kEscaped, si); |
| EXPECT_EQ("(foo(bar))", contents); |
| } |
| |
| } // namespace zxdb |