[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/cppcheck-opensource/cppcheck/main/cli/filelister.cpp [Back]  [Original]

/*
 * Cppcheck - A tool for static C/C++ code analysis
 * Copyright (C) 2007-2026 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 .
 */

#if defined(__CYGWIN__)
#define _BSD_SOURCE // required to have DT_DIR and DT_UNKNOWN
#endif

#include "filelister.h"

#include "filesettings.h"
#include "path.h"
#include "pathmatch.h"
#include "standards.h"
#include "utils.h"

#include 
#include 
#include 
#include 

#ifdef _WIN32

///////////////////////////////////////////////////////////////////////////////
////// This code is WIN32 systems /////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

#include 
#include 

// 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. Thus, we explicitly call *A versions of the functions.

static std::string addFiles2(std::list&files, const std::string &path, const std::set &extra, bool recursive, const PathMatch& ignored, bool debug = false)
{
    const std::string cleanedPath = Path::toNativeSeparators(path);

    // basedir is the base directory which is used to form pathnames.
    // It always has a trailing backslash available for concatenation.
    std::string basedir;

    // searchPattern is the search string passed into FindFirst and FindNext.
    std::string searchPattern = cleanedPath;

    // The user wants to check all files in a dir
    const bool checkAllFilesInDir = Path::isDirectory(cleanedPath);

    if (checkAllFilesInDir) {
        const char c = cleanedPath.back();
        switch (c) {
        case '\\':
            searchPattern += '*';
            basedir = cleanedPath;
            break;
        case '*':
            basedir = cleanedPath.substr(0, cleanedPath.length() - 1);
            break;
        default:
            searchPattern += "\\*";
            if (cleanedPath != ".")
                basedir = cleanedPath + '\\';
        }
    } else {
        const std::string::size_type pos = cleanedPath.find_last_of('\\');
        if (std::string::npos != pos) {
            basedir = cleanedPath.substr(0, pos + 1);
        }
    }

    WIN32_FIND_DATAA ffd;
    HANDLE hFind = FindFirstFileA(searchPattern.c_str(), &ffd);
    if (INVALID_HANDLE_VALUE == hFind) {
        const DWORD err = GetLastError();
        if (err == ERROR_FILE_NOT_FOUND || // the pattern did not match anything
            err == ERROR_PATH_NOT_FOUND)   // the given search path does not exist
        {
            return "";
        }
        return "finding files failed. Search pattern: '" + searchPattern + "'. (error: " + std::to_string(err) + ")";
    }
    std::unique_ptr hFind_deleter(hFind, FindClose);

    do {
        if (ffd.cFileName[0] != '.' && ffd.cFileName[0] != '\0')
        {
            const char* ansiFfd = ffd.cFileName;
            if (std::strchr(ansiFfd,'?')) {
                ansiFfd = ffd.cAlternateFileName;
            }

            const std::string fname(basedir + ansiFfd);

            if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
                // File
                Standards::Language lang = Standards::Language::None;
                if ((!checkAllFilesInDir || Path::acceptFile(fname, extra, &lang))) {
                    if (!ignored.match(fname)) {
                        std::string nativename = Path::fromNativeSeparators(fname);

                        // Limitation: file sizes are assumed to fit in a 'size_t'
#ifdef _WIN64
                        const std::size_t filesize = (static_cast(ffd.nFileSizeHigh) d_type == DT_DIR || (dir_result->d_type == DT_UNKNOWN && Path::isDirectory(new_path)));
#else
        const bool path_is_directory = Path::isDirectory(new_path);
#endif
        if (path_is_directory) {
            if (recursive) {
                if (!ignored.match(new_path, PathMatch::Filemode::directory)) {
                    std::string err = addFiles2(files, new_path, extra, recursive, ignored, debug);
                    if (!err.empty()) {
                        return err;
                    }
                }
                else if (debug)
                {
                    std::cout 

Web Proxy Viewer  |  New URL  |  Original Page