Skip to content

Commit

Permalink
some platform-dependent code cleanups (#310)
Browse files Browse the repository at this point in the history
  • Loading branch information
firewave authored Sep 11, 2023
1 parent ce5f06b commit df40677
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 49 deletions.
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

0 comments on commit df40677

Please sign in to comment.