Merge branch 'master' of github.com:danmar/cppcheck

This commit is contained in:
Zachary Blair 2012-01-19 23:02:33 -08:00
commit 0415444e28
17 changed files with 397 additions and 212 deletions

View File

@ -11,34 +11,73 @@
class SelectFilesModel : public QFileSystemModel { class SelectFilesModel : public QFileSystemModel {
private: private:
QStringList selected; /**
QStringList unselected; * paths that are user-checked. on the screen all children
* for these paths will appear to be checked too unless
* they are "unchecked".
*/
QStringList checked;
/**
* paths that are user-unchecked.
*/
QStringList unchecked;
/** /**
* Get index in stringlist where start of string matches. If * Get index in stringlist where start of string matches. If
* many strings in the stringlist match then return the index * many strings in the stringlist match then return the index
* for the longest string. * for the longest string.
* \param s stringlist with filepaths * \param paths stringlist with filepaths
* \param filepath the filepath that is matched against the stringlist * \param filepath the filepath that is matched against the stringlist
*/ */
int getindex(const QStringList &s, const QString &filepath) const { int getindex(const QStringList &paths, const QString &filepath) const {
int matchlen = 0; int matchlen = 0;
int matchindex = -1; int matchindex = -1;
for (int i = 0; i < s.size(); ++i) { for (int i = 0; i < paths.size(); ++i) {
if (filepath.startsWith(s[i])) { if (filepath.startsWith(paths[i])) {
// not a real match of paths.. // not a real match of paths..
if (s[i].size() < filepath.size() && filepath[s[i].size()] != '/') if (paths[i].size() < filepath.size() && filepath[paths[i].size()] != '/')
continue; continue;
// paths match. the return value is the index for the // paths match. the return value is the index for the
// longest match // longest match
if (s[i].size() > matchlen) if (paths[i].size() > matchlen)
matchindex = i; matchindex = i;
} }
} }
return matchindex; return matchindex;
} }
/**
* Is filepath partially checked?
* \param filepath the filepath to investigate
* \param checkindex result from getindex(checked,filepath). If not given the getindex will be called.
* \return true if filepath is partially checked
*/
bool partiallyChecked(const QString &filepath, int checkindex = -2) const {
const QString filepath2 = filepath.endsWith("/") ? filepath : (filepath + "/");
for (int i = 0; i < unchecked.size(); ++i) {
if (unchecked[i].startsWith(filepath2)) {
return true;
}
}
if (checkindex == -2)
checkindex = getindex(checked, filepath);
if (checkindex == -1) {
for (int i = 0; i < checked.size(); ++i) {
if (checked[i].startsWith(filepath2)) {
return true;
}
}
}
return false;
}
public: public:
SelectFilesModel() : QFileSystemModel() { SelectFilesModel() : QFileSystemModel() {
class FileLister : private FileList { class FileLister : private FileList {
@ -61,14 +100,21 @@ public:
QVariant data(const QModelIndex& index, int role=Qt::DisplayRole) const { QVariant data(const QModelIndex& index, int role=Qt::DisplayRole) const {
if (role == Qt::CheckStateRole) { if (role == Qt::CheckStateRole) {
const QString filepath = filePath(index); const QString filepath = filePath(index);
int selindex = getindex(selected, filepath); const int checkindex = getindex(checked, filepath);
int unselindex = getindex(unselected, filepath); const int uncheckindex = getindex(unchecked, filepath);
if (selindex >= 0 && unselindex == -1)
// If some children are not checked then this item should be partially checked..
if (partiallyChecked(filepath, checkindex))
return Qt::PartiallyChecked;
// Is item selected but not unselected?
if (checkindex >= 0 && uncheckindex == -1)
return Qt::Checked; return Qt::Checked;
if (selindex >= 0 && unselindex >= 0 && if (checkindex >= 0 && uncheckindex >= 0 &&
selected[selindex].size() > unselected[unselindex].size()) checked[checkindex].size() > unchecked[uncheckindex].size())
return Qt::Checked; return Qt::Checked;
// Item is either not selected at all or else it is unselected
return Qt::Unchecked; return Qt::Unchecked;
} }
return QFileSystemModel::data(index, role); return QFileSystemModel::data(index, role);
@ -77,35 +123,49 @@ public:
bool setData(const QModelIndex& index, const QVariant& value, int role) { bool setData(const QModelIndex& index, const QVariant& value, int role) {
if (role == Qt::CheckStateRole) { if (role == Qt::CheckStateRole) {
const QString filepath = filePath(index); const QString filepath = filePath(index);
if (unselected.indexOf(filepath) != -1) {
bool partiallychecked = partiallyChecked(filepath);
if (unchecked.indexOf(filepath) != -1) {
// remove unchecked path // remove unchecked path
unselected.removeAll(filepath); unchecked.removeAll(filepath);
} else if (selected.indexOf(filepath) != -1) { } else if (partiallychecked || checked.indexOf(filepath) != -1) {
// remove child selected paths // remove child selected paths
for (int i = selected.size() - 1; i >= 0; --i) { for (int i = checked.size() - 1; i >= 0; --i) {
if (selected[i].startsWith(filepath)) if (checked[i].startsWith(filepath))
selected.removeAt(i); checked.removeAt(i);
} }
// remove child unselected paths // remove child unselected paths
for (int i = unselected.size() - 1; i >= 0; --i) { for (int i = unchecked.size() - 1; i >= 0; --i) {
if (unselected[i].startsWith(filepath)) if (unchecked[i].startsWith(filepath))
unselected.removeAt(i); unchecked.removeAt(i);
} }
// If partialChecked then select this item
if (partiallychecked)
checked.append(filepath);
} else { } else {
int selindex = getindex(selected, filepath); const int checkindex = getindex(checked, filepath);
int unselindex = getindex(unselected, filepath); const int uncheckindex = getindex(unchecked, filepath);
if (selindex == -1) if (checkindex == -1)
selected.append(filepath); checked.append(filepath);
else if (unselindex >= 0 && selected[selindex].size() < unselected[unselindex].size()) else if (uncheckindex >= 0 && checked[checkindex].size() < unchecked[uncheckindex].size())
selected.append(filepath); checked.append(filepath);
else else
unselected.append(filepath); unchecked.append(filepath);
} }
if (rowCount(index) > 0) if (rowCount(index) > 0)
emit(dataChanged(index, index.child(rowCount(index)-1,0))); emit(dataChanged(index, index.child(rowCount(index)-1,0)));
// update parents
QModelIndex parent = index.parent();
while (parent != QModelIndex()) {
emit(dataChanged(parent,parent));
parent = parent.parent();
}
return true; return true;
} }
return QFileSystemModel::setData(index, value, role); return QFileSystemModel::setData(index, value, role);
@ -114,20 +174,20 @@ public:
QStringList getFiles() const { QStringList getFiles() const {
QStringList ret; QStringList ret;
// List all files in "selected" folders.. // List all files in "checked" folders..
FileList fileLister; FileList fileLister;
fileLister.AddPathList(selected); fileLister.AddPathList(checked);
ret = fileLister.GetFileList(); ret = fileLister.GetFileList();
// Remove all items from ret that are unselected but not selected.. // Remove all items from ret that are unchecked but not checked..
for (int i = ret.size() - 1; i >= 0; i--) { for (int i = ret.size() - 1; i >= 0; i--) {
int unselindex = getindex(unselected, ret[i]); int uncheckindex = getindex(unchecked, ret[i]);
if (unselindex == -1) if (uncheckindex == -1)
continue; continue;
// both selected and unselected, check which to rely on // both checked and unchecked, check which to rely on
int selindex = getindex(selected, ret[i]); int checkindex = getindex(checked, ret[i]);
if (selected[selindex].size() < unselected[unselindex].size()) if (checked[checkindex].size() < unchecked[uncheckindex].size())
ret.removeAt(i); ret.removeAt(i);
} }

View File

@ -442,15 +442,7 @@ void CheckClass::initializeVarList(const Function &func, std::list<std::string>
// the function is external and it's neither friend nor inherited virtual function. // the function is external and it's neither friend nor inherited virtual function.
// assume all variables that are passed to it are initialized.. // assume all variables that are passed to it are initialized..
else { else {
unsigned int indentlevel2 = 0; for (const Token *tok = ftok->tokAt(2); tok && tok != ftok->next()->link(); tok = tok->next()) {
for (const Token *tok = ftok->tokAt(2); tok; tok = tok->next()) {
if (tok->str() == "(")
++indentlevel2;
else if (tok->str() == ")") {
if (indentlevel2 == 0)
break;
--indentlevel2;
}
if (tok->isName()) { if (tok->isName()) {
assignVar(tok->str(), scope, usage); assignVar(tok->str(), scope, usage);
} }

View File

@ -434,23 +434,14 @@ void CheckNullPointer::nullPointerLinkedList()
const std::string varname(tok2->str()); const std::string varname(tok2->str());
// Check usage of dereferenced variable in the loop.. // Check usage of dereferenced variable in the loop..
unsigned int indentlevel3 = 0; for (const Token *tok3 = i->classStart; tok3 && tok3 != i->classEnd; tok3 = tok3->next()) {
for (const Token *tok3 = tok1->next()->link(); tok3; tok3 = tok3->next()) {
if (tok3->str() == "{")
++indentlevel3;
else if (tok3->str() == "}") {
if (indentlevel3 <= 1)
break;
--indentlevel3;
}
// TODO: are there false negatives for "while ( %varid% ||" // TODO: are there false negatives for "while ( %varid% ||"
else if (Token::Match(tok3, "while ( %varid% &&|)", varid)) { if (Token::Match(tok3, "while ( %varid% &&|)", varid)) {
// Make sure there is a "break" or "return" inside the loop. // Make sure there is a "break" or "return" inside the loop.
// Without the "break" a null pointer could be dereferenced in the // Without the "break" a null pointer could be dereferenced in the
// for statement. // for statement.
// indentlevel4 is a counter for { and }. When scanning the code with tok4 // indentlevel4 is a counter for { and }. When scanning the code with tok4
unsigned int indentlevel4 = indentlevel3; unsigned int indentlevel4 = 1;
for (const Token *tok4 = tok3->next()->link(); tok4; tok4 = tok4->next()) { for (const Token *tok4 = tok3->next()->link(); tok4; tok4 = tok4->next()) {
if (tok4->str() == "{") if (tok4->str() == "{")
++indentlevel4; ++indentlevel4;

View File

@ -1212,6 +1212,7 @@ void CheckOther::invalidScanf()
} }
else if (std::isalpha(formatstr[i])) { else if (std::isalpha(formatstr[i])) {
if (formatstr[i] != 'c') // #3490 - field width limits are not necessary for %c
invalidScanfError(tok); invalidScanfError(tok);
format = false; format = false;
} }
@ -1747,8 +1748,7 @@ void CheckOther::checkVariableScope()
continue; continue;
// Walk through all tokens.. // Walk through all tokens..
unsigned int indentlevel = 0; for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
for (const Token *tok = scope->classStart; tok; tok = tok->next()) {
// Skip function local class and struct declarations.. // Skip function local class and struct declarations..
if ((tok->str() == "class") || (tok->str() == "struct") || (tok->str() == "union")) { if ((tok->str() == "class") || (tok->str() == "struct") || (tok->str() == "union")) {
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) { for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
@ -1764,15 +1764,7 @@ void CheckOther::checkVariableScope()
break; break;
} }
else if (tok->str() == "{") { if (Token::Match(tok, "[{};]")) {
++indentlevel;
} else if (tok->str() == "}") {
if (!indentlevel)
break;
--indentlevel;
}
if (indentlevel > 0 && Token::Match(tok, "[{};]")) {
// First token of statement.. // First token of statement..
const Token *tok1 = tok->next(); const Token *tok1 = tok->next();
if (! tok1) if (! tok1)
@ -2004,7 +1996,7 @@ void CheckOther::checkCharVariable()
continue; continue;
// This is an error.. // This is an error..
charBitOpError(tok); charBitOpError(tok->tokAt(4));
} }
else if (Token::Match(tok, "[;{}] %var% = %any% [&|] ( * %var% ) ;")) { else if (Token::Match(tok, "[;{}] %var% = %any% [&|] ( * %var% ) ;")) {
@ -2021,7 +2013,7 @@ void CheckOther::checkCharVariable()
continue; continue;
// This is an error.. // This is an error..
charBitOpError(tok); charBitOpError(tok->tokAt(4));
} }
} }
} }

View File

@ -67,6 +67,7 @@ public:
checkOther.checkDuplicateExpression(); checkOther.checkDuplicateExpression();
checkOther.checkUnreachableCode(); checkOther.checkUnreachableCode();
checkOther.checkSuspiciousSemicolon(); checkOther.checkSuspiciousSemicolon();
checkOther.checkWrongPrintfScanfArguments();
// information checks // information checks
checkOther.checkVariableScope(); checkOther.checkVariableScope();
@ -91,7 +92,6 @@ public:
checkOther.checkCCTypeFunctions(); checkOther.checkCCTypeFunctions();
checkOther.checkFflushOnInputStream(); checkOther.checkFflushOnInputStream();
checkOther.invalidScanf(); checkOther.invalidScanf();
checkOther.checkWrongPrintfScanfArguments();
checkOther.checkCoutCerrMisusage(); checkOther.checkCoutCerrMisusage();
checkOther.checkIncorrectLogicOperator(); checkOther.checkIncorrectLogicOperator();

View File

@ -265,35 +265,16 @@ void CheckStl::stlOutOfBounds()
continue; continue;
// check if the for loop condition is wrong // check if the for loop condition is wrong
unsigned int indent = 0; for (const Token *tok2 = tok->tokAt(2); tok2 && tok2 != tok->next()->link(); tok2 = tok2->next()) {
for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) {
if (tok2->str() == "(")
++indent;
else if (tok2->str() == ")") {
if (indent == 0)
break;
--indent;
}
if (Token::Match(tok2, "; %var% <= %var% . size ( ) ;")) { if (Token::Match(tok2, "; %var% <= %var% . size ( ) ;")) {
// Count { and } for tok3
unsigned int indent3 = 0;
// variable id for loop variable. // variable id for loop variable.
unsigned int numId = tok2->next()->varId(); unsigned int numId = tok2->next()->varId();
// variable id for the container variable // variable id for the container variable
unsigned int varId = tok2->tokAt(3)->varId(); unsigned int varId = tok2->tokAt(3)->varId();
for (const Token *tok3 = tok2->tokAt(8); tok3; tok3 = tok3->next()) { for (const Token *tok3 = tok2->tokAt(8); tok3 && tok3 != i->classEnd; tok3 = tok3->next()) {
if (tok3->str() == "{") if (tok3->varId() == varId) {
++indent3;
else if (tok3->str() == "}") {
if (indent3 <= 1)
break;
--indent3;
} else if (tok3->varId() == varId) {
if (Token::simpleMatch(tok3->next(), ". size ( )")) if (Token::simpleMatch(tok3->next(), ". size ( )"))
break; break;
else if (Token::Match(tok3->next(), "[ %varid% ]", numId)) else if (Token::Match(tok3->next(), "[ %varid% ]", numId))

View File

@ -830,15 +830,7 @@ private:
// Check that the variable hasn't been initialized and // Check that the variable hasn't been initialized and
// that it isn't initialized in the body.. // that it isn't initialized in the body..
if (varid1.find(varid) == varid1.end()) { if (varid1.find(varid) == varid1.end()) {
unsigned int indentlevel = 0; for (const Token *tok3 = tok2->tokAt(5); tok3 && tok3 != tok2->linkAt(4); tok3 = tok3->next()) {
for (const Token *tok3 = tok2->tokAt(5); tok3; tok3 = tok3->next()) {
if (tok3->str() == "{")
++indentlevel;
else if (tok3->str() == "}") {
if (indentlevel == 0)
break;
--indentlevel;
}
if (tok3->varId() == varid) { if (tok3->varId() == varid) {
varid = 0; // variable is used.. maybe it's initialized. clear the variable id. varid = 0; // variable is used.. maybe it's initialized. clear the variable id.
break; break;

View File

@ -2546,7 +2546,7 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
std::map<std::string, PreprocessorMacro *>::iterator it; std::map<std::string, PreprocessorMacro *>::iterator it;
for (it = macros.begin(); it != macros.end(); ++it) for (it = macros.begin(); it != macros.end(); ++it)
delete it->second; delete it->second;
macros.clear();
return ""; return "";
} }
@ -2628,7 +2628,7 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
std::map<std::string, PreprocessorMacro *>::iterator iter; std::map<std::string, PreprocessorMacro *>::iterator iter;
for (iter = macros.begin(); iter != macros.end(); ++iter) for (iter = macros.begin(); iter != macros.end(); ++iter)
delete iter->second; delete iter->second;
macros.clear();
return ""; return "";
} }
@ -2681,6 +2681,7 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
for (std::map<std::string, PreprocessorMacro *>::iterator it = macros.begin(); it != macros.end(); ++it) for (std::map<std::string, PreprocessorMacro *>::iterator it = macros.begin(); it != macros.end(); ++it)
delete it->second; delete it->second;
macros.clear();
return ostr.str(); return ostr.str();
} }

View File

@ -76,7 +76,7 @@ const Token* TemplateSimplifier::hasComplicatedSyntaxErrorsInTemplates(Token *to
// check for more complicated syntax errors when using templates.. // check for more complicated syntax errors when using templates..
for (const Token *tok = tokens; tok; tok = tok->next()) { for (const Token *tok = tokens; tok; tok = tok->next()) {
// skip executing scopes.. // skip executing scopes..
if (Token::Match(tok, ") const| {") || Token::Match(tok, "[,=] {")) { if (Token::simpleMatch(tok, ") {") || Token::Match(tok, ") %var% {") || Token::Match(tok, "[,=] {")) {
while (tok->str() != "{") while (tok->str() != "{")
tok = tok->next(); tok = tok->next();
tok = tok->link(); tok = tok->link();
@ -243,6 +243,7 @@ void TemplateSimplifier::removeTemplates(Token *tok)
} else if (tok2->str() == ")") { // garbage code! (#3504) } else if (tok2->str() == ")") { // garbage code! (#3504)
Token::eraseTokens(tok,tok2); Token::eraseTokens(tok,tok2);
tok->deleteThis(); tok->deleteThis();
break;
} }
else if (tok2->str() == "{") { else if (tok2->str() == "{") {
@ -534,8 +535,16 @@ void TemplateSimplifier::simplifyTemplatesUseDefaultArgumentValues(const std::li
} }
for (std::list<Token *>::iterator it = eq.begin(); it != eq.end(); ++it) { for (std::list<Token *>::iterator it = eq.begin(); it != eq.end(); ++it) {
(*it)->deleteNext(); Token * const eqtok = *it;
(*it)->deleteThis(); const Token *tok2;
for (tok2 = eqtok->next(); tok2; tok2 = tok2->next()) {
if (tok2->str() == "(")
tok2 = tok2->link();
else if (tok2->str() == "," || tok2->str() == ">")
break;
}
Token::eraseTokens(eqtok, tok2);
eqtok->deleteThis();
} }
} }
} }

View File

@ -3892,6 +3892,10 @@ void Tokenizer::simplifyFlowControl()
} }
if (tok->str() == "{") { if (tok->str() == "{") {
if (tok->previous() && tok->previous()->str() == "=") {
tok = tok->link();
continue;
}
beginindent = tok; beginindent = tok;
++indentlevel; ++indentlevel;
} else if (tok->str() == "}") { } else if (tok->str() == "}") {
@ -4144,20 +4148,25 @@ bool Tokenizer::simplifyIfAddBraces()
} }
if (Token::Match(tok, "if|for|while|BOOST_FOREACH (")) { if (Token::Match(tok, "if|for|while|BOOST_FOREACH (")) {
if (tok->strAt(2) == ")") {
//no arguments inside round braces, abort
syntaxError(tok);
return false;
}
// don't add "{}" around ";" in "do {} while();" (#609) // don't add "{}" around ";" in "do {} while();" (#609)
const Token *prev = tok->previous(); const Token *prev = tok->previous();
if (Token::simpleMatch(prev, "} while") && if (prev && prev->str() == "}" && tok->str() == "while") {
prev->link() && prev = prev->link()->previous();
prev->link()->previous() && if (prev && prev->str() == "do")
prev->link()->previous()->str() == "do") {
continue; continue;
} }
// Goto the ending ')' // Goto the ending ')'
tok = tok->next()->link(); tok = tok->next()->link();
// ')' should be followed by '{' // there's already '{' after ')', don't bother
if (Token::simpleMatch(tok, ") {")) if (tok->next() && tok->next()->str() == "{")
continue; continue;
} }
@ -4171,11 +4180,10 @@ bool Tokenizer::simplifyIfAddBraces()
continue; continue;
} }
// If there is no code after the if(), abort // If there is no code after the 'if()' or 'else', abort
if (!tok->next()) { if (!tok->next()) {
// This is a syntax error and we should call syntaxError() and return false but syntaxError(tok);
// many tokenizer tests are written with this syntax error so just ignore it. return false;
return true;
} }
// insert open brace.. // insert open brace..
@ -4183,7 +4191,7 @@ bool Tokenizer::simplifyIfAddBraces()
tok = tok->next(); tok = tok->next();
Token *tempToken = tok; Token *tempToken = tok;
bool innerIf = Token::simpleMatch(tempToken->next(), "if"); bool innerIf = (tempToken->next() && tempToken->next()->str() == "if");
if (Token::simpleMatch(tempToken->next(), "do {")) if (Token::simpleMatch(tempToken->next(), "do {"))
tempToken = tempToken->linkAt(2); tempToken = tempToken->linkAt(2);
@ -4196,7 +4204,12 @@ bool Tokenizer::simplifyIfAddBraces()
// * if (cond1) if (cond2) ; else ; // * if (cond1) if (cond2) ; else ;
while (NULL != (tempToken = tempToken->next())) { while (NULL != (tempToken = tempToken->next())) {
if (tempToken->str() == "{") { if (tempToken->str() == "{") {
if (Token::simpleMatch(tempToken->previous(),"else {")) { if (tempToken->previous()->str() == "=") {
tempToken = tempToken->link();
continue;
}
if (tempToken->previous()->str() == "else") {
if (innerIf) if (innerIf)
tempToken = tempToken->link(); tempToken = tempToken->link();
else else
@ -4204,7 +4217,7 @@ bool Tokenizer::simplifyIfAddBraces()
break; break;
} }
tempToken = tempToken->link(); tempToken = tempToken->link();
if (!tempToken || !tempToken->next()) if (!tempToken->next())
break; break;
if (Token::simpleMatch(tempToken, "} else") && !Token::Match(tempToken->tokAt(2), "if|{")) if (Token::simpleMatch(tempToken, "} else") && !Token::Match(tempToken->tokAt(2), "if|{"))
innerIf = false; innerIf = false;
@ -4228,11 +4241,10 @@ bool Tokenizer::simplifyIfAddBraces()
if (!innerIf) if (!innerIf)
break; break;
if (Token::simpleMatch(tempToken, "; else if")) if (Token::simpleMatch(tempToken, "; else")) {
; if (tempToken->strAt(2) != "if")
else if (Token::simpleMatch(tempToken, "; else"))
innerIf = false; innerIf = false;
else } else
break; break;
} }
} }
@ -5294,14 +5306,14 @@ void Tokenizer::simplifyPlatformTypes()
_settings->platformType == Settings::Win32W || _settings->platformType == Settings::Win32W ||
_settings->platformType == Settings::Win64) { _settings->platformType == Settings::Win64) {
for (Token *tok = _tokens; tok; tok = tok->next()) { for (Token *tok = _tokens; tok; tok = tok->next()) {
if (Token::Match(tok, "BOOL|INT|INT32")) if (Token::Match(tok, "BOOL|INT|INT32|HFILE|LONG32"))
tok->str("int"); tok->str("int");
else if (Token::Match(tok, "BOOLEAN|BYTE|UCHAR")) { else if (Token::Match(tok, "BOOLEAN|BYTE|UCHAR")) {
tok->str("unsigned"); tok->str("unsigned");
tok->insertToken("char"); tok->insertToken("char");
} else if (tok->str() == "CHAR") } else if (tok->str() == "CHAR")
tok->str("char"); tok->str("char");
else if (Token::Match(tok, "DWORD|ULONG|COLORREF")) { else if (Token::Match(tok, "DWORD|ULONG|COLORREF|LCID|LCTYPE|LGRPID")) {
tok->str("unsigned"); tok->str("unsigned");
tok->insertToken("long"); tok->insertToken("long");
} else if (Token::Match(tok, "DWORD_PTR|ULONG_PTR|SIZE_T")) { } else if (Token::Match(tok, "DWORD_PTR|ULONG_PTR|SIZE_T")) {
@ -5311,21 +5323,19 @@ void Tokenizer::simplifyPlatformTypes()
tok->insertToken("long"); tok->insertToken("long");
} else if (tok->str() == "FLOAT") } else if (tok->str() == "FLOAT")
tok->str("float"); tok->str("float");
else if (tok->str() == "HRESULT") else if (Token::Match(tok, "HRESULT|LONG"))
tok->str("long"); tok->str("long");
else if (tok->str() == "INT64") { else if (Token::Match(tok, "INT64|LONG64")) {
tok->str("long"); tok->str("long");
tok->insertToken("long"); tok->insertToken("long");
} else if (tok->str() == "LONG") } else if (Token::Match(tok, "LONG_PTR|LPARAM|LRESULT|SSIZE_T")) {
tok->str("long");
else if (Token::Match(tok, "LONG_PTR|LPARAM|LRESULT")) {
tok->str("long"); tok->str("long");
if (_settings->platformType == Settings::Win64) if (_settings->platformType == Settings::Win64)
tok->insertToken("long"); tok->insertToken("long");
} else if (Token::Match(tok, "LPBOOL|PBOOL")) { } else if (Token::Match(tok, "LPBOOL|PBOOL")) {
tok->str("int"); tok->str("int");
tok->insertToken("*"); tok->insertToken("*");
} else if (Token::Match(tok, "LPBYTE|PBOOLEAN|PBYTE")) { } else if (Token::Match(tok, "LPBYTE|PBOOLEAN|PBYTE|PUCHAR")) {
tok->str("unsigned"); tok->str("unsigned");
tok->insertToken("*"); tok->insertToken("*");
tok->insertToken("char"); tok->insertToken("char");
@ -5337,7 +5347,7 @@ void Tokenizer::simplifyPlatformTypes()
tok->str("const"); tok->str("const");
tok->insertToken("*"); tok->insertToken("*");
tok->insertToken("void"); tok->insertToken("void");
} else if (tok->str() == "LPDWORD") { } else if (Token::Match(tok, "LPDWORD|LPCOLORREF|PDWORD|PULONG")) {
tok->str("unsigned"); tok->str("unsigned");
tok->insertToken("*"); tok->insertToken("*");
tok->insertToken("long"); tok->insertToken("long");
@ -5350,28 +5360,31 @@ void Tokenizer::simplifyPlatformTypes()
} else if (Token::Match(tok, "LPSTR|PSTR|PCHAR")) { } else if (Token::Match(tok, "LPSTR|PSTR|PCHAR")) {
tok->str("char"); tok->str("char");
tok->insertToken("*"); tok->insertToken("*");
} else if (Token::Match(tok, "LPVOID|PVOID|HANDLE|HBITMAP|HBRUSH|HCOLORSPACE|HCURSOR|HDC|HFONT|HGDIOBJ|HGLOBAL|HICON|HINSTANCE|HKEY|HLOCAL|HMENU|HMETAFILE|HMODULE|HPALETTE|HPEN|HRGN|HRSRC|HWND")) { } else if (Token::Match(tok, "LPVOID|PVOID|HANDLE|HBITMAP|HBRUSH|HCOLORSPACE|HCURSOR|HDC|HFONT|HGDIOBJ|HGLOBAL|HICON|HINSTANCE|HKEY|HLOCAL|HMENU|HMETAFILE|HMODULE|HPALETTE|HPEN|HRGN|HRSRC|HWND|SERVICE_STATUS_HANDLE|SC_LOCK|SC_HANDLE|HACCEL|HCONV|HCONVLIST|HDDEDATA|HDESK|HDROP|HDWP|HENHMETAFILE|HHOOK|HKL|HMONITOR|HSZ|HWINSTA")) {
tok->str("void"); tok->str("void");
tok->insertToken("*"); tok->insertToken("*");
} else if ((tok->str() == "PHANDLE")) { } else if ((tok->str() == "PHANDLE")) {
tok->str("void"); tok->str("void");
tok->insertToken("*"); tok->insertToken("*");
tok->insertToken("*"); tok->insertToken("*");
} else if (Token::Match(tok, "LPWORD|PWORD")) { } else if (Token::Match(tok, "LPWORD|PWORD|PWSTR|PWCHAR|PUSHORT")) {
tok->str("unsigned"); tok->str("unsigned");
tok->insertToken("*"); tok->insertToken("*");
tok->insertToken("short"); tok->insertToken("short");
} else if (tok->str() == "SHORT") } else if (tok->str() == "SHORT")
tok->str("short"); tok->str("short");
else if (Token::Match(tok, "UINT|MMRESULT|SOCKET")) { else if (Token::Match(tok, "UINT|MMRESULT|SOCKET|ULONG32|UINT32|DWORD32")) {
tok->str("unsigned"); tok->str("unsigned");
tok->insertToken("int"); tok->insertToken("int");
} else if (Token::Match(tok, "UINT_PTR|WPARAM")) { } else if (Token::Match(tok, "UINT_PTR|WPARAM")) {
tok->str("unsigned"); tok->str("unsigned");
if (_settings->platformType == Settings::Win64) {
tok->insertToken("long"); tok->insertToken("long");
if (_settings->platformType == Settings::Win64)
tok->insertToken("long"); tok->insertToken("long");
} else if (Token::Match(tok, "USHORT|WORD|WCHAR|ATOM|wchar_t")) { } else {
tok->insertToken("int");
}
} else if (Token::Match(tok, "USHORT|WORD|WCHAR|ATOM|wchar_t|LANGID")) {
tok->str("unsigned"); tok->str("unsigned");
tok->insertToken("short"); tok->insertToken("short");
} else if (tok->str() == "VOID") } else if (tok->str() == "VOID")
@ -5383,6 +5396,12 @@ void Tokenizer::simplifyPlatformTypes()
tok->str("unsigned"); tok->str("unsigned");
tok->insertToken("short"); tok->insertToken("short");
} }
} else if (tok->str() == "TBYTE") {
tok->str("unsigned");
if (_settings->platformType == Settings::Win32A)
tok->insertToken("short");
else
tok->insertToken("char");
} else if (Token::Match(tok, "PTSTR|LPTSTR")) { } else if (Token::Match(tok, "PTSTR|LPTSTR")) {
if (_settings->platformType == Settings::Win32A) { if (_settings->platformType == Settings::Win32A) {
tok->str("char"); tok->str("char");
@ -5393,16 +5412,35 @@ void Tokenizer::simplifyPlatformTypes()
tok->insertToken("short"); tok->insertToken("short");
} }
} else if (Token::Match(tok, "PCTSTR|LPCTSTR")) { } else if (Token::Match(tok, "PCTSTR|LPCTSTR")) {
if (_settings->platformType == Settings::Win32A) {
tok->str("const"); tok->str("const");
if (_settings->platformType == Settings::Win32A) {
tok->insertToken("*"); tok->insertToken("*");
tok->insertToken("char"); tok->insertToken("char");
} else { } else {
tok->str("const");
tok->insertToken("*"); tok->insertToken("*");
tok->insertToken("short"); tok->insertToken("short");
tok->insertToken("unsigned"); tok->insertToken("unsigned");
} }
} else if (Token::Match(tok, "ULONG64|DWORD64")) {
tok->str("unsigned");
tok->insertToken("long");
} else if (tok->str() == "HALF_PTR") {
if (_settings->platformType == Settings::Win64)
tok->str("int");
else
tok->str("short");
} else if (tok->str() == "INT_PTR") {
if (_settings->platformType == Settings::Win64) {
tok->str("long");
tok->insertToken("long");
} else {
tok->str("int");
}
} else if (tok->str() == "LPCWSTR") {
tok->str("const");
tok->insertToken("*");
tok->insertToken("short");
tok->insertToken("unsigned");
} }
} }
} }
@ -6707,10 +6745,8 @@ void Tokenizer::simplifyGoto()
} }
} }
if (!indentlevel && Token::Match(tok, ") const| {")) { if (!indentlevel && Token::Match(tok, ") const| {"))
gotos.clear();
beginfunction = tok; beginfunction = tok;
}
else if (indentlevel && Token::Match(tok, "[{};] goto %var% ;")) else if (indentlevel && Token::Match(tok, "[{};] goto %var% ;"))
gotos.push_back(tok->next()); gotos.push_back(tok->next());
@ -7014,22 +7050,25 @@ void Tokenizer::simplifyEnum()
tok = tok->previous(); tok = tok->previous();
} }
if (Token::Match(tok, "class|struct|namespace %any%") && if (Token::Match(tok, "class|struct|namespace") && tok->next() &&
(!tok->previous() || (tok->previous() && tok->previous()->str() != "enum"))) { (!tok->previous() || (tok->previous() && tok->previous()->str() != "enum"))) {
className = tok->next()->str(); className = tok->next()->str();
classLevel = 0; classLevel = 0;
continue;
} else if (tok->str() == "}") { } else if (tok->str() == "}") {
--classLevel; --classLevel;
if (classLevel < 0) if (classLevel < 0)
className = ""; className = "";
continue;
} else if (tok->str() == "{") { } else if (tok->str() == "{") {
++classLevel; ++classLevel;
} else if (tok->str() == "enum") {
Token *temp = tok->next();
if (!temp)
break;
if (Token::Match(temp, "class|struct"))
temp = temp->next();
if (!Token::Match(temp, "[{:]") &&
(!temp->isName() || !Token::Match(temp->next(), "[{:;]")))
continue; continue;
} else if (Token::Match(tok, "enum class|struct| {|:") ||
Token::Match(tok, "enum class|struct| %type% {|:|;")) {
Token *start = tok; Token *start = tok;
Token *enumType = 0; Token *enumType = 0;
Token *typeTokenStart = 0; Token *typeTokenStart = 0;
@ -7040,7 +7079,7 @@ void Tokenizer::simplifyEnum()
tok->deleteNext(); tok->deleteNext();
// check for name // check for name
if (Token::Match(tok->next(), "%type%")) { if (tok->next()->isName()) {
enumType = tok->next(); enumType = tok->next();
tok = tok->next(); tok = tok->next();
} }

View File

@ -28,4 +28,5 @@ astyle $style $options test/*.cpp
astyle $style $options test/*.h astyle $style $options test/*.h
astyle $style $options tools/*.cpp astyle $style $options tools/*.cpp
astyle $style $options --recursive "samples/*.c"

View File

@ -0,0 +1,11 @@
int foo(int *p)
{
int a = p;
return a + 4;
}
int main()
{
int i[10];
foo(i);
}

View File

@ -0,0 +1,11 @@
int* foo(int *p)
{
return p + 4;
}
int main()
{
int i[10];
foo(i);
}

View File

@ -112,7 +112,7 @@ private:
" char ch;\n" " char ch;\n"
" result = a | ch;\n" " result = a | ch;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) When using char variables in bit operations, sign extension can generate unexpected results.\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (warning) When using char variables in bit operations, sign extension can generate unexpected results.\n", errout.str());
} }
void bitop2() { void bitop2() {
@ -159,7 +159,7 @@ private:
" ret |= *p;\n" " ret |= *p;\n"
" return ret;\n" " return ret;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:2]: (warning) When using char variables in bit operations, sign extension can generate unexpected results.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (warning) When using char variables in bit operations, sign extension can generate unexpected results.\n", errout.str());
// fixed code // fixed code
check("void f(char *p) {\n" check("void f(char *p) {\n"

View File

@ -88,6 +88,7 @@ private:
TEST_CASE(testScanf1); TEST_CASE(testScanf1);
TEST_CASE(testScanf2); TEST_CASE(testScanf2);
TEST_CASE(testScanf3); TEST_CASE(testScanf3);
TEST_CASE(testScanf4);
TEST_CASE(testScanfArgument); TEST_CASE(testScanfArgument);
TEST_CASE(testPrintfArgument); TEST_CASE(testPrintfArgument);
@ -2028,9 +2029,9 @@ private:
" fclose(file);\n" " fclose(file);\n"
" return b;\n" " return b;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:6]: (warning) scanf without field width limits can crash with huge input data\n" ASSERT_EQUALS("[test.cpp:8]: (warning) fscanf format string has 0 parameters but 1 are given\n"
"[test.cpp:7]: (warning) scanf without field width limits can crash with huge input data\n" "[test.cpp:6]: (warning) scanf without field width limits can crash with huge input data\n"
"[test.cpp:8]: (warning) fscanf format string has 0 parameters but 1 are given\n", errout.str()); "[test.cpp:7]: (warning) scanf without field width limits can crash with huge input data\n", errout.str());
} }
void testScanf2() { void testScanf2() {
@ -2045,9 +2046,9 @@ private:
" fclose(file);\n" " fclose(file);\n"
" return b;\n" " return b;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:6]: (warning) scanf without field width limits can crash with huge input data\n" ASSERT_EQUALS("[test.cpp:8]: (warning) fscanf format string has 0 parameters but 1 are given\n"
"[test.cpp:7]: (warning) scanf without field width limits can crash with huge input data\n" "[test.cpp:6]: (warning) scanf without field width limits can crash with huge input data\n"
"[test.cpp:8]: (warning) fscanf format string has 0 parameters but 1 are given\n", errout.str()); "[test.cpp:7]: (warning) scanf without field width limits can crash with huge input data\n", errout.str());
} }
void testScanf3() { void testScanf3() {
@ -2076,6 +2077,14 @@ private:
ASSERT_EQUALS("[test.cpp:7]: (warning) fscanf format string has 0 parameters but 1 are given\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (warning) fscanf format string has 0 parameters but 1 are given\n", errout.str());
} }
void testScanf4() {
check("void f() {\n"
" char c;\n"
" scanf(\"%c\", &c);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void testScanfArgument() { void testScanfArgument() {
check("void foo() {\n" check("void foo() {\n"
" scanf(\"%1d\", &foo);\n" " scanf(\"%1d\", &foo);\n"
@ -2213,6 +2222,7 @@ private:
" printf(\"%G\", bp);\n" " printf(\"%G\", bp);\n"
" printf(\"%f\", d);\n" " printf(\"%f\", d);\n"
" printf(\"%f\", b);\n" " printf(\"%f\", b);\n"
" printf(\"%f\", (float)cpi);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:3]: (warning) %e in format string (no. 1) requires a floating point number given in the argument list\n" ASSERT_EQUALS("[test.cpp:3]: (warning) %e in format string (no. 1) requires a floating point number given in the argument list\n"
"[test.cpp:4]: (warning) %E in format string (no. 1) requires a floating point number given in the argument list\n" "[test.cpp:4]: (warning) %E in format string (no. 1) requires a floating point number given in the argument list\n"

View File

@ -447,7 +447,7 @@ private:
void cast() { void cast() {
ASSERT_EQUALS("if ( ! p )", tok("if (p == (char *)0)")); ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (p == (char *)0);"));
ASSERT_EQUALS("return str ;", tok("return (char *)str;")); ASSERT_EQUALS("return str ;", tok("return (char *)str;"));
{ {
@ -469,7 +469,7 @@ private:
ASSERT_EQUALS("if ( * a )", tok("if ((unsigned int)(unsigned char)*a)")); ASSERT_EQUALS("if ( * a )", tok("if ((unsigned int)(unsigned char)*a)"));
ASSERT_EQUALS("class A { A operator* ( int ) ; } ;", tok("class A { A operator *(int); };")); ASSERT_EQUALS("class A { A operator* ( int ) ; } ;", tok("class A { A operator *(int); };"));
ASSERT_EQUALS("class A { A operator* ( int ) const ; } ;", tok("class A { A operator *(int) const; };")); ASSERT_EQUALS("class A { A operator* ( int ) const ; } ;", tok("class A { A operator *(int) const; };"));
ASSERT_EQUALS("if ( ! p )", tok("if (p == (char *)(char *)0)")); ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (p == (char *)(char *)0);"));
// no simplification as the cast may be important here. see #2897 for example // no simplification as the cast may be important here. see #2897 for example
ASSERT_EQUALS("; * ( ( char * ) p + 1 ) = 0 ;", tok("; *((char *)p + 1) = 0;")); ASSERT_EQUALS("; * ( ( char * ) p + 1 ) = 0 ;", tok("; *((char *)p + 1) = 0;"));
@ -2439,17 +2439,17 @@ private:
} }
void ifnot() { void ifnot() {
ASSERT_EQUALS("if ( ! x )", simplifyIfNot("if(0==x)")); ASSERT_EQUALS("if ( ! x ) { ; }", simplifyIfNot("if(0==x);"));
ASSERT_EQUALS("if ( ! x )", simplifyIfNot("if(x==0)")); ASSERT_EQUALS("if ( ! x ) { ; }", simplifyIfNot("if(x==0);"));
ASSERT_EQUALS("if ( ! ( a = b ) )", simplifyIfNot("if(0==(a=b))")); ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", simplifyIfNot("if(0==(a=b));"));
ASSERT_EQUALS("if ( ! x )", simplifyIfNot("if(x==0)")); ASSERT_EQUALS("if ( ! x ) { ; }", simplifyIfNot("if(x==0);"));
ASSERT_EQUALS("if ( ! a && b ( ) )", simplifyIfNot("if( 0 == a && b() )")); ASSERT_EQUALS("if ( ! a && b ( ) ) { ; }", simplifyIfNot("if( 0 == a && b() );"));
ASSERT_EQUALS("if ( b ( ) && ! a )", simplifyIfNot("if( b() && 0 == a )")); ASSERT_EQUALS("if ( b ( ) && ! a ) { ; }", simplifyIfNot("if( b() && 0 == a );"));
ASSERT_EQUALS("if ( ! ( a = b ) )", simplifyIfNot("if((a=b)==0)")); ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", simplifyIfNot("if((a=b)==0);"));
ASSERT_EQUALS("if ( ! x . y )", simplifyIfNot("if(x.y==0)")); ASSERT_EQUALS("if ( ! x . y ) { ; }", simplifyIfNot("if(x.y==0);"));
ASSERT_EQUALS("if ( ! x )", simplifyIfNot("if((x==0))")); ASSERT_EQUALS("if ( ! x ) { ; }", simplifyIfNot("if((x==0));"));
ASSERT_EQUALS("if ( ( ! x ) && ! y )", simplifyIfNot("if((x==0) && y==0)")); ASSERT_EQUALS("if ( ( ! x ) && ! y ) { ; }", simplifyIfNot("if((x==0) && y==0);"));
ASSERT_EQUALS("if ( ! ( ! fclose ( fd ) ) )", simplifyIfNot("if(!(fclose(fd) == 0))")); ASSERT_EQUALS("if ( ! ( ! fclose ( fd ) ) ) { ; }", simplifyIfNot("if(!(fclose(fd) == 0));"));
} }
@ -2470,8 +2470,8 @@ private:
} }
void not1() { void not1() {
ASSERT_EQUALS("if ( ! p )", simplifyLogicalOperators("if (not p)")); ASSERT_EQUALS("if ( ! p ) { ; }", simplifyLogicalOperators("if (not p);"));
ASSERT_EQUALS("if ( p && ! q )", simplifyLogicalOperators("if (p && not q)")); ASSERT_EQUALS("if ( p && ! q ) { ; }", simplifyLogicalOperators("if (p && not q);"));
ASSERT_EQUALS("void foo ( not i )", simplifyLogicalOperators("void foo ( not i )")); ASSERT_EQUALS("void foo ( not i )", simplifyLogicalOperators("void foo ( not i )"));
} }
@ -2488,8 +2488,8 @@ private:
ASSERT_EQUALS("if ( p && bar ( ) ) { ; }", ASSERT_EQUALS("if ( p && bar ( ) ) { ; }",
simplifyLogicalOperators("if (p and bar()) ;")); simplifyLogicalOperators("if (p and bar()) ;"));
ASSERT_EQUALS("if ( p && ! q )", ASSERT_EQUALS("if ( p && ! q ) { ; }",
simplifyLogicalOperators("if (p and not q)")); simplifyLogicalOperators("if (p and not q) ;"));
} }
void or1() { void or1() {
@ -2505,8 +2505,8 @@ private:
ASSERT_EQUALS("if ( p || bar ( ) ) { ; }", ASSERT_EQUALS("if ( p || bar ( ) ) { ; }",
simplifyLogicalOperators("if (p or bar()) ;")); simplifyLogicalOperators("if (p or bar()) ;"));
ASSERT_EQUALS("if ( p || ! q )", ASSERT_EQUALS("if ( p || ! q ) { ; }",
simplifyLogicalOperators("if (p or not q)")); simplifyLogicalOperators("if (p or not q) ;"));
} }
void comma_keyword() { void comma_keyword() {
@ -2800,9 +2800,9 @@ private:
ASSERT_EQUALS(";", tok("; x = x + 0;")); ASSERT_EQUALS(";", tok("; x = x + 0;"));
ASSERT_EQUALS("if ( a == 2 )", tok("if (a==1+1)")); ASSERT_EQUALS("if ( a == 2 ) { ; }", tok("if (a==1+1);"));
ASSERT_EQUALS("if ( a + 2 != 6 )", tok("if (a+1+1!=1+2+3)")); ASSERT_EQUALS("if ( a + 2 != 6 ) { ; }", tok("if (a+1+1!=1+2+3);"));
ASSERT_EQUALS("if ( 4 < a )", tok("if (14-2*5<a*4/(2*2))")); ASSERT_EQUALS("if ( 4 < a ) { ; }", tok("if (14-2*5<a*4/(2*2));"));
ASSERT_EQUALS("( y / 2 - 2 )", tok("(y / 2 - 2)")); ASSERT_EQUALS("( y / 2 - 2 )", tok("(y / 2 - 2)"));
ASSERT_EQUALS("( y % 2 - 2 )", tok("(y % 2 - 2)")); ASSERT_EQUALS("( y % 2 - 2 )", tok("(y % 2 - 2)"));

View File

@ -598,8 +598,13 @@ private:
ASSERT_EQUALS("( X && Y )", tokenizeAndStringify("(X&&Y)")); ASSERT_EQUALS("( X && Y )", tokenizeAndStringify("(X&&Y)"));
} }
void tokenize19() { // #3006 (segmentation fault) void tokenize19() {
// #3006 - added hasComplicatedSyntaxErrorsInTemplates to avoid segmentation fault
tokenizeAndStringify("x < () <"); tokenizeAndStringify("x < () <");
// #3496 - make sure hasComplicatedSyntaxErrorsInTemplates works
ASSERT_EQUALS("void a ( Fred * f ) { for ( ; n < f . x ( ) ; ) { } }",
tokenizeAndStringify("void a(Fred* f) MACRO { for (;n < f->x();) {} }"));
} }
void tokenize20() { // replace C99 _Bool => bool void tokenize20() { // replace C99 _Bool => bool
@ -759,7 +764,7 @@ private:
void removeCast6() { void removeCast6() {
// ticket #2103 // ticket #2103
ASSERT_EQUALS("if ( ! x )", tokenizeAndStringify("if (x == (char *) ((void *)0))", true)); ASSERT_EQUALS("if ( ! x ) { ; }", tokenizeAndStringify("if (x == (char *) ((void *)0)) ;", true));
} }
void removeCast7() { void removeCast7() {
@ -771,16 +776,16 @@ private:
} }
void inlineasm() { void inlineasm() {
ASSERT_EQUALS("; asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify(";asm { mov ax,bx };")); ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("asm { mov ax,bx };"));
ASSERT_EQUALS("; asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify(";_asm { mov ax,bx };")); ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("_asm { mov ax,bx };"));
ASSERT_EQUALS("; asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify(";__asm { mov ax,bx };")); ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("__asm { mov ax,bx };"));
ASSERT_EQUALS("; asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify(";__asm__ __volatile__ ( \"mov ax,bx\" );")); ASSERT_EQUALS("asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify("__asm__ __volatile__ ( \"mov ax,bx\" );"));
ASSERT_EQUALS("; asm ( \"_emit 12h\" ) ;", tokenizeAndStringify(";__asm _emit 12h ;")); ASSERT_EQUALS("asm ( \"_emit 12h\" ) ;", tokenizeAndStringify("__asm _emit 12h ;"));
ASSERT_EQUALS("; asm ( \"mov a , b\" ) ;", tokenizeAndStringify(";__asm mov a, b ;")); ASSERT_EQUALS("asm ( \"mov a , b\" ) ;", tokenizeAndStringify("__asm mov a, b ;"));
ASSERT_EQUALS("; asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify(";asm volatile (\"fnstcw %0\" : \"= m\" (old_cw));")); ASSERT_EQUALS("asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify("asm volatile (\"fnstcw %0\" : \"= m\" (old_cw));"));
ASSERT_EQUALS("; asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify("; __asm__ (\"fnstcw %0\" : \"= m\" (old_cw));")); ASSERT_EQUALS("asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify(" __asm__ (\"fnstcw %0\" : \"= m\" (old_cw));"));
ASSERT_EQUALS("; asm ( \"\"ddd\"\" ) ;", tokenizeAndStringify("; __asm __volatile__ (\"ddd\") ;")); ASSERT_EQUALS("asm ( \"\"ddd\"\" ) ;", tokenizeAndStringify(" __asm __volatile__ (\"ddd\") ;"));
ASSERT_EQUALS("; asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify(";__asm__ volatile ( \"mov ax,bx\" );")); ASSERT_EQUALS("asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify("__asm__ volatile ( \"mov ax,bx\" );"));
// 'asm ( ) ;' should be in the same line // 'asm ( ) ;' should be in the same line
ASSERT_EQUALS(";\n\nasm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify(";\n\n__asm__ volatile ( \"mov ax,bx\" );", true)); ASSERT_EQUALS(";\n\nasm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify(";\n\n__asm__ volatile ( \"mov ax,bx\" );", true));
@ -5869,14 +5874,14 @@ private:
} }
void simplifyLogicalOperators() { void simplifyLogicalOperators() {
ASSERT_EQUALS("if ( a && b )", tokenizeAndStringify("if (a and b)")); ASSERT_EQUALS("if ( a && b ) { ; }", tokenizeAndStringify("if (a and b);"));
ASSERT_EQUALS("if ( a || b )", tokenizeAndStringify("if (a or b)")); ASSERT_EQUALS("if ( a || b ) { ; }", tokenizeAndStringify("if (a or b);"));
ASSERT_EQUALS("if ( a & b )", tokenizeAndStringify("if (a bitand b)")); ASSERT_EQUALS("if ( a & b ) { ; }", tokenizeAndStringify("if (a bitand b);"));
ASSERT_EQUALS("if ( a | b )", tokenizeAndStringify("if (a bitor b)")); ASSERT_EQUALS("if ( a | b ) { ; }", tokenizeAndStringify("if (a bitor b);"));
ASSERT_EQUALS("if ( a ^ b )", tokenizeAndStringify("if (a xor b)")); ASSERT_EQUALS("if ( a ^ b ) { ; }", tokenizeAndStringify("if (a xor b);"));
ASSERT_EQUALS("if ( ~ b )", tokenizeAndStringify("if (compl b)")); ASSERT_EQUALS("if ( ~ b ) { ; }", tokenizeAndStringify("if (compl b);"));
ASSERT_EQUALS("if ( ! b )", tokenizeAndStringify("if (not b)")); ASSERT_EQUALS("if ( ! b ) { ; }", tokenizeAndStringify("if (not b);"));
ASSERT_EQUALS("if ( a != b )", tokenizeAndStringify("if (a not_eq b)")); ASSERT_EQUALS("if ( a != b ) { ; }", tokenizeAndStringify("if (a not_eq b);"));
} }
void simplifyCalculations() { void simplifyCalculations() {
@ -6099,6 +6104,7 @@ private:
} }
void platformWin32() { void platformWin32() {
// WIN32A
const char code[] = "unsigned int sizeof_short = sizeof(short);" const char code[] = "unsigned int sizeof_short = sizeof(short);"
"unsigned int sizeof_unsigned_short = sizeof(unsigned short);" "unsigned int sizeof_unsigned_short = sizeof(unsigned short);"
"unsigned int sizeof_int = sizeof(int);" "unsigned int sizeof_int = sizeof(int);"
@ -6158,7 +6164,45 @@ private:
"SIZE_T Q;" "SIZE_T Q;"
"HRESULT R;" "HRESULT R;"
"LONG_PTR S;" "LONG_PTR S;"
"HANDLE T;"; "HANDLE T;"
"BOOL _bool;"
"HFILE hfile;"
"LONG32 long32;"
"LCID lcid;"
"LCTYPE lctype;"
"LGRPID lgrpid;"
"LONG64 long64;"
"SSIZE_T _ssize_t;"
"PUCHAR puchar;"
"LPCOLORREF lpcolorref;"
"PDWORD pdword;"
"PULONG pulong;"
"SERVICE_STATUS_HANDLE service_status_hanlde;"
"SC_LOCK sc_lock;"
"SC_HANDLE sc_handle;"
"HACCEL haccel;"
"HCONV hconv;"
"HCONVLIST hconvlist;"
"HDDEDATA hddedata;"
"HDESK hdesk;"
"HDROP hdrop;"
"HDWP hdwp;"
"HENHMETAFILE henhmetafile;"
"HHOOK hhook;"
"HKL hkl;"
"HMONITOR hmonitor;"
"HSZ hsz;"
"HWINSTA hwinsta;"
"PWCHAR pwchar;"
"PUSHORT pushort;"
"UINT_PTR uint_ptr;"
"WPARAM wparam;"
"LANGID langid;"
"DWORD64 dword64;"
"ULONG64 ulong64;"
"HALF_PTR half_ptr;"
"INT_PTR int_ptr;"
"LPCWSTR lpcwstr;";
const char expected[] = "unsigned int sizeof_short ; sizeof_short = 2 ; " const char expected[] = "unsigned int sizeof_short ; sizeof_short = 2 ; "
"unsigned int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; " "unsigned int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; "
@ -6219,7 +6263,45 @@ private:
"unsigned long Q ; " "unsigned long Q ; "
"long R ; " "long R ; "
"long S ; " "long S ; "
"void * T ;"; "void * T ; "
"int _bool ; "
"int hfile ; "
"int long32 ; "
"unsigned long lcid ; "
"unsigned long lctype ; "
"unsigned long lgrpid ; "
"long long long64 ; "
"long _ssize_t ; "
"unsigned char * puchar ; "
"unsigned long * lpcolorref ; "
"unsigned long * pdword ; "
"unsigned long * pulong ; "
"void * service_status_hanlde ; "
"void * sc_lock ; "
"void * sc_handle ; "
"void * haccel ; "
"void * hconv ; "
"void * hconvlist ; "
"void * hddedata ; "
"void * hdesk ; "
"void * hdrop ; "
"void * hdwp ; "
"void * henhmetafile ; "
"void * hhook ; "
"void * hkl ; "
"void * hmonitor ; "
"void * hsz ; "
"void * hwinsta ; "
"unsigned short * pwchar ; "
"unsigned short * pushort ; "
"unsigned int uint_ptr ; "
"unsigned int wparam ; "
"unsigned short langid ; "
"unsigned long dword64 ; "
"unsigned long ulong64 ; "
"short half_ptr ; "
"int int_ptr ; "
"const unsigned short * lpcwstr ;";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Win32A)); ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Win32A));
} }
@ -6244,7 +6326,8 @@ private:
" _sntprintf(dst, sizeof(dst) / sizeof(TCHAR), _T(\"Hello world!\n\"));" " _sntprintf(dst, sizeof(dst) / sizeof(TCHAR), _T(\"Hello world!\n\"));"
" _tscanf(_T(\"%s\"), dst);" " _tscanf(_T(\"%s\"), dst);"
" _stscanf(dst, _T(\"%s\"), dst);" " _stscanf(dst, _T(\"%s\"), dst);"
"}"; "}"
"TBYTE tbyte;";
const char expected[] = "unsigned short wc ; " const char expected[] = "unsigned short wc ; "
"char c ; " "char c ; "
"char * ptstr ; " "char * ptstr ; "
@ -6264,7 +6347,8 @@ private:
"snprintf ( dst , sizeof ( dst ) / sizeof ( char ) , \"Hello world!\n\" ) ; " "snprintf ( dst , sizeof ( dst ) / sizeof ( char ) , \"Hello world!\n\" ) ; "
"scanf ( \"%s\" , dst ) ; " "scanf ( \"%s\" , dst ) ; "
"sscanf ( dst , \"%s\" , dst ) ; " "sscanf ( dst , \"%s\" , dst ) ; "
"}"; "} "
"unsigned short tbyte ;";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, false, true, Settings::Win32A)); ASSERT_EQUALS(expected, tokenizeAndStringify(code, false, true, Settings::Win32A));
} }
@ -6275,6 +6359,7 @@ private:
"LPTSTR lptstr;" "LPTSTR lptstr;"
"PCTSTR pctstr;" "PCTSTR pctstr;"
"LPCTSTR lpctstr;" "LPCTSTR lpctstr;"
"TBYTE tbyte;"
"void foo() {" "void foo() {"
" TCHAR tc = _T(\'c\');" " TCHAR tc = _T(\'c\');"
" TCHAR src[10] = _T(\"123456789\");" " TCHAR src[10] = _T(\"123456789\");"
@ -6295,6 +6380,7 @@ private:
"unsigned short * lptstr ; " "unsigned short * lptstr ; "
"const unsigned short * pctstr ; " "const unsigned short * pctstr ; "
"const unsigned short * lpctstr ; " "const unsigned short * lpctstr ; "
"unsigned char tbyte ; "
"void foo ( ) { " "void foo ( ) { "
"unsigned short tc ; tc = \'c\' ; " "unsigned short tc ; tc = \'c\' ; "
"unsigned short src [ 10 ] = \"123456789\" ; " "unsigned short src [ 10 ] = \"123456789\" ; "
@ -6337,7 +6423,11 @@ private:
"SIZE_T Q;" "SIZE_T Q;"
"HRESULT R;" "HRESULT R;"
"LONG_PTR S;" "LONG_PTR S;"
"HANDLE T;"; "HANDLE T;"
"SSIZE_T _ssize_t;"
"UINT_PTR uint_ptr;"
"WPARAM wparam;"
"INT_PTR int_ptr;";
const char expected[] = "unsigned int sizeof_short ; sizeof_short = 2 ; " const char expected[] = "unsigned int sizeof_short ; sizeof_short = 2 ; "
"unsigned int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; " "unsigned int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; "
@ -6363,7 +6453,12 @@ private:
"unsigned long long Q ; " "unsigned long long Q ; "
"long R ; " "long R ; "
"long long S ; " "long long S ; "
"void * T ;"; "void * T ; "
"long long _ssize_t ; "
"unsigned long long uint_ptr ; "
"unsigned long long wparam ; "
"long long int_ptr ;"
;
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Win64)); ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Win64));
} }