mirror of https://github.com/AxioDL/metaforce.git
project path representation
This commit is contained in:
parent
0349e2cea0
commit
851221f861
|
@ -12,6 +12,7 @@
|
||||||
struct SToolPassInfo
|
struct SToolPassInfo
|
||||||
{
|
{
|
||||||
std::string pname;
|
std::string pname;
|
||||||
|
std::string cwd;
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
std::string output;
|
std::string output;
|
||||||
unsigned verbosityLevel = 0;
|
unsigned verbosityLevel = 0;
|
||||||
|
|
|
@ -6,16 +6,27 @@
|
||||||
|
|
||||||
class CToolInit final : public CToolBase
|
class CToolInit final : public CToolBase
|
||||||
{
|
{
|
||||||
|
const std::string* m_dir = NULL;
|
||||||
public:
|
public:
|
||||||
CToolInit(const SToolPassInfo& info)
|
CToolInit(const SToolPassInfo& info)
|
||||||
: CToolBase(info)
|
: CToolBase(info)
|
||||||
{
|
{
|
||||||
|
if (info.args.size())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
m_dir = &info.args[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
~CToolInit()
|
~CToolInit()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int run()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void Help(CHelpOutput& help)
|
static void Help(CHelpOutput& help)
|
||||||
{
|
{
|
||||||
help.secHead("NAME");
|
help.secHead("NAME");
|
||||||
|
@ -44,11 +55,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toolName() const {return "init";}
|
std::string toolName() const {return "init";}
|
||||||
|
|
||||||
int run()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CTOOL_INIT
|
#endif // CTOOL_INIT
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -69,6 +70,9 @@ int main(int argc, const char** argv)
|
||||||
/* Assemble common tool pass info */
|
/* Assemble common tool pass info */
|
||||||
SToolPassInfo info;
|
SToolPassInfo info;
|
||||||
info.pname = argv[0];
|
info.pname = argv[0];
|
||||||
|
char cwdbuf[MAXPATHLEN];
|
||||||
|
if (getcwd(cwdbuf, MAXPATHLEN))
|
||||||
|
info.cwd = cwdbuf;
|
||||||
|
|
||||||
/* Concatenate args */
|
/* Concatenate args */
|
||||||
std::list<std::string> args;
|
std::list<std::string> args;
|
||||||
|
|
|
@ -1,12 +1,34 @@
|
||||||
#ifndef HECL_HPP
|
#ifndef HECL_HPP
|
||||||
#define HECL_HPP
|
#define HECL_HPP
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
char* win_realpath(const char* name, char* restrict resolved);
|
||||||
|
#else
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "../extern/blowfish/blowfish.h"
|
||||||
|
|
||||||
namespace HECL
|
namespace HECL
|
||||||
{
|
{
|
||||||
|
|
||||||
#include "../extern/blowfish/blowfish.h"
|
#if _WIN32
|
||||||
|
typedef std::basic_string<TCHAR> TSystemPath;
|
||||||
|
#else
|
||||||
|
typedef std::string TSystemPath;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class ProjectRootPath;
|
||||||
|
static const std::regex regGLOB("\\*", std::regex::ECMAScript|std::regex::optimize);
|
||||||
|
static const std::regex regPATHCOMP("/([^/]+)", std::regex::ECMAScript|std::regex::optimize);
|
||||||
|
static const std::regex regDRIVELETTER("^([^/]*)/", std::regex::ECMAScript|std::regex::optimize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Severity of a log event
|
* @brief Severity of a log event
|
||||||
|
@ -69,7 +91,177 @@ public:
|
||||||
inline bool operator>=(ObjectHash& other) {return hash >= other.hash;}
|
inline bool operator>=(ObjectHash& other) {return hash >= other.hash;}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int16_t bswap(int16_t val)
|
/**
|
||||||
|
* @brief Canonicalized project path representation using POSIX conventions
|
||||||
|
*
|
||||||
|
* HECL uses POSIX-style paths (with '/' separator) and directory tokens
|
||||||
|
* ('.','..') to resolve files within a project. The database internally
|
||||||
|
* uses this representation to track working files.
|
||||||
|
*
|
||||||
|
* This class provides a convenient way to resolve paths relative to the
|
||||||
|
* project root. Part of this representation involves resolving symbolic
|
||||||
|
* links to regular file/directory paths and determining its type.
|
||||||
|
*
|
||||||
|
* NOTE THAT PROJECT PATHS ARE TREATED AS CASE SENSITIVE!!
|
||||||
|
*/
|
||||||
|
class ProjectPath
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
TSystemPath m_absPath;
|
||||||
|
const char* m_relPath = NULL;
|
||||||
|
ProjectPath() {}
|
||||||
|
bool _canonAbsPath(const TSystemPath& path)
|
||||||
|
{
|
||||||
|
#if _WIN32
|
||||||
|
#else
|
||||||
|
char resolvedPath[PATH_MAX];
|
||||||
|
if (!realpath(path.c_str(), resolvedPath))
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Unable to resolve '" + path + "' as a canonicalized path");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_absPath = resolvedPath;
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Construct a project subpath representation
|
||||||
|
* @param rootPath previously constructed ProjectRootPath held by HECLDatabase::IProject
|
||||||
|
* @param path valid filesystem-path (relative or absolute) to subpath
|
||||||
|
*/
|
||||||
|
ProjectPath(const ProjectRootPath& rootPath, const TSystemPath& path)
|
||||||
|
{
|
||||||
|
_canonAbsPath(path);
|
||||||
|
if (m_absPath.size() < ((ProjectPath&)rootPath).m_absPath.size() ||
|
||||||
|
m_absPath.compare(0, ((ProjectPath&)rootPath).m_absPath.size(),
|
||||||
|
((ProjectPath&)rootPath).m_absPath))
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("'" + m_absPath + "' is not a subpath of '" +
|
||||||
|
((ProjectPath&)rootPath).m_absPath + "'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_absPath.size() == ((ProjectPath&)rootPath).m_absPath.size())
|
||||||
|
{
|
||||||
|
/* Copies of the project root are permitted */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_relPath = m_absPath.c_str() + ((ProjectPath&)rootPath).m_absPath.size();
|
||||||
|
if (m_relPath[0] == '/')
|
||||||
|
++m_relPath;
|
||||||
|
if (m_relPath[0] == '\0')
|
||||||
|
m_relPath = NULL;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Determine if ProjectPath represents project root directory
|
||||||
|
* @return true if project root directory
|
||||||
|
*/
|
||||||
|
inline bool isRoot() {return (m_relPath == NULL);}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Access fully-canonicalized absolute path
|
||||||
|
* @return Absolute path reference
|
||||||
|
*/
|
||||||
|
inline const TSystemPath& getAbsolutePath() {return m_absPath;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Access fully-canonicalized project-relative path
|
||||||
|
* @return Relative pointer to within absolute-path or "." for project root-directory (use isRoot to detect)
|
||||||
|
*/
|
||||||
|
inline const char* getRelativePath()
|
||||||
|
{
|
||||||
|
if (m_relPath)
|
||||||
|
return m_relPath;
|
||||||
|
return ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of path
|
||||||
|
*/
|
||||||
|
enum PathType
|
||||||
|
{
|
||||||
|
PT_NONE, /**< If path doesn't reference a valid filesystem entity, this is returned */
|
||||||
|
PT_FILE, /**< Singular file path (confirmed with filesystem) */
|
||||||
|
PT_DIRECTORY, /**< Singular directory path (confirmed with filesystem) */
|
||||||
|
PT_GLOB /**< Glob-path (whenever one or more '*' occurs in syntax) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get type of path based on syntax and filesystem queries
|
||||||
|
* @return Type of path
|
||||||
|
*/
|
||||||
|
PathType getPathType()
|
||||||
|
{
|
||||||
|
if (std::regex_search(m_absPath, regGLOB))
|
||||||
|
return PT_GLOB;
|
||||||
|
#if _WIN32
|
||||||
|
#else
|
||||||
|
struct stat theStat;
|
||||||
|
if (stat(m_absPath.c_str(), &theStat))
|
||||||
|
return PT_NONE;
|
||||||
|
if (S_ISDIR(theStat.st_mode))
|
||||||
|
return PT_DIRECTORY;
|
||||||
|
if (S_ISREG(theStat.st_mode))
|
||||||
|
return PT_FILE;
|
||||||
|
return PT_NONE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void getGlobResults(std::vector<TSystemPath>& outPaths)
|
||||||
|
{
|
||||||
|
#if _WIN32
|
||||||
|
std::string itStr;
|
||||||
|
std::smatch letterMatch;
|
||||||
|
if (m_absPath.compare(0, 2, "//"))
|
||||||
|
itStr = "\\\\";
|
||||||
|
else if (std::regex_search(m_absPath, letterMatch, regDRIVELETTER))
|
||||||
|
if (letterMatch[1].str().size())
|
||||||
|
itStr = letterMatch[1];
|
||||||
|
#else
|
||||||
|
std::string itStr = "/";
|
||||||
|
#endif
|
||||||
|
bool needSlash = false;
|
||||||
|
|
||||||
|
std::sregex_token_iterator pathComps(m_absPath.begin(), m_absPath.end(), regPATHCOMP);
|
||||||
|
for (; pathComps != std::sregex_token_iterator() ; ++pathComps)
|
||||||
|
{
|
||||||
|
const std::string& comp = *pathComps;
|
||||||
|
if (!std::regex_search(comp, regGLOB))
|
||||||
|
{
|
||||||
|
if (needSlash)
|
||||||
|
itStr += '/';
|
||||||
|
else
|
||||||
|
needSlash = true;
|
||||||
|
itStr += comp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#if _WIN32
|
||||||
|
#else
|
||||||
|
DIR* dir = opendir("");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Special ProjectRootPath subclass for opening HECLDatabase::IProject instances
|
||||||
|
*
|
||||||
|
* Constructing a ProjectPath requires supplying a ProjectRootPath to consistently
|
||||||
|
* resolve canonicalized relative paths.
|
||||||
|
*/
|
||||||
|
class ProjectRootPath : public ProjectPath
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProjectRootPath(const TSystemPath& path)
|
||||||
|
{
|
||||||
|
_canonAbsPath(path);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Type-sensitive byte swappers */
|
||||||
|
static inline int16_t bswap(int16_t val)
|
||||||
{
|
{
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
return __builtin_bswap16(val);
|
return __builtin_bswap16(val);
|
||||||
|
@ -80,7 +272,7 @@ inline int16_t bswap(int16_t val)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16_t bswap(uint16_t val)
|
static inline uint16_t bswap(uint16_t val)
|
||||||
{
|
{
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
return __builtin_bswap16(val);
|
return __builtin_bswap16(val);
|
||||||
|
@ -91,7 +283,7 @@ inline uint16_t bswap(uint16_t val)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int32_t bswap(int32_t val)
|
static inline int32_t bswap(int32_t val)
|
||||||
{
|
{
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
return __builtin_bswap32(val);
|
return __builtin_bswap32(val);
|
||||||
|
@ -104,7 +296,7 @@ inline int32_t bswap(int32_t val)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t bswap(uint32_t val)
|
static inline uint32_t bswap(uint32_t val)
|
||||||
{
|
{
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
return __builtin_bswap32(val);
|
return __builtin_bswap32(val);
|
||||||
|
@ -117,7 +309,7 @@ inline uint32_t bswap(uint32_t val)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int64_t bswap(int64_t val)
|
static inline int64_t bswap(int64_t val)
|
||||||
{
|
{
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
return __builtin_bswap64(val);
|
return __builtin_bswap64(val);
|
||||||
|
@ -135,7 +327,7 @@ inline int64_t bswap(int64_t val)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint64_t bswap(uint64_t val)
|
static inline uint64_t bswap(uint64_t val)
|
||||||
{
|
{
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
return __builtin_bswap64(val);
|
return __builtin_bswap64(val);
|
||||||
|
@ -153,6 +345,14 @@ inline uint64_t bswap(uint64_t val)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
#define HECLMakeBig(val) HECL::bswap(val)
|
||||||
|
#define HECLMakeLittle(val) (val)
|
||||||
|
#else
|
||||||
|
#define HECLMakeBig(val) (val)
|
||||||
|
#define HECLMakeLittle(val) HECL::bswap(val)
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HECL_HPP
|
#endif // HECL_HPP
|
||||||
|
|
|
@ -213,23 +213,16 @@ public:
|
||||||
*
|
*
|
||||||
* Self explanatory
|
* Self explanatory
|
||||||
*/
|
*/
|
||||||
virtual std::string getProjectRootPath(bool absolute=false) const=0;
|
virtual const HECL::ProjectRootPath& getProjectRootPath(bool absolute=false) const=0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Determine if an arbitrary absolute or relative path lies within project
|
* @brief Add given file(s) to the database
|
||||||
* @param subpath directory or file to validate
|
|
||||||
* @return true if valid
|
|
||||||
*/
|
|
||||||
virtual bool validateSubPath(const std::string& subpath) const=0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Add a given file or file-pattern to the database
|
|
||||||
* @param path file or pattern within project
|
* @param path file or pattern within project
|
||||||
* @return true on success
|
* @return true on success
|
||||||
*
|
*
|
||||||
* This method blocks while object hashing takes place
|
* This method blocks while object hashing takes place
|
||||||
*/
|
*/
|
||||||
virtual bool addPath(const std::string& path)=0;
|
virtual bool addPaths(const std::vector<HECL::ProjectPath>& paths)=0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove a given file or file-pattern from the database
|
* @brief Remove a given file or file-pattern from the database
|
||||||
|
@ -240,7 +233,7 @@ public:
|
||||||
* This method will not delete actual working files from the project
|
* This method will not delete actual working files from the project
|
||||||
* directory. It will delete associated cooked objects though.
|
* directory. It will delete associated cooked objects though.
|
||||||
*/
|
*/
|
||||||
virtual bool removePath(const std::string& path, bool recursive=false)=0;
|
virtual bool removePaths(const std::string& path, bool recursive=false)=0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Register a working sub-directory as a Dependency Group
|
* @brief Register a working sub-directory as a Dependency Group
|
||||||
|
@ -323,15 +316,15 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a new (empty) project using specified root directory
|
* @brief Opens an existing or creates a new project using specified root directory
|
||||||
* @param rootPath Path to project root-directory (may be relative)
|
* @param rootPath Path to project root-directory
|
||||||
* @return New project object
|
* @return New project object
|
||||||
*
|
*
|
||||||
* This is the preferred way to open an existing or create a new HECL project.
|
* This is the preferred way to open an existing or create a new HECL project.
|
||||||
* All necessary database index files and object directories will be established
|
* All necessary database index files and object directories will be established
|
||||||
* within the specified directory path.
|
* within the specified directory path.
|
||||||
*/
|
*/
|
||||||
IProject* NewProject(const std::string& rootPath);
|
IProject* OpenProject(const HECL::ProjectRootPath& rootPath);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "HECL.hpp"
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
char* win_realpath(const char* name, char* restrict resolved)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -45,11 +45,7 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getProjectRootPath(bool absolute) const
|
const HECL::ProjectRootPath& getProjectRootPath(bool absolute) const
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validateSubPath(const std::string& subpath) const
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +85,7 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IProject* NewProject(const std::string& rootPath)
|
IProject* OpenProject(const std::string& rootPath)
|
||||||
{
|
{
|
||||||
return new CProject(rootPath);
|
return new CProject(rootPath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,3 +15,6 @@ include (frontend/frontend.pri)
|
||||||
include (backend/backend.pri)
|
include (backend/backend.pri)
|
||||||
include (database/database.pri)
|
include (database/database.pri)
|
||||||
include (runtime/runtime.pri)
|
include (runtime/runtime.pri)
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
HECL.cpp
|
||||||
|
|
Loading…
Reference in New Issue