mirror of https://github.com/AxioDL/metaforce.git
additional tool work
This commit is contained in:
parent
6dda293cb9
commit
270468fb1f
|
@ -12,10 +12,6 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~ToolAdd()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Help(HelpOutput& help)
|
static void Help(HelpOutput& help)
|
||||||
{
|
{
|
||||||
help.secHead(_S("NAME"));
|
help.secHead(_S("NAME"));
|
||||||
|
|
|
@ -11,19 +11,48 @@ public:
|
||||||
ToolInit(const ToolPassInfo& info)
|
ToolInit(const ToolPassInfo& info)
|
||||||
: ToolBase(info)
|
: ToolBase(info)
|
||||||
{
|
{
|
||||||
|
struct stat theStat;
|
||||||
|
const HECL::SystemString* dir;
|
||||||
if (info.args.size())
|
if (info.args.size())
|
||||||
|
dir = &info.args[0];
|
||||||
|
else
|
||||||
|
dir = &info.cwd;
|
||||||
|
|
||||||
|
if (HECL::Stat(dir->c_str(), &theStat))
|
||||||
{
|
{
|
||||||
|
throw HECL::Exception(_S("unable to stat '") + *dir + _S("'"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!S_ISDIR(theStat.st_mode))
|
||||||
|
{
|
||||||
|
throw HECL::Exception(_S("'") + *dir + _S("' is not a directory"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
m_dir = &info.args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
~ToolInit()
|
HECL::SystemString testPath = *dir + _S("/.hecl/index");
|
||||||
{
|
if (!HECL::Stat(testPath.c_str(), &theStat))
|
||||||
|
{
|
||||||
|
throw HECL::Exception(_S("project already exists at '") + *dir + _S("'"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dir = dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
int run()
|
int run()
|
||||||
{
|
{
|
||||||
|
if (!m_dir)
|
||||||
|
return -1;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HECL::Database::Project(HECL::ProjectRootPath(*m_dir));
|
||||||
|
}
|
||||||
|
catch (HECL::Exception& e)
|
||||||
|
{
|
||||||
|
HECL::FPrintf(stderr, _S("unable to init project: '%s'\n"), e.swhat());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
HECL::Printf(_S("initialized project at '%s/.hecl'\n"), m_dir->c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,12 @@
|
||||||
|
|
||||||
bool XTERM_COLOR = false;
|
bool XTERM_COLOR = false;
|
||||||
|
|
||||||
|
/*
|
||||||
#define HECL_GIT 1234567
|
#define HECL_GIT 1234567
|
||||||
#define HECL_GIT_S "1234567"
|
#define HECL_GIT_S "1234567"
|
||||||
#define HECL_BRANCH master
|
#define HECL_BRANCH master
|
||||||
#define HECL_BRANCH_S "master"
|
#define HECL_BRANCH_S "master"
|
||||||
|
*/
|
||||||
|
|
||||||
/* Main usage message */
|
/* Main usage message */
|
||||||
static void printHelp(const HECL::SystemChar* pname)
|
static void printHelp(const HECL::SystemChar* pname)
|
||||||
|
|
|
@ -7,6 +7,7 @@ char* win_realpath(const char* name, char* restrict resolved);
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/file.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -156,12 +157,8 @@ static inline FILE* Fopen(const SystemChar* path, const SystemChar* mode, FileLo
|
||||||
OVERLAPPED ov = {};
|
OVERLAPPED ov = {};
|
||||||
LockFileEx(fhandle, (lock == LWRITE) ? LOCKFILE_EXCLUSIVE_LOCK : 0, 0, 0, 1, &ov);
|
LockFileEx(fhandle, (lock == LWRITE) ? LOCKFILE_EXCLUSIVE_LOCK : 0, 0, 0, 1, &ov);
|
||||||
#else
|
#else
|
||||||
struct flock lk =
|
if (flock(fileno(fp), ((lock == LWRITE) ? LOCK_EX : LOCK_SH) | LOCK_NB))
|
||||||
{
|
throw std::error_code(errno, std::system_category());
|
||||||
(short)((lock == LREAD) ? F_RDLCK : F_WRLCK),
|
|
||||||
SEEK_SET, 0, 0, 0
|
|
||||||
};
|
|
||||||
fcntl(fileno(fp), F_SETLK, &lk);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <list>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
@ -172,6 +173,7 @@ public:
|
||||||
private:
|
private:
|
||||||
ProjectRootPath m_rootPath;
|
ProjectRootPath m_rootPath;
|
||||||
CompiledSpecs m_compiledSpecs;
|
CompiledSpecs m_compiledSpecs;
|
||||||
|
FLogger m_logger;
|
||||||
public:
|
public:
|
||||||
Project(const HECL::ProjectRootPath& rootPath);
|
Project(const HECL::ProjectRootPath& rootPath);
|
||||||
|
|
||||||
|
@ -184,16 +186,16 @@ public:
|
||||||
class ConfigFile
|
class ConfigFile
|
||||||
{
|
{
|
||||||
SystemString m_filepath;
|
SystemString m_filepath;
|
||||||
std::vector<std::string> m_lines;
|
std::list<std::string> m_lines;
|
||||||
FILE* m_lockedFile = NULL;
|
FILE* m_lockedFile = NULL;
|
||||||
public:
|
public:
|
||||||
ConfigFile(const Project& project, const SystemString& name);
|
ConfigFile(const Project& project, const SystemString& name);
|
||||||
const std::vector<std::string>& lockAndRead();
|
std::list<std::string>& lockAndRead();
|
||||||
void addLine(const std::string& line);
|
void addLine(const std::string& line);
|
||||||
void removeLine(const std::string& refLine);
|
void removeLine(const std::string& refLine);
|
||||||
bool checkForLine(const std::string& refLine);
|
bool checkForLine(const std::string& refLine);
|
||||||
void unlockAndDiscard();
|
void unlockAndDiscard();
|
||||||
void unlockAndCommit();
|
bool unlockAndCommit();
|
||||||
};
|
};
|
||||||
ConfigFile m_specs;
|
ConfigFile m_specs;
|
||||||
ConfigFile m_paths;
|
ConfigFile m_paths;
|
||||||
|
@ -233,7 +235,7 @@ public:
|
||||||
const std::vector<ProjectPath*> getChangedPaths();
|
const std::vector<ProjectPath*> getChangedPaths();
|
||||||
void addOrUpdatePath(const ProjectPath& path);
|
void addOrUpdatePath(const ProjectPath& path);
|
||||||
void unlockAndDiscard();
|
void unlockAndDiscard();
|
||||||
void unlockAndCommit(bool onlyUpdated=false);
|
bool unlockAndCommit(bool onlyUpdated=false);
|
||||||
};
|
};
|
||||||
IndexFile m_index;
|
IndexFile m_index;
|
||||||
|
|
||||||
|
|
|
@ -45,12 +45,12 @@ Project::ConfigFile::ConfigFile(const Project& project, const SystemString& name
|
||||||
m_filepath = project.m_rootPath.getAbsolutePath() + _S("/.hecl/config/") + name;
|
m_filepath = project.m_rootPath.getAbsolutePath() + _S("/.hecl/config/") + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string>& Project::ConfigFile::lockAndRead()
|
std::list<std::string>& Project::ConfigFile::lockAndRead()
|
||||||
{
|
{
|
||||||
if (m_lockedFile)
|
if (m_lockedFile)
|
||||||
return m_lines;
|
return m_lines;
|
||||||
|
|
||||||
m_lockedFile = HECL::Fopen(m_filepath.c_str(), _S("r+"), LWRITE);
|
m_lockedFile = HECL::Fopen(m_filepath.c_str(), _S("a+"), LWRITE);
|
||||||
|
|
||||||
std::string mainString;
|
std::string mainString;
|
||||||
char readBuf[1024];
|
char readBuf[1024];
|
||||||
|
@ -93,7 +93,7 @@ void Project::ConfigFile::removeLine(const std::string& refLine)
|
||||||
if (!m_lockedFile)
|
if (!m_lockedFile)
|
||||||
throw HECL::Exception(_S("Project::ConfigFile::lockAndRead not yet called"));
|
throw HECL::Exception(_S("Project::ConfigFile::lockAndRead not yet called"));
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator it=m_lines.begin();
|
for (auto it = m_lines.begin();
|
||||||
it != m_lines.end();
|
it != m_lines.end();
|
||||||
++it)
|
++it)
|
||||||
{
|
{
|
||||||
|
@ -125,25 +125,41 @@ void Project::ConfigFile::unlockAndDiscard()
|
||||||
m_lockedFile = NULL;
|
m_lockedFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Project::ConfigFile::unlockAndCommit()
|
bool Project::ConfigFile::unlockAndCommit()
|
||||||
{
|
{
|
||||||
if (!m_lockedFile)
|
if (!m_lockedFile)
|
||||||
throw HECL::Exception(_S("Project::ConfigFile::lockAndRead not yet called"));
|
throw HECL::Exception(_S("Project::ConfigFile::lockAndRead not yet called"));
|
||||||
|
|
||||||
fseek(m_lockedFile, 0, SEEK_SET);
|
SystemString newPath = m_filepath + _S(".part");
|
||||||
#if _WIN32
|
FILE* newFile = HECL::Fopen(newPath.c_str(), _S("w"), LWRITE);
|
||||||
SetEndOfFile((HANDLE)fileno(m_lockedFile));
|
bool fail = false;
|
||||||
#else
|
|
||||||
ftruncate(fileno(m_lockedFile), 0);
|
|
||||||
#endif
|
|
||||||
for (const std::string& line : m_lines)
|
for (const std::string& line : m_lines)
|
||||||
{
|
{
|
||||||
fwrite(line.c_str(), 1, line.size(), m_lockedFile);
|
if (fwrite(line.c_str(), 1, line.size(), newFile) != line.size())
|
||||||
fwrite("\n", 1, 1, m_lockedFile);
|
{
|
||||||
|
fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (fwrite("\n", 1, 1, newFile) != 1)
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_lines.clear();
|
m_lines.clear();
|
||||||
|
fclose(newFile);
|
||||||
fclose(m_lockedFile);
|
fclose(m_lockedFile);
|
||||||
m_lockedFile = NULL;
|
m_lockedFile = NULL;
|
||||||
|
if (fail)
|
||||||
|
{
|
||||||
|
unlink(newPath.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rename(newPath.c_str(), m_filepath.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************
|
/**********************************************
|
||||||
|
@ -175,19 +191,22 @@ const std::vector<Project::IndexFile::Entry>& Project::IndexFile::lockAndRead()
|
||||||
if (m_lockedFile)
|
if (m_lockedFile)
|
||||||
return m_entryStore;
|
return m_entryStore;
|
||||||
|
|
||||||
m_lockedFile = HECL::Fopen(m_filepath.c_str(), _S("r+"), LWRITE);
|
/* Open file and begin lock cycle */
|
||||||
|
m_lockedFile = HECL::Fopen(m_filepath.c_str(), _S("a+b"), LWRITE);
|
||||||
m_maxPathLen = 0;
|
m_maxPathLen = 0;
|
||||||
m_onlyUpdatedMaxPathLen = 0;
|
m_onlyUpdatedMaxPathLen = 0;
|
||||||
|
|
||||||
|
/* Read index header */
|
||||||
SIndexHeader header;
|
SIndexHeader header;
|
||||||
if (fread(&header, 1, sizeof(header), m_lockedFile) != sizeof(header))
|
if (fread(&header, 1, sizeof(header), m_lockedFile) != sizeof(header))
|
||||||
return m_entryStore;
|
return m_entryStore; /* Not yet written, this commit will take care of it */
|
||||||
header.swapWithNative();
|
header.swapWithNative();
|
||||||
if (header.magic != "HECL")
|
if (header.magic != "HECL")
|
||||||
throw HECL::Exception(_S("unrecognized HECL index"));
|
throw HECL::Exception(_S("unrecognized HECL index"));
|
||||||
if (header.version != 1)
|
if (header.version != 1)
|
||||||
throw HECL::Exception(_S("unrecognized HECL version"));
|
throw HECL::Exception(_S("unrecognized HECL version"));
|
||||||
|
|
||||||
|
/* Iterate existing index entries */
|
||||||
char* pathBuf = new char[header.maxPathLen];
|
char* pathBuf = new char[header.maxPathLen];
|
||||||
for (uint32_t e=0 ; e<header.entryCount ; ++e)
|
for (uint32_t e=0 ; e<header.entryCount ; ++e)
|
||||||
{
|
{
|
||||||
|
@ -205,7 +224,7 @@ const std::vector<Project::IndexFile::Entry>& Project::IndexFile::lockAndRead()
|
||||||
ProjectPath path(m_project.getProjectRootPath(), pathView.sys_str());
|
ProjectPath path(m_project.getProjectRootPath(), pathView.sys_str());
|
||||||
if (m_entryLookup.find(path) == m_entryLookup.end())
|
if (m_entryLookup.find(path) == m_entryLookup.end())
|
||||||
{
|
{
|
||||||
m_entryStore.push_back(Project::IndexFile::Entry(path, mt));
|
m_entryStore.push_back(Entry(path, mt));
|
||||||
m_entryLookup[path] = &m_entryStore.back();
|
m_entryLookup[path] = &m_entryStore.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,7 +238,7 @@ const std::vector<ProjectPath*> Project::IndexFile::getChangedPaths()
|
||||||
throw HECL::Exception(_S("Project::IndexFile::lockAndRead not yet called"));
|
throw HECL::Exception(_S("Project::IndexFile::lockAndRead not yet called"));
|
||||||
|
|
||||||
std::vector<ProjectPath*> retval;
|
std::vector<ProjectPath*> retval;
|
||||||
for (Project::IndexFile::Entry& ent : m_entryStore)
|
for (Entry& ent : m_entryStore)
|
||||||
if (ent.m_lastModtime != ent.m_path.getModtime())
|
if (ent.m_lastModtime != ent.m_path.getModtime())
|
||||||
retval.push_back(&ent.m_path);
|
retval.push_back(&ent.m_path);
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -237,7 +256,7 @@ void Project::IndexFile::addOrUpdatePath(const ProjectPath& path)
|
||||||
std::unordered_map<ProjectPath, Entry*>::iterator it = m_entryLookup.find(path);
|
std::unordered_map<ProjectPath, Entry*>::iterator it = m_entryLookup.find(path);
|
||||||
if (it == m_entryLookup.end())
|
if (it == m_entryLookup.end())
|
||||||
{
|
{
|
||||||
m_entryStore.push_back(Project::IndexFile::Entry(path, path.getModtime()));
|
m_entryStore.push_back(Entry(path, path.getModtime()));
|
||||||
m_entryLookup[path] = &m_entryStore.back();
|
m_entryLookup[path] = &m_entryStore.back();
|
||||||
m_entryStore.back().m_updated = true;
|
m_entryStore.back().m_updated = true;
|
||||||
return;
|
return;
|
||||||
|
@ -257,18 +276,13 @@ void Project::IndexFile::unlockAndDiscard()
|
||||||
m_lockedFile = NULL;
|
m_lockedFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Project::IndexFile::unlockAndCommit(bool onlyUpdated)
|
bool Project::IndexFile::unlockAndCommit(bool onlyUpdated)
|
||||||
{
|
{
|
||||||
if (!m_lockedFile)
|
if (!m_lockedFile)
|
||||||
throw HECL::Exception(_S("Project::IndexFile::lockAndRead not yet called"));
|
throw HECL::Exception(_S("Project::IndexFile::lockAndRead not yet called"));
|
||||||
|
|
||||||
fseek(m_lockedFile, 0, SEEK_SET);
|
SystemString newPath = m_filepath + _S(".part");
|
||||||
#if _WIN32
|
FILE* newFile = HECL::Fopen(newPath.c_str(), _S("wb"), LWRITE);
|
||||||
SetEndOfFile((HANDLE)fileno(m_lockedFile));
|
|
||||||
#else
|
|
||||||
ftruncate(fileno(m_lockedFile), 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SIndexHeader header =
|
SIndexHeader header =
|
||||||
{
|
{
|
||||||
HECL::FourCC("HECL"), 1,
|
HECL::FourCC("HECL"), 1,
|
||||||
|
@ -276,25 +290,53 @@ void Project::IndexFile::unlockAndCommit(bool onlyUpdated)
|
||||||
(uint32_t)(onlyUpdated ? m_onlyUpdatedMaxPathLen : m_maxPathLen)
|
(uint32_t)(onlyUpdated ? m_onlyUpdatedMaxPathLen : m_maxPathLen)
|
||||||
};
|
};
|
||||||
header.swapWithNative();
|
header.swapWithNative();
|
||||||
fwrite(&header, 1, sizeof(header), m_lockedFile);
|
bool fail = false;
|
||||||
|
if (fwrite(&header, 1, sizeof(header), newFile) != sizeof(header))
|
||||||
|
fail = true;
|
||||||
|
|
||||||
for (Project::IndexFile::Entry& ent : m_entryStore)
|
if (!fail)
|
||||||
{
|
{
|
||||||
if (!onlyUpdated || ent.m_updated)
|
for (Entry& ent : m_entryStore)
|
||||||
{
|
{
|
||||||
uint64_t mt = ToBig(ent.m_lastModtime.getTs());
|
if (!onlyUpdated || ent.m_updated)
|
||||||
fwrite(&mt, 1, 8, m_lockedFile);
|
{
|
||||||
size_t strLen = ent.m_path.getRelativePathUTF8().size();
|
uint64_t mt = ToBig(ent.m_lastModtime.getTs());
|
||||||
uint32_t strLenb = ToBig(strLen);
|
if (fwrite(&mt, 1, 8, newFile) != 8)
|
||||||
fwrite(&strLenb, 1, 4, m_lockedFile);
|
{
|
||||||
fwrite(ent.m_path.getRelativePathUTF8().c_str(), 1, strLen, m_lockedFile);
|
fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
size_t strLen = ent.m_path.getRelativePathUTF8().size();
|
||||||
|
uint32_t strLenb = ToBig(strLen);
|
||||||
|
if (fwrite(&strLenb, 1, 4, newFile) != 4)
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (fwrite(ent.m_path.getRelativePathUTF8().c_str(), 1, strLen, newFile) != strLen)
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_entryLookup.clear();
|
m_entryLookup.clear();
|
||||||
m_entryStore.clear();
|
m_entryStore.clear();
|
||||||
|
fclose(newFile);
|
||||||
fclose(m_lockedFile);
|
fclose(m_lockedFile);
|
||||||
m_lockedFile = NULL;
|
m_lockedFile = NULL;
|
||||||
|
if (fail)
|
||||||
|
{
|
||||||
|
unlink(newPath.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rename(newPath.c_str(), m_filepath.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************
|
/**********************************************
|
||||||
|
@ -321,34 +363,78 @@ Project::Project(const ProjectRootPath& rootPath)
|
||||||
HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl"));
|
HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl"));
|
||||||
HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl/cooked"));
|
HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl/cooked"));
|
||||||
HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl/config"));
|
HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl/config"));
|
||||||
|
|
||||||
|
/* Ensure index is initialized */
|
||||||
|
if (m_index.lockAndRead().empty())
|
||||||
|
m_index.unlockAndCommit();
|
||||||
|
else
|
||||||
|
m_index.unlockAndDiscard();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Project::registerLogger(FLogger logger)
|
void Project::registerLogger(FLogger logger)
|
||||||
{
|
{
|
||||||
|
m_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Project::addPaths(const std::vector<ProjectPath>& paths)
|
bool Project::addPaths(const std::vector<ProjectPath>& paths)
|
||||||
{
|
{
|
||||||
|
m_paths.lockAndRead();
|
||||||
|
for (const ProjectPath& path : paths)
|
||||||
|
m_paths.addLine(path.getRelativePathUTF8());
|
||||||
|
return m_paths.unlockAndCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Project::removePaths(const std::vector<ProjectPath>& paths, bool recursive)
|
bool Project::removePaths(const std::vector<ProjectPath>& paths, bool recursive)
|
||||||
{
|
{
|
||||||
|
std::list<std::string>& existingPaths = m_paths.lockAndRead();
|
||||||
|
if (recursive)
|
||||||
|
{
|
||||||
|
for (const ProjectPath& path : paths)
|
||||||
|
{
|
||||||
|
std::string recursiveBase = path.getRelativePathUTF8();
|
||||||
|
for (auto it = existingPaths.begin();
|
||||||
|
it != existingPaths.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
if (!(*it).compare(0, recursiveBase.size(), recursiveBase))
|
||||||
|
it = existingPaths.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (const ProjectPath& path : paths)
|
||||||
|
m_paths.removeLine(path.getRelativePathUTF8());
|
||||||
|
return m_paths.unlockAndCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Project::addGroup(const HECL::ProjectPath& path)
|
bool Project::addGroup(const HECL::ProjectPath& path)
|
||||||
{
|
{
|
||||||
|
m_groups.lockAndRead();
|
||||||
|
m_groups.addLine(path.getRelativePathUTF8());
|
||||||
|
return m_groups.unlockAndCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Project::removeGroup(const ProjectPath& path)
|
bool Project::removeGroup(const ProjectPath& path)
|
||||||
{
|
{
|
||||||
|
m_groups.lockAndRead();
|
||||||
|
m_groups.removeLine(path.getRelativePathUTF8());
|
||||||
|
return m_groups.unlockAndCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Project::enableDataSpecs(const std::vector<std::string>& specs)
|
bool Project::enableDataSpecs(const std::vector<SystemString>& specs)
|
||||||
{
|
{
|
||||||
|
m_specs.lockAndRead();
|
||||||
|
for (const SystemString& spec : specs)
|
||||||
|
m_specs.addLine(spec);
|
||||||
|
return m_specs.unlockAndCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Project::disableDataSpecs(const std::vector<std::string>& specs)
|
bool Project::disableDataSpecs(const std::vector<SystemString>& specs)
|
||||||
{
|
{
|
||||||
|
m_specs.lockAndRead();
|
||||||
|
for (const SystemString& spec : specs)
|
||||||
|
m_specs.removeLine(spec);
|
||||||
|
return m_specs.unlockAndCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Project::cookPath(const ProjectPath& path,
|
bool Project::cookPath(const ProjectPath& path,
|
||||||
|
|
Loading…
Reference in New Issue