From 8caf96be63f08079daa66078dc502d29a452ffed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 20 Mar 2011 14:25:11 +0100 Subject: [PATCH] FileLister: Moved back the code into a single cpp file --- Makefile | 24 +-- cli/cppcheckexecutor.cpp | 4 +- cli/filelister.cpp | 299 ++++++++++++++++++++++++++++++++--- cli/filelister.h | 32 ++-- cli/filelister_unix.cpp | 128 --------------- cli/filelister_unix.h | 45 ------ cli/filelister_win32.cpp | 200 ----------------------- cli/filelister_win32.h | 41 ----- test/testfilelister_unix.cpp | 11 +- tools/dmake.cpp | 14 +- 10 files changed, 309 insertions(+), 489 deletions(-) delete mode 100644 cli/filelister_unix.cpp delete mode 100644 cli/filelister_unix.h delete mode 100644 cli/filelister_win32.cpp delete mode 100644 cli/filelister_win32.h diff --git a/Makefile b/Makefile index c0e5675cc..3c66e8678 100644 --- a/Makefile +++ b/Makefile @@ -61,8 +61,6 @@ LIBOBJ = lib/checkautovariables.o \ CLIOBJ = cli/cmdlineparser.o \ cli/cppcheckexecutor.o \ cli/filelister.o \ - cli/filelister_unix.o \ - cli/filelister_win32.o \ cli/main.o \ cli/pathmatch.o \ cli/threadexecutor.o @@ -122,8 +120,8 @@ cppcheck: $(LIBOBJ) $(CLIOBJ) $(EXTOBJ) all: cppcheck testrunner -testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/filelister.o cli/filelister_unix.o cli/pathmatch.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/filelister.o cli/filelister_unix.o cli/pathmatch.o $(LDFLAGS) +testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/filelister.o cli/pathmatch.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/filelister.o cli/pathmatch.o $(LDFLAGS) test: all ./testrunner @@ -132,7 +130,7 @@ check: all ./testrunner -g -q dmake: tools/dmake.cpp - $(CXX) -o dmake tools/dmake.cpp cli/filelister*.cpp lib/path.cpp -Ilib + $(CXX) -o dmake tools/dmake.cpp cli/filelister.cpp lib/path.cpp -Ilib clean: rm -f lib/*.o cli/*.o test/*.o externals/tinyxml/*.o testrunner cppcheck cppcheck.1 @@ -168,7 +166,7 @@ lib/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/checkexceptionsafet lib/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/checkmemoryleak.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h lib/symboldatabase.h lib/mathlib.h lib/executionpath.h lib/checkuninitvar.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_LIB} -c -o lib/checkmemoryleak.o lib/checkmemoryleak.cpp -lib/checknullpointer.o: lib/checknullpointer.cpp lib/checknullpointer.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h lib/executionpath.h lib/mathlib.h +lib/checknullpointer.o: lib/checknullpointer.cpp lib/checknullpointer.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h lib/executionpath.h lib/mathlib.h lib/symboldatabase.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_LIB} -c -o lib/checknullpointer.o lib/checknullpointer.cpp lib/checkobsoletefunctions.o: lib/checkobsoletefunctions.cpp lib/checkobsoletefunctions.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h @@ -180,7 +178,7 @@ lib/checkother.o: lib/checkother.cpp lib/checkother.h lib/check.h lib/token.h li lib/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/checkpostfixoperator.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_LIB} -c -o lib/checkpostfixoperator.o lib/checkpostfixoperator.cpp -lib/checkstl.o: lib/checkstl.cpp lib/checkstl.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h lib/executionpath.h +lib/checkstl.o: lib/checkstl.cpp lib/checkstl.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h lib/executionpath.h lib/symboldatabase.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_LIB} -c -o lib/checkstl.o lib/checkstl.cpp lib/checkuninitvar.o: lib/checkuninitvar.cpp lib/checkuninitvar.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h lib/mathlib.h lib/executionpath.h lib/checknullpointer.h @@ -228,15 +226,9 @@ cli/cmdlineparser.o: cli/cmdlineparser.cpp lib/cppcheck.h lib/settings.h lib/err cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cppcheckexecutor.h lib/errorlogger.h lib/settings.h lib/cppcheck.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h cli/threadexecutor.h cli/cmdlineparser.h cli/filelister.h lib/path.h cli/pathmatch.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_CLI} -c -o cli/cppcheckexecutor.o cli/cppcheckexecutor.cpp -cli/filelister.o: cli/filelister.cpp cli/filelister.h cli/filelister_win32.h cli/filelister_unix.h +cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/path.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_CLI} -c -o cli/filelister.o cli/filelister.cpp -cli/filelister_unix.o: cli/filelister_unix.cpp lib/path.h cli/filelister.h cli/filelister_unix.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_CLI} -c -o cli/filelister_unix.o cli/filelister_unix.cpp - -cli/filelister_win32.o: cli/filelister_win32.cpp cli/filelister.h cli/filelister_win32.h lib/path.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_CLI} -c -o cli/filelister_win32.o cli/filelister_win32.cpp - cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/errorlogger.h lib/settings.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_CLI} -c -o cli/main.o cli/main.cpp @@ -300,7 +292,7 @@ test/testobsoletefunctions.o: test/testobsoletefunctions.cpp lib/tokenize.h lib/ test/testoptions.o: test/testoptions.cpp test/options.h test/testsuite.h lib/errorlogger.h lib/settings.h test/redirect.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_TEST} -c -o test/testoptions.o test/testoptions.cpp -test/testother.o: test/testother.cpp lib/tokenize.h lib/checkother.h lib/check.h lib/token.h lib/settings.h lib/errorlogger.h test/testsuite.h test/redirect.h +test/testother.o: test/testother.cpp lib/preprocessor.h lib/tokenize.h lib/checkother.h lib/check.h lib/token.h lib/settings.h lib/errorlogger.h test/testsuite.h test/redirect.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_TEST} -c -o test/testother.o test/testother.cpp test/testpath.o: test/testpath.cpp test/testsuite.h lib/errorlogger.h lib/settings.h test/redirect.h lib/path.h @@ -330,7 +322,7 @@ test/teststl.o: test/teststl.cpp lib/tokenize.h lib/checkstl.h lib/check.h lib/t test/testsuite.o: test/testsuite.cpp test/testsuite.h lib/errorlogger.h lib/settings.h test/redirect.h test/options.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_TEST} -c -o test/testsuite.o test/testsuite.cpp -test/testsuppressions.o: test/testsuppressions.cpp lib/cppcheck.h lib/settings.h lib/errorlogger.h lib/checkunusedfunctions.h lib/check.h cli/threadexecutor.h lib/token.h lib/tokenize.h test/testsuite.h test/redirect.h +test/testsuppressions.o: test/testsuppressions.cpp lib/cppcheck.h lib/settings.h lib/errorlogger.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h test/testsuite.h test/redirect.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) ${INCLUDE_FOR_TEST} -c -o test/testsuppressions.o test/testsuppressions.cpp test/testsymboldatabase.o: test/testsymboldatabase.cpp test/testsuite.h lib/errorlogger.h lib/settings.h test/redirect.h test/testutils.h lib/tokenize.h lib/token.h lib/symboldatabase.h diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 33092b363..f484281b4 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -71,7 +71,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c ++iter) { const std::string path(Path::toNativeSeparators(*iter)); - if (!getFileLister()->isDirectory(path.c_str())) + if (!FileLister::isDirectory(path)) { std::cout << "cppcheck: error: Couldn't find path given by -I '" + path + "'" << std::endl; return false; @@ -87,7 +87,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c // Execute recursiveAddFiles() to each given file parameter std::vector::const_iterator iter; for (iter = pathnames.begin(); iter != pathnames.end(); ++iter) - getFileLister()->recursiveAddFiles(filenames, Path::toNativeSeparators(iter->c_str())); + FileLister::recursiveAddFiles(filenames, Path::toNativeSeparators(*iter)); } if (!filenames.empty()) diff --git a/cli/filelister.cpp b/cli/filelister.cpp index 2c15d92dd..e523474cf 100644 --- a/cli/filelister.cpp +++ b/cli/filelister.cpp @@ -21,30 +21,7 @@ #include #include #include "filelister.h" - -#if defined(_WIN32) -#include "filelister_win32.h" -#else // POSIX-style system -#include "filelister_unix.h" -#endif - -// We have one singleton FileLister. - -static FileLister *fileLister; - -FileLister * getFileLister() -{ - if (fileLister == NULL) - { -#if defined(_WIN32) - fileLister = new FileListerWin32; -#else // POSIX-style system - fileLister = new FileListerUnix; -#endif - return fileLister; - } - return fileLister; -} +#include "path.h" // This wrapper exists because Sun's CC does not allow a static_cast // from extern "C" int(*)(int) to int(*)(int). @@ -75,3 +52,277 @@ bool FileLister::acceptFile(const std::string &filename) return false; } + + +#ifdef _WIN32 + +/////////////////////////////////////////////////////////////////////////////// +////// This code is WIN32 systems ///////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +#include +#ifndef __BORLANDC__ +#include +#endif + +// 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. + +// Note that qmake creates VS project files that define UNICODE but don't +// define _UNICODE! Which means e.g. TCHAR macros don't work properly. + +#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 FileLister::recursiveAddFiles(std::vector &filenames, const std::string &path) +{ + // 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::toNativeSeparators(path); + + 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 << "\\*"; + if (cleanedPath != ".") + 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) + const char * ansiFfd = &ffd.cFileName[0]; + if (strchr(ansiFfd,'?')) + { + ansiFfd = &ffd.cAlternateFileName[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 (Path::sameFileName(path,ansiFfd) || FileLister::acceptFile(ansiFfd)) + { + const std::string nativename = Path::fromNativeSeparators(fname.str()); + filenames.push_back(nativename); + } + } + else + { + // Directory + getFileLister()->recursiveAddFiles(filenames, fname.str()); + } +#if defined(UNICODE) + delete [] ansiFfd; +#endif // defined(UNICODE) + } + while (FindNextFile(hFind, &ffd) != FALSE); + + if (INVALID_HANDLE_VALUE != hFind) + { + FindClose(hFind); + hFind = INVALID_HANDLE_VALUE; + } +} + +bool FileLister::isDirectory(const std::string &path) +{ + return (MyIsDirectory(path) != FALSE); +} + + + + +#else + +/////////////////////////////////////////////////////////////////////////////// +////// This code is POSIX-style systems /////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +void FileLister::recursiveAddFiles2(std::vector &relative, + std::vector &absolute, + const std::string &path) +{ + std::ostringstream oss; + oss << path; + if (path.length() > 0 && path[path.length()-1] == '/') + oss << "*"; + + glob_t glob_results; + glob(oss.str().c_str(), GLOB_MARK, 0, &glob_results); + for (unsigned int i = 0; i < glob_results.gl_pathc; i++) + { + const std::string filename = glob_results.gl_pathv[i]; + if (filename == "." || filename == ".." || filename.length() == 0) + continue; + + if (filename[filename.length()-1] != '/') + { + // File +#ifdef PATH_MAX + char fname[PATH_MAX]; + if (realpath(filename.c_str(), fname) == NULL) +#else + char *fname; + if ((fname = realpath(filename.c_str(), NULL)) == NULL) +#endif + { + continue; + } + + // Does absolute path exist? then bail out + if (std::find(absolute.begin(), absolute.end(), std::string(fname)) != absolute.end()) + { +#ifndef PATH_MAX + free(fname); +#endif + continue; + } + + if (Path::sameFileName(path,filename) || FileLister::acceptFile(filename)) + { + relative.push_back(filename); + absolute.push_back(fname); + } + +#ifndef PATH_MAX + free(fname); +#endif + } + else + { + // Directory + recursiveAddFiles2(relative, absolute, filename); + } + } + globfree(&glob_results); +} + + +void FileLister::recursiveAddFiles(std::vector &filenames, const std::string &path) +{ + std::vector abs; + recursiveAddFiles2(filenames, abs, path); +} + +bool FileLister::isDirectory(const std::string &path) +{ + bool ret = false; + + glob_t glob_results; + glob(path.c_str(), GLOB_MARK, 0, &glob_results); + if (glob_results.gl_pathc == 1) + { + const std::string glob_path = glob_results.gl_pathv[0]; + if (!glob_path.empty() && glob_path[glob_path.size() - 1] == '/') + { + ret = true; + } + } + globfree(&glob_results); + + return ret; +} + +#endif diff --git a/cli/filelister.h b/cli/filelister.h index 4c6cd7d03..b2ee6569e 100644 --- a/cli/filelister.h +++ b/cli/filelister.h @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -#ifndef FileListerH -#define FileListerH +#ifndef filelisterH +#define filelisterH #include #include @@ -25,19 +25,10 @@ /// @addtogroup CLI /// @{ -/** - * @brief Base class for Cppcheck filelisters. - * Used to recursively search for source files. This class defines a platform - * independant interface and subclasses will provide platform dependant - * implementation. */ +/** @brief Cross-platform FileLister */ class FileLister { public: - /** - * @brief destructor of class filelister - */ - virtual ~FileLister() {} - /** * @brief Recursively add source files to a vector. * Add source files from given directory and all subdirectries to the @@ -46,8 +37,8 @@ public: * @param filenames output vector that filenames are written to * @param path root path */ - virtual void recursiveAddFiles(std::vector &filenames, - const std::string &path) = 0; + static void recursiveAddFiles(std::vector &filenames, + const std::string &path); /** * @brief Check if the file extension indicates that it's a source file. @@ -61,12 +52,15 @@ public: * @brief Is given path a directory? * @return returns true if the path is a directory */ - virtual bool isDirectory(const std::string &path) = 0; -}; + static bool isDirectory(const std::string &path); -/** @brief get filelister (platform dependent implementation) */ -FileLister * getFileLister(); +#ifndef _WIN32 + static void recursiveAddFiles2(std::vector &relative, + std::vector &absolute, + const std::string &path); +#endif +}; /// @} -#endif // #ifndef FileListerH +#endif // #ifndef filelisterH diff --git a/cli/filelister_unix.cpp b/cli/filelister_unix.cpp deleted file mode 100644 index e961f9a84..000000000 --- a/cli/filelister_unix.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2011 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 -#include -#include -#include -#include - -#ifndef _WIN32 // POSIX-style system -#include -#include -#include -#include -#endif - -#ifndef _WIN32 - -#include "path.h" -#include "filelister.h" -#include "filelister_unix.h" - -/////////////////////////////////////////////////////////////////////////////// -////// This code is POSIX-style systems /////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - -void FileListerUnix::recursiveAddFiles2(std::vector &relative, - std::vector &absolute, - const std::string &path) -{ - std::ostringstream oss; - oss << path; - if (path.length() > 0 && path[path.length()-1] == '/') - oss << "*"; - - glob_t glob_results; - glob(oss.str().c_str(), GLOB_MARK, 0, &glob_results); - for (unsigned int i = 0; i < glob_results.gl_pathc; i++) - { - const std::string filename = glob_results.gl_pathv[i]; - if (filename == "." || filename == ".." || filename.length() == 0) - continue; - - if (filename[filename.length()-1] != '/') - { - // File -#ifdef PATH_MAX - char fname[PATH_MAX]; - if (realpath(filename.c_str(), fname) == NULL) -#else - char *fname; - if ((fname = realpath(filename.c_str(), NULL)) == NULL) -#endif - { - continue; - } - - // Does absolute path exist? then bail out - if (std::find(absolute.begin(), absolute.end(), std::string(fname)) != absolute.end()) - { -#ifndef PATH_MAX - free(fname); -#endif - continue; - } - - if (Path::sameFileName(path,filename) || FileLister::acceptFile(filename)) - { - relative.push_back(filename); - absolute.push_back(fname); - } - -#ifndef PATH_MAX - free(fname); -#endif - } - else - { - // Directory - recursiveAddFiles2(relative, absolute, filename); - } - } - globfree(&glob_results); -} - - -void FileListerUnix::recursiveAddFiles(std::vector &filenames, const std::string &path) -{ - std::vector abs; - recursiveAddFiles2(filenames, abs, path); -} - -bool FileListerUnix::isDirectory(const std::string &path) -{ - bool ret = false; - - glob_t glob_results; - glob(path.c_str(), GLOB_MARK, 0, &glob_results); - if (glob_results.gl_pathc == 1) - { - const std::string glob_path = glob_results.gl_pathv[0]; - if (!glob_path.empty() && glob_path[glob_path.size() - 1] == '/') - { - ret = true; - } - } - globfree(&glob_results); - - return ret; -} - -#endif // _WIN32 diff --git a/cli/filelister_unix.h b/cli/filelister_unix.h deleted file mode 100644 index 594580f0d..000000000 --- a/cli/filelister_unix.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2011 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 FileListerUnixH -#define FileListerUnixH - -#include -#include -#include "filelister.h" - -/// @addtogroup CLI -/// @{ - - -class FileListerUnix : public FileLister -{ -public: - virtual void recursiveAddFiles(std::vector &filenames, const std::string &path); - virtual bool isDirectory(const std::string &path); -private: -#ifndef _WIN32 - void recursiveAddFiles2(std::vector &relative, - std::vector &absolute, - const std::string &path); -#endif -}; - -/// @} - -#endif // #ifndef FileListerUnixH diff --git a/cli/filelister_win32.cpp b/cli/filelister_win32.cpp deleted file mode 100644 index 776e0245a..000000000 --- a/cli/filelister_win32.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2011 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 -#include -#include -#include -#include -#include - -#include "filelister.h" -#include "filelister_win32.h" -#include "path.h" - -#if defined(_WIN32) -#include -#ifndef __BORLANDC__ -#include -#endif -#endif - - -#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. - -// Note that qmake creates VS project files that define UNICODE but don't -// define _UNICODE! Which means e.g. TCHAR macros don't work properly. - -#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) -{ - // 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::toNativeSeparators(path); - - 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 << "\\*"; - if (cleanedPath != ".") - 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) - const char * ansiFfd = &ffd.cFileName[0]; - if (strchr(ansiFfd,'?')) - { - ansiFfd = &ffd.cAlternateFileName[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 (Path::sameFileName(path,ansiFfd) || FileLister::acceptFile(ansiFfd)) - { - const std::string nativename = Path::fromNativeSeparators(fname.str()); - filenames.push_back(nativename); - } - } - else - { - // Directory - getFileLister()->recursiveAddFiles(filenames, fname.str()); - } -#if defined(UNICODE) - delete [] ansiFfd; -#endif // defined(UNICODE) - } - while (FindNextFile(hFind, &ffd) != FALSE); - - if (INVALID_HANDLE_VALUE != hFind) - { - FindClose(hFind); - hFind = INVALID_HANDLE_VALUE; - } -} - -bool FileListerWin32::isDirectory(const std::string &path) -{ - return (MyIsDirectory(path) != FALSE); -} - -#endif // _WIN32 diff --git a/cli/filelister_win32.h b/cli/filelister_win32.h deleted file mode 100644 index 1095c79d7..000000000 --- a/cli/filelister_win32.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2011 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 CLI -/// @{ - - -class FileListerWin32 : public FileLister -{ -public: - virtual void recursiveAddFiles(std::vector &filenames, const std::string &path); - virtual bool isDirectory(const std::string &path); -private: - -}; - -/// @} - -#endif // #ifndef FileListerWin32H diff --git a/test/testfilelister_unix.cpp b/test/testfilelister_unix.cpp index 86b038cec..61e44b73e 100644 --- a/test/testfilelister_unix.cpp +++ b/test/testfilelister_unix.cpp @@ -18,9 +18,7 @@ #include "testsuite.h" -#define private public - -#include "filelister_unix.h" +#include "filelister.h" class TestFileLister: public TestFixture { @@ -32,14 +30,16 @@ public: private: void run() { +#ifndef _WIN32 TEST_CASE(test_recursiveAddFiles2); +#endif } +#ifndef _WIN32 void test_recursiveAddFiles2() { std::vector relative, absolute; - FileListerUnix ful; - ful.recursiveAddFiles2(relative, absolute, "."); + FileLister::recursiveAddFiles2(relative, absolute, "."); ASSERT(relative.size() != 0); ASSERT_EQUALS((int)relative.size(), (int)absolute.size()); @@ -56,6 +56,7 @@ private: ASSERT_EQUALS(r->substr(start_at_relative), a->substr(start_at_absolute)); } } +#endif }; REGISTER_TEST(TestFileLister) diff --git a/tools/dmake.cpp b/tools/dmake.cpp index 3332f14c5..a3819c216 100644 --- a/tools/dmake.cpp +++ b/tools/dmake.cpp @@ -25,11 +25,7 @@ #include #include -#if defined(_WIN32) -#include "../cli/filelister_win32.h" -#else // POSIX-style system -#include "../cli/filelister_unix.h" -#endif +#include "../cli/filelister.h" std::string objfile(std::string cppfile) { @@ -88,7 +84,7 @@ static void compilefiles(std::ostream &fout, const std::vector &fil static void getCppFiles(std::vector &files, const std::string &path) { - getFileLister()->recursiveAddFiles(files, path); + FileLister::recursiveAddFiles(files, path); // only get *.cpp files.. for (std::vector::iterator it = files.begin(); it != files.end();) { @@ -280,14 +276,14 @@ int main(int argc, char **argv) fout << "cppcheck: $(LIBOBJ) $(CLIOBJ) $(EXTOBJ)\n"; fout << "\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o cppcheck $(CLIOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre $(LDFLAGS)\n\n"; fout << "all:\tcppcheck testrunner\n\n"; - fout << "testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/filelister.o cli/filelister_unix.o cli/pathmatch.o\n"; - fout << "\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/filelister.o cli/filelister_unix.o cli/pathmatch.o $(LDFLAGS)\n\n"; + fout << "testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/filelister.o cli/pathmatch.o\n"; + fout << "\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/filelister.o cli/pathmatch.o $(LDFLAGS)\n\n"; fout << "test:\tall\n"; fout << "\t./testrunner\n\n"; fout << "check:\tall\n"; fout << "\t./testrunner -g -q\n\n"; fout << "dmake:\ttools/dmake.cpp\n"; - fout << "\t$(CXX) -o dmake tools/dmake.cpp cli/filelister*.cpp lib/path.cpp -Ilib\n\n"; + fout << "\t$(CXX) -o dmake tools/dmake.cpp cli/filelister.cpp lib/path.cpp -Ilib\n\n"; fout << "clean:\n"; #ifdef _WIN32 fout << "\tdel lib\*.o\n\tdel cli\*.o\n\tdel test\*.o\n\tdel *.exe\n";