Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 83 additions & 19 deletions simplecpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,6 @@
* Copyright (C) 2016-2023 simplecpp team
*/

#if defined(_WIN32)
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0602
# endif
# ifndef NOMINMAX
# define NOMINMAX
# endif
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# undef ERROR
#endif

#include "simplecpp.h"

#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
Expand Down Expand Up @@ -51,10 +37,22 @@
#include <utility>
#include <vector>

#ifdef _WIN32
#if defined(_WIN32)
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0602
# endif
# ifndef NOMINMAX
# define NOMINMAX
# endif
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# undef ERROR
# include <direct.h>
#else
# include <sys/stat.h>
# include <sys/types.h>
#endif

static bool isHex(const std::string &s)
Expand Down Expand Up @@ -3075,6 +3073,65 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
return "";
}

namespace {
struct FileID {
#ifdef _WIN32
struct {
std::uint64_t VolumeSerialNumber;
struct {
std::uint64_t IdentifierHi;
std::uint64_t IdentifierLo;
} FileId;
} fileIdInfo;

bool operator==(const FileID &that) const noexcept {
return fileIdInfo.VolumeSerialNumber == that.fileIdInfo.VolumeSerialNumber &&
fileIdInfo.FileId.IdentifierHi == that.fileIdInfo.FileId.IdentifierHi &&
fileIdInfo.FileId.IdentifierLo == that.fileIdInfo.FileId.IdentifierLo;
}
#else
dev_t dev;
ino_t ino;

bool operator==(const FileID& that) const noexcept {
return dev == that.dev && ino == that.ino;
}
#endif
struct Hasher {
std::size_t operator()(const FileID &id) const {
#ifdef _WIN32
return static_cast<std::size_t>(id.fileIdInfo.FileId.IdentifierHi ^ id.fileIdInfo.FileId.IdentifierLo ^
id.fileIdInfo.VolumeSerialNumber);
#else
return static_cast<std::size_t>(id.dev) ^ static_cast<std::size_t>(id.ino);
#endif
}
};
};
}

struct simplecpp::FileDataCache::Impl
{
void clear()
{
mIdMap.clear();
}

using id_map_type = std::unordered_map<FileID, FileData *, FileID::Hasher>;

id_map_type mIdMap;
};

simplecpp::FileDataCache::FileDataCache()
: mImpl(new Impl)
{}

simplecpp::FileDataCache::~FileDataCache() = default;
simplecpp::FileDataCache::FileDataCache(FileDataCache &&) noexcept = default;
simplecpp::FileDataCache &simplecpp::FileDataCache::operator=(simplecpp::FileDataCache &&) noexcept = default;

static bool getFileId(const std::string &path, FileID &id);

std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDataCache::name_map_type::iterator &name_it, const simplecpp::DUI &dui, std::vector<std::string> &filenames, simplecpp::OutputList *outputList)
{
const std::string &path = name_it->first;
Expand All @@ -3083,8 +3140,8 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
if (!getFileId(path, fileId))
return {nullptr, false};

const auto id_it = mIdMap.find(fileId);
if (id_it != mIdMap.end()) {
const auto id_it = mImpl->mIdMap.find(fileId);
if (id_it != mImpl->mIdMap.end()) {
name_it->second = id_it->second;
return {id_it->second, false};
}
Expand All @@ -3095,7 +3152,7 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
data->tokens.removeComments();

name_it->second = data;
mIdMap.emplace(fileId, data);
mImpl->mIdMap.emplace(fileId, data);
mData.emplace_back(data);

return {data, true};
Expand Down Expand Up @@ -3147,7 +3204,14 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::get(const std::
return {nullptr, false};
}

bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id)
void simplecpp::FileDataCache::clear()
{
mImpl->clear();
mNameMap.clear();
mData.clear();
}

bool getFileId(const std::string &path, FileID &id)
{
#ifdef _WIN32
HANDLE hFile = CreateFileA(path.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
Expand Down
57 changes: 7 additions & 50 deletions simplecpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@
# define SIMPLECPP_LIB
#endif

#ifndef _WIN32
# include <sys/types.h>
#endif

#if defined(_MSC_VER)
# pragma warning(push)
// suppress warnings about "conversion from 'type1' to 'type2', possible loss of data"
Expand Down Expand Up @@ -452,13 +448,14 @@ namespace simplecpp {

class SIMPLECPP_LIB FileDataCache {
public:
FileDataCache() = default;
FileDataCache();
~FileDataCache();

FileDataCache(const FileDataCache &) = delete;
FileDataCache(FileDataCache &&) = default;
FileDataCache(FileDataCache &&) noexcept;

FileDataCache &operator=(const FileDataCache &) = delete;
FileDataCache &operator=(FileDataCache &&) = default;
FileDataCache &operator=(FileDataCache &&) noexcept;

/** Get the cached data for a file, or load and then return it if it isn't cached.
* returns the file data and true if the file was loaded, false if it was cached. */
Expand All @@ -472,11 +469,7 @@ namespace simplecpp {
mNameMap.emplace(newdata->filename, newdata);
}

void clear() {
mNameMap.clear();
mIdMap.clear();
mData.clear();
}
void clear();

using container_type = std::vector<std::unique_ptr<FileData>>;
using iterator = container_type::iterator;
Expand Down Expand Up @@ -506,51 +499,15 @@ namespace simplecpp {
}

private:
struct FileID {
#ifdef _WIN32
struct {
std::uint64_t VolumeSerialNumber;
struct {
std::uint64_t IdentifierHi;
std::uint64_t IdentifierLo;
} FileId;
} fileIdInfo;

bool operator==(const FileID &that) const noexcept {
return fileIdInfo.VolumeSerialNumber == that.fileIdInfo.VolumeSerialNumber &&
fileIdInfo.FileId.IdentifierHi == that.fileIdInfo.FileId.IdentifierHi &&
fileIdInfo.FileId.IdentifierLo == that.fileIdInfo.FileId.IdentifierLo;
}
#else
dev_t dev;
ino_t ino;

bool operator==(const FileID& that) const noexcept {
return dev == that.dev && ino == that.ino;
}
#endif
struct Hasher {
std::size_t operator()(const FileID &id) const {
#ifdef _WIN32
return static_cast<std::size_t>(id.fileIdInfo.FileId.IdentifierHi ^ id.fileIdInfo.FileId.IdentifierLo ^
id.fileIdInfo.VolumeSerialNumber);
#else
return static_cast<std::size_t>(id.dev) ^ static_cast<std::size_t>(id.ino);
#endif
}
};
};
struct Impl;
std::unique_ptr<Impl> mImpl;

using name_map_type = std::unordered_map<std::string, FileData *>;
using id_map_type = std::unordered_map<FileID, FileData *, FileID::Hasher>;

static bool getFileId(const std::string &path, FileID &id);

std::pair<FileData *, bool> tryload(name_map_type::iterator &name_it, const DUI &dui, std::vector<std::string> &filenames, OutputList *outputList);

container_type mData;
name_map_type mNameMap;
id_map_type mIdMap;
};

/** Converts character literal (including prefix, but not ud-suffix) to long long value.
Expand Down
Loading