ultimatepp/uppsrc/ide/Core/Assembly.cpp
2023-02-01 15:27:24 +01:00

265 lines
5.4 KiB
C++

#include "Core.h"
String GetLocalDir()
{
return ConfigFile("UppLocal");
}
String LocalPath(const String& filename)
{
return AppendFileName(GetLocalDir(), filename);
}
String FollowCygwinSymlink(const String& file) {
for(String fn = file;;) {
if(fn.IsEmpty())
return fn;
FileIn fi(fn);
if(!fi.IsOpen())
return fn;
char buffer[10];
if(!fi.GetAll(buffer, 10) || memcmp(buffer, "!<symlink>", 10))
return fn;
fn = NormalizePath(LoadStream(fi), GetFileDirectory(fn));
}
}
Vector<String> SplitDirs(const char *s) {
#ifdef PLATFORM_POSIX
return Split(s, [](int c) { return findarg(c, ';', ':') >= 0 ? c : 0; });
#else
return Split(s, ';');
#endif
}
static String varsname = "default";
String GetVarsName()
{
return varsname;
}
String VarFilePath(String name) {
return ConfigFile(name + ".var");
}
String VarFilePath() {
String p = varsname;
if(IsFullPath(varsname))
return varsname;
return VarFilePath(GetVarsName());
}
bool SaveVarFile(const char *filename, const VectorMap<String, String>& var)
{
FileOut out(filename);
for(int i = 0; i < var.GetCount(); i++)
out << var.GetKey(i) << " = " << AsCString(var[i]) << ";\n";
out.Close();
return !out.IsError();
}
bool LoadVarFile(const char *name, VectorMap<String, String>& _var)
{
try {
VectorMap<String, String> var;
String env = LoadFile(name);
try {
CParser p(env);
while(!p.IsEof()) {
String v = p.ReadId();
p.Char('=');
if(p.IsString())
var.GetAdd(v) = p.ReadString();
else {
String ln;
while(p.PeekChar() != '\r' && p.PeekChar() != '\n' && p.PeekChar() != ';')
ln.Cat(p.GetChar());
var.GetAdd(v) = ln;
p.Spaces();
}
p.Char(';');
}
}
catch(CParser::Error) {}
_var = pick(var);
return true;
}
catch(...) {
return false;
}
}
bool Nest::Save(const char *path)
{
return SaveVarFile(path, var);
}
bool Nest::Load(const char *path)
{
InvalidatePackageCache();
return LoadVarFile(path, var);
}
String Nest::Get(const String& id)
{
return var.Get(id, String());
}
void Nest::Set(const String& id, const String& val)
{
var.GetAdd(id) = val;
InvalidatePackageCache();
}
String Nest::PackagePath0(const String& name)
{
String uppfile = NativePath(name);
if(IsFullPath(uppfile)) return NormalizePath(uppfile);
Vector<String> d = GetUppDirs();
String p;
for(int i = 0; i < d.GetCount(); i++) {
p = NormalizePath(AppendFileName(AppendFileName(d[i], uppfile),
GetFileName(uppfile)) + ".upp");
if(FileExists(p)) return p;
}
return d.GetCount() ? NormalizePath(AppendFileName(AppendFileName(d[0], uppfile),
GetFileName(uppfile)) + ".upp") : "";
}
String Nest::PackagePath(const String& name)
{
int q = package_cache.Find(name);
if(q < 0) {
String h = PackagePath0(name);
package_cache.Add(name, h);
return h;
}
return package_cache[q];
}
Nest& MainNest()
{
return Single<Nest>();
}
bool SaveVars(const char *name)
{
if(!MainNest().Save(VarFilePath(name)))
return false;
varsname = name;
return true;
}
String DefaultHubFilePath()
{
return ConfigFile("UppHub.path");
}
bool hubdir_resolved;
void SetHubDir(const String& path)
{
SaveFile(DefaultHubFilePath(), path);
hubdir_resolved = false;
}
String GetHubDir()
{
static String d;
if(hubdir_resolved)
return d;
hubdir_resolved = true;
d = GetVar("UPPHUB");
if(d.GetCount() == 0 || !DirectoryExists(d)) {
d = LoadFile(DefaultHubFilePath());
if(d.GetCount() == 0 || !DirectoryExists(d)) {
d = ConfigFile("UppHub");
RealizeDirectory(d);
}
}
d = NormalizePath(d);
return d;
}
bool InUppHub(const String& p)
{
return p.StartsWith(GetHubDir());
}
bool LoadVars(const char *name) {
varsname = (name && *name ? name : "default");
return MainNest().Load(VarFilePath());
}
String GetVar(const String& var) {
return MainNest().Get(var);
}
void SetVar(const String& var, const String& val, bool save) {
MainNest().Set(var, val);
if(save)
SaveVars(GetVarsName());
}
bool hub_loaded;
String main_nest;
void SetMainNest(const String& n)
{
main_nest = n;
}
String GetAssemblyId()
{
String id = GetVarsName();
Vector<String> s = SplitDirs(GetVar("UPP"));
if(s.GetCount() && main_nest.GetCount() && s[0] != main_nest)
id << "_" << GetFileName(main_nest);
return id;
}
Vector<String> GetUppDirsRaw()
{
Vector<String> s = SplitDirs(GetVar("UPP"));
static Vector<String> hub_dirs;
if(!hub_loaded) {
hub_dirs.Clear();
for(const FindFile& ff : FindFile(GetHubDir() + "/*.*"))
if(ff.IsFolder())
hub_dirs.Add(ff.GetPath());
hub_loaded = true;
}
s.Append(hub_dirs);
return s;
}
Vector<String> GetUppDirs()
{
Vector<String> s = GetUppDirsRaw();
if(main_nest.GetCount() && (s.GetCount() == 0 || main_nest != s[0]))
s.Insert(0, main_nest);
return s;
}
bool IsHubDir(const String& path)
{
return NormalizePath(path).StartsWith(GetHubDir());
}
void Nest::InvalidatePackageCache()
{
package_cache.Clear();
hub_loaded = false;
}
String GetUppDir() {
Vector<String> s = GetUppDirs();
#ifdef PLATFORM_WIN32
return s.GetCount() == 0 ? GetFileFolder(GetExeFilePath()) : s[0];
#endif
#ifdef PLATFORM_POSIX
return s.GetCount() == 0 ? GetHomeDirectory() : s[0];
#endif
}