blob: 8457b6e4db79b2f1774abe0a6adf970ad2a6c83f [file] [log] [blame]
// 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