Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some platform-dependent code cleanups #310

Merged
merged 1 commit into from
Sep 11, 2023
Merged
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
115 changes: 66 additions & 49 deletions simplecpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
#include <stdexcept>
#include <string>
#if __cplusplus >= 201103L
#ifdef SIMPLECPP_WINDOWS
#include <mutex>
#endif
#include <unordered_map>
#endif
#include <utility>
Expand Down Expand Up @@ -139,11 +142,6 @@ static unsigned long long stringToULL(const std::string &s)
return ret;
}

static bool startsWith(const std::string &str, const std::string &s)
{
return (str.size() >= s.size() && str.compare(0, s.size(), s) == 0);
}

static bool endsWith(const std::string &s, const std::string &e)
{
return (s.size() >= e.size()) && std::equal(e.rbegin(), e.rend(), s.rbegin());
Expand Down Expand Up @@ -2215,6 +2213,12 @@ namespace simplecpp {

namespace simplecpp {

#ifdef __CYGWIN__
bool startsWith(const std::string &str, const std::string &s)
{
return (str.size() >= s.size() && str.compare(0, s.size(), s) == 0);
}

std::string convertCygwinToWindowsPath(const std::string &cygwinPath)
{
std::string windowsPath;
Expand Down Expand Up @@ -2244,67 +2248,86 @@ namespace simplecpp {

return windowsPath;
}
#endif
}

#ifdef SIMPLECPP_WINDOWS

class ScopedLock {
#if __cplusplus >= 201103L
using MyMutex = std::mutex;
template<class T>
using MyLock = std::lock_guard<T>;
#else
class MyMutex {
public:
explicit ScopedLock(CRITICAL_SECTION& criticalSection)
: m_criticalSection(criticalSection) {
EnterCriticalSection(&m_criticalSection);
MyMutex() {
InitializeCriticalSection(&m_criticalSection);
}

~ScopedLock() {
LeaveCriticalSection(&m_criticalSection);
~MyMutex() {
DeleteCriticalSection(&m_criticalSection);
}

CRITICAL_SECTION* lock() {
return &m_criticalSection;
}
private:
ScopedLock& operator=(const ScopedLock&);
ScopedLock(const ScopedLock&);

CRITICAL_SECTION& m_criticalSection;
CRITICAL_SECTION m_criticalSection;
};

class RealFileNameMap {
template<typename T>
class MyLock {
public:
RealFileNameMap() {
InitializeCriticalSection(&m_criticalSection);
explicit MyLock(T& m)
: m_mutex(m) {
EnterCriticalSection(m_mutex.lock());
}

~RealFileNameMap() {
DeleteCriticalSection(&m_criticalSection);
~MyLock() {
LeaveCriticalSection(m_mutex.lock());
}

bool getCacheEntry(const std::string& path, std::string* returnPath) {
ScopedLock lock(m_criticalSection);
private:
MyLock& operator=(const MyLock&);
MyLock(const MyLock&);

T& m_mutex;
};
#endif

class RealFileNameMap {
public:
RealFileNameMap() {}

bool getCacheEntry(const std::string& path, std::string& returnPath) {
MyLock<MyMutex> lock(m_mutex);

std::map<std::string, std::string>::iterator it = m_fileMap.find(path);
const std::map<std::string, std::string>::iterator it = m_fileMap.find(path);
if (it != m_fileMap.end()) {
*returnPath = it->second;
returnPath = it->second;
return true;
}
return false;
}

void addToCache(const std::string& path, const std::string& actualPath) {
ScopedLock lock(m_criticalSection);
MyLock<MyMutex> lock(m_mutex);
m_fileMap[path] = actualPath;
}

private:
std::map<std::string, std::string> m_fileMap;
CRITICAL_SECTION m_criticalSection;
MyMutex m_mutex;
};

static RealFileNameMap realFileNameMap;

static bool realFileName(const std::string &f, std::string *result)
static bool realFileName(const std::string &f, std::string &result)
{
// are there alpha characters in last subpath?
bool alpha = false;
for (std::string::size_type pos = 1; pos <= f.size(); ++pos) {
unsigned char c = f[f.size() - pos];
const unsigned char c = f[f.size() - pos];
if (c == '/' || c == '\\')
break;
if (std::isalpha(c)) {
Expand All @@ -2323,16 +2346,16 @@ static bool realFileName(const std::string &f, std::string *result)
WIN32_FIND_DATAA FindFileData;

#ifdef __CYGWIN__
std::string fConverted = simplecpp::convertCygwinToWindowsPath(f);
HANDLE hFind = FindFirstFileExA(fConverted.c_str(), FindExInfoBasic, &FindFileData, FindExSearchNameMatch, NULL, 0);
const std::string fConverted = simplecpp::convertCygwinToWindowsPath(f);
const HANDLE hFind = FindFirstFileExA(fConverted.c_str(), FindExInfoBasic, &FindFileData, FindExSearchNameMatch, NULL, 0);
#else
HANDLE hFind = FindFirstFileExA(f.c_str(), FindExInfoBasic, &FindFileData, FindExSearchNameMatch, NULL, 0);
#endif

if (INVALID_HANDLE_VALUE == hFind)
return false;
*result = FindFileData.cFileName;
realFileNameMap.addToCache(f, *result);
result = FindFileData.cFileName;
realFileNameMap.addToCache(f, result);
FindClose(hFind);
}
return true;
Expand All @@ -2345,14 +2368,14 @@ static std::string realFilename(const std::string &f)
{
std::string ret;
ret.reserve(f.size()); // this will be the final size
if (realFilePathMap.getCacheEntry(f, &ret))
if (realFilePathMap.getCacheEntry(f, ret))
return ret;

// Current subpath
std::string subpath;

for (std::string::size_type pos = 0; pos < f.size(); ++pos) {
unsigned char c = f[pos];
const unsigned char c = f[pos];

// Separator.. add subpath and separator
if (c == '/' || c == '\\') {
Expand All @@ -2362,12 +2385,12 @@ static std::string realFilename(const std::string &f)
continue;
}

bool isDriveSpecification =
const bool isDriveSpecification =
(pos == 2 && subpath.size() == 2 && std::isalpha(subpath[0]) && subpath[1] == ':');

// Append real filename (proper case)
std::string f2;
if (!isDriveSpecification && realFileName(f.substr(0, pos), &f2))
if (!isDriveSpecification && realFileName(f.substr(0, pos), f2))
ret += f2;
else
ret += subpath;
Expand All @@ -2383,7 +2406,7 @@ static std::string realFilename(const std::string &f)

if (!subpath.empty()) {
std::string f2;
if (realFileName(f,&f2))
if (realFileName(f,f2))
ret += f2;
else
ret += subpath;
Expand Down Expand Up @@ -2902,32 +2925,26 @@ static const simplecpp::Token *gotoNextLine(const simplecpp::Token *tok)

class NonExistingFilesCache {
public:
NonExistingFilesCache() {
InitializeCriticalSection(&m_criticalSection);
}

~NonExistingFilesCache() {
DeleteCriticalSection(&m_criticalSection);
}
NonExistingFilesCache() {}

bool contains(const std::string& path) {
ScopedLock lock(m_criticalSection);
MyLock<MyMutex> lock(m_mutex);
return (m_pathSet.find(path) != m_pathSet.end());
}

void add(const std::string& path) {
ScopedLock lock(m_criticalSection);
MyLock<MyMutex> lock(m_mutex);
m_pathSet.insert(path);
}

void clear() {
ScopedLock lock(m_criticalSection);
MyLock<MyMutex> lock(m_mutex);
m_pathSet.clear();
}

private:
std::set<std::string> m_pathSet;
CRITICAL_SECTION m_criticalSection;
MyMutex m_mutex;
};

static NonExistingFilesCache nonExistingFilesCache;
Expand Down Expand Up @@ -3032,7 +3049,7 @@ std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::To
{
#ifdef SIMPLECPP_WINDOWS
if (dui.clearIncludeCache)
nonExistingFilesCache .clear();
nonExistingFilesCache.clear();
#endif

std::map<std::string, simplecpp::TokenList*> ret;
Expand Down
4 changes: 4 additions & 0 deletions test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ static void constFold()
ASSERT_EQUALS("exception", testConstFold("?2:3"));
}

#ifdef __CYGWIN__
static void convertCygwinPath()
{
// absolute paths
Expand All @@ -472,6 +473,7 @@ static void convertCygwinPath()
ASSERT_EQUALS("\\cygdrive", simplecpp::convertCygwinToWindowsPath("/cygdrive"));
ASSERT_EQUALS("\\cygdrive\\", simplecpp::convertCygwinToWindowsPath("/cygdrive/"));
}
#endif

static void define1()
{
Expand Down Expand Up @@ -2628,7 +2630,9 @@ int main(int argc, char **argv)

TEST_CASE(constFold);

#ifdef __CYGWIN__
TEST_CASE(convertCygwinPath);
#endif

TEST_CASE(define1);
TEST_CASE(define2);
Expand Down