bump simplecpp
This commit is contained in:
parent
3eb5de756c
commit
93194f47a1
|
@ -327,6 +327,15 @@ static void ungetChar(std::istream &istr, unsigned int bom)
|
||||||
istr.unget();
|
istr.unget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned char prevChar(std::istream &istr, unsigned int bom)
|
||||||
|
{
|
||||||
|
ungetChar(istr, bom);
|
||||||
|
ungetChar(istr, bom);
|
||||||
|
unsigned char c = readChar(istr, bom);
|
||||||
|
readChar(istr, bom);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned short getAndSkipBOM(std::istream &istr)
|
static unsigned short getAndSkipBOM(std::istream &istr)
|
||||||
{
|
{
|
||||||
const int ch1 = istr.peek();
|
const int ch1 = istr.peek();
|
||||||
|
@ -384,9 +393,10 @@ static void portabilityBackslash(simplecpp::OutputList *outputList, const std::v
|
||||||
outputList->push_back(err);
|
outputList->push_back(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isRawStringId(const std::string &str)
|
static bool isStringLiteralPrefix(const std::string &str)
|
||||||
{
|
{
|
||||||
return str == "R" || str == "uR" || str == "UR" || str == "LR" || str == "u8R";
|
return str == "u" || str == "U" || str == "L" || str == "u8" ||
|
||||||
|
str == "R" || str == "uR" || str == "UR" || str == "LR" || str == "u8R";
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filename, OutputList *outputList)
|
void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filename, OutputList *outputList)
|
||||||
|
@ -480,7 +490,7 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen
|
||||||
prev = ch;
|
prev = ch;
|
||||||
ch = readChar(istr, bom);
|
ch = readChar(istr, bom);
|
||||||
}
|
}
|
||||||
istr.unget();
|
ungetChar(istr, bom);
|
||||||
push_back(new Token(currentToken, location));
|
push_back(new Token(currentToken, location));
|
||||||
location.adjust(currentToken);
|
location.adjust(currentToken);
|
||||||
continue;
|
continue;
|
||||||
|
@ -512,7 +522,7 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen
|
||||||
++multiline;
|
++multiline;
|
||||||
currentToken.erase(currentToken.size() - 1U);
|
currentToken.erase(currentToken.size() - 1U);
|
||||||
} else {
|
} else {
|
||||||
istr.unget();
|
ungetChar(istr, bom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,31 +555,34 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen
|
||||||
|
|
||||||
// string / char literal
|
// string / char literal
|
||||||
else if (ch == '\"' || ch == '\'') {
|
else if (ch == '\"' || ch == '\'') {
|
||||||
// C++11 raw string literal
|
if (cback() && cback()->name && !std::isspace(prevChar(istr, bom)) && (isStringLiteralPrefix(cback()->str()))) {
|
||||||
if (ch == '\"' && cback() && cback()->name && isRawStringId(cback()->str())) {
|
|
||||||
std::string delim;
|
std::string delim;
|
||||||
ch = readChar(istr,bom);
|
currentToken = ch;
|
||||||
while (istr.good() && ch != '(' && ch != '\n') {
|
bool hasR = *cback()->str().rbegin() == 'R';
|
||||||
delim += ch;
|
std::string prefix = cback()->str();
|
||||||
|
if (hasR) {
|
||||||
|
prefix.resize(prefix.size() - 1);
|
||||||
|
delim = ")";
|
||||||
ch = readChar(istr,bom);
|
ch = readChar(istr,bom);
|
||||||
|
while (istr.good() && ch != '(' && ch != '\n') {
|
||||||
|
delim += ch;
|
||||||
|
ch = readChar(istr,bom);
|
||||||
|
}
|
||||||
|
if (!istr.good() || ch == '\n')
|
||||||
|
// TODO report
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (!istr.good() || ch == '\n')
|
const std::string endOfRawString(delim + currentToken);
|
||||||
// TODO report
|
while (istr.good() && !(endsWith(currentToken, endOfRawString) && currentToken.size() > 1))
|
||||||
return;
|
|
||||||
currentToken = '\"';
|
|
||||||
const std::string endOfRawString(')' + delim + '\"');
|
|
||||||
while (istr.good() && !endsWith(currentToken, endOfRawString))
|
|
||||||
currentToken += readChar(istr,bom);
|
currentToken += readChar(istr,bom);
|
||||||
if (!endsWith(currentToken, endOfRawString))
|
if (!endsWith(currentToken, endOfRawString))
|
||||||
// TODO report
|
// TODO report
|
||||||
return;
|
return;
|
||||||
currentToken.erase(currentToken.size() - endOfRawString.size(), endOfRawString.size() - 1U);
|
currentToken.erase(currentToken.size() - endOfRawString.size(), endOfRawString.size() - 1U);
|
||||||
if (cback()->op == 'R')
|
if (hasR)
|
||||||
back()->setstr(escapeString(currentToken));
|
currentToken = escapeString(currentToken);
|
||||||
else {
|
currentToken.insert(0, prefix);
|
||||||
back()->setstr(cback()->str().substr(0, cback()->str().size() - 1));
|
back()->setstr(currentToken);
|
||||||
push_back(new Token(currentToken, location)); // push string without newlines
|
|
||||||
}
|
|
||||||
location.adjust(currentToken);
|
location.adjust(currentToken);
|
||||||
if (currentToken.find_first_of("\r\n") == std::string::npos)
|
if (currentToken.find_first_of("\r\n") == std::string::npos)
|
||||||
location.col += 2 + 2 * delim.size();
|
location.col += 2 + 2 * delim.size();
|
||||||
|
@ -578,7 +591,7 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentToken = readUntil(istr,location,ch,ch,outputList);
|
currentToken = readUntil(istr,location,ch,ch,outputList,bom);
|
||||||
if (currentToken.size() < 2U)
|
if (currentToken.size() < 2U)
|
||||||
// TODO report
|
// TODO report
|
||||||
return;
|
return;
|
||||||
|
@ -607,7 +620,7 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentToken == "<" && lastLine() == "# include") {
|
if (currentToken == "<" && lastLine() == "# include") {
|
||||||
currentToken = readUntil(istr, location, '<', '>', outputList);
|
currentToken = readUntil(istr, location, '<', '>', outputList, bom);
|
||||||
if (currentToken.size() < 2U)
|
if (currentToken.size() < 2U)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1045,7 +1058,7 @@ void simplecpp::TokenList::removeComments()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string simplecpp::TokenList::readUntil(std::istream &istr, const Location &location, const char start, const char end, OutputList *outputList)
|
std::string simplecpp::TokenList::readUntil(std::istream &istr, const Location &location, const char start, const char end, OutputList *outputList, unsigned int bom)
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret += start;
|
ret += start;
|
||||||
|
@ -1053,7 +1066,7 @@ std::string simplecpp::TokenList::readUntil(std::istream &istr, const Location &
|
||||||
bool backslash = false;
|
bool backslash = false;
|
||||||
char ch = 0;
|
char ch = 0;
|
||||||
while (ch != end && ch != '\r' && ch != '\n' && istr.good()) {
|
while (ch != end && ch != '\r' && ch != '\n' && istr.good()) {
|
||||||
ch = (unsigned char)istr.get();
|
ch = readChar(istr, bom);
|
||||||
if (backslash && ch == '\n') {
|
if (backslash && ch == '\n') {
|
||||||
ch = 0;
|
ch = 0;
|
||||||
backslash = false;
|
backslash = false;
|
||||||
|
@ -1062,7 +1075,7 @@ std::string simplecpp::TokenList::readUntil(std::istream &istr, const Location &
|
||||||
backslash = false;
|
backslash = false;
|
||||||
ret += ch;
|
ret += ch;
|
||||||
if (ch == '\\') {
|
if (ch == '\\') {
|
||||||
const char next = (unsigned char)istr.get();
|
const char next = readChar(istr, bom);
|
||||||
if (next == '\r' || next == '\n') {
|
if (next == '\r' || next == '\n') {
|
||||||
ret.erase(ret.size()-1U);
|
ret.erase(ret.size()-1U);
|
||||||
backslash = (next == '\r');
|
backslash = (next == '\r');
|
||||||
|
@ -1845,6 +1858,39 @@ namespace simplecpp {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace simplecpp {
|
||||||
|
|
||||||
|
std::string convertCygwinToWindowsPath(const std::string &cygwinPath)
|
||||||
|
{
|
||||||
|
std::string windowsPath;
|
||||||
|
|
||||||
|
std::string::size_type pos = 0;
|
||||||
|
if (cygwinPath.size() >= 11 && startsWith(cygwinPath, "/cygdrive/")) {
|
||||||
|
unsigned char driveLetter = cygwinPath[10];
|
||||||
|
if (std::isalpha(driveLetter)) {
|
||||||
|
if (cygwinPath.size() == 11) {
|
||||||
|
windowsPath = toupper(driveLetter);
|
||||||
|
windowsPath += ":\\"; // volume root directory
|
||||||
|
pos = 11;
|
||||||
|
} else if (cygwinPath[11] == '/') {
|
||||||
|
windowsPath = toupper(driveLetter);
|
||||||
|
windowsPath += ":";
|
||||||
|
pos = 11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; pos < cygwinPath.size(); ++pos) {
|
||||||
|
unsigned char c = cygwinPath[pos];
|
||||||
|
if (c == '/')
|
||||||
|
c = '\\';
|
||||||
|
windowsPath += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return windowsPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SIMPLECPP_WINDOWS
|
#ifdef SIMPLECPP_WINDOWS
|
||||||
|
|
||||||
class ScopedLock {
|
class ScopedLock {
|
||||||
|
@ -1875,7 +1921,7 @@ public:
|
||||||
DeleteCriticalSection(&m_criticalSection);
|
DeleteCriticalSection(&m_criticalSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getRealPathFromCache(const std::string& path, std::string* returnPath) {
|
bool getCacheEntry(const std::string& path, std::string* returnPath) {
|
||||||
ScopedLock lock(m_criticalSection);
|
ScopedLock lock(m_criticalSection);
|
||||||
|
|
||||||
std::map<std::string, std::string>::iterator it = m_fileMap.find(path);
|
std::map<std::string, std::string>::iterator it = m_fileMap.find(path);
|
||||||
|
@ -1902,9 +1948,9 @@ static bool realFileName(const std::string &f, std::string *result)
|
||||||
{
|
{
|
||||||
// are there alpha characters in last subpath?
|
// are there alpha characters in last subpath?
|
||||||
bool alpha = false;
|
bool alpha = false;
|
||||||
for (std::string::size_type pos = 1; pos < f.size(); ++pos) {
|
for (std::string::size_type pos = 1; pos <= f.size(); ++pos) {
|
||||||
unsigned char c = f[f.size() - pos];
|
unsigned char c = f[f.size() - pos];
|
||||||
if (c=='/' || c=='\\')
|
if (c == '/' || c == '\\')
|
||||||
break;
|
break;
|
||||||
if (std::isalpha(c)) {
|
if (std::isalpha(c)) {
|
||||||
alpha = true;
|
alpha = true;
|
||||||
|
@ -1917,9 +1963,16 @@ static bool realFileName(const std::string &f, std::string *result)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Lookup filename or foldername on file system
|
// Lookup filename or foldername on file system
|
||||||
if (!realFileNameMap.getRealPathFromCache(f, result)) {
|
if (!realFileNameMap.getCacheEntry(f, result)) {
|
||||||
|
|
||||||
WIN32_FIND_DATAA FindFileData;
|
WIN32_FIND_DATAA FindFileData;
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
std::string fConverted = simplecpp::convertCygwinToWindowsPath(f);
|
||||||
|
HANDLE hFind = FindFirstFileExA(fConverted.c_str(), FindExInfoBasic, &FindFileData, FindExSearchNameMatch, NULL, 0);
|
||||||
|
#else
|
||||||
HANDLE hFind = FindFirstFileExA(f.c_str(), FindExInfoBasic, &FindFileData, FindExSearchNameMatch, NULL, 0);
|
HANDLE hFind = FindFirstFileExA(f.c_str(), FindExInfoBasic, &FindFileData, FindExSearchNameMatch, NULL, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (INVALID_HANDLE_VALUE == hFind)
|
if (INVALID_HANDLE_VALUE == hFind)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1930,12 +1983,14 @@ static bool realFileName(const std::string &f, std::string *result)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static RealFileNameMap realFilePathMap;
|
||||||
|
|
||||||
/** Change case in given path to match filesystem */
|
/** Change case in given path to match filesystem */
|
||||||
static std::string realFilename(const std::string &f)
|
static std::string realFilename(const std::string &f)
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret.reserve(f.size()); // this will be the final size
|
ret.reserve(f.size()); // this will be the final size
|
||||||
if (realFileNameMap.getRealPathFromCache(f, &ret))
|
if (realFilePathMap.getCacheEntry(f, &ret))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
// Current subpath
|
// Current subpath
|
||||||
|
@ -1952,9 +2007,12 @@ static std::string realFilename(const std::string &f)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isDriveSpecification =
|
||||||
|
(pos == 2 && subpath.size() == 2 && std::isalpha(subpath[0]) && subpath[1] == ':');
|
||||||
|
|
||||||
// Append real filename (proper case)
|
// Append real filename (proper case)
|
||||||
std::string f2;
|
std::string f2;
|
||||||
if (realFileName(f.substr(0,pos),&f2))
|
if (!isDriveSpecification && realFileName(f.substr(0, pos), &f2))
|
||||||
ret += f2;
|
ret += f2;
|
||||||
else
|
else
|
||||||
ret += subpath;
|
ret += subpath;
|
||||||
|
@ -1976,7 +2034,7 @@ static std::string realFilename(const std::string &f)
|
||||||
ret += subpath;
|
ret += subpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
realFileNameMap.addToCache(f, ret);
|
realFilePathMap.addToCache(f, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2164,23 +2222,73 @@ static const simplecpp::Token *gotoNextLine(const simplecpp::Token *tok)
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SIMPLECPP_WINDOWS
|
||||||
|
|
||||||
|
class NonExistingFilesCache {
|
||||||
|
public:
|
||||||
|
NonExistingFilesCache() {
|
||||||
|
InitializeCriticalSection(&m_criticalSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
~NonExistingFilesCache() {
|
||||||
|
DeleteCriticalSection(&m_criticalSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(const std::string& path) {
|
||||||
|
ScopedLock lock(m_criticalSection);
|
||||||
|
return (m_pathSet.find(path) != m_pathSet.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(const std::string& path) {
|
||||||
|
ScopedLock lock(m_criticalSection);
|
||||||
|
m_pathSet.insert(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::set<std::string> m_pathSet;
|
||||||
|
CRITICAL_SECTION m_criticalSection;
|
||||||
|
};
|
||||||
|
|
||||||
|
static NonExistingFilesCache nonExistingFilesCache;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static std::string _openHeader(std::ifstream &f, const std::string &path)
|
||||||
|
{
|
||||||
|
#ifdef SIMPLECPP_WINDOWS
|
||||||
|
std::string simplePath = simplecpp::simplifyPath(path);
|
||||||
|
if (nonExistingFilesCache.contains(simplePath))
|
||||||
|
return ""; // file is known not to exist, skip expensive file open call
|
||||||
|
|
||||||
|
f.open(simplePath.c_str());
|
||||||
|
if (f.is_open())
|
||||||
|
return simplePath;
|
||||||
|
else {
|
||||||
|
nonExistingFilesCache.add(simplePath);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
f.open(path.c_str());
|
||||||
|
return f.is_open() ? simplecpp::simplifyPath(path) : "";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader)
|
static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader)
|
||||||
{
|
{
|
||||||
if (isAbsolutePath(header)) {
|
if (isAbsolutePath(header)) {
|
||||||
f.open(header.c_str());
|
return _openHeader(f, header);
|
||||||
return f.is_open() ? simplecpp::simplifyPath(header) : "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!systemheader) {
|
if (!systemheader) {
|
||||||
if (sourcefile.find_first_of("\\/") != std::string::npos) {
|
if (sourcefile.find_first_of("\\/") != std::string::npos) {
|
||||||
const std::string s = sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header;
|
const std::string s = sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header;
|
||||||
f.open(s.c_str());
|
std::string simplePath = _openHeader(f, s);
|
||||||
if (f.is_open())
|
if (!simplePath.empty())
|
||||||
return simplecpp::simplifyPath(s);
|
return simplePath;
|
||||||
} else {
|
} else {
|
||||||
f.open(header.c_str());
|
std::string simplePath = _openHeader(f, header);
|
||||||
if (f.is_open())
|
if (!simplePath.empty())
|
||||||
return simplecpp::simplifyPath(header);
|
return simplePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2189,9 +2297,10 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
|
||||||
if (!s.empty() && s[s.size()-1U]!='/' && s[s.size()-1U]!='\\')
|
if (!s.empty() && s[s.size()-1U]!='/' && s[s.size()-1U]!='\\')
|
||||||
s += '/';
|
s += '/';
|
||||||
s += header;
|
s += header;
|
||||||
f.open(s.c_str());
|
|
||||||
if (f.is_open())
|
std::string simplePath = _openHeader(f, s);
|
||||||
return simplecpp::simplifyPath(s);
|
if (!simplePath.empty())
|
||||||
|
return simplePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -258,7 +258,7 @@ namespace simplecpp {
|
||||||
void constFoldLogicalOp(Token *tok);
|
void constFoldLogicalOp(Token *tok);
|
||||||
void constFoldQuestionOp(Token **tok1);
|
void constFoldQuestionOp(Token **tok1);
|
||||||
|
|
||||||
std::string readUntil(std::istream &istr, const Location &location, const char start, const char end, OutputList *outputList);
|
std::string readUntil(std::istream &istr, const Location &location, const char start, const char end, OutputList *outputList, unsigned int bom);
|
||||||
|
|
||||||
std::string lastLine(int maxsize=100000) const;
|
std::string lastLine(int maxsize=100000) const;
|
||||||
|
|
||||||
|
@ -312,6 +312,9 @@ namespace simplecpp {
|
||||||
|
|
||||||
/** Simplify path */
|
/** Simplify path */
|
||||||
SIMPLECPP_LIB std::string simplifyPath(std::string path);
|
SIMPLECPP_LIB std::string simplifyPath(std::string path);
|
||||||
|
|
||||||
|
/** Convert Cygwin path to Windows path */
|
||||||
|
SIMPLECPP_LIB std::string convertCygwinToWindowsPath(const std::string &cygwinPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue