Continuing verification on Windows
* Move path manipulation functions out of StringUtils into FileUtils
* Don't assume forward/back slash when dealing with paths. Handle both.
* Reimplement (and renamed StringUtils::eliminateRelativePath) to be
more specific of its purpose. Logic now handles both relative and
absolute paths on both unix and windows platform.
MODIFY
src/Cache/PPCache.cpp
src/Cache/PPCache.cpp
@@ -54,9 +54,8 @@ std::string PPCache::getCacheFileName_(std::string svFileName) {
m_pp->getCompileSourceFile()->getCommandLineParser()->getCacheDir();
if (svFileName == "") svFileName = m_pp->getFileName(LINE1);
- std::string root = svFileName;
- root = StringUtils::getRootFileName(root);
- if (prec->isFilePrecompiled(root)) {
+ svFileName = FileUtils::fileName(svFileName);
+ if (prec->isFilePrecompiled(svFileName)) {
std::string packageRepDir = m_pp->getSymbol(m_pp->getCompileSourceFile()
->getCommandLineParser()
->getPrecompiledDir());
@@ -71,7 +70,6 @@ std::string PPCache::getCacheFileName_(std::string svFileName) {
Library* lib = m_pp->getLibrary();
std::string libName = lib->getName() + "/";
- svFileName = StringUtils::getRootFileName(svFileName);
std::string cacheFileName = cacheDirName + libName + svFileName + ".slpp";
FileUtils::mkDir(std::string(cacheDirName + libName).c_str());
return cacheFileName;

MODIFY
src/Cache/ParseCache.cpp
src/Cache/ParseCache.cpp
@@ -60,9 +60,8 @@ std::string ParseCache::getCacheFileName_(std::string svFileName) {
SymbolId cacheDirId =
m_parse->getCompileSourceFile()->getCommandLineParser()->getCacheDir();
if (svFileName == "") svFileName = m_parse->getPpFileName();
- std::string root = svFileName;
- root = StringUtils::getRootFileName(root);
- if (prec->isFilePrecompiled(root)) {
+ svFileName = FileUtils::fileName(svFileName);
+ if (prec->isFilePrecompiled(svFileName)) {
std::string packageRepDir =
m_parse->getSymbol(m_parse->getCompileSourceFile()
->getCommandLineParser()
@@ -77,7 +76,6 @@ std::string ParseCache::getCacheFileName_(std::string svFileName) {
std::string cacheDirName = m_parse->getSymbol(cacheDirId);
Library* lib = m_parse->getLibrary();
std::string libName = lib->getName() + "/";
- svFileName = StringUtils::getRootFileName(svFileName);
std::string cacheFileName = cacheDirName + libName + svFileName + ".slpa";
FileUtils::mkDir(std::string(cacheDirName + libName).c_str());
return cacheFileName;

MODIFY
src/Cache/PythonAPICache.cpp
src/Cache/PythonAPICache.cpp
@@ -61,7 +61,7 @@ std::string PythonAPICache::getCacheFileName_(std::string svFileName) {
std::string cacheDirName = m_listener->getParseFile()->getSymbol(cacheDirId);
if (svFileName == "")
svFileName = m_listener->getParseFile()->getFileName(LINE1);
- svFileName = StringUtils::getRootFileName(svFileName);
+ svFileName = FileUtils::fileName(svFileName);
Library* lib = m_listener->getCompileSourceFile()->getLibrary();
std::string libName = lib->getName() + "/";
std::string cacheFileName = cacheDirName + libName + svFileName + ".slpy";

MODIFY
src/CommandLine/CommandLineParser.cpp
src/CommandLine/CommandLineParser.cpp
#include <sstream>
#include <cstdlib>
#include <string.h>
-#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
+
+#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
+ #include <direct.h>
+ #define PATH_MAX _MAX_PATH
+#else
+ #include <sys/param.h>
#include <unistd.h>
+#endif
#include <fstream>
#include <iostream>

MODIFY
src/SourceCompile/CompileSourceFile.cpp
src/SourceCompile/CompileSourceFile.cpp
@@ -218,7 +218,7 @@ bool CompileSourceFile::parse_() {
bool CompileSourceFile::preprocess_() {
Precompiled* prec = Precompiled::getSingleton();
std::string root = getSymbolTable()->getSymbol(m_fileId);
- root = StringUtils::getRootFileName(root);
+ root = FileUtils::fileName(root);
PreprocessFile::SpecialInstructions instructions(
PreprocessFile::SpecialInstructions::DontMute,
@@ -261,17 +261,14 @@ bool CompileSourceFile::postPreprocess_() {
(m_commandLineParser->writePpOutputFileId() != 0)) {
const std::string& directory =
symbolTable->getSymbol(m_commandLineParser->getFullCompileDir());
- std::string fileName = symbolTable->getSymbol(m_fileId);
- std::string fullPath = FileUtils::getFullPath(fileName);
- fileName = StringUtils::eliminateRelativePath(fileName);
+ std::string fileName = FileUtils::makeRelativePath(symbolTable->getSymbol(m_fileId));
const std::string& writePpOutputFileName =
symbolTable->getSymbol(m_commandLineParser->writePpOutputFileId());
std::string libName = m_library->getName() + "/";
string ppFileName = m_commandLineParser->writePpOutput()
? directory + libName + fileName
: writePpOutputFileName;
- std::string dirPpFile = ppFileName;
- StringUtils::rtrim(dirPpFile, '/');
+ std::string dirPpFile = FileUtils::getPathName(ppFileName);
SymbolId ppOutId = symbolTable->registerSymbol(ppFileName);
m_ppResultFileId = m_symbolTable->registerSymbol(ppFileName);
SymbolId ppDirId = symbolTable->registerSymbol(dirPpFile);

MODIFY
src/SourceCompile/Compiler.cpp
src/SourceCompile/Compiler.cpp
@@ -252,7 +252,7 @@ bool Compiler::createFileList_()
for (unsigned int i = 0; i < size; i++) {
std::string fileName = m_compilers[i]->getSymbolTable()->getSymbol(
m_compilers[i]->getPpOutputFileId());
- fileName = StringUtils::replaceAll(fileName, "//", "/");
+ fileName = FileUtils::getPreferredPath(fileName);
ofs << fileName << std::flush << std::endl;
}
ofs.close();
@@ -299,7 +299,7 @@ bool Compiler::createMultiProcess_() {
Precompiled* prec = Precompiled::getSingleton();
for (unsigned int i = 0; i < m_compilers.size(); i++) {
std::string root = m_compilers[i]->getSymbolTable()->getSymbol(m_compilers[i]->getFileId());
- root = StringUtils::getRootFileName(root);
+ root = FileUtils::fileName(root);
if (prec->isFilePrecompiled(root)) {
continue;
}
@@ -417,8 +417,7 @@ bool Compiler::parseinit_() {
std::string origFile = m_compilers[i]->getSymbolTable()->getSymbol(
m_compilers[i]->getFileId());
unsigned int nbThreads = m_commandLineParser->getNbMaxTreads();
- std::string root = fileName;
- root = StringUtils::getRootFileName(root);
+ std::string root = FileUtils::fileName(fileName);
if (prec->isFilePrecompiled(root)) {
nbThreads = 0;
}

MODIFY
src/SourceCompile/ParseFile.cpp
src/SourceCompile/ParseFile.cpp
@@ -343,8 +343,7 @@ std::string ParseFile::getProfileInfo() {
bool ParseFile::parse() {
Precompiled* prec = Precompiled::getSingleton();
- std::string root = this->getPpFileName();
- root = StringUtils::getRootFileName(root);
+ std::string root = FileUtils::fileName(this->getPpFileName());
bool precompiled = false;
if (prec->isFilePrecompiled(root)) precompiled = true;

MODIFY
src/SourceCompile/PreprocessFile.cpp
src/SourceCompile/PreprocessFile.cpp
@@ -296,8 +296,7 @@ bool PreprocessFile::preprocess() {
m_result = "";
std::string fileName = getSymbol(m_fileId);
Precompiled* prec = Precompiled::getSingleton();
- std::string root = fileName;
- root = StringUtils::getRootFileName(root);
+ std::string root = FileUtils::fileName(fileName);
bool precompiled = false;
if (prec->isFilePrecompiled(root)) precompiled = true;

MODIFY
src/Utils/FileUtils.cpp
src/Utils/FileUtils.cpp
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
#include <direct.h>
#define PATH_MAX _MAX_PATH
- // Supress the warning for the time being until we upgrade to C++17
- #define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
#else
#include <dirent.h>
#include <unistd.h>
@@ -64,15 +62,13 @@ FileUtils::FileUtils(const FileUtils& orig) {}
FileUtils::~FileUtils() {}
bool FileUtils::fileExists(const std::string name) {
- struct stat buffer;
- return (stat(name.c_str(), &buffer) == 0);
+ std::error_code ec;
+ return fs::exists(name, ec);
}
unsigned long FileUtils::fileSize(const std::string name) {
- struct stat buf;
- stat(name.c_str(), &buf);
- off_t size = buf.st_size;
- return size;
+ std::error_code ec;
+ return fs::file_size(name, ec);
}
bool FileUtils::fileIsDirectory(const std::string name) {
@@ -285,3 +281,27 @@ std::string FileUtils::fileName(std::string str) {
return fs::path(str).filename().string();
}
+std::string FileUtils::getPreferredPath(const std::string& path) {
+ return fs::path(path).make_preferred().string();
+}
+
+std::string FileUtils::makeRelativePath(std::string path) {
+ // Replace everything that's not alpha-numeric with an '_'
+ const std::string allowed_in_dir = "-/\\";
+ const std::string allowed_in_file = ".";
+ std::string dir = FileUtils::getPathName(path);
+ std::string file = FileUtils::fileName(path);
+ std::replace_if(
+ dir.begin(), dir.end(),
+ [&allowed_in_dir](std::string::value_type ch) {
+ return !std::isalnum(ch) && (allowed_in_dir.find(ch) == std::string::npos);
+ },
+ '_');
+ std::replace_if(
+ file.begin(), file.end(),
+ [&allowed_in_file](std::string::value_type ch) {
+ return !std::isalnum(ch) && (allowed_in_file.find(ch) == std::string::npos);
+ },
+ '_');
+ return (fs::path(dir) / file).string();
+}

MODIFY
src/Utils/FileUtils.h
src/Utils/FileUtils.h
@@ -60,6 +60,8 @@ class FileUtils {
static std::vector<SymbolId> collectFiles(std::string pathSpec,
SymbolTable* symbols);
static std::string getFileContent(const std::string name);
+ static std::string getPreferredPath(const std::string &path);
+ static std::string makeRelativePath(std::string path);
private:
FileUtils();

MODIFY
src/Utils/StringUtils.cpp
src/Utils/StringUtils.cpp
@@ -275,14 +275,6 @@ std::string StringUtils::leaf(std::string str) {
return str;
}
-std::string& StringUtils::getRootFileName(std::string& str) {
- bool found = true;
- while (found) {
- found = ltrimStat(str, '/');
- }
- return str;
-}
-
std::string StringUtils::replaceAll(std::string str, const std::string& from,
const std::string& to) {
size_t start_pos = 0;
@@ -294,10 +286,6 @@ std::string StringUtils::replaceAll(std::string str, const std::string& from,
return str;
}
-std::string StringUtils::eliminateRelativePath(std::string path) {
- return replaceAll(path, "..", "__");
-}
-
std::string StringUtils::getLineInString(std::string& bulk, unsigned int line) {
std::string lineText;
unsigned int size = bulk.size();

MODIFY
src/Utils/StringUtils.h
src/Utils/StringUtils.h
@@ -52,8 +52,6 @@ class StringUtils {
static std::string& rtrim(std::string& str, char c);
static std::string leaf(std::string str);
- static std::string& getRootFileName(std::string& str);
- static std::string eliminateRelativePath(std::string path);
static std::string replaceAll(std::string str, const std::string& from,
const std::string& to);
static std::string getLineInString(std::string& bulk, unsigned int line);

MODIFY
src/main.cpp
src/main.cpp
#include <string>
#include <vector>
#include <sys/stat.h>
+#include <fstream>
+
+#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
+ #include <direct.h>
+ #include <process.h>
+#else
#include <sys/param.h>
#include <unistd.h>
-#include <fstream>
+#endif
#include "surelog.h"
#include "ErrorReporting/Report.h"
@@ -225,8 +231,8 @@ int main(int argc, const char ** argv) {
printf("fork() failed!\n");
return 1;
}
- break;
#endif
+ break;
}
case NORMAL:
codedReturn = executeCompilation(argc, argv, false, false);

Continuing verification on Windows
* Move path manipulation functions out of StringUtils into FileUtils
* Don't assume forward/back slash when dealing with paths. Handle both.
* Reimplement (and renamed StringUtils::eliminateRelativePath) to be
  more specific of its purpose. Logic now handles both relative and
  absolute paths on both unix and windows platform.