diff --git a/cli/cppcheck.vcproj b/cli/cppcheck.vcproj
index 9f49e54eb..fe7319d19 100755
--- a/cli/cppcheck.vcproj
+++ b/cli/cppcheck.vcproj
@@ -268,6 +268,10 @@
RelativePath="..\lib\filelister.cpp"
>
+
+
@@ -370,6 +374,10 @@
RelativePath="..\lib\filelister.h"
>
+
+
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index 6e92366c2..1508f62bb 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -379,7 +379,7 @@ QStringList MainWindow::RemoveUnacceptedFiles(const QStringList &list)
QString str;
foreach(str, list)
{
- if (FileLister::acceptFile(str.toStdString()))
+ if (getFileLister()->acceptFile(str.toStdString()))
{
result << str;
}
diff --git a/lib/checkheaders.cpp b/lib/checkheaders.cpp
index 3125e3016..36c0cabbf 100644
--- a/lib/checkheaders.cpp
+++ b/lib/checkheaders.cpp
@@ -100,7 +100,7 @@ void CheckHeaders::warningIncludeHeader()
const std::string includefile = includetok->strAt(1);
while (hfile < _tokenizer->getFiles()->size())
{
- if (FileLister::sameFileName(_tokenizer->getFiles()->at(hfile), includefile))
+ if (getFileLister()->sameFileName(_tokenizer->getFiles()->at(hfile), includefile))
break;
++hfile;
}
diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp
index 33c47e3ec..e9e8d5119 100644
--- a/lib/cppcheck.cpp
+++ b/lib/cppcheck.cpp
@@ -61,7 +61,7 @@ void CppCheck::settings(const Settings &settings)
void CppCheck::addFile(const std::string &path)
{
- FileLister::recursiveAddFiles(_filenames, path.c_str(), true);
+ getFileLister()->recursiveAddFiles(_filenames, path.c_str(), true);
}
void CppCheck::addFile(const std::string &path, const std::string &content)
@@ -373,7 +373,7 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[])
// Execute recursiveAddFiles() to each given file parameter
std::vector::const_iterator iter;
for (iter = pathnames.begin(); iter != pathnames.end(); ++iter)
- FileLister::recursiveAddFiles(_filenames, iter->c_str(), true);
+ getFileLister()->recursiveAddFiles(_filenames, iter->c_str(), true);
}
if (argc <= 1 || showHelp)
diff --git a/lib/filelister.cpp b/lib/filelister.cpp
index 615dcdce0..1aa7da105 100644
--- a/lib/filelister.cpp
+++ b/lib/filelister.cpp
@@ -17,6 +17,7 @@
*/
#include "filelister.h"
+#include "fileLister_win32.h"
#include
#include
#include
@@ -34,6 +35,18 @@
#include
#endif
+static FileLister *fileLister;
+
+FileLister * getFileLister()
+{
+ if (fileLister == NULL)
+ {
+ fileLister = new FileListerWin32;
+ return fileLister;
+ }
+ return fileLister;
+}
+
std::string FileLister::simplifyPath(const char *originalPath)
{
std::string subPath = "";
diff --git a/lib/filelister.h b/lib/filelister.h
index 181c5840a..879fa839c 100644
--- a/lib/filelister.h
+++ b/lib/filelister.h
@@ -29,14 +29,16 @@
class FileLister
{
public:
- static void recursiveAddFiles(std::vector &filenames, const std::string &path, bool recursive);
- static std::string simplifyPath(const char *originalPath);
- static bool sameFileName(const std::string &fname1, const std::string &fname2);
- static bool acceptFile(const std::string &filename);
+ virtual void recursiveAddFiles(std::vector &filenames, const std::string &path, bool recursive);
+ virtual std::string simplifyPath(const char *originalPath);
+ virtual bool sameFileName(const std::string &fname1, const std::string &fname2);
+ virtual bool acceptFile(const std::string &filename);
private:
};
+FileLister * getFileLister();
+
/// @}
-#endif // #ifndef FILELISTER_H
+#endif // #ifndef FileListerH
diff --git a/lib/filelister_win32.cpp b/lib/filelister_win32.cpp
new file mode 100644
index 000000000..8ef5b37ad
--- /dev/null
+++ b/lib/filelister_win32.cpp
@@ -0,0 +1,201 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2009 Daniel Marjamäki and Cppcheck team.
+ *
+ * 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
+ * along with this program. If not, see .
+ */
+
+#include "filelister_win32.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if defined(_WIN32)
+#include
+#ifndef __BORLANDC__
+#include
+#endif
+#endif
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+////// This code is for Microsoft Windows /////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#if defined(_WIN32)
+
+// Here is the catch: cppcheck core is Ansi code (using char type).
+// When compiling Unicode targets WinAPI automatically uses *W Unicode versions
+// of called functions. So we must convert data given to WinAPI functions from
+// ANSI to Unicode. Likewise we must convert data we get from WinAPI from
+// Unicode to ANSI.
+
+#if defined(UNICODE)
+
+static bool TransformUcs2ToAnsi(LPCWSTR psUcs, LPSTR psAnsi, int nAnsi)
+{
+ WideCharToMultiByte(CP_ACP, 0, psUcs, -1, psAnsi, nAnsi, NULL, NULL);
+ return true;
+}
+
+static bool TransformAnsiToUcs2(LPCSTR psAnsi, LPWSTR psUcs, UINT nUcs)
+{
+ MultiByteToWideChar(CP_ACP, 0, psAnsi, -1, psUcs, nUcs);
+ return true;
+}
+
+static BOOL MyIsDirectory(std::string path)
+{
+ WCHAR * unicodeCleanPath = new WCHAR[path.size() + 1];
+ TransformAnsiToUcs2(path.c_str(), unicodeCleanPath,
+ (path.size() * sizeof(WCHAR)) + 1);
+ // See http://msdn.microsoft.com/en-us/library/bb773621(VS.85).aspx
+ BOOL res = PathIsDirectory(unicodeCleanPath);
+ delete [] unicodeCleanPath;
+ return res;
+}
+
+static HANDLE MyFindFirstFile(std::string path, LPWIN32_FIND_DATA findData)
+{
+ WCHAR * unicodeOss = new wchar_t[path.size() + 1];
+ TransformAnsiToUcs2(path.c_str(), unicodeOss, (path.size() + 1) * sizeof(WCHAR));
+ HANDLE hFind = FindFirstFile(unicodeOss, findData);
+ delete [] unicodeOss;
+ return hFind;
+}
+
+#else // defined(UNICODE)
+
+static BOOL MyIsDirectory(std::string path)
+{
+#ifdef __BORLANDC__
+ return (GetFileAttributes(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY);
+#else
+// See http://msdn.microsoft.com/en-us/library/bb773621(VS.85).aspx
+return PathIsDirectory(path.c_str());
+#endif
+}
+
+static HANDLE MyFindFirstFile(std::string path, LPWIN32_FIND_DATA findData)
+{
+ HANDLE hFind = FindFirstFile(path.c_str(), findData);
+ return hFind;
+}
+
+#endif // defined(UNICODE)
+
+void FileListerWin32::recursiveAddFiles(std::vector &filenames, const std::string &path, bool recursive)
+{
+ // oss is the search string passed into FindFirst and FindNext.
+ // bdir is the base directory which is used to form pathnames.
+ // It always has a trailing backslash available for concatenation.
+ std::ostringstream bdir, oss;
+
+ std::string cleanedPath = path;
+ std::replace(cleanedPath.begin(), cleanedPath.end(), '/', '\\');
+
+ oss << cleanedPath;
+
+ if (MyIsDirectory(cleanedPath.c_str()))
+ {
+ char c = cleanedPath[ cleanedPath.size()-1 ];
+ switch (c)
+ {
+ case '\\':
+ oss << '*';
+ bdir << cleanedPath;
+ break;
+ case '*':
+ bdir << cleanedPath.substr(0, cleanedPath.length() - 1);
+ break;
+ default:
+ oss << "\\*";
+ bdir << cleanedPath << '\\';
+ }
+ }
+ else
+ {
+ std::string::size_type pos;
+ pos = cleanedPath.find_last_of('\\');
+ if (std::string::npos != pos)
+ {
+ bdir << cleanedPath.substr(0, pos + 1);
+ }
+ }
+
+ WIN32_FIND_DATA ffd;
+ HANDLE hFind = MyFindFirstFile(oss.str(), &ffd);
+ if (INVALID_HANDLE_VALUE == hFind)
+ return;
+
+ do
+ {
+ if (ffd.cFileName[0] == '.' || ffd.cFileName[0] == '\0')
+ continue;
+
+#if defined(UNICODE)
+ char * ansiFfd = new char[wcslen(ffd.cFileName) + 1];
+ TransformUcs2ToAnsi(ffd.cFileName, ansiFfd, wcslen(ffd.cFileName) + 1);
+#else // defined(UNICODE)
+ char * ansiFfd = &ffd.cFileName[0];
+#endif // defined(UNICODE)
+
+ std::ostringstream fname;
+ fname << bdir.str().c_str() << ansiFfd;
+
+ if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
+ {
+ // File
+
+ // If recursive is not used, accept all files given by user
+ if (!recursive || FileLister::acceptFile(ansiFfd))
+ filenames.push_back(fname.str());
+ }
+ else if (recursive)
+ {
+ // Directory
+ FileLister::recursiveAddFiles(filenames, fname.str().c_str(), recursive);
+ }
+#if defined(UNICODE)
+ delete [] ansiFfd;
+#endif // defined(UNICODE)
+ }
+ while (FindNextFile(hFind, &ffd) != FALSE);
+
+ if (INVALID_HANDLE_VALUE != hFind)
+ {
+ FindClose(hFind);
+ hFind = INVALID_HANDLE_VALUE;
+ }
+}
+
+#endif
+
+//---------------------------------------------------------------------------
+
+bool FileListerWin32::sameFileName(const std::string &fname1, const std::string &fname2)
+{
+#ifdef __BORLANDC__
+ return bool(stricmp(fname1.c_str(), fname2.c_str()) == 0);
+#endif
+#ifdef _MSC_VER
+ return bool(_stricmp(fname1.c_str(), fname2.c_str()) == 0);
+#endif
+}
diff --git a/lib/filelister_win32.h b/lib/filelister_win32.h
new file mode 100644
index 000000000..467ccca0d
--- /dev/null
+++ b/lib/filelister_win32.h
@@ -0,0 +1,43 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2009 Daniel Marjamäki and Cppcheck team.
+ *
+ * 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
+ * along with this program. If not, see .
+ */
+
+#ifndef FileListerWin32H
+#define FileListerWin32H
+
+#include
+#include
+#include "filelister.h"
+
+/// @addtogroup Core
+/// @{
+
+
+class FileListerWin32 : public FileLister
+{
+public:
+ virtual void recursiveAddFiles(std::vector &filenames, const std::string &path, bool recursive);
+// virtual static std::string simplifyPath(const char *originalPath);
+ virtual bool sameFileName(const std::string &fname1, const std::string &fname2);
+// virtual static bool acceptFile(const std::string &filename);
+private:
+
+};
+
+/// @}
+
+#endif // #ifndef FileListerWin32H
diff --git a/lib/lib.pri b/lib/lib.pri
index 24e2ca24e..d56336bbb 100644
--- a/lib/lib.pri
+++ b/lib/lib.pri
@@ -21,6 +21,10 @@ HEADERS += $$PWD/check.h \
$$PWD/token.h \
$$PWD/tokenize.h
+win32 {
+HEADERS += $$PWD/filelister_win32.h
+}
+
SOURCES += $$PWD/checkautovariables.cpp \
$$PWD/checkbufferoverrun.cpp \
$$PWD/checkclass.cpp \
@@ -40,3 +44,7 @@ SOURCES += $$PWD/checkautovariables.cpp \
$$PWD/settings.cpp \
$$PWD/token.cpp \
$$PWD/tokenize.cpp
+
+win32 {
+SOURCES += $$PWD/filelister_win32.cpp
+}
diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp
index 5f296e730..df960aea2 100644
--- a/lib/preprocessor.cpp
+++ b/lib/preprocessor.cpp
@@ -1325,7 +1325,7 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filename
if (fileOpened)
{
- std::string tempFile = FileLister::simplifyPath(filename.c_str());
+ std::string tempFile = getFileLister()->simplifyPath(filename.c_str());
std::transform(tempFile.begin(), tempFile.end(), tempFile.begin(), tolowerWrapper);
if (handledFiles.find(tempFile) != handledFiles.end())
{
diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp
index 30ded2a40..289778808 100644
--- a/lib/tokenize.cpp
+++ b/lib/tokenize.cpp
@@ -230,7 +230,7 @@ void Tokenizer::createTokens(std::istream &code)
fileIndexes.push_back(FileIndex);
for (unsigned int i = 0; i < _files.size(); i++)
{
- if (FileLister::sameFileName(_files[i].c_str(), line.c_str()))
+ if (getFileLister()->sameFileName(_files[i].c_str(), line.c_str()))
{
// Use this index
foundOurfile = true;
@@ -241,7 +241,7 @@ void Tokenizer::createTokens(std::istream &code)
if (!foundOurfile)
{
// The "_files" vector remembers what files have been tokenized..
- _files.push_back(FileLister::simplifyPath(line.c_str()));
+ _files.push_back(getFileLister()->simplifyPath(line.c_str()));
FileIndex = static_cast(_files.size() - 1);
}
@@ -1094,7 +1094,7 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
_configuration = configuration;
// The "_files" vector remembers what files have been tokenized..
- _files.push_back(FileLister::simplifyPath(FileName));
+ _files.push_back(getFileLister()->simplifyPath(FileName));
createTokens(code);