Blame test/testtoken.cpp

Packit 2035a7
/*
Packit 2035a7
 * Cppcheck - A tool for static C/C++ code analysis
Packit 2035a7
 * Copyright (C) 2007-2017 Cppcheck team.
Packit 2035a7
 *
Packit 2035a7
 * This program is free software: you can redistribute it and/or modify
Packit 2035a7
 * it under the terms of the GNU General Public License as published by
Packit 2035a7
 * the Free Software Foundation, either version 3 of the License, or
Packit 2035a7
 * (at your option) any later version.
Packit 2035a7
 *
Packit 2035a7
 * This program is distributed in the hope that it will be useful,
Packit 2035a7
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 2035a7
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 2035a7
 * GNU General Public License for more details.
Packit 2035a7
 *
Packit 2035a7
 * You should have received a copy of the GNU General Public License
Packit 2035a7
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit 2035a7
 */
Packit 2035a7
Packit 2035a7
#include "settings.h"
Packit 2035a7
#include "testsuite.h"
Packit 2035a7
#include "testutils.h"
Packit 2035a7
#include "token.h"
Packit 2035a7
#include "tokenize.h"
Packit 2035a7
#include "tokenlist.h"
Packit 2035a7
Packit 2035a7
#include <string>
Packit 2035a7
#include <vector>
Packit 2035a7
Packit 2035a7
struct InternalError;
Packit 2035a7
Packit 2035a7
Packit 2035a7
class TestToken : public TestFixture {
Packit 2035a7
public:
Packit 2035a7
    TestToken() : TestFixture("TestToken") {
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
private:
Packit 2035a7
    std::vector<std::string> arithmeticalOps;
Packit 2035a7
    std::vector<std::string> logicalOps;
Packit 2035a7
    std::vector<std::string> bitOps;
Packit 2035a7
    std::vector<std::string> comparisonOps;
Packit 2035a7
    std::vector<std::string> extendedOps;
Packit 2035a7
    std::vector<std::string> assignmentOps;
Packit 2035a7
Packit 2035a7
    void run() {
Packit 2035a7
        initOps();
Packit 2035a7
Packit 2035a7
        TEST_CASE(nextprevious);
Packit 2035a7
        TEST_CASE(multiCompare);
Packit 2035a7
        TEST_CASE(multiCompare2);                   // #3294 - false negative multi compare between "=" and "=="
Packit 2035a7
        TEST_CASE(multiCompare3);                   // false positive for %or% on code using "|="
Packit 2035a7
        TEST_CASE(multiCompare4);
Packit 2035a7
        TEST_CASE(multiCompare5);
Packit 2035a7
        TEST_CASE(getStrLength);
Packit 2035a7
        TEST_CASE(getStrSize);
Packit 2035a7
        TEST_CASE(strValue);
Packit 2035a7
Packit 2035a7
        TEST_CASE(deleteLast);
Packit 2035a7
        TEST_CASE(nextArgument);
Packit 2035a7
        TEST_CASE(eraseTokens);
Packit 2035a7
Packit 2035a7
        TEST_CASE(matchAny);
Packit 2035a7
        TEST_CASE(matchSingleChar);
Packit 2035a7
        TEST_CASE(matchNothingOrAnyNotElse);
Packit 2035a7
        TEST_CASE(matchType);
Packit 2035a7
        TEST_CASE(matchChar);
Packit 2035a7
        TEST_CASE(matchCompOp);
Packit 2035a7
        TEST_CASE(matchStr);
Packit 2035a7
        TEST_CASE(matchVarid);
Packit 2035a7
        TEST_CASE(matchNumeric);
Packit 2035a7
        TEST_CASE(matchBoolean);
Packit 2035a7
        TEST_CASE(matchOr);
Packit 2035a7
        TEST_CASE(matchOp);
Packit 2035a7
        TEST_CASE(matchConstOp);
Packit 2035a7
Packit 2035a7
        TEST_CASE(isArithmeticalOp);
Packit 2035a7
        TEST_CASE(isOp);
Packit 2035a7
        TEST_CASE(isConstOp);
Packit 2035a7
        TEST_CASE(isExtendedOp);
Packit 2035a7
        TEST_CASE(isAssignmentOp);
Packit 2035a7
        TEST_CASE(isStandardType);
Packit 2035a7
        TEST_CASE(literals);
Packit 2035a7
        TEST_CASE(operators);
Packit 2035a7
Packit 2035a7
        TEST_CASE(updateProperties)
Packit 2035a7
        TEST_CASE(updatePropertiesConcatStr)
Packit 2035a7
        TEST_CASE(isNameGuarantees1)
Packit 2035a7
        TEST_CASE(isNameGuarantees2)
Packit 2035a7
        TEST_CASE(isNameGuarantees3)
Packit 2035a7
        TEST_CASE(isNameGuarantees4)
Packit 2035a7
        TEST_CASE(isNameGuarantees5)
Packit 2035a7
        TEST_CASE(isNameGuarantees6)
Packit 2035a7
Packit 2035a7
        TEST_CASE(canFindMatchingBracketsNeedsOpen);
Packit 2035a7
        TEST_CASE(canFindMatchingBracketsInnerPair);
Packit 2035a7
        TEST_CASE(canFindMatchingBracketsOuterPair);
Packit 2035a7
        TEST_CASE(canFindMatchingBracketsWithTooManyClosing);
Packit 2035a7
        TEST_CASE(canFindMatchingBracketsWithTooManyOpening);
Packit 2035a7
        TEST_CASE(findClosingBracket);
Packit 2035a7
Packit 2035a7
        TEST_CASE(expressionString);
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void nextprevious() const {
Packit 2035a7
        Token *token = new Token(0);
Packit 2035a7
        token->str("1");
Packit 2035a7
        token->insertToken("2");
Packit 2035a7
        token->next()->insertToken("3");
Packit 2035a7
        Token *last = token->tokAt(2);
Packit 2035a7
        ASSERT_EQUALS(token->str(), "1");
Packit 2035a7
        ASSERT_EQUALS(token->next()->str(), "2");
Packit 2035a7
        ASSERT_EQUALS(token->tokAt(2)->str(), "3");
Packit 2035a7
        if (last->next())
Packit 2035a7
            ASSERT_EQUALS("Null was expected", "");
Packit 2035a7
Packit 2035a7
        ASSERT_EQUALS(last->str(), "3");
Packit 2035a7
        ASSERT_EQUALS(last->previous()->str(), "2");
Packit 2035a7
        ASSERT_EQUALS(last->tokAt(-2)->str(), "1");
Packit 2035a7
        if (token->previous())
Packit 2035a7
            ASSERT_EQUALS("Null was expected", "");
Packit 2035a7
Packit 2035a7
        TokenList::deleteTokens(token);
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    bool Match(const std::string &code, const std::string &pattern, unsigned int varid=0) {
Packit 2035a7
        static const Settings settings;
Packit 2035a7
        Tokenizer tokenizer(&settings, this);
Packit 2035a7
        std::istringstream istr(";" + code + ";");
Packit 2035a7
        try {
Packit 2035a7
            tokenizer.tokenize(istr, "test.cpp");
Packit 2035a7
        } catch (...) {}
Packit 2035a7
        return Token::Match(tokenizer.tokens()->next(), pattern.c_str(), varid);
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void multiCompare() const {
Packit 2035a7
        // Test for found
Packit 2035a7
        Token one(0);
Packit 2035a7
        one.str("one");
Packit 2035a7
        ASSERT_EQUALS(1, Token::multiCompare(&one, "one|two", 0));
Packit 2035a7
Packit 2035a7
        Token two(0);
Packit 2035a7
        two.str("two");
Packit 2035a7
        ASSERT_EQUALS(1, Token::multiCompare(&two, "one|two", 0));
Packit 2035a7
        ASSERT_EQUALS(1, Token::multiCompare(&two, "verybig|two|", 0));
Packit 2035a7
Packit 2035a7
        // Test for empty string found
Packit 2035a7
        Token notfound(0);
Packit 2035a7
        notfound.str("notfound");
Packit 2035a7
        ASSERT_EQUALS(0, Token::multiCompare(&notfound, "one|two|", 0));
Packit 2035a7
Packit 2035a7
        // Test for not found
Packit 2035a7
        ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(&notfound, "one|two", 0)));
Packit 2035a7
Packit 2035a7
        Token s(0);
Packit 2035a7
        s.str("s");
Packit 2035a7
        ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(&s, "verybig|two", 0)));
Packit 2035a7
Packit 2035a7
        Token ne(0);
Packit 2035a7
        ne.str("ne");
Packit 2035a7
        ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(&ne, "one|two", 0)));
Packit 2035a7
Packit 2035a7
        Token a(0);
Packit 2035a7
        a.str("a");
Packit 2035a7
        ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(&a, "abc|def", 0)));
Packit 2035a7
Packit 2035a7
        Token abcd(0);
Packit 2035a7
        abcd.str("abcd");
Packit 2035a7
        ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(&abcd, "abc|def", 0)));
Packit 2035a7
Packit 2035a7
        Token def(0);
Packit 2035a7
        def.str("default");
Packit 2035a7
        ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(&def, "abc|def", 0)));
Packit 2035a7
Packit 2035a7
        // %op%
Packit 2035a7
        Token plus(0);
Packit 2035a7
        plus.str("+");
Packit 2035a7
        ASSERT_EQUALS(1, Token::multiCompare(&plus, "one|%op%", 0));
Packit 2035a7
        ASSERT_EQUALS(1, Token::multiCompare(&plus, "%op%|two", 0));
Packit 2035a7
        Token x(0);
Packit 2035a7
        x.str("x");
Packit 2035a7
        ASSERT_EQUALS(-1, Token::multiCompare(&x, "one|%op%", 0));
Packit 2035a7
        ASSERT_EQUALS(-1, Token::multiCompare(&x, "%op%|two", 0));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void multiCompare2() const { // #3294
Packit 2035a7
        // Original pattern that failed: [[,(=<>+-*|&^] %num% [+-*/] %num% ]|,|)|;|=|%op%
Packit 2035a7
        givenACodeSampleToTokenize toks("a == 1", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(toks.tokens(), "a =|%op%"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void multiCompare3() const {
Packit 2035a7
        // Original pattern that failed: "return|(|&&|%oror% %name% &&|%oror%|==|!=|<=|>=|<|>|-|%or% %name% )|&&|%oror%|;"
Packit 2035a7
        // Code snippet that failed: "return lv@86 |= rv@87 ;"
Packit 2035a7
Packit 2035a7
        // Note: Also test "reverse" alternative pattern, two different code paths to handle it
Packit 2035a7
        givenACodeSampleToTokenize toks("return a |= b ;", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(toks.tokens(), "return %name% xyz|%or% %name% ;"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(toks.tokens(), "return %name% %or%|xyz %name% ;"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize toks2("return a | b ;", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(toks2.tokens(), "return %name% xyz|%or% %name% ;"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(toks2.tokens(), "return %name% %or%|xyz %name% ;"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize toks3("return a || b ;", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(toks3.tokens(), "return %name% xyz|%or% %name% ;"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(toks3.tokens(), "return %name% %or%|xyz %name% ;"));
Packit 2035a7
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(toks3.tokens(), "return %name% xyz|%oror% %name% ;"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(toks3.tokens(), "return %name% %oror%|xyz %name% ;"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize toks4("a % b ;", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(toks4.tokens(), "%name% >>|<<|&|%or%|^|% %name% ;"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(toks4.tokens(), "%name% %|>>|<<|&|%or%|^ %name% ;"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(toks4.tokens(), "%name% >>|<<|&|%or%|%|^ %name% ;"));
Packit 2035a7
Packit 2035a7
        //%name%|%num% support
Packit 2035a7
        givenACodeSampleToTokenize num("100", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(num.tokens(), "%num%|%name%"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(num.tokens(), "%name%|%num%"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(num.tokens(), "%name%|%num%|%bool%"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(num.tokens(), "%name%|%bool%|%num%"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(num.tokens(), "%name%|%bool%|%str%|%num%"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(num.tokens(), "%bool%|%name%"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(num.tokens(), "%type%|%bool%|%char%"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(num.tokens(), "%type%|%bool%|100"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize numparen("( 100 )", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %num%|%name% )|"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %name%|%num% )|"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %name%|%num%|%bool% )|"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %name%|%bool%|%num% )|"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %name%|%bool%|%str%|%num% )|"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(numparen.tokens(), "(| %bool%|%name% )|"));
Packit 2035a7
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %num%|%name%| )|"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %name%|%num%| )|"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %name%|%num%|%bool%| )|"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %name%|%bool%|%num%| )|"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %name%|%bool%|%str%|%num%| )|"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %bool%|%name%| )|"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void multiCompare4() const {
Packit 2035a7
        givenACodeSampleToTokenize var("std :: queue < int > foo ;");
Packit 2035a7
Packit 2035a7
        ASSERT_EQUALS(Token::eBracket, var.tokens()->tokAt(3)->tokType());
Packit 2035a7
        ASSERT_EQUALS(Token::eBracket, var.tokens()->tokAt(5)->tokType());
Packit 2035a7
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(var.tokens(), "std :: queue %op%"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(var.tokens(), "std :: queue x|%op%"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(var.tokens(), "std :: queue %op%|x"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void multiCompare5() const {
Packit 2035a7
        Token tok(0);
Packit 2035a7
        tok.str("||");
Packit 2035a7
        ASSERT_EQUALS(true, Token::multiCompare(&tok, "+|%or%|%oror%", 0) >= 0);
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void getStrLength() const {
Packit 2035a7
        Token tok(0);
Packit 2035a7
Packit 2035a7
        tok.str("\"\"");
Packit 2035a7
        ASSERT_EQUALS(0, (int)Token::getStrLength(&tok));
Packit 2035a7
Packit 2035a7
        tok.str("\"test\"");
Packit 2035a7
        ASSERT_EQUALS(4, (int)Token::getStrLength(&tok));
Packit 2035a7
Packit 2035a7
        tok.str("\"test \\\\test\"");
Packit 2035a7
        ASSERT_EQUALS(10, (int)Token::getStrLength(&tok));
Packit 2035a7
Packit 2035a7
        tok.str("\"a\\0\"");
Packit 2035a7
        ASSERT_EQUALS(1, (int)Token::getStrLength(&tok));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void getStrSize() const {
Packit 2035a7
        Token tok(0);
Packit 2035a7
Packit 2035a7
        tok.str("\"abc\"");
Packit 2035a7
        ASSERT_EQUALS(sizeof("abc"), Token::getStrSize(&tok));
Packit 2035a7
Packit 2035a7
        tok.str("\"\\0abc\"");
Packit 2035a7
        ASSERT_EQUALS(sizeof("\0abc"), Token::getStrSize(&tok));
Packit 2035a7
Packit 2035a7
        tok.str("\"\\\\\"");
Packit 2035a7
        ASSERT_EQUALS(sizeof("\\"), Token::getStrSize(&tok));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void strValue() const {
Packit 2035a7
        Token tok(0);
Packit 2035a7
Packit 2035a7
        tok.str("\"\"");
Packit 2035a7
        ASSERT_EQUALS("", tok.strValue());
Packit 2035a7
Packit 2035a7
        tok.str("\"0\"");
Packit 2035a7
        ASSERT_EQUALS("0", tok.strValue());
Packit 2035a7
Packit 2035a7
        tok.str("\"a\\n\"");
Packit 2035a7
        ASSERT_EQUALS("a\n", tok.strValue());
Packit 2035a7
Packit 2035a7
        tok.str("\"a\\r\"");
Packit 2035a7
        ASSERT_EQUALS("a\r", tok.strValue());
Packit 2035a7
Packit 2035a7
        tok.str("\"a\\t\"");
Packit 2035a7
        ASSERT_EQUALS("a\t", tok.strValue());
Packit 2035a7
Packit 2035a7
        tok.str("\"\\\\\"");
Packit 2035a7
        ASSERT_EQUALS("\\", tok.strValue());
Packit 2035a7
Packit 2035a7
        tok.str("\"a\\0\"");
Packit 2035a7
        ASSERT_EQUALS("a", tok.strValue());
Packit 2035a7
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
Packit 2035a7
    void deleteLast() const {
Packit 2035a7
        Token *tokensBack = 0;
Packit 2035a7
        Token tok(&tokensBack);
Packit 2035a7
        tok.insertToken("aba");
Packit 2035a7
        ASSERT_EQUALS(true, tokensBack == tok.next());
Packit 2035a7
        tok.deleteNext();
Packit 2035a7
        ASSERT_EQUALS(true, tokensBack == &tok;;
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void nextArgument() const {
Packit 2035a7
        givenACodeSampleToTokenize example1("foo(1, 2, 3, 4);");
Packit 2035a7
        ASSERT_EQUALS(true, Token::simpleMatch(example1.tokens()->tokAt(2)->nextArgument(), "2 , 3"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::simpleMatch(example1.tokens()->tokAt(4)->nextArgument(), "3 , 4"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize example2("foo();");
Packit 2035a7
        ASSERT_EQUALS(true, example2.tokens()->tokAt(2)->nextArgument() == 0);
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize example3("foo(bar(a, b), 2, 3);");
Packit 2035a7
        ASSERT_EQUALS(true, Token::simpleMatch(example3.tokens()->tokAt(2)->nextArgument(), "2 , 3"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize example4("foo(x.i[1], \"\", 3);");
Packit 2035a7
        ASSERT_EQUALS(true, Token::simpleMatch(example4.tokens()->tokAt(2)->nextArgument(), "\"\" , 3"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void eraseTokens() const {
Packit 2035a7
        givenACodeSampleToTokenize code("begin ; { this code will be removed } end", true);
Packit 2035a7
        Token::eraseTokens(code.tokens()->next(), code.tokens()->tokAt(9));
Packit 2035a7
        ASSERT_EQUALS("begin ; end", code.tokens()->stringifyList(0, false));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
Packit 2035a7
    void matchAny() const {
Packit 2035a7
        givenACodeSampleToTokenize varBitOrVar("abc|def", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(varBitOrVar.tokens(), "%name% %or% %name%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize varLogOrVar("abc||def", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(varLogOrVar.tokens(), "%name% %oror% %name%"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void matchSingleChar() const {
Packit 2035a7
        givenACodeSampleToTokenize singleChar("a", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(singleChar.tokens(), "[a|bc]"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(singleChar.tokens(), "[d|ef]"));
Packit 2035a7
Packit 2035a7
        Token multiChar(0);
Packit 2035a7
        multiChar.str("[ab");
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(&multiChar, "[ab|def]"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void matchNothingOrAnyNotElse() const {
Packit 2035a7
        givenACodeSampleToTokenize empty_String("", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(empty_String.tokens(), "!!else"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(empty_String.tokens(), "!!else something"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize ifSemicolon("if ;", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(ifSemicolon.tokens(), "if ; !!else"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize ifSemicolonSomething("if ; something", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(ifSemicolonSomething.tokens(), "if ; !!else"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize justElse("else", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(justElse.tokens(), "!!else"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize ifSemicolonElse("if ; else", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(ifSemicolonElse.tokens(), "if ; !!else"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void matchType() const {
Packit 2035a7
        givenACodeSampleToTokenize type("abc", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(type.tokens(), "%type%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize isVar("int a = 3 ;");
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(isVar.tokens(), "%type%"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(isVar.tokens(), "%type% %name%"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(isVar.tokens(), "%type% %type%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize noType1_cpp("delete", true, true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(noType1_cpp.tokens(), "%type%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize noType1_c("delete", true, false);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(noType1_c.tokens(), "%type%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize noType2("void delete", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(noType2.tokens(), "!!foo %type%"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void matchChar() const {
Packit 2035a7
        givenACodeSampleToTokenize chr1("'a'", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(chr1.tokens(), "%char%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize chr2("'1'", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(chr2.tokens(), "%char%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize noChr("\"10\"", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(noChr.tokens(), "%char%"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void matchCompOp() const {
Packit 2035a7
        givenACodeSampleToTokenize comp1("<=", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(comp1.tokens(), "%comp%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize comp2(">", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(comp2.tokens(), "%comp%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize noComp("=", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(noComp.tokens(), "%comp%"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void matchStr() const {
Packit 2035a7
        givenACodeSampleToTokenize noStr1("abc", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(noStr1.tokens(), "%str%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize noStr2("'a'", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(noStr2.tokens(), "%str%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize str("\"abc\"", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(str.tokens(), "%str%"));
Packit 2035a7
Packit 2035a7
        // Empty string
Packit 2035a7
        givenACodeSampleToTokenize emptyStr("\"\"", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(emptyStr.tokens(), "%str%"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void matchVarid() const {
Packit 2035a7
        givenACodeSampleToTokenize var("int a ; int b ;");
Packit 2035a7
Packit 2035a7
        // Varid == 0 should throw exception
Packit 2035a7
        ASSERT_THROW(Token::Match(var.tokens(), "%type% %varid% ; %type% %name%", 0),InternalError);
Packit 2035a7
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(var.tokens(), "%type% %varid% ; %type% %name%", 1));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(var.tokens(), "%type% %name% ; %type% %varid%", 2));
Packit 2035a7
Packit 2035a7
        // Try to match two different varids in one match call
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(var.tokens(), "%type% %varid% ; %type% %varid%", 2));
Packit 2035a7
Packit 2035a7
        // %var% matches with every varid other than 0
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(var.tokens(), "%type% %var% ;"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(var.tokens(), "%var% %var% ;"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void matchNumeric() const {
Packit 2035a7
        givenACodeSampleToTokenize nonNumeric("abc", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(nonNumeric.tokens(), "%num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize binary("101010b", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(binary.tokens(), "%num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize octal("0123", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(octal.tokens(), "%num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize decimal("4567", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(decimal.tokens(), "%num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize hexadecimal("0xDEADBEEF", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(hexadecimal.tokens(), "%num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize floatingPoint("0.0f", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(floatingPoint.tokens(), "%num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize doublePrecision("0.0d", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(doublePrecision.tokens(), "%num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize signedLong("0L", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(signedLong.tokens(), "%num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize negativeSignedLong("-0L", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(negativeSignedLong.tokens(), "- %num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize positiveSignedLong("+0L", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(positiveSignedLong.tokens(), "+ %num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize unsignedInt("0U", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(unsignedInt.tokens(), "%num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize unsignedLong("0UL", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(unsignedLong.tokens(), "%num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize unsignedLongLong("0ULL", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(unsignedLongLong.tokens(), "%num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize positive("+666", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(positive.tokens(), "+ %num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize negative("-42", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(negative.tokens(), "- %num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize negativeNull("-.0", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(negativeNull.tokens(), "- %num%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize positiveNull("+.0", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(positiveNull.tokens(), "+ %num%"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
Packit 2035a7
    void matchBoolean() const {
Packit 2035a7
        givenACodeSampleToTokenize yes("YES", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(yes.tokens(), "%bool%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize positive("true", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(positive.tokens(), "%bool%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize negative("false", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(negative.tokens(), "%bool%"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void matchOr() const {
Packit 2035a7
        givenACodeSampleToTokenize bitwiseOr(";|;", true);
Packit 2035a7
        ASSERT_EQUALS(true,  Token::Match(bitwiseOr.tokens(), "; %or%"));
Packit 2035a7
        ASSERT_EQUALS(true,  Token::Match(bitwiseOr.tokens(), "; %op%"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(bitwiseOr.tokens(), "; %oror%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize bitwiseOrAssignment(";|=;");
Packit 2035a7
        ASSERT_EQUALS(false,  Token::Match(bitwiseOrAssignment.tokens(), "; %or%"));
Packit 2035a7
        ASSERT_EQUALS(true,  Token::Match(bitwiseOrAssignment.tokens(), "; %op%"));
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "; %oror%"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize logicalOr(";||;", true);
Packit 2035a7
        ASSERT_EQUALS(false, Token::Match(logicalOr.tokens(), "; %or%"));
Packit 2035a7
        ASSERT_EQUALS(true,  Token::Match(logicalOr.tokens(), "; %op%"));
Packit 2035a7
        ASSERT_EQUALS(true,  Token::Match(logicalOr.tokens(), "; %oror%"));
Packit 2035a7
        ASSERT_EQUALS(true,  Token::Match(logicalOr.tokens(), "; &&|%oror%"));
Packit 2035a7
        ASSERT_EQUALS(true,  Token::Match(logicalOr.tokens(), "; %oror%|&&"));
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize logicalAnd(";&&;", true);
Packit 2035a7
        ASSERT_EQUALS(true, Token::simpleMatch(logicalAnd.tokens(), "; &&"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "; &&|%oror%"));
Packit 2035a7
        ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "; %oror%|&&"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    static void append_vector(std::vector<std::string> &dest, const std::vector<std::string> &src) {
Packit 2035a7
        dest.insert(dest.end(), src.begin(), src.end());
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void initOps() {
Packit 2035a7
        arithmeticalOps.push_back("+");
Packit 2035a7
        arithmeticalOps.push_back("-");
Packit 2035a7
        arithmeticalOps.push_back("*");
Packit 2035a7
        arithmeticalOps.push_back("/");
Packit 2035a7
        arithmeticalOps.push_back("%");
Packit 2035a7
        arithmeticalOps.push_back("<<");
Packit 2035a7
        arithmeticalOps.push_back(">>");
Packit 2035a7
Packit 2035a7
        logicalOps.push_back("&&";;
Packit 2035a7
        logicalOps.push_back("||");
Packit 2035a7
        logicalOps.push_back("!");
Packit 2035a7
        comparisonOps.push_back("==");
Packit 2035a7
        comparisonOps.push_back("!=");
Packit 2035a7
        comparisonOps.push_back("<");
Packit 2035a7
        comparisonOps.push_back("<=");
Packit 2035a7
        comparisonOps.push_back(">");
Packit 2035a7
        comparisonOps.push_back(">=");
Packit 2035a7
        bitOps.push_back("&";;
Packit 2035a7
        bitOps.push_back("|");
Packit 2035a7
        bitOps.push_back("^");
Packit 2035a7
        bitOps.push_back("~");
Packit 2035a7
Packit 2035a7
        extendedOps.push_back(",");
Packit 2035a7
        extendedOps.push_back("[");
Packit 2035a7
        extendedOps.push_back("]");
Packit 2035a7
        extendedOps.push_back("(");
Packit 2035a7
        extendedOps.push_back(")");
Packit 2035a7
        extendedOps.push_back("?");
Packit 2035a7
        extendedOps.push_back(":");
Packit 2035a7
Packit 2035a7
        assignmentOps.push_back("=");
Packit 2035a7
        assignmentOps.push_back("+=");
Packit 2035a7
        assignmentOps.push_back("-=");
Packit 2035a7
        assignmentOps.push_back("*=");
Packit 2035a7
        assignmentOps.push_back("/=");
Packit 2035a7
        assignmentOps.push_back("%=");
Packit 2035a7
        assignmentOps.push_back("&=");
Packit 2035a7
        assignmentOps.push_back("^=");
Packit 2035a7
        assignmentOps.push_back("|=");
Packit 2035a7
        assignmentOps.push_back("<<=");
Packit 2035a7
        assignmentOps.push_back(">>=");
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void matchOp() {
Packit 2035a7
        std::vector<std::string> test_ops;
Packit 2035a7
        append_vector(test_ops, arithmeticalOps);
Packit 2035a7
        append_vector(test_ops, bitOps);
Packit 2035a7
        append_vector(test_ops, comparisonOps);
Packit 2035a7
        append_vector(test_ops, logicalOps);
Packit 2035a7
        append_vector(test_ops, assignmentOps);
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
Packit 2035a7
        for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
Packit 2035a7
            ASSERT_EQUALS(true, Match(*test_op, "%op%"));
Packit 2035a7
        }
Packit 2035a7
Packit 2035a7
        // Negative test against other operators
Packit 2035a7
        std::vector<std::string> other_ops;
Packit 2035a7
        append_vector(other_ops, extendedOps);
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
Packit 2035a7
        for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
Packit 2035a7
            ASSERT_EQUALS_MSG(false, Match(*other_op, "%op%"), "Failing other operator: " + *other_op);
Packit 2035a7
        }
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void matchConstOp() {
Packit 2035a7
        std::vector<std::string> test_ops;
Packit 2035a7
        append_vector(test_ops, arithmeticalOps);
Packit 2035a7
        append_vector(test_ops, bitOps);
Packit 2035a7
        append_vector(test_ops, comparisonOps);
Packit 2035a7
        append_vector(test_ops, logicalOps);
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
Packit 2035a7
        for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
Packit 2035a7
            ASSERT_EQUALS(true, Match(*test_op, "%cop%"));
Packit 2035a7
        }
Packit 2035a7
Packit 2035a7
        // Negative test against other operators
Packit 2035a7
        std::vector<std::string> other_ops;
Packit 2035a7
        append_vector(other_ops, extendedOps);
Packit 2035a7
        append_vector(other_ops, assignmentOps);
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
Packit 2035a7
        for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
Packit 2035a7
            ASSERT_EQUALS_MSG(false, Match(*other_op, "%cop%"), "Failing other operator: " + *other_op);
Packit 2035a7
        }
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
Packit 2035a7
    void isArithmeticalOp() const {
Packit 2035a7
        std::vector<std::string>::const_iterator test_op, test_ops_end = arithmeticalOps.end();
Packit 2035a7
        for (test_op = arithmeticalOps.begin(); test_op != test_ops_end; ++test_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*test_op);
Packit 2035a7
            ASSERT_EQUALS(true, tok.isArithmeticalOp());
Packit 2035a7
        }
Packit 2035a7
Packit 2035a7
        // Negative test against other operators
Packit 2035a7
        std::vector<std::string> other_ops;
Packit 2035a7
        append_vector(other_ops, bitOps);
Packit 2035a7
        append_vector(other_ops, comparisonOps);
Packit 2035a7
        append_vector(other_ops, logicalOps);
Packit 2035a7
        append_vector(other_ops, extendedOps);
Packit 2035a7
        append_vector(other_ops, assignmentOps);
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
Packit 2035a7
        for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*other_op);
Packit 2035a7
            ASSERT_EQUALS_MSG(false, tok.isArithmeticalOp(), "Failing arithmetical operator: " + *other_op);
Packit 2035a7
        }
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void isOp() const {
Packit 2035a7
        std::vector<std::string> test_ops;
Packit 2035a7
        append_vector(test_ops, arithmeticalOps);
Packit 2035a7
        append_vector(test_ops, bitOps);
Packit 2035a7
        append_vector(test_ops, comparisonOps);
Packit 2035a7
        append_vector(test_ops, logicalOps);
Packit 2035a7
        append_vector(test_ops, assignmentOps);
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
Packit 2035a7
        for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*test_op);
Packit 2035a7
            ASSERT_EQUALS(true, tok.isOp());
Packit 2035a7
        }
Packit 2035a7
Packit 2035a7
        // Negative test against other operators
Packit 2035a7
        std::vector<std::string> other_ops;
Packit 2035a7
        append_vector(other_ops, extendedOps);
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
Packit 2035a7
        for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*other_op);
Packit 2035a7
            ASSERT_EQUALS_MSG(false, tok.isOp(), "Failing normal operator: " + *other_op);
Packit 2035a7
        }
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void isConstOp() const {
Packit 2035a7
        std::vector<std::string> test_ops;
Packit 2035a7
        append_vector(test_ops, arithmeticalOps);
Packit 2035a7
        append_vector(test_ops, bitOps);
Packit 2035a7
        append_vector(test_ops, comparisonOps);
Packit 2035a7
        append_vector(test_ops, logicalOps);
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
Packit 2035a7
        for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*test_op);
Packit 2035a7
            ASSERT_EQUALS(true, tok.isConstOp());
Packit 2035a7
        }
Packit 2035a7
Packit 2035a7
        // Negative test against other operators
Packit 2035a7
        std::vector<std::string> other_ops;
Packit 2035a7
        append_vector(other_ops, extendedOps);
Packit 2035a7
        append_vector(other_ops, assignmentOps);
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
Packit 2035a7
        for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*other_op);
Packit 2035a7
            ASSERT_EQUALS_MSG(false, tok.isConstOp(), "Failing normal operator: " + *other_op);
Packit 2035a7
        }
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void isExtendedOp() const {
Packit 2035a7
        std::vector<std::string> test_ops;
Packit 2035a7
        append_vector(test_ops, arithmeticalOps);
Packit 2035a7
        append_vector(test_ops, bitOps);
Packit 2035a7
        append_vector(test_ops, comparisonOps);
Packit 2035a7
        append_vector(test_ops, logicalOps);
Packit 2035a7
        append_vector(test_ops, extendedOps);
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
Packit 2035a7
        for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*test_op);
Packit 2035a7
            ASSERT_EQUALS(true, tok.isExtendedOp());
Packit 2035a7
        }
Packit 2035a7
Packit 2035a7
        // Negative test against assignment operators
Packit 2035a7
        std::vector<std::string>::const_iterator other_op, other_ops_end = assignmentOps.end();
Packit 2035a7
        for (other_op = assignmentOps.begin(); other_op != other_ops_end; ++other_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*other_op);
Packit 2035a7
            ASSERT_EQUALS_MSG(false, tok.isExtendedOp(), "Failing assignment operator: " + *other_op);
Packit 2035a7
        }
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void isAssignmentOp() const {
Packit 2035a7
        std::vector<std::string>::const_iterator test_op, test_ops_end = assignmentOps.end();
Packit 2035a7
        for (test_op = assignmentOps.begin(); test_op != test_ops_end; ++test_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*test_op);
Packit 2035a7
            ASSERT_EQUALS(true, tok.isAssignmentOp());
Packit 2035a7
        }
Packit 2035a7
Packit 2035a7
        // Negative test against other operators
Packit 2035a7
        std::vector<std::string> other_ops;
Packit 2035a7
        append_vector(other_ops, arithmeticalOps);
Packit 2035a7
        append_vector(other_ops, bitOps);
Packit 2035a7
        append_vector(other_ops, comparisonOps);
Packit 2035a7
        append_vector(other_ops, logicalOps);
Packit 2035a7
        append_vector(other_ops, extendedOps);
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
Packit 2035a7
        for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*other_op);
Packit 2035a7
            ASSERT_EQUALS_MSG(false, tok.isAssignmentOp(), "Failing assignment operator: " + *other_op);
Packit 2035a7
        }
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void operators() const {
Packit 2035a7
        std::vector<std::string>::const_iterator test_op;
Packit 2035a7
        for (test_op = extendedOps.begin(); test_op != extendedOps.end(); ++test_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*test_op);
Packit 2035a7
            ASSERT_EQUALS(Token::eExtendedOp, tok.tokType());
Packit 2035a7
        }
Packit 2035a7
        for (test_op = logicalOps.begin(); test_op != logicalOps.end(); ++test_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*test_op);
Packit 2035a7
            ASSERT_EQUALS(Token::eLogicalOp, tok.tokType());
Packit 2035a7
        }
Packit 2035a7
        for (test_op = bitOps.begin(); test_op != bitOps.end(); ++test_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*test_op);
Packit 2035a7
            ASSERT_EQUALS(Token::eBitOp, tok.tokType());
Packit 2035a7
        }
Packit 2035a7
        for (test_op = comparisonOps.begin(); test_op != comparisonOps.end(); ++test_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*test_op);
Packit 2035a7
            ASSERT_EQUALS(Token::eComparisonOp, tok.tokType());
Packit 2035a7
        }
Packit 2035a7
        Token tok(nullptr);
Packit 2035a7
        tok.str("++");
Packit 2035a7
        ASSERT_EQUALS(Token::eIncDecOp, tok.tokType());
Packit 2035a7
        tok.str("--");
Packit 2035a7
        ASSERT_EQUALS(Token::eIncDecOp, tok.tokType());
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void literals() const {
Packit 2035a7
        Token tok(nullptr);
Packit 2035a7
Packit 2035a7
        tok.str("\"foo\"");
Packit 2035a7
        ASSERT(tok.tokType() == Token::eString);
Packit 2035a7
        tok.str("\"\"");
Packit 2035a7
        ASSERT(tok.tokType() == Token::eString);
Packit 2035a7
        tok.str("'f'");
Packit 2035a7
        ASSERT(tok.tokType() == Token::eChar);
Packit 2035a7
        tok.str("12345");
Packit 2035a7
        ASSERT(tok.tokType() == Token::eNumber);
Packit 2035a7
        tok.str("-55");
Packit 2035a7
        ASSERT(tok.tokType() == Token::eNumber);
Packit 2035a7
        tok.str("true");
Packit 2035a7
        ASSERT(tok.tokType() == Token::eBoolean);
Packit 2035a7
        tok.str("false");
Packit 2035a7
        ASSERT(tok.tokType() == Token::eBoolean);
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void isStandardType() const {
Packit 2035a7
        std::vector<std::string> standard_types;
Packit 2035a7
        standard_types.push_back("bool");
Packit 2035a7
        standard_types.push_back("char");
Packit 2035a7
        standard_types.push_back("short");
Packit 2035a7
        standard_types.push_back("int");
Packit 2035a7
        standard_types.push_back("long");
Packit 2035a7
        standard_types.push_back("float");
Packit 2035a7
        standard_types.push_back("double");
Packit 2035a7
        standard_types.push_back("size_t");
Packit 2035a7
Packit 2035a7
        std::vector<std::string>::const_iterator test_op, test_ops_end = standard_types.end();
Packit 2035a7
        for (test_op = standard_types.begin(); test_op != test_ops_end; ++test_op) {
Packit 2035a7
            Token tok(nullptr);
Packit 2035a7
            tok.str(*test_op);
Packit 2035a7
            ASSERT_EQUALS_MSG(true, tok.isStandardType(), "Failing standard type: " + *test_op);
Packit 2035a7
        }
Packit 2035a7
Packit 2035a7
        // Negative test
Packit 2035a7
        Token tok(nullptr);
Packit 2035a7
        tok.str("string");
Packit 2035a7
        ASSERT_EQUALS(false, tok.isStandardType());
Packit 2035a7
Packit 2035a7
        // Change back to standard type
Packit 2035a7
        tok.str("int");
Packit 2035a7
        ASSERT_EQUALS(true, tok.isStandardType());
Packit 2035a7
Packit 2035a7
        // token can't be both type and variable
Packit 2035a7
        tok.str("abc");
Packit 2035a7
        tok.isStandardType(true);
Packit 2035a7
        tok.varId(123);
Packit 2035a7
        ASSERT_EQUALS(false, tok.isStandardType());
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void updateProperties() const {
Packit 2035a7
        Token tok(nullptr);
Packit 2035a7
        tok.str("foobar");
Packit 2035a7
Packit 2035a7
        ASSERT_EQUALS(true, tok.isName());
Packit 2035a7
        ASSERT_EQUALS(false, tok.isNumber());
Packit 2035a7
Packit 2035a7
        tok.str("123456");
Packit 2035a7
Packit 2035a7
        ASSERT_EQUALS(false, tok.isName());
Packit 2035a7
        ASSERT_EQUALS(true, tok.isNumber());
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void updatePropertiesConcatStr() const {
Packit 2035a7
        Token tok(nullptr);
Packit 2035a7
        tok.str("true");
Packit 2035a7
Packit 2035a7
        ASSERT_EQUALS(true, tok.isBoolean());
Packit 2035a7
Packit 2035a7
        tok.concatStr("123");
Packit 2035a7
Packit 2035a7
        ASSERT_EQUALS(false, tok.isBoolean());
Packit 2035a7
        ASSERT_EQUALS("tru23", tok.str());
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void isNameGuarantees1() const {
Packit 2035a7
        Token tok(nullptr);
Packit 2035a7
        tok.str("Name");
Packit 2035a7
        ASSERT_EQUALS(true, tok.isName());
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void isNameGuarantees2() const {
Packit 2035a7
        Token tok(nullptr);
Packit 2035a7
        tok.str("_name");
Packit 2035a7
        ASSERT_EQUALS(true, tok.isName());
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void isNameGuarantees3() const {
Packit 2035a7
        Token tok(nullptr);
Packit 2035a7
        tok.str("_123");
Packit 2035a7
        ASSERT_EQUALS(true, tok.isName());
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void isNameGuarantees4() const {
Packit 2035a7
        Token tok(nullptr);
Packit 2035a7
        tok.str("123456");
Packit 2035a7
        ASSERT_EQUALS(false, tok.isName());
Packit 2035a7
        ASSERT_EQUALS(true, tok.isNumber());
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void isNameGuarantees5() const {
Packit 2035a7
        Token tok(nullptr);
Packit 2035a7
        tok.str("a123456");
Packit 2035a7
        ASSERT_EQUALS(true, tok.isName());
Packit 2035a7
        ASSERT_EQUALS(false, tok.isNumber());
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void isNameGuarantees6() const {
Packit 2035a7
        Token tok(nullptr);
Packit 2035a7
        tok.str("$f");
Packit 2035a7
        ASSERT_EQUALS(true, tok.isName());
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void canFindMatchingBracketsNeedsOpen() const {
Packit 2035a7
        givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
Packit 2035a7
Packit 2035a7
        const Token* t = var.tokens()->findClosingBracket();
Packit 2035a7
        ASSERT(t == nullptr);
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void canFindMatchingBracketsInnerPair() const {
Packit 2035a7
        givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
Packit 2035a7
Packit 2035a7
        Token* t = const_cast<Token*>(var.tokens()->tokAt(7))->findClosingBracket();
Packit 2035a7
        ASSERT_EQUALS(">", t->str());
Packit 2035a7
        ASSERT(var.tokens()->tokAt(9) == t);
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void canFindMatchingBracketsOuterPair() const {
Packit 2035a7
        givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
Packit 2035a7
Packit 2035a7
        const Token* t = var.tokens()->tokAt(3)->findClosingBracket();
Packit 2035a7
        ASSERT_EQUALS(">", t->str());
Packit 2035a7
        ASSERT(var.tokens()->tokAt(10) == t);
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void canFindMatchingBracketsWithTooManyClosing() const {
Packit 2035a7
        givenACodeSampleToTokenize var("X< 1>2 > x1;\n");
Packit 2035a7
Packit 2035a7
        const Token* t = var.tokens()->next()->findClosingBracket();
Packit 2035a7
        ASSERT_EQUALS(">", t->str());
Packit 2035a7
        ASSERT(var.tokens()->tokAt(3) == t);
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void canFindMatchingBracketsWithTooManyOpening() const {
Packit 2035a7
        givenACodeSampleToTokenize var("X < (2 < 1) > x1;\n");
Packit 2035a7
Packit 2035a7
        const Token* t = var.tokens()->next()->findClosingBracket();
Packit 2035a7
        ASSERT(t != nullptr && t->str() == ">");
Packit 2035a7
Packit 2035a7
        t = var.tokens()->tokAt(4)->findClosingBracket();
Packit 2035a7
        ASSERT(t == nullptr);
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void findClosingBracket() {
Packit 2035a7
        givenACodeSampleToTokenize var("template<typename X, typename...Y> struct S : public Fred<Wilma<Y...>> {}");
Packit 2035a7
Packit 2035a7
        const Token* t = var.tokens()->next()->findClosingBracket();
Packit 2035a7
        ASSERT(Token::simpleMatch(t, "> struct"));
Packit 2035a7
    }
Packit 2035a7
Packit 2035a7
    void expressionString() {
Packit 2035a7
        givenACodeSampleToTokenize var1("void f() { *((unsigned long long *)x) = 0; }");
Packit 2035a7
        const Token *tok1 = Token::findsimplematch(var1.tokens(), "*");
Packit 2035a7
        ASSERT_EQUALS("*((unsigned long long*)x)", tok1->expressionString());
Packit 2035a7
Packit 2035a7
        givenACodeSampleToTokenize var2("typedef unsigned long long u64; void f() { *((u64 *)x) = 0; }");
Packit 2035a7
        const Token *tok2 = Token::findsimplematch(var2.tokens(), "*");
Packit 2035a7
        ASSERT_EQUALS("*((unsigned long long*)x)", tok2->expressionString());
Packit 2035a7
    }
Packit 2035a7
};
Packit 2035a7
Packit 2035a7
REGISTER_TEST(TestToken)