diff --git a/FileLister.cpp b/FileLister.cpp new file mode 100644 index 000000000..8b6b49a39 --- /dev/null +++ b/FileLister.cpp @@ -0,0 +1,216 @@ +/* + * c++check - c/c++ syntax checking + * Copyright (C) 2007-2008 Daniel Marjamäki and Reijo Tomperi + * + * 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 + +#ifdef __GNUC__ +#include +#include +#endif +#ifdef __BORLANDC__ +#include +#endif +#ifdef _MSC_VER +#include +#endif + +bool FileLister::AcceptFile( const std::string &filename ) +{ + std::string::size_type dotLocation = filename.find_last_of ( '.' ); + if ( dotLocation == std::string::npos ) + return false; + + std::string extension = filename.substr( dotLocation ); + + if( extension == ".cpp" || + extension == ".cc" || + extension == ".c" ) + { + return true; + } + + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +////// This code is for __GNUC__ only ///////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUC__ +// gcc / cygwin.. +void FileLister::RecursiveAddFiles( std::vector &filenames, const std::string &path, bool recursive ) +{ + std::ostringstream oss; + oss << path; + if( recursive ) + { + if ( path.length() > 0 && path[path.length()-1] != '/' ) + oss << "/"; + + 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++ ) + { + std::string filename = glob_results.gl_pathv[i]; + if ( filename == "." || filename == ".." || filename.length() == 0 ) + continue; + + if ( filename[filename.length()-1] != '/' ) + { + // File + + // If recursive is not used, accept all files given by user + if( !recursive || FileLister::AcceptFile( filename ) ) + filenames.push_back( filename ); + } + else if( recursive ) + { + // Directory + FileLister::RecursiveAddFiles( filenames, filename, recursive ); + } + } + globfree(&glob_results); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +////// This code is for __BORLANDC__ only ///////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +#ifdef __BORLANDC__ + +void FileLister::AddFiles( std::vector &filenames, const std::string &path, const std::string &pattern ) +{ + struct ffblk f; + for ( int done = findfirst(pattern.c_str(), &f, 0); ! done; done = findnext(&f) ) + { + std::ostringstream fname; + fname << path << f.ff_name; + filenames.push_back( fname.str() ); + } + findclose(&f); +} + + +// TODO, this should be complitely rewritten to work similarly like with __GNUC__, +// but I don't have a compiler to do the work +void FileLister::RecursiveAddFiles( std::vector &filenames, const std::string &path, bool recursive ) +{ + if( !recursive ) + { + // Simulate old behaviour + if ( path.find( '*' ) == std::string::npos ) + filenames.push_back( path ); + else + FileLister::AddFiles( filenames, "", path ); + + return; + } + + AddFiles( filenames, path, "*.cpp" ); + AddFiles( filenames, path, "*.cc" ); + AddFiles( filenames, path, "*.c" ); + + struct ffblk f ; + for ( int done = findfirst("*", &f, FA_DIREC); ! done; done = findnext(&f) ) + { + if ( f.ff_attrib != FA_DIREC || f.ff_name[0] == '.' ) + continue; + chdir( f.ff_name ); + std::ostringstream curdir; + curdir << path << f.ff_name << "/"; + FileLister::RecursiveAddFiles( filenames, curdir.str().c_str(), true ); + chdir( ".." ); + } + findclose(&f); +} + +#endif + +/////////////////////////////////////////////////////////////////////////////// +////// This code is for _MSC_VER only ///////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +#ifdef _MSC_VER + +void FileLister::AddFiles( std::vector &filenames, const std::string &path, const std::string &pattern ) +{ + + WIN32_FIND_DATA ffd; + HANDLE hFind = FindFirstFile(pattern.c_str(), &ffd); + if (INVALID_HANDLE_VALUE != hFind) + { + do + { + std::ostringstream fname; + fname << path << ffd.cFileName; + filenames.push_back( fname.str() ); + } + while (FindNextFile(hFind, &ffd) != 0); + } +} + +// TODO, this should be complitely rewritten to work similarly like with __GNUC__, +// but I don't have a compiler to do the work +void FileLister::RecursiveAddFiles( std::vector &filenames, const std::string &path, bool recursive ) +{ + if( !recursive ) + { + // Simulate old behaviour + if ( path.find( '*' ) == std::string::npos ) + filenames.push_back( path ); + else + FileLister::AddFiles( filenames, "", path ); + + return; + } + + AddFiles( filenames, path, "*.cpp" ); + AddFiles( filenames, path, "*.cc" ); + AddFiles( filenames, path, "*.c" ); + + WIN32_FIND_DATA ffd; + HANDLE hFind = FindFirstFile("*", &ffd); + if (INVALID_HANDLE_VALUE != hFind) + { + do + { + if ( (ffd.cFileName[0]!='.') && + (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) + { + SetCurrentDirectory( ffd.cFileName ); + std::ostringstream curdir; + curdir << path << ffd.cFileName << "/"; + FileLister::RecursiveAddFiles( filenames, curdir.str().c_str(), true ); + SetCurrentDirectory( ".." ); + } + } + while (FindNextFile(hFind, &ffd) != 0); + } +} + + +#endif + + + + diff --git a/FileLister.h b/FileLister.h new file mode 100644 index 000000000..3bc5c67d1 --- /dev/null +++ b/FileLister.h @@ -0,0 +1,55 @@ +/* + * c++check - c/c++ syntax checking + * Copyright (C) 2007-2008 Daniel Marjamäki and Reijo Tomperi + * + * 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 + +// Check that the compiler are supported +// This program should be compiled with either GCC/BORLAND/MSC to work.. +#ifndef __GNUC__ +#ifndef __BORLANDC__ +#ifndef _MSC_VER +#error "C++Check must be compiled by either GCC/BORLAND/MSC to work fully.\n" +#error "Please report that you couldn't compile c++check through the web page:\n" +#error " https://sourceforge.net/projects/cppcheck/" +#endif +#endif +#endif + + +class FileLister +{ +private: + static bool AcceptFile( const std::string &filename ); + +#ifdef __BORLANDC__ + static void AddFiles( std::vector &filenames, const std::string &path, const std::string &pattern ); +#endif + +#ifdef _MSC_VER + static void AddFiles( std::vector &filenames, const std::string &path, const std::string &pattern ); +#endif + +public: + static void RecursiveAddFiles( std::vector &filenames, const std::string &path, bool recursive ); +}; + +#endif // #ifndef FILELISTER_H diff --git a/Makefile b/Makefile index 28ff3a422..da67e2a5f 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -SRCS=CheckBufferOverrun.cpp CheckClass.cpp CheckHeaders.cpp CheckMemoryLeak.cpp CheckOther.cpp CommonCheck.cpp preprocessor.cpp tokenize.cpp +SRCS=CheckBufferOverrun.cpp CheckClass.cpp CheckHeaders.cpp CheckMemoryLeak.cpp CheckOther.cpp CommonCheck.cpp FileLister.cpp preprocessor.cpp tokenize.cpp OBJS=$(SRCS:%.cpp=%.o) TESTS=testbufferoverrun.o testcharvar.o testconstructors.o testdivision.o testmemleak.o testother.o testpreprocessor.o testunusedvar.o BIN = ${DESTDIR}/usr/bin diff --git a/main.cpp b/main.cpp index 01d65b1ae..d62a3e6b0 100644 --- a/main.cpp +++ b/main.cpp @@ -20,12 +20,12 @@ #include "preprocessor.h" // preprocessor. #include "tokenize.h" // <- Tokenizer #include "CommonCheck.h" - #include "CheckMemoryLeak.h" #include "CheckBufferOverrun.h" #include "CheckClass.h" #include "CheckHeaders.h" #include "CheckOther.h" +#include "FileLister.h" #include #include @@ -34,31 +34,6 @@ #include #include - -// Check that the compiler are supported -// This program should be compiled with either GCC/BORLAND/MSC to work.. -#ifndef __GNUC__ -#ifndef __BORLANDC__ -#ifndef _MSC_VER -#error "C++Check must be compiled by either GCC/BORLAND/MSC to work fully.\n" -#error "Please report that you couldn't compile c++check through the web page:\n" -#error " https://sourceforge.net/projects/cppcheck/" -#endif -#endif -#endif - - -#ifdef __GNUC__ -#include -#include -#endif -#ifdef __BORLANDC__ -#include -#endif -#ifdef _MSC_VER -#include -#endif - //--------------------------------------------------------------------------- bool Debug = false; bool ShowAll = false; @@ -68,116 +43,13 @@ bool CheckCodingStyle = false; static void CppCheck(const std::string &code, const char FileName[], unsigned int FileId); -static void AddFiles( std::vector &filenames, const char path[], const char pattern[] ) -{ - #ifdef __GNUC__ - glob_t glob_results; - glob(pattern, 0, 0, &glob_results); - for ( unsigned int i = 0; i < glob_results.gl_pathc; i++ ) - { - std::ostringstream fname; - fname << path << glob_results.gl_pathv[i]; - filenames.push_back( fname.str() ); - } - globfree(&glob_results); - #endif - #ifdef __BORLANDC__ - struct ffblk f; - for ( int done = findfirst(pattern, &f, 0); ! done; done = findnext(&f) ) - { - std::ostringstream fname; - fname << path << f.ff_name; - filenames.push_back( fname.str() ); - } - findclose(&f); - #endif - #ifdef _MSC_VER - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(pattern, &ffd); - if (INVALID_HANDLE_VALUE != hFind) - { - do - { - std::ostringstream fname; - fname << path << ffd.cFileName; - filenames.push_back( fname.str() ); - } - while (FindNextFile(hFind, &ffd) != 0); - } - #endif -} - -static void RecursiveAddFiles( std::vector &filenames, const char path[] ) -{ - AddFiles( filenames, path, "*.cpp" ); - AddFiles( filenames, path, "*.cc" ); - AddFiles( filenames, path, "*.c" ); - - #ifdef __GNUC__ - // gcc / cygwin.. - glob_t glob_results; - glob("*", GLOB_MARK, 0, &glob_results); - for ( unsigned int i = 0; i < glob_results.gl_pathc; i++ ) - { - const char *dirname = glob_results.gl_pathv[i]; - if ( dirname[0] == '.' ) - continue; - - if ( strchr(dirname, '/') == 0 ) - continue; - - chdir( dirname ); - std::ostringstream curdir; - curdir << path << dirname; - RecursiveAddFiles( filenames, curdir.str().c_str() ); - chdir( ".." ); - } - globfree(&glob_results); - #endif - #ifdef __BORLANDC__ - struct ffblk f ; - for ( int done = findfirst("*", &f, FA_DIREC); ! done; done = findnext(&f) ) - { - if ( f.ff_attrib != FA_DIREC || f.ff_name[0] == '.' ) - continue; - chdir( f.ff_name ); - std::ostringstream curdir; - curdir << path << f.ff_name << "/"; - RecursiveAddFiles( filenames, curdir.str().c_str() ); - chdir( ".." ); - } - findclose(&f); - #endif - #ifdef _MSC_VER - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile("*", &ffd); - if (INVALID_HANDLE_VALUE != hFind) - { - do - { - if ( (ffd.cFileName[0]!='.') && - (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) - { - SetCurrentDirectory( ffd.cFileName ); - std::ostringstream curdir; - curdir << path << ffd.cFileName << "/"; - RecursiveAddFiles( filenames, curdir.str().c_str() ); - SetCurrentDirectory( ".." ); - } - } - while (FindNextFile(hFind, &ffd) != 0); - } - #endif -} - //--------------------------------------------------------------------------- // Main function of cppcheck //--------------------------------------------------------------------------- int main(int argc, char* argv[]) { - std::vector filenames; - + std::vector pathnames; bool Recursive = false; for (int i = 1; i < argc; i++) @@ -195,21 +67,37 @@ int main(int argc, char* argv[]) else if (strcmp(argv[i],"--recursive")==0) Recursive = true; - - else if (strchr(argv[i],'*')) - { - AddFiles( filenames, "", argv[i] ); - } - else - { - filenames.push_back( argv[i] ); - } + pathnames.push_back( argv[i] ); } - // No filename given.. automaticly search for available files. + std::vector filenames; + // --recursive was used if ( Recursive ) - RecursiveAddFiles( filenames, "" ); + { + if( pathnames.size() == 0 ) + { + // Handle situation: cppcheck --recursive + FileLister::RecursiveAddFiles( filenames, "", true ); + } + else + { + // Handle situation: cppcheck --recursive path1 path2 + + // 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 ); + } + } + else + { + std::vector::const_iterator iter; + for(iter=pathnames.begin(); iter!=pathnames.end(); iter++) + FileLister::RecursiveAddFiles( filenames, iter->c_str(), false ); + } + + if (filenames.empty()) {