From 97d427785424dc5d901829dd953a72b7605f5dd4 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Thu, 22 Sep 2011 19:59:56 -0400 Subject: [PATCH] add Microsoft memory function conversions to standard cstring functions --- lib/tokenize.cpp | 92 +++++++++++++++++++++++++++++++++++++ lib/tokenize.h | 13 +++++- test/testsimplifytokens.cpp | 6 ++- test/testtokenize.cpp | 22 +++++++++ 4 files changed, 129 insertions(+), 4 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index c7aeeaa1d..9ff9243cf 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2547,6 +2547,9 @@ bool Tokenizer::tokenize(std::istream &code, // remove Microsoft MFC.. simplifyMicrosoftMFC(); + // convert Microsoft memory functions + simplifyMicrosoftMemoryFunctions(); + // Remove Qt signals and slots simplifyQtSignalsSlots(); @@ -10437,6 +10440,95 @@ void Tokenizer::simplifyMicrosoftMFC() } } +void Tokenizer::simplifyMicrosoftMemoryFunctions() +{ + // skip if not Windows + if (!(_settings->platformType == Settings::Win32 || + _settings->platformType == Settings::Win64)) + return; + + for (Token *tok = _tokens; tok; tok = tok->next()) + { + if (Token::simpleMatch(tok, "CopyMemory (")) + { + tok->str("memcpy"); + } + else if (Token::simpleMatch(tok, "MoveMemory (")) + { + tok->str("memmove"); + } + else if (Token::simpleMatch(tok, "FillMemory (")) + { + // FillMemory(dst, len, val) -> memset(dst, val, len) + tok->str("memset"); + + // find first ',' + Token *tok1 = tok->tokAt(2); + unsigned int level = 0; + while (tok1) + { + if (tok1->str() == "(") + level++; + else if (tok1->str() == ")") + level--; + else if (level == 0 && tok1->str() == ",") + break; + + tok1 = tok1->next(); + } + + // find second ',' + if (tok1) + { + Token *tok2 = tok1->next(); + level = 0; + while (tok2) + { + if (tok2->str() == "(") + level++; + else if (tok2->str() == ")") + level--; + else if (level == 0 && tok2->str() == ",") + break; + + tok2 = tok2->next(); + } + + // move second argument to third position + if (tok2) + { + Token::move(tok1, tok2->previous(), tok->next()->link()->previous()); + } + } + } + else if (Token::simpleMatch(tok, "ZeroMemory (")) + { + // ZeroMemory(dst, len) -> memset(dst, 0, len) + tok->str("memset"); + + Token *tok1 = tok->tokAt(2); + unsigned int level = 0; + while (tok1) + { + if (tok1->str() == "(") + level++; + else if (tok1->str() == ")") + level--; + else if (level == 0 && tok1->str() == ",") + break; + + tok1 = tok1->next(); + } + + if (tok1) + { + tok1->insertToken("0"); + tok1 = tok1->next(); + tok1->insertToken(","); + } + } + } +} // Remove Borland code void Tokenizer::simplifyBorland() diff --git a/lib/tokenize.h b/lib/tokenize.h index 17ff051e7..aada8ceaa 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -619,8 +619,17 @@ public: void simplifyMicrosoftMFC(); /** - * Remove Borland code - */ + * Convert Microsoft memory functions + * CopyMemory(dst, src, len) -> memcpy(dst, src, len) + * FillMemory(dst, len, val) -> memset(dst, val, len) + * MoveMemory(dst, src, len) -> memmove(dst, src, len) + * ZeroMemory(dst, len) -> memset(dst, 0, len) + */ + void simplifyMicrosoftMemoryFunctions(); + + /** + * Remove Borland code + */ void simplifyBorland(); /** diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 609764190..64a4de1f3 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -862,11 +862,12 @@ private: // Simplify 'sizeof'.. - std::string sizeof_(const char code[], bool simplify = true) + std::string sizeof_(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Host) { errout.str(""); Settings settings; + settings.platform(type); // tokenize.. Tokenizer tokenizer(&settings, this); @@ -975,7 +976,8 @@ private: { const char code[] = ";INT32 i[10];\n" "sizeof(i[0]);\n"; - ASSERT_EQUALS("; INT32 i [ 10 ] ; sizeof ( i [ 0 ] ) ;", sizeof_(code)); + ASSERT_EQUALS("; INT32 i [ 10 ] ; sizeof ( i [ 0 ] ) ;", sizeof_(code, true, Settings::Host)); + ASSERT_EQUALS("; int i [ 10 ] ; 4 ;", sizeof_(code, true, Settings::Win32)); } void sizeof8() diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 49ac03386..844e38b36 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -319,6 +319,7 @@ private: TEST_CASE(bitfields11); // ticket #2845 (segmentation fault) TEST_CASE(microsoftMFC); + TEST_CASE(microsoftMemory); TEST_CASE(borland); @@ -5556,6 +5557,27 @@ private: ASSERT_EQUALS("class MyDialog : public CDialog { private: CString text ; } ;", tokenizeAndStringify(code4,false,true,Settings::Win32)); } + void microsoftMemory() + { + const char code1[] = "void foo() { int a[10], b[10]; CopyMemory(a, b, sizeof(a)); }"; + ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memcpy ( a , b , sizeof ( a ) ) ; }", tokenizeAndStringify(code1,false,true,Settings::Win32)); + + const char code2[] = "void foo() { int a[10]; FillMemory(a, sizeof(a), 255); }"; + ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; memset ( a , 255 , sizeof ( a ) ) ; }", tokenizeAndStringify(code2,false,true,Settings::Win32)); + + const char code3[] = "void foo() { int a[10], b[10]; MoveMemory(a, b, sizeof(a)); }"; + ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memmove ( a , b , sizeof ( a ) ) ; }", tokenizeAndStringify(code3,false,true,Settings::Win32)); + + const char code4[] = "void foo() { int a[10]; ZeroMemory(a, sizeof(a)); }"; + ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; memset ( a , 0 , sizeof ( a ) ) ; }", tokenizeAndStringify(code4,false,true,Settings::Win32)); + + const char code5[] = "void foo() { ZeroMemory(f(1, g(a, b)), h(i, j(0, 1))); }"; + ASSERT_EQUALS("void foo ( ) { memset ( f ( 1 , g ( a , b ) ) , 0 , h ( i , j ( 0 , 1 ) ) ) ; }", tokenizeAndStringify(code5,false,true,Settings::Win32)); + + const char code6[] = "void foo() { FillMemory(f(1, g(a, b)), h(i, j(0, 1)), 255); }"; + ASSERT_EQUALS("void foo ( ) { memset ( f ( 1 , g ( a , b ) ) , 255 , h ( i , j ( 0 , 1 ) ) ) ; }", tokenizeAndStringify(code6,false,true,Settings::Win32)); + } + void borland() { // __closure