2008-12-18 22:28:57 +01:00
|
|
|
/*
|
2009-01-21 21:04:20 +01:00
|
|
|
* Cppcheck - A tool for static C/C++ code analysis
|
2022-02-05 11:45:17 +01:00
|
|
|
* Copyright (C) 2007-2022 Cppcheck team.
|
2008-12-18 22:28:57 +01:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2009-09-27 17:08:31 +02:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2008-12-18 22:28:57 +01:00
|
|
|
*/
|
|
|
|
|
2022-01-27 19:03:20 +01:00
|
|
|
#include "config.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "settings.h"
|
2008-12-18 22:28:57 +01:00
|
|
|
#include "testsuite.h"
|
2010-12-30 09:46:44 +01:00
|
|
|
#include "testutils.h"
|
2009-10-25 12:49:06 +01:00
|
|
|
#include "token.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "tokenize.h"
|
|
|
|
#include "tokenlist.h"
|
2022-01-27 19:03:20 +01:00
|
|
|
#include "valueflow.h"
|
2009-10-25 12:49:06 +01:00
|
|
|
|
2022-01-27 19:03:20 +01:00
|
|
|
#include <algorithm>
|
|
|
|
#include <iosfwd>
|
2011-11-06 21:20:13 +01:00
|
|
|
#include <string>
|
2017-05-27 04:33:47 +02:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
struct InternalError;
|
2008-12-18 22:28:57 +01:00
|
|
|
|
2015-03-11 22:26:33 +01:00
|
|
|
|
2011-10-13 20:53:06 +02:00
|
|
|
class TestToken : public TestFixture {
|
2008-12-18 22:28:57 +01:00
|
|
|
public:
|
2021-08-07 20:51:18 +02:00
|
|
|
TestToken() : TestFixture("TestToken") {}
|
2008-12-18 22:28:57 +01:00
|
|
|
|
|
|
|
private:
|
2011-11-06 21:20:13 +01:00
|
|
|
std::vector<std::string> arithmeticalOps;
|
2012-04-23 21:05:26 +02:00
|
|
|
std::vector<std::string> logicalOps;
|
|
|
|
std::vector<std::string> bitOps;
|
2013-02-10 07:43:09 +01:00
|
|
|
std::vector<std::string> comparisonOps;
|
2011-11-06 21:20:13 +01:00
|
|
|
std::vector<std::string> extendedOps;
|
|
|
|
std::vector<std::string> assignmentOps;
|
2008-12-18 22:28:57 +01:00
|
|
|
|
2019-01-12 15:45:25 +01:00
|
|
|
void run() OVERRIDE {
|
2018-04-09 09:41:24 +02:00
|
|
|
arithmeticalOps = { "+", "-", "*", "/", "%", "<<", ">>" };
|
|
|
|
logicalOps = { "&&", "||", "!" };
|
|
|
|
comparisonOps = { "==", "!=", "<", "<=", ">", ">=" };
|
|
|
|
bitOps = { "&", "|", "^", "~" };
|
|
|
|
extendedOps = { ",", "[", "]", "(", ")", "?", ":" };
|
|
|
|
assignmentOps = { "=", "+=", "-=", "*=", "/=", "%=", "&=", "^=", "|=", "<<=", ">>=" };
|
2011-11-06 21:20:13 +01:00
|
|
|
|
2009-01-05 16:49:57 +01:00
|
|
|
TEST_CASE(nextprevious);
|
2009-05-12 20:28:02 +02:00
|
|
|
TEST_CASE(multiCompare);
|
2011-11-05 14:04:23 +01:00
|
|
|
TEST_CASE(multiCompare2); // #3294 - false negative multi compare between "=" and "=="
|
2011-11-06 22:12:28 +01:00
|
|
|
TEST_CASE(multiCompare3); // false positive for %or% on code using "|="
|
2013-01-07 23:42:25 +01:00
|
|
|
TEST_CASE(multiCompare4);
|
2014-06-26 18:17:05 +02:00
|
|
|
TEST_CASE(multiCompare5);
|
Set correct type and size of string and char literals (#2275)
* Set correct type and size of string and char literals
Use that string and char literal tokens store the prefix. This makes
it possible to distinghuish between different type of string literals
(i.e., utf8 encoded strings, utf16, wide strings, etc) which have
different type.
When the tokens holding the string and character values have the correct
type, it is possible to improve Token::getStrSize() to give the correct
result for all string types. Previously, it would return the number of
characters in the string, i.e., it would give the wrong size unless
the type of the string was char*.
Since strings now can have different size (in number of bytes) and
length (in number of elements), add a new helper function that returns
the number of characters. Checkers have been updated to use the correct
functions.
Having the size makes it possible to find more problems with prefixed
strings, and to reduce false positives, for example in the buffer
overflow checker.
Also, improve the stringLiteralWrite error message to also print the
prefix of the string (if there is one).
* Add comment and update string length
2019-10-20 07:11:57 +02:00
|
|
|
TEST_CASE(charTypes);
|
|
|
|
TEST_CASE(stringTypes);
|
2009-08-30 13:07:10 +02:00
|
|
|
TEST_CASE(getStrLength);
|
2014-08-01 13:12:18 +02:00
|
|
|
TEST_CASE(getStrSize);
|
2019-04-25 07:08:13 +02:00
|
|
|
TEST_CASE(getCharAt);
|
2009-09-12 22:54:47 +02:00
|
|
|
TEST_CASE(strValue);
|
2019-11-08 08:03:45 +01:00
|
|
|
TEST_CASE(concatStr);
|
2010-01-06 20:19:27 +01:00
|
|
|
|
|
|
|
TEST_CASE(deleteLast);
|
2018-05-25 07:15:05 +02:00
|
|
|
TEST_CASE(deleteFirst);
|
2011-10-23 11:23:48 +02:00
|
|
|
TEST_CASE(nextArgument);
|
2011-11-08 18:59:31 +01:00
|
|
|
TEST_CASE(eraseTokens);
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2010-09-26 05:31:36 +02:00
|
|
|
TEST_CASE(matchAny);
|
2011-07-15 19:01:36 +02:00
|
|
|
TEST_CASE(matchSingleChar);
|
2010-09-26 05:31:36 +02:00
|
|
|
TEST_CASE(matchNothingOrAnyNotElse);
|
2011-11-06 18:30:34 +01:00
|
|
|
TEST_CASE(matchType);
|
2012-11-04 16:34:32 +01:00
|
|
|
TEST_CASE(matchChar);
|
2012-12-01 00:47:07 +01:00
|
|
|
TEST_CASE(matchCompOp);
|
2011-11-06 18:30:34 +01:00
|
|
|
TEST_CASE(matchStr);
|
2011-11-06 18:37:00 +01:00
|
|
|
TEST_CASE(matchVarid);
|
2010-09-26 05:31:36 +02:00
|
|
|
TEST_CASE(matchNumeric);
|
|
|
|
TEST_CASE(matchBoolean);
|
2010-10-25 03:14:21 +02:00
|
|
|
TEST_CASE(matchOr);
|
2011-11-06 18:02:18 +01:00
|
|
|
TEST_CASE(matchOp);
|
2013-03-01 11:43:59 +01:00
|
|
|
TEST_CASE(matchConstOp);
|
2011-10-23 20:38:03 +02:00
|
|
|
|
2011-11-06 18:55:02 +01:00
|
|
|
TEST_CASE(isArithmeticalOp);
|
2011-11-06 21:20:13 +01:00
|
|
|
TEST_CASE(isOp);
|
2013-02-28 21:50:29 +01:00
|
|
|
TEST_CASE(isConstOp);
|
2011-11-06 18:19:27 +01:00
|
|
|
TEST_CASE(isExtendedOp);
|
|
|
|
TEST_CASE(isAssignmentOp);
|
2011-11-06 18:55:02 +01:00
|
|
|
TEST_CASE(isStandardType);
|
2012-04-23 21:05:26 +02:00
|
|
|
TEST_CASE(literals);
|
|
|
|
TEST_CASE(operators);
|
2011-11-06 18:19:27 +01:00
|
|
|
|
2020-04-21 17:27:51 +02:00
|
|
|
TEST_CASE(updateProperties);
|
|
|
|
TEST_CASE(isNameGuarantees1);
|
|
|
|
TEST_CASE(isNameGuarantees2);
|
|
|
|
TEST_CASE(isNameGuarantees3);
|
|
|
|
TEST_CASE(isNameGuarantees4);
|
|
|
|
TEST_CASE(isNameGuarantees5);
|
|
|
|
TEST_CASE(isNameGuarantees6);
|
2012-04-18 16:02:03 +02:00
|
|
|
|
|
|
|
TEST_CASE(canFindMatchingBracketsNeedsOpen);
|
|
|
|
TEST_CASE(canFindMatchingBracketsInnerPair);
|
|
|
|
TEST_CASE(canFindMatchingBracketsOuterPair);
|
|
|
|
TEST_CASE(canFindMatchingBracketsWithTooManyClosing);
|
|
|
|
TEST_CASE(canFindMatchingBracketsWithTooManyOpening);
|
2018-01-01 15:20:21 +01:00
|
|
|
TEST_CASE(findClosingBracket);
|
2017-07-21 09:16:42 +02:00
|
|
|
|
2017-07-21 09:17:25 +02:00
|
|
|
TEST_CASE(expressionString);
|
2019-07-27 08:25:07 +02:00
|
|
|
|
|
|
|
TEST_CASE(hasKnownIntValue);
|
2008-12-18 22:28:57 +01:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void nextprevious() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token *token = new Token();
|
2009-01-05 16:49:57 +01:00
|
|
|
token->str("1");
|
|
|
|
token->insertToken("2");
|
|
|
|
token->next()->insertToken("3");
|
2009-06-14 08:20:51 +02:00
|
|
|
Token *last = token->tokAt(2);
|
2009-01-05 16:49:57 +01:00
|
|
|
ASSERT_EQUALS(token->str(), "1");
|
|
|
|
ASSERT_EQUALS(token->next()->str(), "2");
|
2021-01-12 20:48:25 +01:00
|
|
|
// cppcheck-suppress redundantNextPrevious - this is intentional
|
2009-06-14 08:20:51 +02:00
|
|
|
ASSERT_EQUALS(token->tokAt(2)->str(), "3");
|
2020-03-25 16:11:05 +01:00
|
|
|
ASSERT_EQUALS_MSG(true, last->next() == nullptr, "Null was expected");
|
2009-01-05 16:49:57 +01:00
|
|
|
|
|
|
|
ASSERT_EQUALS(last->str(), "3");
|
|
|
|
ASSERT_EQUALS(last->previous()->str(), "2");
|
2021-01-12 20:48:25 +01:00
|
|
|
// cppcheck-suppress redundantNextPrevious - this is intentional
|
2009-06-14 08:26:20 +02:00
|
|
|
ASSERT_EQUALS(last->tokAt(-2)->str(), "1");
|
2020-03-25 16:11:05 +01:00
|
|
|
ASSERT_EQUALS_MSG(true, token->previous() == nullptr, "Null was expected");
|
2009-03-17 20:59:40 +01:00
|
|
|
|
2012-05-05 18:33:26 +02:00
|
|
|
TokenList::deleteTokens(token);
|
2008-12-18 22:28:57 +01:00
|
|
|
}
|
|
|
|
|
2021-11-29 07:34:39 +01:00
|
|
|
#define MatchCheck(...) MatchCheck_(__FILE__, __LINE__, __VA_ARGS__)
|
|
|
|
bool MatchCheck_(const char* file, int line, const std::string& code, const std::string& pattern, unsigned int varid = 0) {
|
2012-05-05 18:33:26 +02:00
|
|
|
static const Settings settings;
|
2012-01-06 09:03:23 +01:00
|
|
|
Tokenizer tokenizer(&settings, this);
|
2016-11-20 17:59:50 +01:00
|
|
|
std::istringstream istr(";" + code + ";");
|
2014-03-27 13:15:21 +01:00
|
|
|
try {
|
2021-11-29 07:34:39 +01:00
|
|
|
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
|
2014-03-27 13:15:21 +01:00
|
|
|
} catch (...) {}
|
2016-11-20 17:59:50 +01:00
|
|
|
return Token::Match(tokenizer.tokens()->next(), pattern.c_str(), varid);
|
2012-01-06 09:03:23 +01:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void multiCompare() const {
|
2009-05-12 20:28:02 +02:00
|
|
|
// Test for found
|
2018-05-25 07:15:05 +02:00
|
|
|
Token one;
|
2013-04-07 18:43:18 +02:00
|
|
|
one.str("one");
|
2014-06-26 18:17:05 +02:00
|
|
|
ASSERT_EQUALS(1, Token::multiCompare(&one, "one|two", 0));
|
2013-01-09 16:53:19 +01:00
|
|
|
|
2018-05-25 07:15:05 +02:00
|
|
|
Token two;
|
2013-04-07 18:43:18 +02:00
|
|
|
two.str("two");
|
2014-06-26 18:17:05 +02:00
|
|
|
ASSERT_EQUALS(1, Token::multiCompare(&two, "one|two", 0));
|
|
|
|
ASSERT_EQUALS(1, Token::multiCompare(&two, "verybig|two|", 0));
|
2009-05-12 20:28:02 +02:00
|
|
|
|
|
|
|
// Test for empty string found
|
2018-05-25 07:15:05 +02:00
|
|
|
Token notfound;
|
2013-04-07 18:43:18 +02:00
|
|
|
notfound.str("notfound");
|
2014-06-26 18:17:05 +02:00
|
|
|
ASSERT_EQUALS(0, Token::multiCompare(¬found, "one|two|", 0));
|
2008-12-18 22:28:57 +01:00
|
|
|
|
2009-05-12 20:28:02 +02:00
|
|
|
// Test for not found
|
2014-06-26 18:17:05 +02:00
|
|
|
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(¬found, "one|two", 0)));
|
2013-01-09 16:53:19 +01:00
|
|
|
|
2018-05-25 07:15:05 +02:00
|
|
|
Token s;
|
2013-04-07 18:43:18 +02:00
|
|
|
s.str("s");
|
2014-06-26 18:17:05 +02:00
|
|
|
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(&s, "verybig|two", 0)));
|
2013-01-09 16:53:19 +01:00
|
|
|
|
2018-05-25 07:15:05 +02:00
|
|
|
Token ne;
|
2013-04-07 18:43:18 +02:00
|
|
|
ne.str("ne");
|
2014-06-26 18:17:05 +02:00
|
|
|
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(&ne, "one|two", 0)));
|
2013-01-09 16:53:19 +01:00
|
|
|
|
2018-05-25 07:15:05 +02:00
|
|
|
Token a;
|
2013-04-07 18:43:18 +02:00
|
|
|
a.str("a");
|
2014-06-26 18:17:05 +02:00
|
|
|
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(&a, "abc|def", 0)));
|
2013-01-09 16:53:19 +01:00
|
|
|
|
2018-05-25 07:15:05 +02:00
|
|
|
Token abcd;
|
2013-04-07 18:43:18 +02:00
|
|
|
abcd.str("abcd");
|
2014-06-26 18:17:05 +02:00
|
|
|
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(&abcd, "abc|def", 0)));
|
2013-01-09 16:53:19 +01:00
|
|
|
|
2018-05-25 07:15:05 +02:00
|
|
|
Token def;
|
2013-04-07 18:43:18 +02:00
|
|
|
def.str("default");
|
2014-06-26 18:17:05 +02:00
|
|
|
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(&def, "abc|def", 0)));
|
2011-04-09 18:09:13 +02:00
|
|
|
|
|
|
|
// %op%
|
2018-05-25 07:15:05 +02:00
|
|
|
Token plus;
|
2013-04-07 18:43:18 +02:00
|
|
|
plus.str("+");
|
2014-06-26 18:17:05 +02:00
|
|
|
ASSERT_EQUALS(1, Token::multiCompare(&plus, "one|%op%", 0));
|
|
|
|
ASSERT_EQUALS(1, Token::multiCompare(&plus, "%op%|two", 0));
|
2018-05-25 07:15:05 +02:00
|
|
|
Token x;
|
2013-04-07 18:43:18 +02:00
|
|
|
x.str("x");
|
2014-06-26 18:17:05 +02:00
|
|
|
ASSERT_EQUALS(-1, Token::multiCompare(&x, "one|%op%", 0));
|
|
|
|
ASSERT_EQUALS(-1, Token::multiCompare(&x, "%op%|two", 0));
|
2009-05-12 20:28:02 +02:00
|
|
|
}
|
2009-08-30 13:07:10 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void multiCompare2() const { // #3294
|
2011-11-05 14:04:23 +01:00
|
|
|
// Original pattern that failed: [[,(=<>+-*|&^] %num% [+-*/] %num% ]|,|)|;|=|%op%
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize toks("a == 1", true);
|
2011-11-05 19:24:21 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(toks.tokens(), "a =|%op%"));
|
2011-11-05 14:04:23 +01:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void multiCompare3() const {
|
2015-01-31 10:50:39 +01:00
|
|
|
// Original pattern that failed: "return|(|&&|%oror% %name% &&|%oror%|==|!=|<=|>=|<|>|-|%or% %name% )|&&|%oror%|;"
|
2011-11-06 22:12:28 +01:00
|
|
|
// Code snippet that failed: "return lv@86 |= rv@87 ;"
|
|
|
|
|
|
|
|
// Note: Also test "reverse" alternative pattern, two different code paths to handle it
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize toks("return a |= b ;", true);
|
2015-01-31 10:50:39 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(toks.tokens(), "return %name% xyz|%or% %name% ;"));
|
|
|
|
ASSERT_EQUALS(false, Token::Match(toks.tokens(), "return %name% %or%|xyz %name% ;"));
|
2011-11-06 22:12:28 +01:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize toks2("return a | b ;", true);
|
2015-01-31 10:50:39 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(toks2.tokens(), "return %name% xyz|%or% %name% ;"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(toks2.tokens(), "return %name% %or%|xyz %name% ;"));
|
2011-11-06 22:12:28 +01:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize toks3("return a || b ;", true);
|
2015-01-31 10:50:39 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(toks3.tokens(), "return %name% xyz|%or% %name% ;"));
|
|
|
|
ASSERT_EQUALS(false, Token::Match(toks3.tokens(), "return %name% %or%|xyz %name% ;"));
|
2011-11-06 22:12:28 +01:00
|
|
|
|
2015-01-31 10:50:39 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(toks3.tokens(), "return %name% xyz|%oror% %name% ;"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(toks3.tokens(), "return %name% %oror%|xyz %name% ;"));
|
2012-08-30 13:33:19 +02:00
|
|
|
|
|
|
|
givenACodeSampleToTokenize toks4("a % b ;", true);
|
2015-01-31 10:50:39 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(toks4.tokens(), "%name% >>|<<|&|%or%|^|% %name% ;"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(toks4.tokens(), "%name% %|>>|<<|&|%or%|^ %name% ;"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(toks4.tokens(), "%name% >>|<<|&|%or%|%|^ %name% ;"));
|
2012-11-17 20:25:12 +01:00
|
|
|
|
2015-01-31 10:50:39 +01:00
|
|
|
//%name%|%num% support
|
2012-11-17 20:25:12 +01:00
|
|
|
givenACodeSampleToTokenize num("100", true);
|
2015-01-31 10:50:39 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%num%|%name%"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%name%|%num%"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%name%|%num%|%bool%"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%name%|%bool%|%num%"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%name%|%bool%|%str%|%num%"));
|
|
|
|
ASSERT_EQUALS(false, Token::Match(num.tokens(), "%bool%|%name%"));
|
2012-11-17 20:25:12 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(num.tokens(), "%type%|%bool%|%char%"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%type%|%bool%|100"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize numparen("( 100 )", true);
|
2015-01-31 10:50:39 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %num%|%name% )|"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %name%|%num% )|"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %name%|%num%|%bool% )|"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %name%|%bool%|%num% )|"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %name%|%bool%|%str%|%num% )|"));
|
|
|
|
ASSERT_EQUALS(false, Token::Match(numparen.tokens(), "(| %bool%|%name% )|"));
|
|
|
|
|
|
|
|
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %num%|%name%| )|"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %name%|%num%| )|"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %name%|%num%|%bool%| )|"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %name%|%bool%|%num%| )|"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %name%|%bool%|%str%|%num%| )|"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %bool%|%name%| )|"));
|
2011-11-06 22:12:28 +01:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void multiCompare4() const {
|
2013-01-07 23:42:25 +01:00
|
|
|
givenACodeSampleToTokenize var("std :: queue < int > foo ;");
|
|
|
|
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT_EQUALS(Token::eBracket, var.tokens()->tokAt(3)->tokType());
|
|
|
|
ASSERT_EQUALS(Token::eBracket, var.tokens()->tokAt(5)->tokType());
|
2013-01-07 23:42:25 +01:00
|
|
|
|
|
|
|
ASSERT_EQUALS(false, Token::Match(var.tokens(), "std :: queue %op%"));
|
2013-01-09 16:53:19 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(var.tokens(), "std :: queue x|%op%"));
|
|
|
|
ASSERT_EQUALS(false, Token::Match(var.tokens(), "std :: queue %op%|x"));
|
2013-01-07 23:42:25 +01:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void multiCompare5() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2014-06-26 18:17:05 +02:00
|
|
|
tok.str("||");
|
|
|
|
ASSERT_EQUALS(true, Token::multiCompare(&tok, "+|%or%|%oror%", 0) >= 0);
|
|
|
|
}
|
|
|
|
|
Set correct type and size of string and char literals (#2275)
* Set correct type and size of string and char literals
Use that string and char literal tokens store the prefix. This makes
it possible to distinghuish between different type of string literals
(i.e., utf8 encoded strings, utf16, wide strings, etc) which have
different type.
When the tokens holding the string and character values have the correct
type, it is possible to improve Token::getStrSize() to give the correct
result for all string types. Previously, it would return the number of
characters in the string, i.e., it would give the wrong size unless
the type of the string was char*.
Since strings now can have different size (in number of bytes) and
length (in number of elements), add a new helper function that returns
the number of characters. Checkers have been updated to use the correct
functions.
Having the size makes it possible to find more problems with prefixed
strings, and to reduce false positives, for example in the buffer
overflow checker.
Also, improve the stringLiteralWrite error message to also print the
prefix of the string (if there is one).
* Add comment and update string length
2019-10-20 07:11:57 +02:00
|
|
|
void charTypes() const {
|
|
|
|
Token tok;
|
|
|
|
|
|
|
|
tok.str("'a'");
|
|
|
|
ASSERT_EQUALS(true, tok.isCChar());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf8());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf16());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf32());
|
|
|
|
ASSERT_EQUALS(false, tok.isLong());
|
|
|
|
ASSERT_EQUALS(false, tok.isCMultiChar());
|
|
|
|
|
|
|
|
tok.str("u8'a'");
|
|
|
|
ASSERT_EQUALS(false, tok.isCChar());
|
|
|
|
ASSERT_EQUALS(true, tok.isUtf8());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf16());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf32());
|
|
|
|
ASSERT_EQUALS(false, tok.isLong());
|
|
|
|
ASSERT_EQUALS(false, tok.isCMultiChar());
|
|
|
|
|
|
|
|
tok.str("u'a'");
|
|
|
|
ASSERT_EQUALS(false, tok.isCChar());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf8());
|
|
|
|
ASSERT_EQUALS(true, tok.isUtf16());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf32());
|
|
|
|
ASSERT_EQUALS(false, tok.isLong());
|
|
|
|
ASSERT_EQUALS(false, tok.isCMultiChar());
|
|
|
|
|
|
|
|
tok.str("U'a'");
|
|
|
|
ASSERT_EQUALS(false, tok.isCChar());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf8());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf16());
|
|
|
|
ASSERT_EQUALS(true, tok.isUtf32());
|
|
|
|
ASSERT_EQUALS(false, tok.isLong());
|
|
|
|
ASSERT_EQUALS(false, tok.isCMultiChar());
|
|
|
|
|
|
|
|
tok.str("L'a'");
|
|
|
|
ASSERT_EQUALS(false, tok.isCChar());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf8());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf16());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf32());
|
|
|
|
ASSERT_EQUALS(true, tok.isLong());
|
|
|
|
ASSERT_EQUALS(false, tok.isCMultiChar());
|
|
|
|
|
|
|
|
tok.str("'aaa'");
|
|
|
|
ASSERT_EQUALS(false, tok.isCChar());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf8());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf16());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf32());
|
|
|
|
ASSERT_EQUALS(false, tok.isLong());
|
|
|
|
ASSERT_EQUALS(true, tok.isCMultiChar());
|
|
|
|
}
|
|
|
|
|
|
|
|
void stringTypes() const {
|
|
|
|
Token tok;
|
|
|
|
|
|
|
|
tok.str("\"a\"");
|
|
|
|
ASSERT_EQUALS(true, tok.isCChar());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf8());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf16());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf32());
|
|
|
|
ASSERT_EQUALS(false, tok.isLong());
|
|
|
|
ASSERT_EQUALS(false, tok.isCMultiChar());
|
|
|
|
|
|
|
|
tok.str("u8\"a\"");
|
|
|
|
ASSERT_EQUALS(false, tok.isCChar());
|
|
|
|
ASSERT_EQUALS(true, tok.isUtf8());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf16());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf32());
|
|
|
|
ASSERT_EQUALS(false, tok.isLong());
|
|
|
|
ASSERT_EQUALS(false, tok.isCMultiChar());
|
|
|
|
|
|
|
|
tok.str("u\"a\"");
|
|
|
|
ASSERT_EQUALS(false, tok.isCChar());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf8());
|
|
|
|
ASSERT_EQUALS(true, tok.isUtf16());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf32());
|
|
|
|
ASSERT_EQUALS(false, tok.isLong());
|
|
|
|
ASSERT_EQUALS(false, tok.isCMultiChar());
|
|
|
|
|
|
|
|
tok.str("U\"a\"");
|
|
|
|
ASSERT_EQUALS(false, tok.isCChar());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf8());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf16());
|
|
|
|
ASSERT_EQUALS(true, tok.isUtf32());
|
|
|
|
ASSERT_EQUALS(false, tok.isLong());
|
|
|
|
ASSERT_EQUALS(false, tok.isCMultiChar());
|
|
|
|
|
|
|
|
tok.str("L\"a\"");
|
|
|
|
ASSERT_EQUALS(false, tok.isCChar());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf8());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf16());
|
|
|
|
ASSERT_EQUALS(false, tok.isUtf32());
|
|
|
|
ASSERT_EQUALS(true, tok.isLong());
|
|
|
|
ASSERT_EQUALS(false, tok.isCMultiChar());
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void getStrLength() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2009-08-30 13:07:10 +02:00
|
|
|
|
2009-09-13 10:07:26 +02:00
|
|
|
tok.str("\"\"");
|
2019-03-18 06:18:25 +01:00
|
|
|
ASSERT_EQUALS(0, Token::getStrLength(&tok));
|
2009-08-30 13:07:10 +02:00
|
|
|
|
2009-09-13 10:07:26 +02:00
|
|
|
tok.str("\"test\"");
|
2019-03-18 06:18:25 +01:00
|
|
|
ASSERT_EQUALS(4, Token::getStrLength(&tok));
|
2009-08-30 13:07:10 +02:00
|
|
|
|
2009-09-13 10:07:26 +02:00
|
|
|
tok.str("\"test \\\\test\"");
|
2019-03-18 06:18:25 +01:00
|
|
|
ASSERT_EQUALS(10, Token::getStrLength(&tok));
|
2009-09-26 17:58:14 +02:00
|
|
|
|
|
|
|
tok.str("\"a\\0\"");
|
2019-03-18 06:18:25 +01:00
|
|
|
ASSERT_EQUALS(1, Token::getStrLength(&tok));
|
|
|
|
|
|
|
|
tok.str("L\"\"");
|
|
|
|
ASSERT_EQUALS(0, Token::getStrLength(&tok));
|
|
|
|
|
|
|
|
tok.str("u8\"test\"");
|
|
|
|
ASSERT_EQUALS(4, Token::getStrLength(&tok));
|
|
|
|
|
|
|
|
tok.str("U\"test \\\\test\"");
|
|
|
|
ASSERT_EQUALS(10, Token::getStrLength(&tok));
|
|
|
|
|
|
|
|
tok.str("u\"a\\0\"");
|
|
|
|
ASSERT_EQUALS(1, Token::getStrLength(&tok));
|
2009-08-30 13:07:10 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void getStrSize() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
Set correct type and size of string and char literals (#2275)
* Set correct type and size of string and char literals
Use that string and char literal tokens store the prefix. This makes
it possible to distinghuish between different type of string literals
(i.e., utf8 encoded strings, utf16, wide strings, etc) which have
different type.
When the tokens holding the string and character values have the correct
type, it is possible to improve Token::getStrSize() to give the correct
result for all string types. Previously, it would return the number of
characters in the string, i.e., it would give the wrong size unless
the type of the string was char*.
Since strings now can have different size (in number of bytes) and
length (in number of elements), add a new helper function that returns
the number of characters. Checkers have been updated to use the correct
functions.
Having the size makes it possible to find more problems with prefixed
strings, and to reduce false positives, for example in the buffer
overflow checker.
Also, improve the stringLiteralWrite error message to also print the
prefix of the string (if there is one).
* Add comment and update string length
2019-10-20 07:11:57 +02:00
|
|
|
Settings settings;
|
2014-08-01 13:12:18 +02:00
|
|
|
|
2019-04-25 07:08:13 +02:00
|
|
|
tok.str("\"\"");
|
Set correct type and size of string and char literals (#2275)
* Set correct type and size of string and char literals
Use that string and char literal tokens store the prefix. This makes
it possible to distinghuish between different type of string literals
(i.e., utf8 encoded strings, utf16, wide strings, etc) which have
different type.
When the tokens holding the string and character values have the correct
type, it is possible to improve Token::getStrSize() to give the correct
result for all string types. Previously, it would return the number of
characters in the string, i.e., it would give the wrong size unless
the type of the string was char*.
Since strings now can have different size (in number of bytes) and
length (in number of elements), add a new helper function that returns
the number of characters. Checkers have been updated to use the correct
functions.
Having the size makes it possible to find more problems with prefixed
strings, and to reduce false positives, for example in the buffer
overflow checker.
Also, improve the stringLiteralWrite error message to also print the
prefix of the string (if there is one).
* Add comment and update string length
2019-10-20 07:11:57 +02:00
|
|
|
ASSERT_EQUALS(sizeof(""), Token::getStrSize(&tok, &settings));
|
2019-04-25 07:08:13 +02:00
|
|
|
|
2014-08-01 13:12:18 +02:00
|
|
|
tok.str("\"abc\"");
|
Set correct type and size of string and char literals (#2275)
* Set correct type and size of string and char literals
Use that string and char literal tokens store the prefix. This makes
it possible to distinghuish between different type of string literals
(i.e., utf8 encoded strings, utf16, wide strings, etc) which have
different type.
When the tokens holding the string and character values have the correct
type, it is possible to improve Token::getStrSize() to give the correct
result for all string types. Previously, it would return the number of
characters in the string, i.e., it would give the wrong size unless
the type of the string was char*.
Since strings now can have different size (in number of bytes) and
length (in number of elements), add a new helper function that returns
the number of characters. Checkers have been updated to use the correct
functions.
Having the size makes it possible to find more problems with prefixed
strings, and to reduce false positives, for example in the buffer
overflow checker.
Also, improve the stringLiteralWrite error message to also print the
prefix of the string (if there is one).
* Add comment and update string length
2019-10-20 07:11:57 +02:00
|
|
|
ASSERT_EQUALS(sizeof("abc"), Token::getStrSize(&tok, &settings));
|
2014-08-01 13:12:18 +02:00
|
|
|
|
|
|
|
tok.str("\"\\0abc\"");
|
Set correct type and size of string and char literals (#2275)
* Set correct type and size of string and char literals
Use that string and char literal tokens store the prefix. This makes
it possible to distinghuish between different type of string literals
(i.e., utf8 encoded strings, utf16, wide strings, etc) which have
different type.
When the tokens holding the string and character values have the correct
type, it is possible to improve Token::getStrSize() to give the correct
result for all string types. Previously, it would return the number of
characters in the string, i.e., it would give the wrong size unless
the type of the string was char*.
Since strings now can have different size (in number of bytes) and
length (in number of elements), add a new helper function that returns
the number of characters. Checkers have been updated to use the correct
functions.
Having the size makes it possible to find more problems with prefixed
strings, and to reduce false positives, for example in the buffer
overflow checker.
Also, improve the stringLiteralWrite error message to also print the
prefix of the string (if there is one).
* Add comment and update string length
2019-10-20 07:11:57 +02:00
|
|
|
ASSERT_EQUALS(sizeof("\0abc"), Token::getStrSize(&tok, &settings));
|
2014-08-01 13:12:18 +02:00
|
|
|
|
|
|
|
tok.str("\"\\\\\"");
|
Set correct type and size of string and char literals (#2275)
* Set correct type and size of string and char literals
Use that string and char literal tokens store the prefix. This makes
it possible to distinghuish between different type of string literals
(i.e., utf8 encoded strings, utf16, wide strings, etc) which have
different type.
When the tokens holding the string and character values have the correct
type, it is possible to improve Token::getStrSize() to give the correct
result for all string types. Previously, it would return the number of
characters in the string, i.e., it would give the wrong size unless
the type of the string was char*.
Since strings now can have different size (in number of bytes) and
length (in number of elements), add a new helper function that returns
the number of characters. Checkers have been updated to use the correct
functions.
Having the size makes it possible to find more problems with prefixed
strings, and to reduce false positives, for example in the buffer
overflow checker.
Also, improve the stringLiteralWrite error message to also print the
prefix of the string (if there is one).
* Add comment and update string length
2019-10-20 07:11:57 +02:00
|
|
|
ASSERT_EQUALS(sizeof("\\"), Token::getStrSize(&tok, &settings));
|
2014-08-01 13:12:18 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 07:08:13 +02:00
|
|
|
void getCharAt() const {
|
|
|
|
Token tok;
|
|
|
|
|
|
|
|
tok.str("\"asdf\"");
|
|
|
|
ASSERT_EQUALS("a", Token::getCharAt(&tok, 0));
|
|
|
|
ASSERT_EQUALS("s", Token::getCharAt(&tok, 1));
|
|
|
|
|
|
|
|
tok.str("\"a\\ts\"");
|
|
|
|
ASSERT_EQUALS("\\t", Token::getCharAt(&tok, 1));
|
|
|
|
|
|
|
|
tok.str("\"\"");
|
|
|
|
ASSERT_EQUALS("\\0", Token::getCharAt(&tok, 0));
|
|
|
|
|
|
|
|
tok.str("L\"a\\ts\"");
|
|
|
|
ASSERT_EQUALS("a", Token::getCharAt(&tok, 0));
|
|
|
|
ASSERT_EQUALS("\\t", Token::getCharAt(&tok, 1));
|
|
|
|
|
|
|
|
tok.str("u\"a\\ts\"");
|
|
|
|
ASSERT_EQUALS("\\t", Token::getCharAt(&tok, 1));
|
|
|
|
ASSERT_EQUALS("s", Token::getCharAt(&tok, 2));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void strValue() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2015-06-07 11:25:33 +02:00
|
|
|
|
2009-09-12 22:54:47 +02:00
|
|
|
tok.str("\"\"");
|
2013-03-12 15:42:00 +01:00
|
|
|
ASSERT_EQUALS("", tok.strValue());
|
2009-09-12 22:54:47 +02:00
|
|
|
|
|
|
|
tok.str("\"0\"");
|
2013-03-12 15:42:00 +01:00
|
|
|
ASSERT_EQUALS("0", tok.strValue());
|
2015-06-07 11:25:33 +02:00
|
|
|
|
|
|
|
tok.str("\"a\\n\"");
|
|
|
|
ASSERT_EQUALS("a\n", tok.strValue());
|
|
|
|
|
|
|
|
tok.str("\"a\\r\"");
|
|
|
|
ASSERT_EQUALS("a\r", tok.strValue());
|
|
|
|
|
|
|
|
tok.str("\"a\\t\"");
|
|
|
|
ASSERT_EQUALS("a\t", tok.strValue());
|
|
|
|
|
|
|
|
tok.str("\"\\\\\"");
|
|
|
|
ASSERT_EQUALS("\\", tok.strValue());
|
|
|
|
|
|
|
|
tok.str("\"a\\0\"");
|
|
|
|
ASSERT_EQUALS("a", tok.strValue());
|
|
|
|
|
2019-04-25 07:08:13 +02:00
|
|
|
tok.str("L\"a\\t\"");
|
|
|
|
ASSERT_EQUALS("a\t", tok.strValue());
|
|
|
|
|
|
|
|
tok.str("U\"a\\0\"");
|
|
|
|
ASSERT_EQUALS("a", tok.strValue());
|
2009-09-12 22:54:47 +02:00
|
|
|
}
|
2010-01-06 20:19:27 +01:00
|
|
|
|
2019-11-08 08:03:45 +01:00
|
|
|
void concatStr() const {
|
|
|
|
Token tok;
|
|
|
|
|
|
|
|
tok.str("\"\"");
|
|
|
|
tok.concatStr("\"\"");
|
|
|
|
ASSERT_EQUALS("", tok.strValue());
|
|
|
|
ASSERT(tok.isCChar());
|
|
|
|
|
|
|
|
tok.str("\"ab\"");
|
|
|
|
tok.concatStr("\"cd\"");
|
|
|
|
ASSERT_EQUALS("abcd", tok.strValue());
|
|
|
|
ASSERT(tok.isCChar());
|
|
|
|
|
|
|
|
tok.str("L\"ab\"");
|
|
|
|
tok.concatStr("L\"cd\"");
|
|
|
|
ASSERT_EQUALS("abcd", tok.strValue());
|
|
|
|
ASSERT(tok.isLong());
|
|
|
|
|
|
|
|
tok.str("L\"ab\"");
|
|
|
|
tok.concatStr("\"cd\"");
|
|
|
|
ASSERT_EQUALS("abcd", tok.strValue());
|
|
|
|
ASSERT(tok.isLong());
|
|
|
|
|
|
|
|
tok.str("\"ab\"");
|
|
|
|
tok.concatStr("L\"cd\"");
|
|
|
|
ASSERT_EQUALS("abcd", tok.strValue());
|
|
|
|
ASSERT(tok.isLong());
|
|
|
|
|
|
|
|
tok.str("\"ab\"");
|
|
|
|
tok.concatStr("L\"\"");
|
|
|
|
ASSERT_EQUALS("ab", tok.strValue());
|
|
|
|
ASSERT(tok.isLong());
|
|
|
|
|
|
|
|
tok.str("\"ab\"");
|
|
|
|
tok.concatStr("u8\"cd\"");
|
|
|
|
ASSERT_EQUALS("abcd", tok.strValue());
|
|
|
|
ASSERT(tok.isUtf8());
|
|
|
|
}
|
2010-01-06 20:19:27 +01:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void deleteLast() const {
|
2019-06-30 21:39:22 +02:00
|
|
|
TokensFrontBack listEnds{ nullptr };
|
2018-09-24 15:08:16 +02:00
|
|
|
Token ** const tokensBack = &(listEnds.back);
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok(&listEnds);
|
2010-01-06 20:19:27 +01:00
|
|
|
tok.insertToken("aba");
|
2018-05-25 07:15:05 +02:00
|
|
|
ASSERT_EQUALS(true, *tokensBack == tok.next());
|
2010-01-06 20:19:27 +01:00
|
|
|
tok.deleteNext();
|
2018-05-25 07:15:05 +02:00
|
|
|
ASSERT_EQUALS(true, *tokensBack == &tok);
|
|
|
|
}
|
|
|
|
|
|
|
|
void deleteFirst() const {
|
2019-06-30 21:39:22 +02:00
|
|
|
TokensFrontBack listEnds{ nullptr };
|
2018-09-24 15:08:16 +02:00
|
|
|
Token ** const tokensFront = &(listEnds.front);
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok(&listEnds);
|
|
|
|
|
|
|
|
tok.insertToken("aba");
|
|
|
|
|
|
|
|
ASSERT_EQUALS(true, *tokensFront == tok.previous());
|
|
|
|
tok.deletePrevious();
|
|
|
|
ASSERT_EQUALS(true, *tokensFront == &tok);
|
2010-01-06 20:19:27 +01:00
|
|
|
}
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void nextArgument() const {
|
2011-10-23 11:23:48 +02:00
|
|
|
givenACodeSampleToTokenize example1("foo(1, 2, 3, 4);");
|
2011-10-28 22:30:33 +02:00
|
|
|
ASSERT_EQUALS(true, Token::simpleMatch(example1.tokens()->tokAt(2)->nextArgument(), "2 , 3"));
|
2013-04-04 15:12:18 +02:00
|
|
|
ASSERT_EQUALS(true, Token::simpleMatch(example1.tokens()->tokAt(4)->nextArgument(), "3 , 4"));
|
2011-10-23 11:23:48 +02:00
|
|
|
|
|
|
|
givenACodeSampleToTokenize example2("foo();");
|
2019-06-30 21:39:22 +02:00
|
|
|
ASSERT_EQUALS(true, example2.tokens()->tokAt(2)->nextArgument() == nullptr);
|
2011-10-23 11:23:48 +02:00
|
|
|
|
|
|
|
givenACodeSampleToTokenize example3("foo(bar(a, b), 2, 3);");
|
2011-10-28 22:30:33 +02:00
|
|
|
ASSERT_EQUALS(true, Token::simpleMatch(example3.tokens()->tokAt(2)->nextArgument(), "2 , 3"));
|
2013-04-04 15:12:18 +02:00
|
|
|
|
|
|
|
givenACodeSampleToTokenize example4("foo(x.i[1], \"\", 3);");
|
|
|
|
ASSERT_EQUALS(true, Token::simpleMatch(example4.tokens()->tokAt(2)->nextArgument(), "\"\" , 3"));
|
2011-10-23 11:23:48 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void eraseTokens() const {
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize code("begin ; { this code will be removed } end", true);
|
2011-11-08 18:59:31 +01:00
|
|
|
Token::eraseTokens(code.tokens()->next(), code.tokens()->tokAt(9));
|
2019-06-30 21:39:22 +02:00
|
|
|
ASSERT_EQUALS("begin ; end", code.tokens()->stringifyList(nullptr, false));
|
2011-11-08 18:59:31 +01:00
|
|
|
}
|
|
|
|
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchAny() const {
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize varBitOrVar("abc|def", true);
|
2015-01-31 10:50:39 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(varBitOrVar.tokens(), "%name% %or% %name%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize varLogOrVar("abc||def", true);
|
2015-01-31 10:50:39 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(varLogOrVar.tokens(), "%name% %oror% %name%"));
|
2010-09-26 05:31:36 +02:00
|
|
|
}
|
2011-07-15 19:02:16 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchSingleChar() const {
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize singleChar("a", true);
|
2011-07-15 19:01:36 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(singleChar.tokens(), "[a|bc]"));
|
|
|
|
ASSERT_EQUALS(false, Token::Match(singleChar.tokens(), "[d|ef]"));
|
|
|
|
|
2018-05-25 07:15:05 +02:00
|
|
|
Token multiChar;
|
2011-07-15 19:01:36 +02:00
|
|
|
multiChar.str("[ab");
|
|
|
|
ASSERT_EQUALS(false, Token::Match(&multiChar, "[ab|def]"));
|
|
|
|
}
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchNothingOrAnyNotElse() const {
|
2014-06-26 20:34:07 +02:00
|
|
|
givenACodeSampleToTokenize empty_String("", true);
|
|
|
|
ASSERT_EQUALS(true, Token::Match(empty_String.tokens(), "!!else"));
|
|
|
|
ASSERT_EQUALS(false, Token::Match(empty_String.tokens(), "!!else something"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize ifSemicolon("if ;", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(ifSemicolon.tokens(), "if ; !!else"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize ifSemicolonSomething("if ; something", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(ifSemicolonSomething.tokens(), "if ; !!else"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize justElse("else", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(false, Token::Match(justElse.tokens(), "!!else"));
|
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize ifSemicolonElse("if ; else", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(false, Token::Match(ifSemicolonElse.tokens(), "if ; !!else"));
|
2010-09-07 20:42:29 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchType() const {
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize type("abc", true);
|
2011-11-06 18:30:34 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(type.tokens(), "%type%"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize isVar("int a = 3 ;");
|
|
|
|
ASSERT_EQUALS(true, Token::Match(isVar.tokens(), "%type%"));
|
2015-01-31 10:50:39 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(isVar.tokens(), "%type% %name%"));
|
2011-11-06 18:30:34 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(isVar.tokens(), "%type% %type%"));
|
|
|
|
|
2014-06-04 22:33:08 +02:00
|
|
|
givenACodeSampleToTokenize noType1_cpp("delete", true, true);
|
|
|
|
ASSERT_EQUALS(false, Token::Match(noType1_cpp.tokens(), "%type%"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize noType1_c("delete", true, false);
|
|
|
|
ASSERT_EQUALS(true, Token::Match(noType1_c.tokens(), "%type%"));
|
2013-01-08 00:10:36 +01:00
|
|
|
|
|
|
|
givenACodeSampleToTokenize noType2("void delete", true);
|
2013-01-09 20:11:02 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(noType2.tokens(), "!!foo %type%"));
|
2011-11-06 18:30:34 +01:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchChar() const {
|
2012-11-04 16:34:32 +01:00
|
|
|
givenACodeSampleToTokenize chr1("'a'", true);
|
|
|
|
ASSERT_EQUALS(true, Token::Match(chr1.tokens(), "%char%"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize chr2("'1'", true);
|
|
|
|
ASSERT_EQUALS(true, Token::Match(chr2.tokens(), "%char%"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize noChr("\"10\"", true);
|
|
|
|
ASSERT_EQUALS(false, Token::Match(noChr.tokens(), "%char%"));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchCompOp() const {
|
2012-12-01 00:47:07 +01:00
|
|
|
givenACodeSampleToTokenize comp1("<=", true);
|
|
|
|
ASSERT_EQUALS(true, Token::Match(comp1.tokens(), "%comp%"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize comp2(">", true);
|
|
|
|
ASSERT_EQUALS(true, Token::Match(comp2.tokens(), "%comp%"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize noComp("=", true);
|
|
|
|
ASSERT_EQUALS(false, Token::Match(noComp.tokens(), "%comp%"));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchStr() const {
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize noStr1("abc", true);
|
2011-11-06 18:30:34 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(noStr1.tokens(), "%str%"));
|
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize noStr2("'a'", true);
|
2011-11-06 18:30:34 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(noStr2.tokens(), "%str%"));
|
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize str("\"abc\"", true);
|
2011-11-06 18:30:34 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(str.tokens(), "%str%"));
|
2011-11-06 21:20:13 +01:00
|
|
|
|
|
|
|
// Empty string
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize emptyStr("\"\"", true);
|
2011-11-06 21:20:13 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(emptyStr.tokens(), "%str%"));
|
2011-11-06 18:30:34 +01:00
|
|
|
}
|
2010-09-26 05:31:36 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchVarid() const {
|
2011-11-06 18:37:00 +01:00
|
|
|
givenACodeSampleToTokenize var("int a ; int b ;");
|
2011-11-20 22:38:37 +01:00
|
|
|
|
|
|
|
// Varid == 0 should throw exception
|
2019-08-02 07:57:34 +02:00
|
|
|
ASSERT_THROW((void)Token::Match(var.tokens(), "%type% %varid% ; %type% %name%", 0),InternalError);
|
2011-11-06 18:37:00 +01:00
|
|
|
|
2015-01-31 10:50:39 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(var.tokens(), "%type% %varid% ; %type% %name%", 1));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(var.tokens(), "%type% %name% ; %type% %varid%", 2));
|
2011-11-06 18:37:00 +01:00
|
|
|
|
|
|
|
// Try to match two different varids in one match call
|
|
|
|
ASSERT_EQUALS(false, Token::Match(var.tokens(), "%type% %varid% ; %type% %varid%", 2));
|
2015-01-31 10:50:39 +01:00
|
|
|
|
|
|
|
// %var% matches with every varid other than 0
|
|
|
|
ASSERT_EQUALS(true, Token::Match(var.tokens(), "%type% %var% ;"));
|
|
|
|
ASSERT_EQUALS(false, Token::Match(var.tokens(), "%var% %var% ;"));
|
2011-11-06 18:37:00 +01:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchNumeric() const {
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize nonNumeric("abc", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(false, Token::Match(nonNumeric.tokens(), "%num%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize binary("101010b", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(binary.tokens(), "%num%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize octal("0123", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(octal.tokens(), "%num%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize decimal("4567", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(decimal.tokens(), "%num%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize hexadecimal("0xDEADBEEF", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(hexadecimal.tokens(), "%num%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize floatingPoint("0.0f", true);
|
2013-09-21 17:40:18 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(floatingPoint.tokens(), "%num%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize doublePrecision("0.0d", true);
|
2013-09-21 17:40:18 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(doublePrecision.tokens(), "%num%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2013-10-01 00:55:36 +02:00
|
|
|
givenACodeSampleToTokenize signedLong("0L", true);
|
|
|
|
ASSERT_EQUALS(true, Token::Match(signedLong.tokens(), "%num%"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize negativeSignedLong("-0L", true);
|
|
|
|
ASSERT_EQUALS(true, Token::Match(negativeSignedLong.tokens(), "- %num%"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize positiveSignedLong("+0L", true);
|
|
|
|
ASSERT_EQUALS(true, Token::Match(positiveSignedLong.tokens(), "+ %num%"));
|
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize unsignedInt("0U", true);
|
2013-09-21 17:40:18 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(unsignedInt.tokens(), "%num%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize unsignedLong("0UL", true);
|
2013-09-21 17:40:18 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(unsignedLong.tokens(), "%num%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize unsignedLongLong("0ULL", true);
|
2013-09-21 17:40:18 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(unsignedLongLong.tokens(), "%num%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize positive("+666", true);
|
2010-09-26 08:39:19 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(positive.tokens(), "+ %num%"));
|
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize negative("-42", true);
|
2010-09-26 08:39:19 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(negative.tokens(), "- %num%"));
|
2013-10-01 00:55:36 +02:00
|
|
|
|
|
|
|
givenACodeSampleToTokenize negativeNull("-.0", true);
|
|
|
|
ASSERT_EQUALS(true, Token::Match(negativeNull.tokens(), "- %num%"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize positiveNull("+.0", true);
|
|
|
|
ASSERT_EQUALS(true, Token::Match(positiveNull.tokens(), "+ %num%"));
|
2010-09-26 05:31:36 +02:00
|
|
|
}
|
2010-09-07 20:42:29 +02:00
|
|
|
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchBoolean() const {
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize yes("YES", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(false, Token::Match(yes.tokens(), "%bool%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize positive("true", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(positive.tokens(), "%bool%"));
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2012-05-16 18:04:03 +02:00
|
|
|
givenACodeSampleToTokenize negative("false", true);
|
2010-09-26 05:31:36 +02:00
|
|
|
ASSERT_EQUALS(true, Token::Match(negative.tokens(), "%bool%"));
|
|
|
|
}
|
2010-09-07 20:42:29 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchOr() const {
|
2016-11-20 17:59:50 +01:00
|
|
|
givenACodeSampleToTokenize bitwiseOr(";|;", true);
|
2021-01-12 20:48:25 +01:00
|
|
|
// cppcheck-suppress simplePatternError - this is intentional
|
2016-11-20 17:59:50 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(bitwiseOr.tokens(), "; %or%"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(bitwiseOr.tokens(), "; %op%"));
|
2021-01-12 20:48:25 +01:00
|
|
|
// cppcheck-suppress simplePatternError - this is intentional
|
2016-11-20 17:59:50 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(bitwiseOr.tokens(), "; %oror%"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize bitwiseOrAssignment(";|=;");
|
2021-01-12 20:48:25 +01:00
|
|
|
// cppcheck-suppress simplePatternError - this is intentional
|
2016-11-20 17:59:50 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "; %or%"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(bitwiseOrAssignment.tokens(), "; %op%"));
|
2021-01-12 20:48:25 +01:00
|
|
|
// cppcheck-suppress simplePatternError - this is intentional
|
2016-11-20 17:59:50 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "; %oror%"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize logicalOr(";||;", true);
|
2021-01-12 20:48:25 +01:00
|
|
|
// cppcheck-suppress simplePatternError - this is intentional
|
2016-11-20 17:59:50 +01:00
|
|
|
ASSERT_EQUALS(false, Token::Match(logicalOr.tokens(), "; %or%"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "; %op%"));
|
2021-01-12 20:48:25 +01:00
|
|
|
// cppcheck-suppress simplePatternError - this is intentional
|
2016-11-20 17:59:50 +01:00
|
|
|
ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "; %oror%"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "; &&|%oror%"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "; %oror%|&&"));
|
|
|
|
|
|
|
|
givenACodeSampleToTokenize logicalAnd(";&&;", true);
|
|
|
|
ASSERT_EQUALS(true, Token::simpleMatch(logicalAnd.tokens(), "; &&"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "; &&|%oror%"));
|
|
|
|
ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "; %oror%|&&"));
|
2010-10-25 03:14:21 +02:00
|
|
|
}
|
2011-04-10 11:15:57 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
static void append_vector(std::vector<std::string> &dest, const std::vector<std::string> &src) {
|
2011-11-06 21:20:13 +01:00
|
|
|
dest.insert(dest.end(), src.begin(), src.end());
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchOp() {
|
2011-11-06 21:20:13 +01:00
|
|
|
std::vector<std::string> test_ops;
|
|
|
|
append_vector(test_ops, arithmeticalOps);
|
2012-04-23 21:05:26 +02:00
|
|
|
append_vector(test_ops, bitOps);
|
2013-02-10 07:43:09 +01:00
|
|
|
append_vector(test_ops, comparisonOps);
|
2012-04-23 21:05:26 +02:00
|
|
|
append_vector(test_ops, logicalOps);
|
2013-03-01 11:43:59 +01:00
|
|
|
append_vector(test_ops, assignmentOps);
|
2011-11-06 21:20:13 +01:00
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
|
|
|
|
for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
|
2021-11-29 07:34:39 +01:00
|
|
|
ASSERT_EQUALS(true, MatchCheck(*test_op, "%op%"));
|
2011-11-06 21:20:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Negative test against other operators
|
|
|
|
std::vector<std::string> other_ops;
|
|
|
|
append_vector(other_ops, extendedOps);
|
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
|
|
|
|
for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
|
2021-11-29 07:34:39 +01:00
|
|
|
ASSERT_EQUALS_MSG(false, MatchCheck(*other_op, "%op%"), "Failing other operator: " + *other_op);
|
2011-11-06 21:20:13 +01:00
|
|
|
}
|
2011-04-10 11:15:57 +02:00
|
|
|
}
|
2011-10-23 20:38:03 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void matchConstOp() {
|
2013-03-01 11:43:59 +01:00
|
|
|
std::vector<std::string> test_ops;
|
|
|
|
append_vector(test_ops, arithmeticalOps);
|
|
|
|
append_vector(test_ops, bitOps);
|
|
|
|
append_vector(test_ops, comparisonOps);
|
|
|
|
append_vector(test_ops, logicalOps);
|
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
|
|
|
|
for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
|
2021-11-29 07:34:39 +01:00
|
|
|
ASSERT_EQUALS(true, MatchCheck(*test_op, "%cop%"));
|
2013-03-01 11:43:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Negative test against other operators
|
|
|
|
std::vector<std::string> other_ops;
|
|
|
|
append_vector(other_ops, extendedOps);
|
|
|
|
append_vector(other_ops, assignmentOps);
|
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
|
|
|
|
for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
|
2021-11-29 07:34:39 +01:00
|
|
|
ASSERT_EQUALS_MSG(false, MatchCheck(*other_op, "%cop%"), "Failing other operator: " + *other_op);
|
2013-03-01 11:43:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void isArithmeticalOp() const {
|
2011-11-06 21:20:13 +01:00
|
|
|
std::vector<std::string>::const_iterator test_op, test_ops_end = arithmeticalOps.end();
|
|
|
|
for (test_op = arithmeticalOps.begin(); test_op != test_ops_end; ++test_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-11-06 21:20:13 +01:00
|
|
|
tok.str(*test_op);
|
|
|
|
ASSERT_EQUALS(true, tok.isArithmeticalOp());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Negative test against other operators
|
|
|
|
std::vector<std::string> other_ops;
|
2012-04-23 21:05:26 +02:00
|
|
|
append_vector(other_ops, bitOps);
|
2013-02-10 07:43:09 +01:00
|
|
|
append_vector(other_ops, comparisonOps);
|
2012-04-23 21:05:26 +02:00
|
|
|
append_vector(other_ops, logicalOps);
|
2011-11-06 21:20:13 +01:00
|
|
|
append_vector(other_ops, extendedOps);
|
|
|
|
append_vector(other_ops, assignmentOps);
|
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
|
|
|
|
for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-11-06 21:20:13 +01:00
|
|
|
tok.str(*other_op);
|
|
|
|
ASSERT_EQUALS_MSG(false, tok.isArithmeticalOp(), "Failing arithmetical operator: " + *other_op);
|
|
|
|
}
|
|
|
|
}
|
2011-11-06 18:55:02 +01:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void isOp() const {
|
2011-11-06 21:20:13 +01:00
|
|
|
std::vector<std::string> test_ops;
|
|
|
|
append_vector(test_ops, arithmeticalOps);
|
2012-04-23 21:05:26 +02:00
|
|
|
append_vector(test_ops, bitOps);
|
2013-02-10 07:43:09 +01:00
|
|
|
append_vector(test_ops, comparisonOps);
|
2012-04-23 21:05:26 +02:00
|
|
|
append_vector(test_ops, logicalOps);
|
2013-02-28 21:50:29 +01:00
|
|
|
append_vector(test_ops, assignmentOps);
|
2011-11-06 21:20:13 +01:00
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
|
|
|
|
for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-11-06 21:20:13 +01:00
|
|
|
tok.str(*test_op);
|
|
|
|
ASSERT_EQUALS(true, tok.isOp());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Negative test against other operators
|
|
|
|
std::vector<std::string> other_ops;
|
|
|
|
append_vector(other_ops, extendedOps);
|
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
|
|
|
|
for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-11-06 21:20:13 +01:00
|
|
|
tok.str(*other_op);
|
|
|
|
ASSERT_EQUALS_MSG(false, tok.isOp(), "Failing normal operator: " + *other_op);
|
|
|
|
}
|
2011-11-06 18:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void isConstOp() const {
|
2013-02-28 21:50:29 +01:00
|
|
|
std::vector<std::string> test_ops;
|
|
|
|
append_vector(test_ops, arithmeticalOps);
|
|
|
|
append_vector(test_ops, bitOps);
|
|
|
|
append_vector(test_ops, comparisonOps);
|
|
|
|
append_vector(test_ops, logicalOps);
|
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
|
|
|
|
for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2013-02-28 21:50:29 +01:00
|
|
|
tok.str(*test_op);
|
|
|
|
ASSERT_EQUALS(true, tok.isConstOp());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Negative test against other operators
|
|
|
|
std::vector<std::string> other_ops;
|
|
|
|
append_vector(other_ops, extendedOps);
|
|
|
|
append_vector(other_ops, assignmentOps);
|
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
|
|
|
|
for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2013-02-28 21:50:29 +01:00
|
|
|
tok.str(*other_op);
|
|
|
|
ASSERT_EQUALS_MSG(false, tok.isConstOp(), "Failing normal operator: " + *other_op);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void isExtendedOp() const {
|
2011-11-06 21:20:13 +01:00
|
|
|
std::vector<std::string> test_ops;
|
|
|
|
append_vector(test_ops, arithmeticalOps);
|
2012-04-23 21:05:26 +02:00
|
|
|
append_vector(test_ops, bitOps);
|
2013-02-10 07:43:09 +01:00
|
|
|
append_vector(test_ops, comparisonOps);
|
2012-04-23 21:05:26 +02:00
|
|
|
append_vector(test_ops, logicalOps);
|
2011-11-06 21:20:13 +01:00
|
|
|
append_vector(test_ops, extendedOps);
|
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
|
|
|
|
for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-11-06 21:20:13 +01:00
|
|
|
tok.str(*test_op);
|
|
|
|
ASSERT_EQUALS(true, tok.isExtendedOp());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Negative test against assignment operators
|
|
|
|
std::vector<std::string>::const_iterator other_op, other_ops_end = assignmentOps.end();
|
|
|
|
for (other_op = assignmentOps.begin(); other_op != other_ops_end; ++other_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-11-06 21:20:13 +01:00
|
|
|
tok.str(*other_op);
|
|
|
|
ASSERT_EQUALS_MSG(false, tok.isExtendedOp(), "Failing assignment operator: " + *other_op);
|
|
|
|
}
|
2011-11-06 18:19:27 +01:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void isAssignmentOp() const {
|
2011-11-06 21:20:13 +01:00
|
|
|
std::vector<std::string>::const_iterator test_op, test_ops_end = assignmentOps.end();
|
|
|
|
for (test_op = assignmentOps.begin(); test_op != test_ops_end; ++test_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-11-06 21:20:13 +01:00
|
|
|
tok.str(*test_op);
|
|
|
|
ASSERT_EQUALS(true, tok.isAssignmentOp());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Negative test against other operators
|
|
|
|
std::vector<std::string> other_ops;
|
|
|
|
append_vector(other_ops, arithmeticalOps);
|
2012-04-23 21:05:26 +02:00
|
|
|
append_vector(other_ops, bitOps);
|
2013-02-10 07:43:09 +01:00
|
|
|
append_vector(other_ops, comparisonOps);
|
2012-04-23 21:05:26 +02:00
|
|
|
append_vector(other_ops, logicalOps);
|
2011-11-06 21:20:13 +01:00
|
|
|
append_vector(other_ops, extendedOps);
|
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
|
|
|
|
for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-11-06 21:20:13 +01:00
|
|
|
tok.str(*other_op);
|
|
|
|
ASSERT_EQUALS_MSG(false, tok.isAssignmentOp(), "Failing assignment operator: " + *other_op);
|
|
|
|
}
|
2011-11-06 18:19:27 +01:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void operators() const {
|
2012-04-23 21:05:26 +02:00
|
|
|
std::vector<std::string>::const_iterator test_op;
|
|
|
|
for (test_op = extendedOps.begin(); test_op != extendedOps.end(); ++test_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str(*test_op);
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT_EQUALS(Token::eExtendedOp, tok.tokType());
|
2012-04-23 21:05:26 +02:00
|
|
|
}
|
|
|
|
for (test_op = logicalOps.begin(); test_op != logicalOps.end(); ++test_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str(*test_op);
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT_EQUALS(Token::eLogicalOp, tok.tokType());
|
2012-04-23 21:05:26 +02:00
|
|
|
}
|
|
|
|
for (test_op = bitOps.begin(); test_op != bitOps.end(); ++test_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str(*test_op);
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT_EQUALS(Token::eBitOp, tok.tokType());
|
2012-04-23 21:05:26 +02:00
|
|
|
}
|
2013-02-10 07:43:09 +01:00
|
|
|
for (test_op = comparisonOps.begin(); test_op != comparisonOps.end(); ++test_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str(*test_op);
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT_EQUALS(Token::eComparisonOp, tok.tokType());
|
2012-04-23 21:05:26 +02:00
|
|
|
}
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str("++");
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT_EQUALS(Token::eIncDecOp, tok.tokType());
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str("--");
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT_EQUALS(Token::eIncDecOp, tok.tokType());
|
2012-04-23 21:05:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void literals() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2012-04-23 21:05:26 +02:00
|
|
|
|
|
|
|
tok.str("\"foo\"");
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT(tok.tokType() == Token::eString);
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str("\"\"");
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT(tok.tokType() == Token::eString);
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str("'f'");
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT(tok.tokType() == Token::eChar);
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str("12345");
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT(tok.tokType() == Token::eNumber);
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str("-55");
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT(tok.tokType() == Token::eNumber);
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str("true");
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT(tok.tokType() == Token::eBoolean);
|
2012-04-23 21:05:26 +02:00
|
|
|
tok.str("false");
|
2015-08-14 20:46:13 +02:00
|
|
|
ASSERT(tok.tokType() == Token::eBoolean);
|
2012-04-23 21:05:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void isStandardType() const {
|
2011-11-06 21:20:13 +01:00
|
|
|
std::vector<std::string> standard_types;
|
2019-09-25 15:25:19 +02:00
|
|
|
standard_types.emplace_back("bool");
|
|
|
|
standard_types.emplace_back("char");
|
|
|
|
standard_types.emplace_back("short");
|
|
|
|
standard_types.emplace_back("int");
|
|
|
|
standard_types.emplace_back("long");
|
|
|
|
standard_types.emplace_back("float");
|
|
|
|
standard_types.emplace_back("double");
|
|
|
|
standard_types.emplace_back("size_t");
|
2011-11-06 21:20:13 +01:00
|
|
|
|
|
|
|
std::vector<std::string>::const_iterator test_op, test_ops_end = standard_types.end();
|
|
|
|
for (test_op = standard_types.begin(); test_op != test_ops_end; ++test_op) {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-11-06 21:20:13 +01:00
|
|
|
tok.str(*test_op);
|
|
|
|
ASSERT_EQUALS_MSG(true, tok.isStandardType(), "Failing standard type: " + *test_op);
|
|
|
|
}
|
2011-11-06 18:55:02 +01:00
|
|
|
|
|
|
|
// Negative test
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-11-06 18:55:02 +01:00
|
|
|
tok.str("string");
|
|
|
|
ASSERT_EQUALS(false, tok.isStandardType());
|
2011-11-09 21:45:59 +01:00
|
|
|
|
|
|
|
// Change back to standard type
|
|
|
|
tok.str("int");
|
|
|
|
ASSERT_EQUALS(true, tok.isStandardType());
|
2016-11-26 22:39:47 +01:00
|
|
|
|
|
|
|
// token can't be both type and variable
|
|
|
|
tok.str("abc");
|
|
|
|
tok.isStandardType(true);
|
|
|
|
tok.varId(123);
|
|
|
|
ASSERT_EQUALS(false, tok.isStandardType());
|
2011-11-06 18:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void updateProperties() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-10-23 20:38:03 +02:00
|
|
|
tok.str("foobar");
|
|
|
|
|
|
|
|
ASSERT_EQUALS(true, tok.isName());
|
|
|
|
ASSERT_EQUALS(false, tok.isNumber());
|
|
|
|
|
|
|
|
tok.str("123456");
|
|
|
|
|
|
|
|
ASSERT_EQUALS(false, tok.isName());
|
|
|
|
ASSERT_EQUALS(true, tok.isNumber());
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void isNameGuarantees1() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-10-23 20:38:03 +02:00
|
|
|
tok.str("Name");
|
|
|
|
ASSERT_EQUALS(true, tok.isName());
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void isNameGuarantees2() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-10-23 20:38:03 +02:00
|
|
|
tok.str("_name");
|
|
|
|
ASSERT_EQUALS(true, tok.isName());
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void isNameGuarantees3() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-10-23 20:38:03 +02:00
|
|
|
tok.str("_123");
|
|
|
|
ASSERT_EQUALS(true, tok.isName());
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void isNameGuarantees4() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-10-23 20:38:03 +02:00
|
|
|
tok.str("123456");
|
|
|
|
ASSERT_EQUALS(false, tok.isName());
|
|
|
|
ASSERT_EQUALS(true, tok.isNumber());
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void isNameGuarantees5() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2011-10-23 20:38:03 +02:00
|
|
|
tok.str("a123456");
|
|
|
|
ASSERT_EQUALS(true, tok.isName());
|
|
|
|
ASSERT_EQUALS(false, tok.isNumber());
|
|
|
|
}
|
2012-04-18 16:02:03 +02:00
|
|
|
|
2016-07-29 13:42:11 +02:00
|
|
|
void isNameGuarantees6() const {
|
2018-05-25 07:15:05 +02:00
|
|
|
Token tok;
|
2016-07-29 13:42:11 +02:00
|
|
|
tok.str("$f");
|
|
|
|
ASSERT_EQUALS(true, tok.isName());
|
|
|
|
}
|
2012-04-18 16:02:03 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void canFindMatchingBracketsNeedsOpen() const {
|
2012-04-18 16:02:03 +02:00
|
|
|
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
|
|
|
|
|
2018-09-24 15:08:16 +02:00
|
|
|
const Token* const t = var.tokens()->findClosingBracket();
|
2014-02-16 10:32:10 +01:00
|
|
|
ASSERT(t == nullptr);
|
2012-04-18 16:02:03 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void canFindMatchingBracketsInnerPair() const {
|
2012-04-18 16:02:03 +02:00
|
|
|
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
|
|
|
|
|
2019-06-16 10:09:38 +02:00
|
|
|
const Token * const t = var.tokens()->tokAt(7)->findClosingBracket();
|
2012-04-18 16:02:03 +02:00
|
|
|
ASSERT_EQUALS(">", t->str());
|
|
|
|
ASSERT(var.tokens()->tokAt(9) == t);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void canFindMatchingBracketsOuterPair() const {
|
2012-04-18 16:02:03 +02:00
|
|
|
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
|
|
|
|
|
2018-09-24 15:08:16 +02:00
|
|
|
const Token* const t = var.tokens()->tokAt(3)->findClosingBracket();
|
2012-04-18 16:02:03 +02:00
|
|
|
ASSERT_EQUALS(">", t->str());
|
|
|
|
ASSERT(var.tokens()->tokAt(10) == t);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void canFindMatchingBracketsWithTooManyClosing() const {
|
2021-02-20 12:58:42 +01:00
|
|
|
givenACodeSampleToTokenize var("X< 1>2 > x1;");
|
2012-04-18 16:02:03 +02:00
|
|
|
|
2018-09-24 15:08:16 +02:00
|
|
|
const Token* const t = var.tokens()->next()->findClosingBracket();
|
2012-04-18 16:02:03 +02:00
|
|
|
ASSERT_EQUALS(">", t->str());
|
|
|
|
ASSERT(var.tokens()->tokAt(3) == t);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void canFindMatchingBracketsWithTooManyOpening() const {
|
2021-02-20 12:58:42 +01:00
|
|
|
givenACodeSampleToTokenize var("X < (2 < 1) > x1;");
|
2012-04-18 16:02:03 +02:00
|
|
|
|
2013-07-31 10:30:20 +02:00
|
|
|
const Token* t = var.tokens()->next()->findClosingBracket();
|
2014-02-16 10:32:10 +01:00
|
|
|
ASSERT(t != nullptr && t->str() == ">");
|
2012-04-18 16:02:03 +02:00
|
|
|
|
2013-07-31 10:30:20 +02:00
|
|
|
t = var.tokens()->tokAt(4)->findClosingBracket();
|
2016-02-04 10:00:54 +01:00
|
|
|
ASSERT(t == nullptr);
|
2012-04-18 16:02:03 +02:00
|
|
|
}
|
2017-07-21 09:16:42 +02:00
|
|
|
|
2018-01-01 15:20:21 +01:00
|
|
|
void findClosingBracket() {
|
|
|
|
givenACodeSampleToTokenize var("template<typename X, typename...Y> struct S : public Fred<Wilma<Y...>> {}");
|
|
|
|
|
2018-09-24 15:08:16 +02:00
|
|
|
const Token* const t = var.tokens()->next()->findClosingBracket();
|
2018-01-01 15:20:21 +01:00
|
|
|
ASSERT(Token::simpleMatch(t, "> struct"));
|
|
|
|
}
|
|
|
|
|
2017-07-21 09:17:25 +02:00
|
|
|
void expressionString() {
|
2017-07-21 09:16:42 +02:00
|
|
|
givenACodeSampleToTokenize var1("void f() { *((unsigned long long *)x) = 0; }");
|
2018-09-24 15:08:16 +02:00
|
|
|
const Token *const tok1 = Token::findsimplematch(var1.tokens(), "*");
|
2017-07-21 09:17:25 +02:00
|
|
|
ASSERT_EQUALS("*((unsigned long long*)x)", tok1->expressionString());
|
2017-07-21 09:16:42 +02:00
|
|
|
|
|
|
|
givenACodeSampleToTokenize var2("typedef unsigned long long u64; void f() { *((u64 *)x) = 0; }");
|
2018-09-24 15:08:16 +02:00
|
|
|
const Token *const tok2 = Token::findsimplematch(var2.tokens(), "*");
|
2017-07-21 09:17:25 +02:00
|
|
|
ASSERT_EQUALS("*((unsigned long long*)x)", tok2->expressionString());
|
2018-12-14 18:56:09 +01:00
|
|
|
|
2020-04-11 17:36:11 +02:00
|
|
|
givenACodeSampleToTokenize data3("void f() { return (t){1,2}; }");
|
|
|
|
ASSERT_EQUALS("return(t){1,2}", data3.tokens()->tokAt(5)->expressionString());
|
2019-04-25 07:08:13 +02:00
|
|
|
|
2020-04-11 17:36:11 +02:00
|
|
|
givenACodeSampleToTokenize data4("void f() { return L\"a\"; }");
|
|
|
|
ASSERT_EQUALS("returnL\"a\"", data4.tokens()->tokAt(5)->expressionString());
|
2019-10-16 11:41:33 +02:00
|
|
|
|
2020-04-11 17:36:11 +02:00
|
|
|
givenACodeSampleToTokenize data5("void f() { return U\"a\"; }");
|
|
|
|
ASSERT_EQUALS("returnU\"a\"", data5.tokens()->tokAt(5)->expressionString());
|
2020-09-04 20:43:54 +02:00
|
|
|
|
|
|
|
givenACodeSampleToTokenize data6("x = \"\\0\\x1\\x2\\x3\\x4\\x5\\x6\\x7\";");
|
|
|
|
ASSERT_EQUALS("x=\"\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\"", data6.tokens()->next()->expressionString());
|
2017-07-21 09:17:25 +02:00
|
|
|
}
|
2019-07-27 08:25:07 +02:00
|
|
|
|
|
|
|
void hasKnownIntValue() {
|
|
|
|
// pointer might be NULL
|
|
|
|
ValueFlow::Value v1(0);
|
|
|
|
|
|
|
|
// pointer points at buffer that is 2 bytes
|
|
|
|
ValueFlow::Value v2(2);
|
2021-01-02 09:30:00 +01:00
|
|
|
v2.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE;
|
2019-07-27 08:25:07 +02:00
|
|
|
v2.setKnown();
|
|
|
|
|
|
|
|
Token token;
|
|
|
|
ASSERT_EQUALS(true, token.addValue(v1));
|
|
|
|
ASSERT_EQUALS(true, token.addValue(v2));
|
|
|
|
ASSERT_EQUALS(false, token.hasKnownIntValue());
|
|
|
|
}
|
2008-12-18 22:28:57 +01:00
|
|
|
};
|
|
|
|
|
2010-04-05 10:15:30 +02:00
|
|
|
REGISTER_TEST(TestToken)
|