diff --git a/uppsrc/ide/Browser/TopicWin.cpp b/uppsrc/ide/Browser/TopicWin.cpp
index e76cb4852..2d619d798 100644
--- a/uppsrc/ide/Browser/TopicWin.cpp
+++ b/uppsrc/ide/Browser/TopicWin.cpp
@@ -127,6 +127,22 @@ void TopicEditor::ExportGroupPdf()
}
}
+String MakeHtml(const char *title, String css, String body)
+{
+ String h =
+ "\r\n"
+ "
\t\n"
+ "\t\n"
+ "\t\n"
+ "" + String(title) + "\r\n"
+ ;
+ if(!IsNull(css))
+ h << "\r\n";
+ h << "" << body << "";
+ return h;
+}
+
void TopicEditor::ExportHTML()
{
String path = SelectFileSaveAs("HTML files\t*.html\nAll files\t*.*");
@@ -136,7 +152,7 @@ void TopicEditor::ExportHTML()
String html = EncodeHtml(editor.Get(), css,
VectorMap(), VectorMap(),
GetFileFolder(path));
- SaveFile(path, HtmlHeader((String)~title, AsCss(css)) / html);
+ SaveFile(path, MakeHtml((String)~title, AsCss(css), html));
// SaveFile(ForceExt(path, ".css"), AsCss(css));
}
@@ -154,7 +170,7 @@ void TopicEditor::ExportGroupHTML()
String html = EncodeHtml(ParseQTF(t.text), css,
VectorMap(), VectorMap(),
dir);
- html = HtmlHeader(t.title, AsCss(css)) / html;
+ html = MakeHtml(t.title, AsCss(css), html);
String path = AppendFileName(dir, GetFileTitle(ff.GetName()) + ".html");
if(LoadFile(path) != html)
SaveFile(path, html);
diff --git a/uppsrc/ide/Builders/Build.cpp b/uppsrc/ide/Builders/Build.cpp
index 015b9b86c..8cc06dc0b 100644
--- a/uppsrc/ide/Builders/Build.cpp
+++ b/uppsrc/ide/Builders/Build.cpp
@@ -1,744 +1,749 @@
-#include "Builders.h"
-
-#include
-
-#define LDUMP(x) // DUMP(x)
-
-MakeBuild::MakeBuild()
-{
- targetmode = 0;
- stoponerrors = true;
- use_target = false;
-}
-
-const TargetMode& MakeBuild::GetTargetMode()
-{
- return (targetmode == 0 ? debug : release);
-}
-
-Index MakeBuild::PackageConfig(const Workspace& wspc, int package,
- const VectorMap& bm, String mainparam,
- Host& host, Builder& b, String *target)
-{
- String packagepath = PackagePath(wspc[package]);
- const Package& pkg = wspc.package[package];
- Index cfg;
- mainparam << ' ' << bm.Get(targetmode ? "RELEASE_FLAGS" : "DEBUG_FLAGS", NULL);
- cfg = SplitFlags(mainparam, package == 0, wspc.GetAllAccepts(package));
- cfg.FindAdd(bm.Get("BUILDER", "GCC"));
- const TargetMode& m = GetTargetMode();
- if(targetmode == 0)
- cfg.FindAdd("DEBUG");
- switch(m.linkmode) {
- case 2:
- cfg.FindAdd("SO");
- case 1:
- cfg.FindAdd("SHARED");
- }
- if(targetmode == 2)
- cfg.FindAdd("FORCE_SPEED");
- if(targetmode == 3)
- cfg.FindAdd("FORCE_SIZE");
- int q = m.package.Find(wspc[package]);
- if(q >= 0) {
- const PackageMode& p = m.package[q];
- switch(p.debug >= 0 ? p.debug : m.def.debug) {
- case 1: cfg.FindAdd("DEBUG_MINIMAL"); break;
- case 2: cfg.FindAdd("DEBUG_FULL"); break;
- }
- if(!pkg.noblitz && (p.blitz >= 0 ? p.blitz : m.def.blitz))
- cfg.FindAdd("BLITZ");
- }
- else {
- switch(m.def.debug) {
- case 1: cfg.FindAdd("DEBUG_MINIMAL"); break;
- case 2: cfg.FindAdd("DEBUG_FULL"); break;
- }
- if(!pkg.noblitz && m.def.blitz)
- cfg.FindAdd("BLITZ");
- }
- host.AddFlags(cfg);
- b.AddFlags(cfg);
- for(int i = 0; i < pkg.flag.GetCount(); i++) {
- if(MatchWhen(pkg.flag[i].when, cfg.GetKeys()))
- cfg.Add(pkg.flag[i].text);
- }
- if(target)
- *target = Gather(pkg.target, cfg.GetKeys(), true);
- return cfg;
-}
-
-String NoCr(const char *s)
-{
- String out;
- while(*s)
- {
- const char *b = s;
- while(*s && *s != '\r')
- s++;
- out.Cat(b, int(s - b));
- if(*s == '\r')
- s++;
- }
- return out;
-}
-
-bool MakeBuild::SyncHostFiles(RemoteHost& host)
-{
- HdependTimeDirty();
- String query = "<";
-// Vector remotepath;
- Vector fdata;
- ArrayMap info;
- Vector nocrsize;
- const Workspace& wspc = GetIdeWorkspace();
- int p;
- for(p = 0; p < wspc.GetCount(); p++) {
- const Package& pkg = wspc.GetPackage(p);
- String pn = wspc[p];
- for(int f = -1; f < pkg.file.GetCount(); f++)
- if(f < 0 || !pkg.file[f].separator) {
- Vector pkgfiles;
- String pk = (f >= 0 ? SourcePath(pn, pkg.file[f]) : PackagePath(pn));
- if(!FindFile(pk).IsFile())
- continue;
- pkgfiles.Add(f >= 0 ? SourcePath(pn, pkg.file[f]) : PackagePath(pn));
- pkgfiles.AppendPick(HdependGetDependencies(pkgfiles[0]));
- for(int d = 0; d < pkgfiles.GetCount(); d++) {
- TransferFileInfo newinfo;
- newinfo.sourcepath = pkgfiles[d];
- String rp = host.GetHostPath(newinfo.sourcepath);
- if(info.Find(rp) >= 0 || (d && UnixPath(rp) == UnixPath(newinfo.sourcepath)))
- continue;
- FindFile ff(newinfo.sourcepath);
- newinfo.filetime = (int)(Time(ff.GetLastWriteTime()) - RemoteHost::TimeBase());
- newinfo.filesize = (int)ff.GetLength();
- int pos = transferfilecache.Find(rp);
- if(pos < 0 || transferfilecache[pos].filetime != newinfo.filetime
- || transferfilecache[pos].filesize != newinfo.filesize)
- {
- String content = NoCr(LoadFile(newinfo.sourcepath));
- query << rp << '\t' << newinfo.filetime << '\t' << content.GetLength() << '\n';
- // remotepath.Add(rp);
- fdata.Add(content);
- info.Add(rp, newinfo);
- nocrsize.Add(content.GetLength());
- PutVerbose("Checking remote " + rp);
- /*
- if(msecs(ticks) >= 0)
- {
- ShowConsole();
- console.Sync();
- ticks = msecs(-200);
- }
- */ }
- }
- }
- }
- if(info.IsEmpty())
- return true;
-// String host = GetVar("REMOTE_HOST");
-// int port = 2346;
-// int ppos = host.Find(':');
-// if(ppos >= 0)
-// {
-// port = ScanInt(host.GetIter(ppos + 1));
-// host.Trim(ppos);
-// }
-
- Index ignore;
- {
- PutConsole(NFormat("Retrieving update list for remote filesystem %s", host.host));
- ConsoleShow();
- String out = host.RemoteExec(query);
- if(out[0] != 'O' || out[1] != 'K') {
- PutConsole(out);
- return false;
- }
-
- const char *s = out;
- while(*s && *s++ != '\n')
- ;
- while(*s)
- {
- const char *b = s;
- while(*s && *s != '\n')
- s++;
- ignore.FindAdd(NormalizePath(NativePath(String(b, s))));
- if(*s)
- s++;
- }
- if(ignore.GetCount() == info.GetCount())
- PutConsole("Remote source tree is up to date.");
- else
- {
- PutConsole(NFormat("%d file(s) missing in remote source tree:", info.GetCount() - ignore.GetCount()));
- for(p = 0; p < info.GetCount(); p++)
- {
-// console << " " << remotepath[p] << " - "
-// << FormatInt(p) << " @ " << FormatInt(ignore.Find(remotepath[p])) << "\n";
- if(ignore.Find(NormalizePath(NativePath(info.GetKey(p)))) < 0)
- PutConsole(String().Cat() << " " << info.GetKey(p));
- }
- }
- }
-
- Vector update;
- for(p = 0; p < info.GetCount(); p++)
- if(ignore.Find(NormalizePath(NativePath(info.GetKey(p)))) < 0)
- {
- String rawdata = fdata[p];
- PutConsole(String().Cat() << "Compressing " << info[p].sourcepath << " (" << FormatInt(rawdata.GetLength()) << " B)\n");
- ConsoleSync();
- String bzdata = BZ2Compress(rawdata);
- String comp = ASCII85Encode(bzdata);
- if(update.IsEmpty() || update.Top().GetLength() + comp.GetLength() >= 500000)
- update.Add(">");
- update.Top() << info.GetKey(p) << '\t' << info[p].filetime << '\t' << nocrsize[p] << '\t' << comp << '\n';
- }
-
- for(p = 0; p < update.GetCount(); p++)
- {
- PutConsole(NFormat("Uploading block %d / %d (%d B)", p + 1, update.GetCount(), update[p].GetLength()));
- ConsoleShow();
- String result = host.RemoteExec(update[p]);
- if(result[0] != 'O' || result[1] != 'K') {
- PutConsole(result);
- return false;
- }
- }
-
- for(p = 0; p < info.GetCount(); p++)
- transferfilecache.GetAdd(info.GetKey(p)) = info[p];
- return true;
-}
-
-One MakeBuild::CreateHost(bool sync_files)
-{
- SetupDefaultMethod();
- VectorMap bm = GetMethodVars(method);
- String rm = bm.Get("REMOTE_HOST", Null);
- One outhost;
- if(!IsNull(rm)) {
- One host = new RemoteHost;
- host->host = rm;
- host->port = 2346;
- int f = rm.Find(':');
- if(f >= 0) {
- host->host = rm.Left(f);
- host->port = Nvl(ScanInt(rm.GetIter(f + 1)), host->port);
- }
- host->os_type = bm.Get("REMOTE_OS", "UNIX");
- Vector path_map = Split(bm.Get("REMOTE_MAP", Null), ';');
- for(int p = 0; p < path_map.GetCount(); p++) {
- f = path_map[p].Find('>');
- if(f >= 0) {
- host->path_map_local.Add(path_map[p].Left(f));
- host->path_map_remote.Add(path_map[p].Mid(f + 1));
- }
- }
- VectorMap env(Environment(), 1);
- Vector exedirs = SplitDirs(bm.Get("PATH", "") + ';' + env.Get("PATH", ""));
- env.GetAdd("PATH") = Join(exedirs, ";");
- for(int i = 0; i < env.GetCount(); i++)
- host->environment << env.GetKey(i) << '=' << env[i] << '\0';
- host->environment.Cat(0);
- if(sync_files && bm.Get("REMOTE_TRANSFER", Null) != "0")
- SyncHostFiles(*host);
- outhost = -host;
- }
- else {
- One host = new LocalHost;
- VectorMap env(Environment(), 1);
- host->exedirs = SplitDirs(bm.Get("PATH", "") + ';' + env.Get("PATH", ""));
- env.GetAdd("PATH") = Join(host->exedirs, ";");
- env.GetAdd("UPP_MAIN__") = GetFileDirectory(PackagePath(GetMain()));
- env.GetAdd("UPP_ASSEMBLY__") = GetVar("UPP");
- for(int i = 0; i < env.GetCount(); i++) {
- LDUMP(env.GetKey(i));
- LDUMP(env[i]);
- host->environment << env.GetKey(i) << '=' << env[i] << '\0';
- }
- host->environment.Cat(0);
- host->cmdout = &cmdout;
- outhost = -host;
- }
- return outhost;
-}
-
-One MakeBuild::CreateBuilder(Host *host)
-{
- SetupDefaultMethod();
- VectorMap bm = GetMethodVars(method);
- String builder = bm.Get("BUILDER", "GCC");
- int q = BuilderMap().Find(builder);
- if(q < 0) {
- PutConsole("Invalid builder " + builder);
- ConsoleShow();
- return NULL;
- }
- One b = (*BuilderMap().Get(builder))();
- b->host = host;
- b->compiler = bm.Get("COMPILER", "");
- b->include = SplitDirs(GetVar("UPP") + ';' + bm.Get("INCLUDE", ""));
- const Workspace& wspc = GetIdeWorkspace();
- for(int i = 0; i < wspc.GetCount(); i++) {
- const Package& pkg = wspc.GetPackage(i);
- for(int j = 0; j < pkg.include.GetCount(); j++)
- b->include.Add(SourcePath(wspc[i], pkg.include[j].text));
- }
- b->libpath = SplitDirs(bm.Get("LIB", ""));
- b->debug_options = bm.Get("DEBUG_OPTIONS", "");
- b->release_options = bm.Get("RELEASE_OPTIONS", "");
- b->release_size_options = bm.Get("RELEASE_SIZE_OPTIONS", "");
- b->debug_link = bm.Get("DEBUG_LINK", "");
- b->release_link = bm.Get("RELEASE_LINK", "");
- b->script = bm.Get("SCRIPT", "");
- return b;
-}
-
-int CharFilterSlash(int c)
-{
- return c == '\\' ? '/' : c;
-}
-
-bool output_per_assembly;
-
-String MakeBuild::OutDir(const Index& cfg, const String& package, const VectorMap& bm,
- bool use_target)
-{
- Index excl;
- excl.Add(bm.Get("BUILDER", "GCC"));
- excl.Add("MSC");
- LocalHost().AddFlags(excl);
- Vector x;
- bool dbg = cfg.Find("DEBUG_FULL") >= 0 || cfg.Find("DEBUG_MINIMAL") >= 0;
- if(cfg.Find("DEBUG") >= 0) {
- excl.Add("BLITZ");
- if(cfg.Find("BLITZ") < 0)
- x.Add("NOBLITZ");
- }
- else
- if(dbg)
- x.Add("RELEASE");
- if(use_target)
- excl.Add("MAIN");
- for(int i = 0; i < cfg.GetCount(); i++)
- if(excl.Find(cfg[i]) < 0)
- x.Add(cfg[i]);
- Sort(x);
- for(int i = 0; i < x.GetCount(); i++)
- x[i] = InitCaps(x[i]);
- String outdir = GetVar("OUTPUT");
- if(output_per_assembly)
- outdir = AppendFileName(outdir, GetVarsName());
- if(!use_target)
- outdir = AppendFileName(outdir, package);
- outdir = AppendFileName(outdir, GetFileTitle(method) + "." + Join(x, "."));
- outdir = Filter(outdir, CharFilterSlash);
- return outdir;
-}
-
-struct OneFileHost : Host {
- One host;
- String onefile;
-
- virtual String GetEnvironment() { return host->GetEnvironment(); }
- virtual String GetHostPath(const String& path) { return host->GetHostPath(path); }
- virtual String GetLocalPath(const String& path) { return host->GetLocalPath(path); }
- virtual String NormalizePath(const String& path) { return host->NormalizePath(path); }
- virtual void DeleteFile(const Vector& path) { host->DeleteFile(path); }
- virtual void DeleteFolderDeep(const String& folder) { host->DeleteFolderDeep(folder); }
- virtual void ChDir(const String& path) { host->ChDir(path); }
- virtual void RealizeDir(const String& path) { host->RealizeDir(path); }
- virtual void SaveFile(const String& path, const String& data) { host->SaveFile(path, data); }
- virtual String LoadFile(const String& path) { return host->LoadFile(path); }
- virtual int Execute(const char *c) { return host->Execute(c); }
- virtual int ExecuteWithInput(const char *c) { return host->ExecuteWithInput(c); }
- virtual int Execute(const char *c, Stream& o) { return host->Execute(c, o); }
- virtual int AllocSlot() { return host->AllocSlot(); }
- virtual bool Run(const char *cmdline, int slot, String key, int blitz_count) { return host->Run(cmdline, slot, key, blitz_count); }
- virtual bool Run(const char *cmdline, Stream& out, int slot, String key, int blitz_count) { return host->Run(cmdline, out, slot, key, blitz_count); }
- virtual bool Wait() { return host->Wait(); }
- virtual One StartProcess(const char *c) { return host->StartProcess(c); }
- virtual void Launch(const char *cmdline, bool) { host->Launch(cmdline); }
- virtual void AddFlags(Index& cfg) { host->AddFlags(cfg); }
-
- virtual Vector GetFileInfo(const Vector& path) {
- Vector fi = host->GetFileInfo(path);
- for(int i = 0; i < path.GetCount(); i++)
- if(path[i] == onefile)
- (Time &)fi[i] = GetSysTime();
- else
- (Time &)fi[i] = Time::Low();
- return fi;
- }
-};
-
-bool MakeBuild::BuildPackage(const Workspace& wspc, int pkindex, int pknumber, int pkcount,
- String mainparam, String outfile, Vector& linkfile, String& linkopt, bool link)
-{
- String package = wspc[pkindex];
- String mainpackage = wspc[0];
- const Package& pkg = wspc.package[pkindex];
- VectorMap bm = GetMethodVars(method);
- if(bm.GetCount() == 0) {
- PutConsole("Invalid build method");
- ConsoleShow();
- return false;
- }
- One host = CreateHost(false);
- if(!IsNull(onefile)) {
- OneFileHost *h = new OneFileHost;
- h->host = host;
- h->onefile = onefile;
- host = h;
- }
- One b = CreateBuilder(~host);
- if(!b)
- return false;
- b->config = PackageConfig(wspc, pkindex, bm, mainparam, *host, *b);
- const TargetMode& m = targetmode == 0 ? debug : release;
- b->version = m.version;
- b->method = method;
- b->outdir = OutDir(b->config, package, bm);
- host->RealizeDir(b->outdir);
- String mainfn = Null;
- Index mcfg = PackageConfig(wspc, 0, bm, mainparam, *host, *b, &mainfn);
- HdependClearDependencies();
- for(int i = 0; i < pkg.GetCount(); i++) {
- const Array& f = pkg[i].depends;
- for(int j = 0; j < f.GetCount(); j++)
- if(MatchWhen(f[j].when, mcfg.GetKeys()))
- HdependAddDependency(SourcePath(package, pkg[i]), SourcePath(package, f[j].text));
- }
- String tout = OutDir(mcfg, mainpackage, bm, use_target);
- host->RealizeDir(tout);
- if(IsNull(mainfn))
- mainfn = GetFileTitle(mainpackage) + b->GetTargetExt();
- if(!IsNull(outfile))
- target = NormalizePath(outfile, tout);
- else {
- if(m.target_override && !IsNull(m.target) && IsFolder(m.target))
- target = host->NormalizePath(AppendFileName(m.target, mainfn));
- else
- if(m.target_override && (IsFullPath(m.target) || *m.target == '/' || *m.target == '\\'))
- target = m.target;
- else
- if(m.target_override && !IsNull(m.target))
- target = host->NormalizePath(AppendFileName(tout, m.target));
- else
- if(IsFullPath(mainfn))
- target = mainfn;
- else
- target = host->NormalizePath(AppendFileName(tout, mainfn));
- }
- b->target = target;
- b->mainpackage = mainpackage;
- if(IsNull(onefile)) {
- String out;
- out << "----- " << package << " ( " << Join(b->config.GetKeys(), " ") << " )";
- if(pkcount > 1)
- out << " (" << (pknumber + 1) << " / " << pkcount << ')';
- PutConsole(out);
- }
- else
- b->config.FindAdd("NOLIB");
- bool ok = b->BuildPackage(package, linkfile, linkopt,
- GetAllUses(wspc, pkindex),
- GetAllLibraries(wspc, pkindex, bm, mainparam, *host, *b),
- targetmode - 1);
- Vector errors = PickErrors();
- host->DeleteFile(errors);
- if(!ok || !errors.IsEmpty())
- return false;
- if(link) {
- ok = b->Link(linkfile, linkopt, GetTargetMode().createmap);
- errors = PickErrors();
- host->DeleteFile(errors);
- if(!ok || !errors.IsEmpty())
- return false;
- }
- return true;
-}
-
-void MakeBuild::SetHdependDirs()
-{
- Vector include = SplitDirs(GetVar("UPP") + ';'
- + GetMethodVars(method).Get("INCLUDE", "") + ';'
- + Environment().Get("INCLUDE", "")
-#ifdef PLATFORM_POSIX
- + ";/usr/include;/usr/local/include"
-#endif
- );
- // Also adding internal includes
- const Workspace& wspc = GetIdeWorkspace();
- for(int i = 0; i < wspc.GetCount(); i++) {
- const Package& pkg = wspc.GetPackage(i);
- for(int j = 0; j < pkg.include.GetCount(); j++)
- include.Add(SourcePath(wspc[i], pkg.include[j].text));
- }
-
- HdependSetDirs(include);
-}
-
-Vector MakeBuild::GetAllUses(const Workspace& wspc, int f)
-{ // Warning: This does not seem to do what it is supposed to do...
- String package = wspc[f];
- Index all_uses;
- bool warn = true;
- int n = 0;
- while(f >= 0) {
- const Package& p = wspc.package[f];
- for(int fu = 0; fu < p.uses.GetCount(); fu++)
- if(p.uses[fu].text != package)
- all_uses.FindAdd(p.uses[fu].text);
- else if(warn) {
- PutConsole(NFormat("%s: circular 'uses' chain", package));
- warn = false;
- }
- f = -1;
- while(n < all_uses.GetCount() && (f = wspc.package.Find(all_uses[n++])) < 0)
- ;
- }
- return all_uses.PickKeys();
-}
-
-Vector MakeBuild::GetAllLibraries(const Workspace& wspc, int index,
- const VectorMap& bm, String mainparam,
- Host& host, Builder& builder)
-{ // Warning: This does not seem to do what it is supposed to do...
- Vector uses = GetAllUses(wspc, index);
- uses.Add(wspc[index]);
- Index libraries;
-
- for(int i = 0; i < uses.GetCount(); i++) {
- int f = wspc.package.Find(UnixPath(uses[i]));
- if(f >= 0) {
- const Package& pk = wspc.package[f];
- Index config = PackageConfig(wspc, f, bm, mainparam, host, builder);
- Vector pklibs = Split(Gather(pk.library, config.GetKeys()), ' ');
- FindAppend(libraries, pklibs);
- }
- }
- return libraries.PickKeys();
-}
-
-bool MakeBuild::Build(const Workspace& wspc, String mainparam, String outfile, bool clear_console)
-{
- ClearErrorEditor();
- BeginBuilding(true, clear_console);
- bool ok = true;
- if(wspc.GetCount()) {
- Vector build_order;
- if(GetTargetMode().linkmode != 2) {
- for(int i = 1; i < wspc.GetCount(); i++)
- build_order.Add(i);
- }
- else {
- Index remaining;
- for(int i = 1; i < wspc.GetCount(); i++)
- remaining.Add(i);
- while(!remaining.IsEmpty()) {
- int t;
- for(t = 0; t < remaining.GetCount(); t++) {
- const Package& pk = wspc.package[remaining[t]];
- bool delay = false;
- for(int u = 0; u < pk.uses.GetCount(); u++)
- if(remaining.Find(wspc.package.Find(pk.uses[u].text)) >= 0) {
- delay = true;
- break;
- }
- if(!delay)
- break;
- }
- if(t >= remaining.GetCount())
- t = 0;
- build_order.Add(remaining[t]);
- remaining.Remove(t);
- }
- }
- String mainpackage = wspc[0];
- Vector linkfile;
- String linkopt = GetMethodVars(method).Get(targetmode ? "RELEASE_LINK" : "DEBUG_LINK", Null);
- if(linkopt.GetCount())
- linkopt << ' ';
- ok = true;
- int ms = msecs();
- for(int i = 0; i < build_order.GetCount() && (ok || !stoponerrors); i++) {
- int px = build_order[i];
- ok = BuildPackage(wspc, px, i, build_order.GetCount() + 1,
- mainparam, Null, linkfile, linkopt) && ok;
- if(msecs() - ms >= 200) {
- DoProcessEvents();
- ms = msecs();
- }
- }
- if(ok || !stoponerrors)
- ok = BuildPackage(wspc, 0, build_order.GetCount(), build_order.GetCount() + 1,
- mainparam, outfile, linkfile, linkopt, ok) && ok;
- }
- EndBuilding(ok);
- ReQualifyCodeBase();
- SetErrorEditor();
- return ok;
-}
-
-bool MakeBuild::Build()
-{
- VectorMap bm = GetMethodVars(method);
- if(bm.GetCount() == 0) {
- PutConsole("Invalid build method");
- ConsoleShow();
- return false;
- }
- One host = CreateHost(false);
- One builder = CreateBuilder(~host);
- if(!builder)
- return false;
- Index p = PackageConfig(GetIdeWorkspace(), 0, bm, mainconfigparam,
- *host, *builder);
- Workspace wspc;
- wspc.Scan(GetMain(), p.GetKeys());
- return Build(wspc, mainconfigparam, Null);
-}
-
-void MakeBuild::CleanPackage(const Workspace& wspc, int package)
-{
- PutConsole(NFormat("Cleaning %s", wspc[package]));
- One host = CreateHost(false);
- One builder = CreateBuilder(~host);
- if(!builder)
- return;
- host->DeleteFolderDeep(OutDir(PackageConfig(wspc, package, GetMethodVars(method), mainconfigparam,
- *host, *builder), wspc[package], GetMethodVars(method)));
-}
-
-void MakeBuild::Clean()
-{
- ConsoleClear();
- const Workspace& wspc = GetIdeWorkspace();
- for(int i = 0; i < wspc.GetCount(); i++)
- CleanPackage(wspc, i);
- PutConsole("...done");
-}
-
-void MakeBuild::RebuildAll()
-{
- Clean();
- Build();
-}
-
-void MakeBuild::SaveMakeFile(const String& fn, bool exporting)
-{
- BeginBuilding(false, true);
-
- VectorMap bm = GetMethodVars(method);
- One host = CreateHost(false);
- One b = CreateBuilder(~host);
-
- if(!b)
- return;
-
- const TargetMode& tm = GetTargetMode();
-
- String makefile;
-
- Vector uppdirs = GetUppDirs();
- String uppout = exporting ? host->GetHostPath(GetVar("OUTPUT")) : "_out/";
- String inclist;
-
- Index allconfig = PackageConfig(GetIdeWorkspace(), 0, bm, mainconfigparam, *host, *b);
- bool win32 = allconfig.Find("WIN32") >= 0;
-
- Workspace wspc;
- wspc.Scan(GetMain(), allconfig.GetKeys());
-
- for(int i = 1; i < wspc.GetCount(); i++) {
- Index modconfig = PackageConfig(wspc, i, bm, mainconfigparam, *host, *b);
- for(int a = allconfig.GetCount(); --a >= 0;)
- if(modconfig.Find(allconfig[a]) < 0)
- allconfig.Remove(a);
- }
-
- if(!exporting)
- for(int i = 0; i < uppdirs.GetCount(); i++) {
- String srcdir = GetMakePath(AdjustMakePath(host->GetHostPath(AppendFileName(uppdirs[i], ""))), win32);
- makefile << "UPPDIR" << (i + 1) << " = " << srcdir << "\n";
- inclist << " -I$(UPPDIR" << (i + 1) << ")";
- }
- else
- inclist << "-I./";
- Vector includes = SplitDirs(bm.Get("INCLUDE",""));
- for(int i = 0; i < includes.GetCount(); i++)
- inclist << " -I" << includes[i];
-
- makefile << "\n"
- "UPPOUT = " << (exporting ? "_out/" : GetMakePath(AdjustMakePath(host->GetHostPath(AppendFileName(uppout, ""))), win32)) << "\n"
- "CINC = " << inclist << "\n"
- "Macro = ";
-
- for(int i = 0; i < allconfig.GetCount(); i++)
- makefile << " -Dflag" << allconfig[i];
- makefile << "\n";
-
- String output, config, install, rules, linkdep, linkfiles, linkfileend;
-
- for(int i = 0; i < wspc.GetCount(); i++) {
- b->config = PackageConfig(wspc, i, bm, mainconfigparam, *host, *b);
- b->version = tm.version;
- b->method = method;
- MakeFile mf;
- b->AddMakeFile(mf, wspc[i], GetAllUses(wspc, i),
- GetAllLibraries(wspc, i, bm, mainconfigparam, *host, *b), allconfig,
- exporting);
- if(!i) {
- String tdir = mf.outdir;
- String trg;
- if(tm.target_override) {
- trg = GetMakePath(AdjustMakePath(tm.target), win32);
- if(!trg.IsEmpty() && *trg.Last() == (win32 ? '\\' : '/'))
- trg << mf.outfile;
- else if(trg.Find(win32 ? '\\' : '/') < 0)
- trg.Insert(0, "$(OutDir)");
- }
- output = Nvl(trg, mf.output);
- if(exporting)
- output = wspc[i] + ".out";
- install << "\n"
- "OutDir = " << tdir << "\n"
- "OutFile = " << output << "\n"
- "\n"
- ".PHONY: all\n"
- "all: prepare $(OutFile)\n"
- "\n"
- ".PHONY: prepare\n"
- "prepare:\n";
- }
- config << mf.config;
- install << mf.install;
- rules << mf.rules;
- linkdep << mf.linkdep;
- linkfiles << mf.linkfiles;
- linkfileend << mf.linkfileend;
- }
-
- makefile
- << config
- << install
- << "\n"
- "$(OutFile): " << linkdep << "\n\t" << linkfiles << linkfileend << " -Wl,--end-group\n\n"
- << rules
- << ".PHONY: clean\n"
- << "clean:\n"
- << "\tif [ -d $(UPPOUT) ]; then rm -rf $(UPPOUT); fi;\n";
-
- bool sv = ::SaveFile(fn, makefile);
- if(!exporting)
- if(sv)
- PutConsole(NFormat("%s(1): makefile generation complete", fn));
- else
- PutConsole(NFormat("%s: error writing makefile", fn));
-
- EndBuilding(true);
-}
+#include "Builders.h"
+
+#include
+
+#define LDUMP(x) // DUMP(x)
+
+MakeBuild::MakeBuild()
+{
+ targetmode = 0;
+ stoponerrors = true;
+ use_target = false;
+}
+
+const TargetMode& MakeBuild::GetTargetMode()
+{
+ return (targetmode == 0 ? debug : release);
+}
+
+Index MakeBuild::PackageConfig(const Workspace& wspc, int package,
+ const VectorMap& bm, String mainparam,
+ Host& host, Builder& b, String *target)
+{
+ String packagepath = PackagePath(wspc[package]);
+ const Package& pkg = wspc.package[package];
+ Index cfg;
+ mainparam << ' ' << bm.Get(targetmode ? "RELEASE_FLAGS" : "DEBUG_FLAGS", NULL);
+ cfg = SplitFlags(mainparam, package == 0, wspc.GetAllAccepts(package));
+ cfg.FindAdd(bm.Get("BUILDER", "GCC"));
+ const TargetMode& m = GetTargetMode();
+ if(targetmode == 0)
+ cfg.FindAdd("DEBUG");
+ switch(m.linkmode) {
+ case 2:
+ cfg.FindAdd("SO");
+ case 1:
+ cfg.FindAdd("SHARED");
+ }
+ if(targetmode == 2)
+ cfg.FindAdd("FORCE_SPEED");
+ if(targetmode == 3)
+ cfg.FindAdd("FORCE_SIZE");
+ int q = m.package.Find(wspc[package]);
+ if(q >= 0) {
+ const PackageMode& p = m.package[q];
+ switch(p.debug >= 0 ? p.debug : m.def.debug) {
+ case 1: cfg.FindAdd("DEBUG_MINIMAL"); break;
+ case 2: cfg.FindAdd("DEBUG_FULL"); break;
+ }
+ if(!pkg.noblitz && (p.blitz >= 0 ? p.blitz : m.def.blitz))
+ cfg.FindAdd("BLITZ");
+ }
+ else {
+ switch(m.def.debug) {
+ case 1: cfg.FindAdd("DEBUG_MINIMAL"); break;
+ case 2: cfg.FindAdd("DEBUG_FULL"); break;
+ }
+ if(!pkg.noblitz && m.def.blitz)
+ cfg.FindAdd("BLITZ");
+ }
+ host.AddFlags(cfg);
+ b.AddFlags(cfg);
+ for(int i = 0; i < pkg.flag.GetCount(); i++) {
+ if(MatchWhen(pkg.flag[i].when, cfg.GetKeys()))
+ cfg.Add(pkg.flag[i].text);
+ }
+ if(target)
+ *target = Gather(pkg.target, cfg.GetKeys(), true);
+ return cfg;
+}
+
+String NoCr(const char *s)
+{
+ String out;
+ while(*s)
+ {
+ const char *b = s;
+ while(*s && *s != '\r')
+ s++;
+ out.Cat(b, int(s - b));
+ if(*s == '\r')
+ s++;
+ }
+ return out;
+}
+
+#if 0 // REMOTE REMOVED
+bool MakeBuild::SyncHostFiles(RemoteHost& host)
+{
+ HdependTimeDirty();
+ String query = "<";
+// Vector remotepath;
+ Vector fdata;
+ ArrayMap info;
+ Vector nocrsize;
+ const Workspace& wspc = GetIdeWorkspace();
+ int p;
+ for(p = 0; p < wspc.GetCount(); p++) {
+ const Package& pkg = wspc.GetPackage(p);
+ String pn = wspc[p];
+ for(int f = -1; f < pkg.file.GetCount(); f++)
+ if(f < 0 || !pkg.file[f].separator) {
+ Vector pkgfiles;
+ String pk = (f >= 0 ? SourcePath(pn, pkg.file[f]) : PackagePath(pn));
+ if(!FindFile(pk).IsFile())
+ continue;
+ pkgfiles.Add(f >= 0 ? SourcePath(pn, pkg.file[f]) : PackagePath(pn));
+ pkgfiles.AppendPick(HdependGetDependencies(pkgfiles[0]));
+ for(int d = 0; d < pkgfiles.GetCount(); d++) {
+ TransferFileInfo newinfo;
+ newinfo.sourcepath = pkgfiles[d];
+ String rp = host.GetHostPath(newinfo.sourcepath);
+ if(info.Find(rp) >= 0 || (d && UnixPath(rp) == UnixPath(newinfo.sourcepath)))
+ continue;
+ FindFile ff(newinfo.sourcepath);
+ newinfo.filetime = (int)(Time(ff.GetLastWriteTime()) - RemoteHost::TimeBase());
+ newinfo.filesize = (int)ff.GetLength();
+ int pos = transferfilecache.Find(rp);
+ if(pos < 0 || transferfilecache[pos].filetime != newinfo.filetime
+ || transferfilecache[pos].filesize != newinfo.filesize)
+ {
+ String content = NoCr(LoadFile(newinfo.sourcepath));
+ query << rp << '\t' << newinfo.filetime << '\t' << content.GetLength() << '\n';
+ // remotepath.Add(rp);
+ fdata.Add(content);
+ info.Add(rp, newinfo);
+ nocrsize.Add(content.GetLength());
+ PutVerbose("Checking remote " + rp);
+ /*
+ if(msecs(ticks) >= 0)
+ {
+ ShowConsole();
+ console.Sync();
+ ticks = msecs(-200);
+ }
+ */ }
+ }
+ }
+ }
+ if(info.IsEmpty())
+ return true;
+// String host = GetVar("REMOTE_HOST");
+// int port = 2346;
+// int ppos = host.Find(':');
+// if(ppos >= 0)
+// {
+// port = ScanInt(host.GetIter(ppos + 1));
+// host.Trim(ppos);
+// }
+
+ Index ignore;
+ {
+ PutConsole(NFormat("Retrieving update list for remote filesystem %s", host.host));
+ ConsoleShow();
+ String out = host.RemoteExec(query);
+ if(out[0] != 'O' || out[1] != 'K') {
+ PutConsole(out);
+ return false;
+ }
+
+ const char *s = out;
+ while(*s && *s++ != '\n')
+ ;
+ while(*s)
+ {
+ const char *b = s;
+ while(*s && *s != '\n')
+ s++;
+ ignore.FindAdd(NormalizePath(NativePath(String(b, s))));
+ if(*s)
+ s++;
+ }
+ if(ignore.GetCount() == info.GetCount())
+ PutConsole("Remote source tree is up to date.");
+ else
+ {
+ PutConsole(NFormat("%d file(s) missing in remote source tree:", info.GetCount() - ignore.GetCount()));
+ for(p = 0; p < info.GetCount(); p++)
+ {
+// console << " " << remotepath[p] << " - "
+// << FormatInt(p) << " @ " << FormatInt(ignore.Find(remotepath[p])) << "\n";
+ if(ignore.Find(NormalizePath(NativePath(info.GetKey(p)))) < 0)
+ PutConsole(String().Cat() << " " << info.GetKey(p));
+ }
+ }
+ }
+
+ Vector update;
+ for(p = 0; p < info.GetCount(); p++)
+ if(ignore.Find(NormalizePath(NativePath(info.GetKey(p)))) < 0)
+ {
+ String rawdata = fdata[p];
+ PutConsole(String().Cat() << "Compressing " << info[p].sourcepath << " (" << FormatInt(rawdata.GetLength()) << " B)\n");
+ ConsoleSync();
+ String bzdata = BZ2Compress(rawdata);
+ String comp = ASCII85Encode(bzdata);
+ if(update.IsEmpty() || update.Top().GetLength() + comp.GetLength() >= 500000)
+ update.Add(">");
+ update.Top() << info.GetKey(p) << '\t' << info[p].filetime << '\t' << nocrsize[p] << '\t' << comp << '\n';
+ }
+
+ for(p = 0; p < update.GetCount(); p++)
+ {
+ PutConsole(NFormat("Uploading block %d / %d (%d B)", p + 1, update.GetCount(), update[p].GetLength()));
+ ConsoleShow();
+ String result = host.RemoteExec(update[p]);
+ if(result[0] != 'O' || result[1] != 'K') {
+ PutConsole(result);
+ return false;
+ }
+ }
+
+ for(p = 0; p < info.GetCount(); p++)
+ transferfilecache.GetAdd(info.GetKey(p)) = info[p];
+ return true;
+}
+#endif
+
+One MakeBuild::CreateHost(bool sync_files)
+{
+ SetupDefaultMethod();
+ VectorMap bm = GetMethodVars(method);
+ One outhost;
+#if 0 // REMOTE REMOVED
+ String rm = bm.Get("REMOTE_HOST", Null);
+ if(!IsNull(rm)) {
+ One host = new RemoteHost;
+ host->host = rm;
+ host->port = 2346;
+ int f = rm.Find(':');
+ if(f >= 0) {
+ host->host = rm.Left(f);
+ host->port = Nvl(ScanInt(rm.GetIter(f + 1)), host->port);
+ }
+ host->os_type = bm.Get("REMOTE_OS", "UNIX");
+ Vector path_map = Split(bm.Get("REMOTE_MAP", Null), ';');
+ for(int p = 0; p < path_map.GetCount(); p++) {
+ f = path_map[p].Find('>');
+ if(f >= 0) {
+ host->path_map_local.Add(path_map[p].Left(f));
+ host->path_map_remote.Add(path_map[p].Mid(f + 1));
+ }
+ }
+ VectorMap env(Environment(), 1);
+ Vector exedirs = SplitDirs(bm.Get("PATH", "") + ';' + env.Get("PATH", ""));
+ env.GetAdd("PATH") = Join(exedirs, ";");
+ for(int i = 0; i < env.GetCount(); i++)
+ host->environment << env.GetKey(i) << '=' << env[i] << '\0';
+ host->environment.Cat(0);
+ if(sync_files && bm.Get("REMOTE_TRANSFER", Null) != "0")
+ SyncHostFiles(*host);
+ outhost = -host;
+ }
+ else
+#endif
+ {
+ One host = new LocalHost;
+ VectorMap env(Environment(), 1);
+ host->exedirs = SplitDirs(bm.Get("PATH", "") + ';' + env.Get("PATH", ""));
+ env.GetAdd("PATH") = Join(host->exedirs, ";");
+ env.GetAdd("UPP_MAIN__") = GetFileDirectory(PackagePath(GetMain()));
+ env.GetAdd("UPP_ASSEMBLY__") = GetVar("UPP");
+ for(int i = 0; i < env.GetCount(); i++) {
+ LDUMP(env.GetKey(i));
+ LDUMP(env[i]);
+ host->environment << env.GetKey(i) << '=' << env[i] << '\0';
+ }
+ host->environment.Cat(0);
+ host->cmdout = &cmdout;
+ outhost = -host;
+ }
+ return outhost;
+}
+
+One MakeBuild::CreateBuilder(Host *host)
+{
+ SetupDefaultMethod();
+ VectorMap bm = GetMethodVars(method);
+ String builder = bm.Get("BUILDER", "GCC");
+ int q = BuilderMap().Find(builder);
+ if(q < 0) {
+ PutConsole("Invalid builder " + builder);
+ ConsoleShow();
+ return NULL;
+ }
+ One b = (*BuilderMap().Get(builder))();
+ b->host = host;
+ b->compiler = bm.Get("COMPILER", "");
+ b->include = SplitDirs(GetVar("UPP") + ';' + bm.Get("INCLUDE", ""));
+ const Workspace& wspc = GetIdeWorkspace();
+ for(int i = 0; i < wspc.GetCount(); i++) {
+ const Package& pkg = wspc.GetPackage(i);
+ for(int j = 0; j < pkg.include.GetCount(); j++)
+ b->include.Add(SourcePath(wspc[i], pkg.include[j].text));
+ }
+ b->libpath = SplitDirs(bm.Get("LIB", ""));
+ b->debug_options = bm.Get("DEBUG_OPTIONS", "");
+ b->release_options = bm.Get("RELEASE_OPTIONS", "");
+ b->release_size_options = bm.Get("RELEASE_SIZE_OPTIONS", "");
+ b->debug_link = bm.Get("DEBUG_LINK", "");
+ b->release_link = bm.Get("RELEASE_LINK", "");
+ b->script = bm.Get("SCRIPT", "");
+ return b;
+}
+
+int CharFilterSlash(int c)
+{
+ return c == '\\' ? '/' : c;
+}
+
+bool output_per_assembly;
+
+String MakeBuild::OutDir(const Index& cfg, const String& package, const VectorMap& bm,
+ bool use_target)
+{
+ Index excl;
+ excl.Add(bm.Get("BUILDER", "GCC"));
+ excl.Add("MSC");
+ LocalHost().AddFlags(excl);
+ Vector x;
+ bool dbg = cfg.Find("DEBUG_FULL") >= 0 || cfg.Find("DEBUG_MINIMAL") >= 0;
+ if(cfg.Find("DEBUG") >= 0) {
+ excl.Add("BLITZ");
+ if(cfg.Find("BLITZ") < 0)
+ x.Add("NOBLITZ");
+ }
+ else
+ if(dbg)
+ x.Add("RELEASE");
+ if(use_target)
+ excl.Add("MAIN");
+ for(int i = 0; i < cfg.GetCount(); i++)
+ if(excl.Find(cfg[i]) < 0)
+ x.Add(cfg[i]);
+ Sort(x);
+ for(int i = 0; i < x.GetCount(); i++)
+ x[i] = InitCaps(x[i]);
+ String outdir = GetVar("OUTPUT");
+ if(output_per_assembly)
+ outdir = AppendFileName(outdir, GetVarsName());
+ if(!use_target)
+ outdir = AppendFileName(outdir, package);
+ outdir = AppendFileName(outdir, GetFileTitle(method) + "." + Join(x, "."));
+ outdir = Filter(outdir, CharFilterSlash);
+ return outdir;
+}
+
+struct OneFileHost : Host {
+ One host;
+ String onefile;
+
+ virtual String GetEnvironment() { return host->GetEnvironment(); }
+ virtual String GetHostPath(const String& path) { return host->GetHostPath(path); }
+ virtual String GetLocalPath(const String& path) { return host->GetLocalPath(path); }
+ virtual String NormalizePath(const String& path) { return host->NormalizePath(path); }
+ virtual void DeleteFile(const Vector& path) { host->DeleteFile(path); }
+ virtual void DeleteFolderDeep(const String& folder) { host->DeleteFolderDeep(folder); }
+ virtual void ChDir(const String& path) { host->ChDir(path); }
+ virtual void RealizeDir(const String& path) { host->RealizeDir(path); }
+ virtual void SaveFile(const String& path, const String& data) { host->SaveFile(path, data); }
+ virtual String LoadFile(const String& path) { return host->LoadFile(path); }
+ virtual int Execute(const char *c) { return host->Execute(c); }
+ virtual int ExecuteWithInput(const char *c) { return host->ExecuteWithInput(c); }
+ virtual int Execute(const char *c, Stream& o) { return host->Execute(c, o); }
+ virtual int AllocSlot() { return host->AllocSlot(); }
+ virtual bool Run(const char *cmdline, int slot, String key, int blitz_count) { return host->Run(cmdline, slot, key, blitz_count); }
+ virtual bool Run(const char *cmdline, Stream& out, int slot, String key, int blitz_count) { return host->Run(cmdline, out, slot, key, blitz_count); }
+ virtual bool Wait() { return host->Wait(); }
+ virtual One StartProcess(const char *c) { return host->StartProcess(c); }
+ virtual void Launch(const char *cmdline, bool) { host->Launch(cmdline); }
+ virtual void AddFlags(Index& cfg) { host->AddFlags(cfg); }
+
+ virtual Vector GetFileInfo(const Vector& path) {
+ Vector fi = host->GetFileInfo(path);
+ for(int i = 0; i < path.GetCount(); i++)
+ if(path[i] == onefile)
+ (Time &)fi[i] = GetSysTime();
+ else
+ (Time &)fi[i] = Time::Low();
+ return fi;
+ }
+};
+
+bool MakeBuild::BuildPackage(const Workspace& wspc, int pkindex, int pknumber, int pkcount,
+ String mainparam, String outfile, Vector& linkfile, String& linkopt, bool link)
+{
+ String package = wspc[pkindex];
+ String mainpackage = wspc[0];
+ const Package& pkg = wspc.package[pkindex];
+ VectorMap bm = GetMethodVars(method);
+ if(bm.GetCount() == 0) {
+ PutConsole("Invalid build method");
+ ConsoleShow();
+ return false;
+ }
+ One host = CreateHost(false);
+ if(!IsNull(onefile)) {
+ OneFileHost *h = new OneFileHost;
+ h->host = host;
+ h->onefile = onefile;
+ host = h;
+ }
+ One b = CreateBuilder(~host);
+ if(!b)
+ return false;
+ b->config = PackageConfig(wspc, pkindex, bm, mainparam, *host, *b);
+ const TargetMode& m = targetmode == 0 ? debug : release;
+ b->version = m.version;
+ b->method = method;
+ b->outdir = OutDir(b->config, package, bm);
+ host->RealizeDir(b->outdir);
+ String mainfn = Null;
+ Index mcfg = PackageConfig(wspc, 0, bm, mainparam, *host, *b, &mainfn);
+ HdependClearDependencies();
+ for(int i = 0; i < pkg.GetCount(); i++) {
+ const Array& f = pkg[i].depends;
+ for(int j = 0; j < f.GetCount(); j++)
+ if(MatchWhen(f[j].when, mcfg.GetKeys()))
+ HdependAddDependency(SourcePath(package, pkg[i]), SourcePath(package, f[j].text));
+ }
+ String tout = OutDir(mcfg, mainpackage, bm, use_target);
+ host->RealizeDir(tout);
+ if(IsNull(mainfn))
+ mainfn = GetFileTitle(mainpackage) + b->GetTargetExt();
+ if(!IsNull(outfile))
+ target = NormalizePath(outfile, tout);
+ else {
+ if(m.target_override && !IsNull(m.target) && IsFolder(m.target))
+ target = host->NormalizePath(AppendFileName(m.target, mainfn));
+ else
+ if(m.target_override && (IsFullPath(m.target) || *m.target == '/' || *m.target == '\\'))
+ target = m.target;
+ else
+ if(m.target_override && !IsNull(m.target))
+ target = host->NormalizePath(AppendFileName(tout, m.target));
+ else
+ if(IsFullPath(mainfn))
+ target = mainfn;
+ else
+ target = host->NormalizePath(AppendFileName(tout, mainfn));
+ }
+ b->target = target;
+ b->mainpackage = mainpackage;
+ if(IsNull(onefile)) {
+ String out;
+ out << "----- " << package << " ( " << Join(b->config.GetKeys(), " ") << " )";
+ if(pkcount > 1)
+ out << " (" << (pknumber + 1) << " / " << pkcount << ')';
+ PutConsole(out);
+ }
+ else
+ b->config.FindAdd("NOLIB");
+ bool ok = b->BuildPackage(package, linkfile, linkopt,
+ GetAllUses(wspc, pkindex),
+ GetAllLibraries(wspc, pkindex, bm, mainparam, *host, *b),
+ targetmode - 1);
+ Vector errors = PickErrors();
+ host->DeleteFile(errors);
+ if(!ok || !errors.IsEmpty())
+ return false;
+ if(link) {
+ ok = b->Link(linkfile, linkopt, GetTargetMode().createmap);
+ errors = PickErrors();
+ host->DeleteFile(errors);
+ if(!ok || !errors.IsEmpty())
+ return false;
+ }
+ return true;
+}
+
+void MakeBuild::SetHdependDirs()
+{
+ Vector include = SplitDirs(GetVar("UPP") + ';'
+ + GetMethodVars(method).Get("INCLUDE", "") + ';'
+ + Environment().Get("INCLUDE", "")
+#ifdef PLATFORM_POSIX
+ + ";/usr/include;/usr/local/include"
+#endif
+ );
+ // Also adding internal includes
+ const Workspace& wspc = GetIdeWorkspace();
+ for(int i = 0; i < wspc.GetCount(); i++) {
+ const Package& pkg = wspc.GetPackage(i);
+ for(int j = 0; j < pkg.include.GetCount(); j++)
+ include.Add(SourcePath(wspc[i], pkg.include[j].text));
+ }
+
+ HdependSetDirs(include);
+}
+
+Vector MakeBuild::GetAllUses(const Workspace& wspc, int f)
+{ // Warning: This does not seem to do what it is supposed to do...
+ String package = wspc[f];
+ Index all_uses;
+ bool warn = true;
+ int n = 0;
+ while(f >= 0) {
+ const Package& p = wspc.package[f];
+ for(int fu = 0; fu < p.uses.GetCount(); fu++)
+ if(p.uses[fu].text != package)
+ all_uses.FindAdd(p.uses[fu].text);
+ else if(warn) {
+ PutConsole(NFormat("%s: circular 'uses' chain", package));
+ warn = false;
+ }
+ f = -1;
+ while(n < all_uses.GetCount() && (f = wspc.package.Find(all_uses[n++])) < 0)
+ ;
+ }
+ return all_uses.PickKeys();
+}
+
+Vector MakeBuild::GetAllLibraries(const Workspace& wspc, int index,
+ const VectorMap& bm, String mainparam,
+ Host& host, Builder& builder)
+{ // Warning: This does not seem to do what it is supposed to do...
+ Vector uses = GetAllUses(wspc, index);
+ uses.Add(wspc[index]);
+ Index libraries;
+
+ for(int i = 0; i < uses.GetCount(); i++) {
+ int f = wspc.package.Find(UnixPath(uses[i]));
+ if(f >= 0) {
+ const Package& pk = wspc.package[f];
+ Index config = PackageConfig(wspc, f, bm, mainparam, host, builder);
+ Vector pklibs = Split(Gather(pk.library, config.GetKeys()), ' ');
+ FindAppend(libraries, pklibs);
+ }
+ }
+ return libraries.PickKeys();
+}
+
+bool MakeBuild::Build(const Workspace& wspc, String mainparam, String outfile, bool clear_console)
+{
+ ClearErrorEditor();
+ BeginBuilding(true, clear_console);
+ bool ok = true;
+ if(wspc.GetCount()) {
+ Vector build_order;
+ if(GetTargetMode().linkmode != 2) {
+ for(int i = 1; i < wspc.GetCount(); i++)
+ build_order.Add(i);
+ }
+ else {
+ Index remaining;
+ for(int i = 1; i < wspc.GetCount(); i++)
+ remaining.Add(i);
+ while(!remaining.IsEmpty()) {
+ int t;
+ for(t = 0; t < remaining.GetCount(); t++) {
+ const Package& pk = wspc.package[remaining[t]];
+ bool delay = false;
+ for(int u = 0; u < pk.uses.GetCount(); u++)
+ if(remaining.Find(wspc.package.Find(pk.uses[u].text)) >= 0) {
+ delay = true;
+ break;
+ }
+ if(!delay)
+ break;
+ }
+ if(t >= remaining.GetCount())
+ t = 0;
+ build_order.Add(remaining[t]);
+ remaining.Remove(t);
+ }
+ }
+ String mainpackage = wspc[0];
+ Vector linkfile;
+ String linkopt = GetMethodVars(method).Get(targetmode ? "RELEASE_LINK" : "DEBUG_LINK", Null);
+ if(linkopt.GetCount())
+ linkopt << ' ';
+ ok = true;
+ int ms = msecs();
+ for(int i = 0; i < build_order.GetCount() && (ok || !stoponerrors); i++) {
+ int px = build_order[i];
+ ok = BuildPackage(wspc, px, i, build_order.GetCount() + 1,
+ mainparam, Null, linkfile, linkopt) && ok;
+ if(msecs() - ms >= 200) {
+ DoProcessEvents();
+ ms = msecs();
+ }
+ }
+ if(ok || !stoponerrors)
+ ok = BuildPackage(wspc, 0, build_order.GetCount(), build_order.GetCount() + 1,
+ mainparam, outfile, linkfile, linkopt, ok) && ok;
+ }
+ EndBuilding(ok);
+ ReQualifyCodeBase();
+ SetErrorEditor();
+ return ok;
+}
+
+bool MakeBuild::Build()
+{
+ VectorMap bm = GetMethodVars(method);
+ if(bm.GetCount() == 0) {
+ PutConsole("Invalid build method");
+ ConsoleShow();
+ return false;
+ }
+ One host = CreateHost(false);
+ One builder = CreateBuilder(~host);
+ if(!builder)
+ return false;
+ Index p = PackageConfig(GetIdeWorkspace(), 0, bm, mainconfigparam,
+ *host, *builder);
+ Workspace wspc;
+ wspc.Scan(GetMain(), p.GetKeys());
+ return Build(wspc, mainconfigparam, Null);
+}
+
+void MakeBuild::CleanPackage(const Workspace& wspc, int package)
+{
+ PutConsole(NFormat("Cleaning %s", wspc[package]));
+ One host = CreateHost(false);
+ One builder = CreateBuilder(~host);
+ if(!builder)
+ return;
+ host->DeleteFolderDeep(OutDir(PackageConfig(wspc, package, GetMethodVars(method), mainconfigparam,
+ *host, *builder), wspc[package], GetMethodVars(method)));
+}
+
+void MakeBuild::Clean()
+{
+ ConsoleClear();
+ const Workspace& wspc = GetIdeWorkspace();
+ for(int i = 0; i < wspc.GetCount(); i++)
+ CleanPackage(wspc, i);
+ PutConsole("...done");
+}
+
+void MakeBuild::RebuildAll()
+{
+ Clean();
+ Build();
+}
+
+void MakeBuild::SaveMakeFile(const String& fn, bool exporting)
+{
+ BeginBuilding(false, true);
+
+ VectorMap bm = GetMethodVars(method);
+ One host = CreateHost(false);
+ One b = CreateBuilder(~host);
+
+ if(!b)
+ return;
+
+ const TargetMode& tm = GetTargetMode();
+
+ String makefile;
+
+ Vector uppdirs = GetUppDirs();
+ String uppout = exporting ? host->GetHostPath(GetVar("OUTPUT")) : "_out/";
+ String inclist;
+
+ Index allconfig = PackageConfig(GetIdeWorkspace(), 0, bm, mainconfigparam, *host, *b);
+ bool win32 = allconfig.Find("WIN32") >= 0;
+
+ Workspace wspc;
+ wspc.Scan(GetMain(), allconfig.GetKeys());
+
+ for(int i = 1; i < wspc.GetCount(); i++) {
+ Index modconfig = PackageConfig(wspc, i, bm, mainconfigparam, *host, *b);
+ for(int a = allconfig.GetCount(); --a >= 0;)
+ if(modconfig.Find(allconfig[a]) < 0)
+ allconfig.Remove(a);
+ }
+
+ if(!exporting)
+ for(int i = 0; i < uppdirs.GetCount(); i++) {
+ String srcdir = GetMakePath(AdjustMakePath(host->GetHostPath(AppendFileName(uppdirs[i], ""))), win32);
+ makefile << "UPPDIR" << (i + 1) << " = " << srcdir << "\n";
+ inclist << " -I$(UPPDIR" << (i + 1) << ")";
+ }
+ else
+ inclist << "-I./";
+ Vector includes = SplitDirs(bm.Get("INCLUDE",""));
+ for(int i = 0; i < includes.GetCount(); i++)
+ inclist << " -I" << includes[i];
+
+ makefile << "\n"
+ "UPPOUT = " << (exporting ? "_out/" : GetMakePath(AdjustMakePath(host->GetHostPath(AppendFileName(uppout, ""))), win32)) << "\n"
+ "CINC = " << inclist << "\n"
+ "Macro = ";
+
+ for(int i = 0; i < allconfig.GetCount(); i++)
+ makefile << " -Dflag" << allconfig[i];
+ makefile << "\n";
+
+ String output, config, install, rules, linkdep, linkfiles, linkfileend;
+
+ for(int i = 0; i < wspc.GetCount(); i++) {
+ b->config = PackageConfig(wspc, i, bm, mainconfigparam, *host, *b);
+ b->version = tm.version;
+ b->method = method;
+ MakeFile mf;
+ b->AddMakeFile(mf, wspc[i], GetAllUses(wspc, i),
+ GetAllLibraries(wspc, i, bm, mainconfigparam, *host, *b), allconfig,
+ exporting);
+ if(!i) {
+ String tdir = mf.outdir;
+ String trg;
+ if(tm.target_override) {
+ trg = GetMakePath(AdjustMakePath(tm.target), win32);
+ if(!trg.IsEmpty() && *trg.Last() == (win32 ? '\\' : '/'))
+ trg << mf.outfile;
+ else if(trg.Find(win32 ? '\\' : '/') < 0)
+ trg.Insert(0, "$(OutDir)");
+ }
+ output = Nvl(trg, mf.output);
+ if(exporting)
+ output = wspc[i] + ".out";
+ install << "\n"
+ "OutDir = " << tdir << "\n"
+ "OutFile = " << output << "\n"
+ "\n"
+ ".PHONY: all\n"
+ "all: prepare $(OutFile)\n"
+ "\n"
+ ".PHONY: prepare\n"
+ "prepare:\n";
+ }
+ config << mf.config;
+ install << mf.install;
+ rules << mf.rules;
+ linkdep << mf.linkdep;
+ linkfiles << mf.linkfiles;
+ linkfileend << mf.linkfileend;
+ }
+
+ makefile
+ << config
+ << install
+ << "\n"
+ "$(OutFile): " << linkdep << "\n\t" << linkfiles << linkfileend << " -Wl,--end-group\n\n"
+ << rules
+ << ".PHONY: clean\n"
+ << "clean:\n"
+ << "\tif [ -d $(UPPOUT) ]; then rm -rf $(UPPOUT); fi;\n";
+
+ bool sv = ::SaveFile(fn, makefile);
+ if(!exporting)
+ if(sv)
+ PutConsole(NFormat("%s(1): makefile generation complete", fn));
+ else
+ PutConsole(NFormat("%s: error writing makefile", fn));
+
+ EndBuilding(true);
+}
diff --git a/uppsrc/ide/Builders/Build.h b/uppsrc/ide/Builders/Build.h
index 9a90bfb26..c8aaf1537 100644
--- a/uppsrc/ide/Builders/Build.h
+++ b/uppsrc/ide/Builders/Build.h
@@ -63,7 +63,7 @@ struct MakeBuild {
const TargetMode& GetTargetMode();
Index PackageConfig(const Workspace& wspc, int package, const VectorMap& bm,
String mainparam, Host& host, Builder& b, String *target = NULL);
- bool SyncHostFiles(RemoteHost& host);
+// bool SyncHostFiles(RemoteHost& host);
One CreateHost(bool sync_files);
One CreateBuilder(Host *host);
String OutDir(const Index& cfg, const String& package,
diff --git a/uppsrc/ide/Console.cpp b/uppsrc/ide/Console.cpp
index 2cad23988..5cb7a9a22 100644
--- a/uppsrc/ide/Console.cpp
+++ b/uppsrc/ide/Console.cpp
@@ -146,7 +146,7 @@ int Console::Flush()
return !running ? -1 : done_output ? 1 : 0;
}
-int Console::Execute(One p, const char *command, Stream *out, bool q)
+int Console::Execute(One p, const char *command, Stream *out, bool q)
{
Wait();
if(!Run(p, command, out, q, 0))
@@ -159,12 +159,14 @@ int Console::Execute(const char *command, Stream *out, const char *envptr, bool
{
try {
Wait();
- return Execute(StartProcess(command, envptr, REMOTE_TIMEOUT), command, out, q);
+ One p;
+ if(p.Create().Start(command, envptr))
+ return Execute(p, command, out, q);
}
catch(Exc e) {
- ProcessEvents();
- return Null;
}
+ ProcessEvents();
+ return Null;
}
int Console::AllocSlot()
@@ -188,17 +190,18 @@ bool Console::Run(const char *cmdline, Stream *out, const char *envptr, bool qui
{
try {
Wait(slot);
- One sproc = StartProcess(cmdline, envptr, REMOTE_TIMEOUT);
- return !!sproc && Run(sproc, cmdline, out, quiet, slot, key, blitz_count);
+ One sproc;
+ return sproc.Create().Start(cmdline, envptr) &&
+ Run(sproc, cmdline, out, quiet, slot, key, blitz_count);
}
catch(Exc e) {
Append(e);
- ProcessEvents();
- return false;
}
+ ProcessEvents();
+ return false;
}
-bool Console::Run(One process, const char *cmdline, Stream *out, bool quiet, int slot, String key, int blitz_count)
+bool Console::Run(One process, const char *cmdline, Stream *out, bool quiet, int slot, String key, int blitz_count)
{
if(!process) {
if(verbosebuild)
@@ -300,7 +303,8 @@ void Console::Kill(int islot)
{
Slot& slot = processes[islot];
if(slot.process) {
- slot.process->Kill();
+ if(slot.process->IsRunning())
+ slot.process->Kill();
slot.exitcode = slot.process->GetExitCode();
if(slot.exitcode != 0 && !IsNull(slot.key))
error_keys.Add(slot.key);
diff --git a/uppsrc/ide/Core/Core.cpp b/uppsrc/ide/Core/Core.cpp
index 21aa88673..4881b8bb7 100644
--- a/uppsrc/ide/Core/Core.cpp
+++ b/uppsrc/ide/Core/Core.cpp
@@ -146,7 +146,7 @@ int IdeConsoleExecuteWithInput(const char *cmdline, Stream *out, const char *env
return the_ide ? the_ide->IdeConsoleExecuteWithInput(cmdline, out, envptr, quiet) : -1;
}
-int IdeConsoleExecute(One process, const char *cmdline, Stream *out, bool quiet)
+int IdeConsoleExecute(One process, const char *cmdline, Stream *out, bool quiet)
{
return the_ide ? the_ide->IdeConsoleExecute(process, cmdline, out, quiet) : -1;
}
@@ -161,7 +161,7 @@ bool IdeConsoleRun(const char *cmdline, Stream *out, const char *envptr, bool qu
return the_ide && the_ide->IdeConsoleRun(cmdline, out, envptr, quiet, slot, key, blitz_count);
}
-bool IdeConsoleRun(One process, const char *cmdline, Stream *out, bool quiet, int slot, String key, int blitz_count)
+bool IdeConsoleRun(One process, const char *cmdline, Stream *out, bool quiet, int slot, String key, int blitz_count)
{
return the_ide && the_ide->IdeConsoleRun(process, cmdline, out, quiet, slot, key, blitz_count);
}
diff --git a/uppsrc/ide/Core/Core.h b/uppsrc/ide/Core/Core.h
index 9289a9c5f..49a23c7c8 100644
--- a/uppsrc/ide/Core/Core.h
+++ b/uppsrc/ide/Core/Core.h
@@ -2,7 +2,7 @@
#define COMMON_H
#include
-#include
+// #include
#include
#include
@@ -45,10 +45,10 @@ public:
virtual String IdeGetOneFile() const = 0;
virtual int IdeConsoleExecute(const char *cmdline, Stream *out = NULL, const char *envptr = NULL, bool quiet = false) = 0;
virtual int IdeConsoleExecuteWithInput(const char *cmdline, Stream *out, const char *envptr, bool quiet) = 0;
- virtual int IdeConsoleExecute(One process, const char *cmdline, Stream *out = NULL, bool quiet = false) = 0;
+ virtual int IdeConsoleExecute(One process, const char *cmdline, Stream *out = NULL, bool quiet = false) = 0;
virtual int IdeConsoleAllocSlot() = 0;
virtual bool IdeConsoleRun(const char *cmdline, Stream *out = NULL, const char *envptr = NULL, bool quiet = false, int slot = 0, String key = Null, int blitz_count = 1) = 0;
- virtual bool IdeConsoleRun(One process, const char *cmdline, Stream *out = NULL, bool quiet = false, int slot = 0, String key = Null, int blitz_count = 1) = 0;
+ virtual bool IdeConsoleRun(One process, const char *cmdline, Stream *out = NULL, bool quiet = false, int slot = 0, String key = Null, int blitz_count = 1) = 0;
virtual void IdeConsoleFlush() = 0;
virtual void IdeConsoleBeginGroup(String group) = 0;
virtual void IdeConsoleEndGroup() = 0;
@@ -95,10 +95,10 @@ bool IdeIsBuilding();
String IdeGetOneFile();
int IdeConsoleExecute(const char *cmdline, Stream *out = NULL, const char *envptr = NULL, bool quiet = false);
int IdeConsoleExecuteWithInput(const char *cmdline, Stream *out, const char *envptr, bool quiet);
-int IdeConsoleExecute(One process, const char *cmdline, Stream *out = NULL, bool quiet = false);
+int IdeConsoleExecute(One process, const char *cmdline, Stream *out = NULL, bool quiet = false);
int IdeConsoleAllocSlot();
bool IdeConsoleRun(const char *cmdline, Stream *out = NULL, const char *envptr = NULL, bool quiet = false, int slot = 0, String key = Null, int blitz_count = 1);
-bool IdeConsoleRun(One process, const char *cmdline, Stream *out = NULL, bool quiet = false, int slot = 0, String key = Null, int blitz_count = 1);
+bool IdeConsoleRun(One process, const char *cmdline, Stream *out = NULL, bool quiet = false, int slot = 0, String key = Null, int blitz_count = 1);
void IdeConsoleFlush();
void IdeConsoleBeginGroup(String group);
void IdeConsoleEndGroup();
diff --git a/uppsrc/ide/Core/Core.upp b/uppsrc/ide/Core/Core.upp
index 7e9a75e01..4c393950a 100644
--- a/uppsrc/ide/Core/Core.upp
+++ b/uppsrc/ide/Core/Core.upp
@@ -2,7 +2,6 @@ description "TheIDE - common library\377B";
uses
Esc,
- Web,
coff/binobj,
plugin/bz2;
diff --git a/uppsrc/ide/Core/Host.cpp b/uppsrc/ide/Core/Host.cpp
index f6f446fa8..e4f7a9563 100644
--- a/uppsrc/ide/Core/Host.cpp
+++ b/uppsrc/ide/Core/Host.cpp
@@ -1,573 +1,577 @@
-#include "Core.h"
-
-#define LLOG(x)
-
-#include
-
-String LocalHost::GetEnvironment()
-{
- return environment;
-}
-
-String LocalHost::GetHostPath(const String& path)
-{
- return path;
-}
-
-String LocalHost::GetLocalPath(const String& path)
-{
- return path;
-}
-
-String LocalHost::NormalizePath(const String& path)
-{
- return ::NormalizePath(path);
-}
-
-Vector LocalHost::GetFileInfo(const Vector& path)
-{
- Vector fi;
- for(int i = 0; i < path.GetCount(); i++) {
- FindFile ff(path[i]);
- FileInfo& f = fi.Add();
- if(ff) {
- (Time&)f = ff.GetLastWriteTime();
-#ifdef PLATFORM_WIN32
- f.second = f.second & ~1; // FAT vs NTFS accuracy fix
-#endif
- f.length = ff.IsFile() ? (int)ff.GetLength() : -1;
- }
- else {
- (Time&)f = Time::Low();
- f.length = Null;
- }
- }
- return fi;
-}
-
-void LocalHost::DeleteFile(const Vector& path)
-{
- for(int i = 0; i < path.GetCount(); i++)
- ::DeleteFile(path[i]);
-}
-
-void LocalHost::DeleteFolderDeep(const String& folder)
-{
- ::DeleteFolderDeep(folder);
-}
-
-void LocalHost::ChDir(const String& path)
-{
-#ifdef PLATFORM_WIN32
- SetCurrentDirectory(path);
-#endif
-#ifdef PLATFORM_POSIX
- IGNORE_RESULT( chdir(path) );
-#endif
- if(cmdout)
- *cmdout << "cd \"" << GetHostPath(path) << "\"\n";
-}
-
-void LocalHost::DoDir(const String& dir)
-{
- if(dir.GetLength() > 3) {
- DoDir(GetFileFolder(dir));
- *cmdout << "mkdir \"" << dir << "\"\n";
- }
-}
-
-void LocalHost::RealizeDir(const String& path)
-{
- RealizeDirectory(path);
- if(cmdout)
- DoDir(path);
-}
-
-void LocalHost::SaveFile(const String& path, const String& data)
-{
- ::SaveFile(path, data);
-}
-
-String LocalHost::LoadFile(const String& path)
-{
- return ::LoadFile(path);
-}
-
-int LocalHost::Execute(const char *cmdline)
-{
- if(cmdout)
- *cmdout << cmdline << '\n';
- PutVerbose(cmdline);
- int q = IdeConsoleExecute(FindCommand(exedirs, cmdline), NULL, environment, false);
- PutVerbose(Format("Exitcode: %d", q));
- return q;
-}
-
-int LocalHost::ExecuteWithInput(const char *cmdline)
-{
- if(cmdout)
- *cmdout << cmdline << '\n';
- PutVerbose(cmdline);
- int q = IdeConsoleExecuteWithInput(FindCommand(exedirs, cmdline), NULL, environment, false);
- PutVerbose(Format("Exitcode: %d", q));
- return q;
-}
-
-int LocalHost::Execute(const char *cmdline, Stream& out)
-{
- PutVerbose(cmdline);
- int q = IdeConsoleExecute(FindCommand(exedirs, cmdline), &out, environment, true);
- PutVerbose(Format("Exitcode: %d", q));
- return q;
-}
-
-int LocalHost::AllocSlot()
-{
- return IdeConsoleAllocSlot();
-}
-
-bool LocalHost::Run(const char *cmdline, int slot, String key, int blitz_count)
-{
- return IdeConsoleRun(FindCommand(exedirs, cmdline), NULL, environment, false, slot, key, blitz_count);
-}
-
-bool LocalHost::Run(const char *cmdline, Stream& out, int slot, String key, int blitz_count)
-{
- return IdeConsoleRun(FindCommand(exedirs, cmdline), &out, environment, true, slot, key, blitz_count);
-}
-
-bool LocalHost::Wait()
-{
- return IdeConsoleWait();
-}
-
-One LocalHost::StartProcess(const char *cmdline)
-{
- try {
- PutVerbose(cmdline);
- return ::StartProcess(FindCommand(exedirs, cmdline), environment, REMOTE_TIMEOUT);
- }
- catch(...) {
- return NULL;
- }
-}
-
-#ifdef PLATFORM_POSIX
-//#BLITZ_APPROVE
-#include
-#include
-#include
-
-static Vector& sPid()
-{
- static Vector q;
- return q;
-}
-
-void sCleanZombies(int signal_number)
-{
- Vector& pid = sPid();
- int i = 0;
- while(i < pid.GetCount())
- if(pid[i] && waitpid(pid[i], 0, WNOHANG | WUNTRACED) > 0)
- pid.Remove(i);
- else
- i++;
-}
-#endif
-
-String LinuxHostConsole = "/usr/bin/xterm -e";
-
-void LocalHost::Launch(const char *_cmdline, bool console)
-{
- String cmdline = FindCommand(exedirs, _cmdline);
- PutVerbose(cmdline);
-#ifdef PLATFORM_WIN32
- if(console)
- cmdline = GetExeFilePath() + " ! " + cmdline;
- int n = cmdline.GetLength() + 1;
- Buffer cmd(n);
- memcpy(cmd, cmdline, n);
- SECURITY_ATTRIBUTES sa;
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = TRUE;
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- ZeroMemory(&si, sizeof(STARTUPINFO));
- si.cb = sizeof(STARTUPINFO);
- String ev = ToSystemCharset(environment);
- Buffer env(ev.GetCount() + 1);
- memcpy(env, ev, ev.GetCount() + 1);
- if(CreateProcess(NULL, cmd, &sa, &sa, TRUE,
- NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE,
- ~env, NULL, &si, &pi)) {
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- }
- else
- PutConsole("Unable to launch " + String(_cmdline));
-#endif
-#ifdef PLATFORM_POSIX
- String script = ConfigFile("console-script-" + AsString(getpid()) + ".tmp");
- int c = LinuxHostConsole.FindFirstOf(" ");
- String lc = c < 0 ? LinuxHostConsole : LinuxHostConsole.Left(c);
- if(FileExists(lc)) {
-
- if(console) {
- FileStream out(script, FileStream::CREATE, 0777);
- out << "#!/bin/sh\n"
- << cmdline << '\n'
- << "echo \"<--- Finished, press any key to close the window --->\"\nread dummy\n";
- cmdline = LinuxHostConsole + " sh " + script;
- }
- }
- else
- if(LinuxHostConsole.GetCount())
- PutConsole("Warning: Terminal '" + lc + "' not found, executing in background.");
- Buffer cmd_buf(strlen(cmdline) + 1);
- char *cmd_out = cmd_buf;
- Vector args;
- const char *p = cmdline;
- const char *b = p;
- while(*p && (byte)*p > ' ')
- if(*p++ == '\"')
- while(*p && *p++ != '\"')
- ;
- args.Add(cmd_out);
- memcpy(cmd_out, b, p - b);
- cmd_out += p - b;
- *cmd_out++ = '\0';
-
- while(*p)
- if((byte)*p <= ' ')
- p++;
- else {
- args.Add(cmd_out);
- b = p;
- while(*p && (byte)*p > ' ')
- if(*p++ == '\"')
- {
- memcpy(cmd_out, b, p - b - 1);
- cmd_out += p - b - 1;
- b = p;
- while(*p && *p != '\"')
- p++;
- memcpy(cmd_out, b, p - b);
- cmd_out += p - b;
- if(*p == '\"')
- p++;
- b = p;
- }
- memcpy(cmd_out, b, p - b);
- cmd_out += p - b;
- *cmd_out++ = '\0';
- }
-
- args.Add(NULL);
-
- ONCELOCK {
- struct sigaction sigchld_action;
- memset(&sigchld_action, 0, sizeof(sigchld_action));
- sigchld_action.sa_handler = sCleanZombies;
- sigaction(SIGCHLD, &sigchld_action, NULL);
- }
-
- pid_t pid = fork();
- if(pid == 0)
- {
- const char *from = environment;
- Vector env;
- while(*from) {
- env.Add(from);
- from += strlen(from) + 1;
- }
- env.Add(NULL);
- const char **envp = env.Begin();
- execve(args[0], args, (char *const *)envp);
- abort();
- }
- LLOG("Launch pid: " << pid);
- sPid().Add(pid);
-#endif
-}
-
-void LocalHost::AddFlags(Index& cfg)
-{
-#if defined(PLATFORM_WIN32)
- cfg.Add("WIN32");
-#endif
-
-#ifdef PLATFORM_LINUX
- cfg.Add("LINUX");
-#endif
-
-#ifdef PLATFORM_POSIX
- cfg.Add("POSIX");
-#endif
-
-#ifdef PLATFORM_BSD
- cfg.Add("BSD");
-#endif
-
-#ifdef PLATFORM_FREEBSD
- cfg.Add("FREEBSD");
-#endif
-
-#ifdef PLATFORM_OPENBSD
- cfg.Add("OPENBSD");
-#endif
-
-#ifdef PLATFORM_NETBSD
- cfg.Add("NETBSD");
-#endif
-
-#ifdef PLATFORM_SOLARIS
- cfg.Add("SOLARIS");
-#endif
-
-#ifdef PLATFORM_OSX11
- cfg.Add("OSX11");
-#endif
-}
-
-static bool IsSamePath(const char *a, const char *b, int count) {
- for(; --count >= 0; a++, b++)
- if(a != b && ToLower(*a) != ToLower(*b) && !((*a == '\\' || *a == '/') && (*b == '\\' || *b == '/')))
- return false;
- return true;
-}
-
-String RemoteHost::GetEnvironment()
-{
- return environment;
-}
-
-String RemoteHost::GetHostPath(const String& path)
-{
- bool slash = (os_type != "WINDOWS");
- for(int i = 0; i < path_map_local.GetCount(); i++) {
- String lc = path_map_local[i];
- if(path.GetLength() >= lc.GetLength() && IsSamePath(path, lc, lc.GetLength()))
- {
- String r = CatAnyPath(path_map_remote[i], path.Mid(lc.GetLength()));
- return slash ? UnixPath(r) : WinPath(r);
- }
- }
- return slash ? UnixPath(path) : WinPath(path);
-}
-
-String RemoteHost::GetLocalPath(const String& path)
-{
- for(int i = 0; i < path_map_remote.GetCount(); i++) {
- String rc = path_map_remote[i];
- if(path.GetLength() >= rc.GetLength() && IsSamePath(path, rc, rc.GetLength()))
- return path_map_local[i] + path.Mid(rc.GetLength());
- }
- if(!memcmp(path, "/cygdrive/", 10))
- {
- const char *s = path.Begin() + 10;
- String out;
- if(*s)
- out << *s++ << ':';
- out << s;
- return out;
- }
- return NativePath(path);
-}
-
-String RemoteHost::NormalizePath(const String& path)
-{
- return path;
-}
-
-String RemoteHost::RemoteExec(String cmd)
-{
- Socket socket;
- String sockerr;
-/*
- String hostname = host;
- int port = 2346;
- int ppos = hostname.Find(':');
- if(ppos >= 0)
- {
- port = atoi(host.GetIter(ppos + 1));
- hostname.Trim(ppos);
- }
-*/
- if(!ClientSocket(socket, host, port, true, NULL, 2000)) {
- PutConsole(NFormat("Error connecting to '%s', port %d: %s", host, port, Socket::GetErrorText()));
- return String::GetVoid();
- }
- socket.Write(cmd);
- socket.Write("\0", 1);
- return socket.ReadUntil('\0', Null, 10000000);
-}
-
-Vector RemoteHost::GetFileInfo(const Vector& path)
-{
- VectorMap out;
- out.Reserve(path.GetCount());
- String request;
- request << "@" << (int)(GetSysTime() - TimeBase()) << ":";
- for(int i = 0; i < path.GetCount(); i++)
- {
- String hp = GetHostPath(path[i]);
- request << hp << "\n";
- FileInfo& fi = out.Add(hp);
- (Time&)fi = Time::Low();
- fi.length = Null;
- }
- String result = RemoteExec(request);
- const char *p = result;
- while(*p)
- {
- const char *b = p;
- while(*p && *p != '\n' && *p != '\t')
- p++;
- String fn(b, p);
- Time time = Time::Low();
- int size = Null;
- if(*p == '\t')
- {
- int t = ScanInt(p + 1, &p);
- if(!IsNull(t))
- time = TimeBase() + t;
- if(*p == '\t')
- size = ScanInt(p + 1, &p);
- }
- int ifn = out.Find(fn);
- if(ifn >= 0)
- {
- (Time&)out[ifn] = time;
- out[ifn].length = size;
- }
- while(*p && *p++ != '\n')
- ;
- }
- return out.PickValues();
-}
-
-void RemoteHost::DeleteFile(const Vector& path)
-{
- String request = "-";
- for(int i = 0; i < path.GetCount(); i++)
- request << GetHostPath(path[i]) << "\n";
- String out = RemoteExec(request);
- if(!IsNull(out) && out != "OK")
- PutVerbose(out);
-}
-
-void RemoteHost::DeleteFolderDeep(const String& folder)
-{
- String out = RemoteExec("~" + GetHostPath(folder));
- if(out != "OK")
- PutConsole(out);
-}
-
-void RemoteHost::ChDir(const String& path)
-{
- chdir_path = GetHostPath(path);
-}
-
-void RemoteHost::RealizeDir(const String& path)
-{
- RemoteExec("*" + GetHostPath(path));
-}
-
-void RemoteHost::SaveFile(const String& path, const String& data)
-{
- String request;
- request << ">" << GetHostPath(path)
- << "\t" << int(GetSysTime() - TimeBase())
- << "\t" << data.GetLength()
- << "\t" << ASCII85Encode(BZ2Compress(data))
- << "\n";
- String out = RemoteExec(request);
- if(out != "OK")
- PutConsole(out);
-}
-
-String RemoteHost::LoadFile(const String& path)
-{
- String hpath = GetHostPath(path);
- String request = "^" + hpath;
- String out = RemoteExec(request);
- const char *p = out;
- while(*p && *p != '\n' && *p != '\t')
- p++;
- if(*p++ != '\t')
- return String::GetVoid();
- int len = ScanInt(p, &p);
- if(IsNull(len) || len <= 0 || *p++ != '\t')
- return String::GetVoid();
- String data = BZ2Decompress(ASCII85Decode(p));
- if(data.GetLength() != len)
- {
- PutConsole(NFormat("%s: decompressed length (%d) doesn't match length in header (%d)",
- hpath, data.GetLength(), len));
- return String::GetVoid();
- }
- return data;
-}
-
-int RemoteHost::Execute(const char *cmdline)
-{
- int q = IdeConsoleExecute(StartProcess(cmdline), cmdline);
- PutVerbose(Format("Exitcode: %d", q));
- return q;
-}
-
-int RemoteHost::ExecuteWithInput(const char *cmdline)
-{
- int q = IdeConsoleExecute(StartProcess(cmdline), cmdline);
- PutVerbose(Format("Exitcode: %d", q));
- return q;
-}
-
-int RemoteHost::Execute(const char *cmdline, Stream& out)
-{
- int q = IdeConsoleExecute(StartProcess(cmdline), cmdline, &out, true);
- PutVerbose(Format("Exitcode: %d", q));
- return q;
-}
-
-int RemoteHost::AllocSlot()
-{
- return IdeConsoleAllocSlot();
-}
-
-bool RemoteHost::Run(const char *cmdline, int slot, String key, int blitz_count)
-{
- return IdeConsoleRun(StartProcess(cmdline), cmdline, NULL, false, slot, key, blitz_count);
-}
-
-bool RemoteHost::Run(const char *cmdline, Stream& out, int slot, String key, int blitz_count)
-{
- return IdeConsoleRun(StartProcess(cmdline), cmdline, &out, false, slot, key, blitz_count);
-}
-
-bool RemoteHost::Wait()
-{
- return IdeConsoleWait();
-}
-
-One RemoteHost::StartProcess(const char *cmdline)
-{
- try {
- PutVerbose(cmdline);
- return StartRemoteProcess(host, port, cmdline, environment, REMOTE_TIMEOUT);
- }
- catch(...) {
- return NULL;
- }
-}
-
-void RemoteHost::Launch(const char *_cmdline, bool)
-{
-}
-
-void RemoteHost::AddFlags(Index& cfg)
-{
- cfg.Add(os_type);
-}
+#include "Core.h"
+
+#define LLOG(x)
+
+#include
+
+String LocalHost::GetEnvironment()
+{
+ return environment;
+}
+
+String LocalHost::GetHostPath(const String& path)
+{
+ return path;
+}
+
+String LocalHost::GetLocalPath(const String& path)
+{
+ return path;
+}
+
+String LocalHost::NormalizePath(const String& path)
+{
+ return ::NormalizePath(path);
+}
+
+Vector LocalHost::GetFileInfo(const Vector& path)
+{
+ Vector fi;
+ for(int i = 0; i < path.GetCount(); i++) {
+ FindFile ff(path[i]);
+ FileInfo& f = fi.Add();
+ if(ff) {
+ (Time&)f = ff.GetLastWriteTime();
+#ifdef PLATFORM_WIN32
+ f.second = f.second & ~1; // FAT vs NTFS accuracy fix
+#endif
+ f.length = ff.IsFile() ? (int)ff.GetLength() : -1;
+ }
+ else {
+ (Time&)f = Time::Low();
+ f.length = Null;
+ }
+ }
+ return fi;
+}
+
+void LocalHost::DeleteFile(const Vector& path)
+{
+ for(int i = 0; i < path.GetCount(); i++)
+ ::DeleteFile(path[i]);
+}
+
+void LocalHost::DeleteFolderDeep(const String& folder)
+{
+ ::DeleteFolderDeep(folder);
+}
+
+void LocalHost::ChDir(const String& path)
+{
+#ifdef PLATFORM_WIN32
+ SetCurrentDirectory(path);
+#endif
+#ifdef PLATFORM_POSIX
+ IGNORE_RESULT( chdir(path) );
+#endif
+ if(cmdout)
+ *cmdout << "cd \"" << GetHostPath(path) << "\"\n";
+}
+
+void LocalHost::DoDir(const String& dir)
+{
+ if(dir.GetLength() > 3) {
+ DoDir(GetFileFolder(dir));
+ *cmdout << "mkdir \"" << dir << "\"\n";
+ }
+}
+
+void LocalHost::RealizeDir(const String& path)
+{
+ RealizeDirectory(path);
+ if(cmdout)
+ DoDir(path);
+}
+
+void LocalHost::SaveFile(const String& path, const String& data)
+{
+ ::SaveFile(path, data);
+}
+
+String LocalHost::LoadFile(const String& path)
+{
+ return ::LoadFile(path);
+}
+
+int LocalHost::Execute(const char *cmdline)
+{
+ if(cmdout)
+ *cmdout << cmdline << '\n';
+ PutVerbose(cmdline);
+ int q = IdeConsoleExecute(FindCommand(exedirs, cmdline), NULL, environment, false);
+ PutVerbose(Format("Exitcode: %d", q));
+ return q;
+}
+
+int LocalHost::ExecuteWithInput(const char *cmdline)
+{
+ if(cmdout)
+ *cmdout << cmdline << '\n';
+ PutVerbose(cmdline);
+ int q = IdeConsoleExecuteWithInput(FindCommand(exedirs, cmdline), NULL, environment, false);
+ PutVerbose(Format("Exitcode: %d", q));
+ return q;
+}
+
+int LocalHost::Execute(const char *cmdline, Stream& out)
+{
+ PutVerbose(cmdline);
+ int q = IdeConsoleExecute(FindCommand(exedirs, cmdline), &out, environment, true);
+ PutVerbose(Format("Exitcode: %d", q));
+ return q;
+}
+
+int LocalHost::AllocSlot()
+{
+ return IdeConsoleAllocSlot();
+}
+
+bool LocalHost::Run(const char *cmdline, int slot, String key, int blitz_count)
+{
+ return IdeConsoleRun(FindCommand(exedirs, cmdline), NULL, environment, false, slot, key, blitz_count);
+}
+
+bool LocalHost::Run(const char *cmdline, Stream& out, int slot, String key, int blitz_count)
+{
+ return IdeConsoleRun(FindCommand(exedirs, cmdline), &out, environment, true, slot, key, blitz_count);
+}
+
+bool LocalHost::Wait()
+{
+ return IdeConsoleWait();
+}
+
+One LocalHost::StartProcess(const char *cmdline)
+{
+ try {
+ PutVerbose(cmdline);
+ One p;
+ if(p.Create().Start(FindCommand(exedirs, cmdline), environment))
+ return p;
+ }
+ catch(...) {
+ }
+ return NULL;
+}
+
+#ifdef PLATFORM_POSIX
+//#BLITZ_APPROVE
+#include
+#include
+#include
+
+static Vector& sPid()
+{
+ static Vector q;
+ return q;
+}
+
+void sCleanZombies(int signal_number)
+{
+ Vector& pid = sPid();
+ int i = 0;
+ while(i < pid.GetCount())
+ if(pid[i] && waitpid(pid[i], 0, WNOHANG | WUNTRACED) > 0)
+ pid.Remove(i);
+ else
+ i++;
+}
+#endif
+
+String LinuxHostConsole = "/usr/bin/xterm -e";
+
+void LocalHost::Launch(const char *_cmdline, bool console)
+{
+ String cmdline = FindCommand(exedirs, _cmdline);
+ PutVerbose(cmdline);
+#ifdef PLATFORM_WIN32
+ if(console)
+ cmdline = GetExeFilePath() + " ! " + cmdline;
+ int n = cmdline.GetLength() + 1;
+ Buffer cmd(n);
+ memcpy(cmd, cmdline, n);
+ SECURITY_ATTRIBUTES sa;
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+ ZeroMemory(&si, sizeof(STARTUPINFO));
+ si.cb = sizeof(STARTUPINFO);
+ String ev = ToSystemCharset(environment);
+ Buffer env(ev.GetCount() + 1);
+ memcpy(env, ev, ev.GetCount() + 1);
+ if(CreateProcess(NULL, cmd, &sa, &sa, TRUE,
+ NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE,
+ ~env, NULL, &si, &pi)) {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+ else
+ PutConsole("Unable to launch " + String(_cmdline));
+#endif
+#ifdef PLATFORM_POSIX
+ String script = ConfigFile("console-script-" + AsString(getpid()) + ".tmp");
+ int c = LinuxHostConsole.FindFirstOf(" ");
+ String lc = c < 0 ? LinuxHostConsole : LinuxHostConsole.Left(c);
+ if(FileExists(lc)) {
+
+ if(console) {
+ FileStream out(script, FileStream::CREATE, 0777);
+ out << "#!/bin/sh\n"
+ << cmdline << '\n'
+ << "echo \"<--- Finished, press any key to close the window --->\"\nread dummy\n";
+ cmdline = LinuxHostConsole + " sh " + script;
+ }
+ }
+ else
+ if(LinuxHostConsole.GetCount())
+ PutConsole("Warning: Terminal '" + lc + "' not found, executing in background.");
+ Buffer cmd_buf(strlen(cmdline) + 1);
+ char *cmd_out = cmd_buf;
+ Vector args;
+ const char *p = cmdline;
+ const char *b = p;
+ while(*p && (byte)*p > ' ')
+ if(*p++ == '\"')
+ while(*p && *p++ != '\"')
+ ;
+ args.Add(cmd_out);
+ memcpy(cmd_out, b, p - b);
+ cmd_out += p - b;
+ *cmd_out++ = '\0';
+
+ while(*p)
+ if((byte)*p <= ' ')
+ p++;
+ else {
+ args.Add(cmd_out);
+ b = p;
+ while(*p && (byte)*p > ' ')
+ if(*p++ == '\"')
+ {
+ memcpy(cmd_out, b, p - b - 1);
+ cmd_out += p - b - 1;
+ b = p;
+ while(*p && *p != '\"')
+ p++;
+ memcpy(cmd_out, b, p - b);
+ cmd_out += p - b;
+ if(*p == '\"')
+ p++;
+ b = p;
+ }
+ memcpy(cmd_out, b, p - b);
+ cmd_out += p - b;
+ *cmd_out++ = '\0';
+ }
+
+ args.Add(NULL);
+
+ ONCELOCK {
+ struct sigaction sigchld_action;
+ memset(&sigchld_action, 0, sizeof(sigchld_action));
+ sigchld_action.sa_handler = sCleanZombies;
+ sigaction(SIGCHLD, &sigchld_action, NULL);
+ }
+
+ pid_t pid = fork();
+ if(pid == 0)
+ {
+ const char *from = environment;
+ Vector env;
+ while(*from) {
+ env.Add(from);
+ from += strlen(from) + 1;
+ }
+ env.Add(NULL);
+ const char **envp = env.Begin();
+ execve(args[0], args, (char *const *)envp);
+ abort();
+ }
+ LLOG("Launch pid: " << pid);
+ sPid().Add(pid);
+#endif
+}
+
+void LocalHost::AddFlags(Index& cfg)
+{
+#if defined(PLATFORM_WIN32)
+ cfg.Add("WIN32");
+#endif
+
+#ifdef PLATFORM_LINUX
+ cfg.Add("LINUX");
+#endif
+
+#ifdef PLATFORM_POSIX
+ cfg.Add("POSIX");
+#endif
+
+#ifdef PLATFORM_BSD
+ cfg.Add("BSD");
+#endif
+
+#ifdef PLATFORM_FREEBSD
+ cfg.Add("FREEBSD");
+#endif
+
+#ifdef PLATFORM_OPENBSD
+ cfg.Add("OPENBSD");
+#endif
+
+#ifdef PLATFORM_NETBSD
+ cfg.Add("NETBSD");
+#endif
+
+#ifdef PLATFORM_SOLARIS
+ cfg.Add("SOLARIS");
+#endif
+
+#ifdef PLATFORM_OSX11
+ cfg.Add("OSX11");
+#endif
+}
+
+static bool IsSamePath(const char *a, const char *b, int count) {
+ for(; --count >= 0; a++, b++)
+ if(a != b && ToLower(*a) != ToLower(*b) && !((*a == '\\' || *a == '/') && (*b == '\\' || *b == '/')))
+ return false;
+ return true;
+}
+
+#if 0
+String RemoteHost::GetEnvironment()
+{
+ return environment;
+}
+
+String RemoteHost::GetHostPath(const String& path)
+{
+ bool slash = (os_type != "WINDOWS");
+ for(int i = 0; i < path_map_local.GetCount(); i++) {
+ String lc = path_map_local[i];
+ if(path.GetLength() >= lc.GetLength() && IsSamePath(path, lc, lc.GetLength()))
+ {
+ String r = CatAnyPath(path_map_remote[i], path.Mid(lc.GetLength()));
+ return slash ? UnixPath(r) : WinPath(r);
+ }
+ }
+ return slash ? UnixPath(path) : WinPath(path);
+}
+
+String RemoteHost::GetLocalPath(const String& path)
+{
+ for(int i = 0; i < path_map_remote.GetCount(); i++) {
+ String rc = path_map_remote[i];
+ if(path.GetLength() >= rc.GetLength() && IsSamePath(path, rc, rc.GetLength()))
+ return path_map_local[i] + path.Mid(rc.GetLength());
+ }
+ if(!memcmp(path, "/cygdrive/", 10))
+ {
+ const char *s = path.Begin() + 10;
+ String out;
+ if(*s)
+ out << *s++ << ':';
+ out << s;
+ return out;
+ }
+ return NativePath(path);
+}
+
+String RemoteHost::NormalizePath(const String& path)
+{
+ return path;
+}
+
+String RemoteHost::RemoteExec(String cmd)
+{
+ Socket socket;
+ String sockerr;
+/*
+ String hostname = host;
+ int port = 2346;
+ int ppos = hostname.Find(':');
+ if(ppos >= 0)
+ {
+ port = atoi(host.GetIter(ppos + 1));
+ hostname.Trim(ppos);
+ }
+*/
+ if(!ClientSocket(socket, host, port, true, NULL, 2000)) {
+ PutConsole(NFormat("Error connecting to '%s', port %d: %s", host, port, Socket::GetErrorText()));
+ return String::GetVoid();
+ }
+ socket.Write(cmd);
+ socket.Write("\0", 1);
+ return socket.ReadUntil('\0', Null, 10000000);
+}
+
+Vector RemoteHost::GetFileInfo(const Vector& path)
+{
+ VectorMap out;
+ out.Reserve(path.GetCount());
+ String request;
+ request << "@" << (int)(GetSysTime() - TimeBase()) << ":";
+ for(int i = 0; i < path.GetCount(); i++)
+ {
+ String hp = GetHostPath(path[i]);
+ request << hp << "\n";
+ FileInfo& fi = out.Add(hp);
+ (Time&)fi = Time::Low();
+ fi.length = Null;
+ }
+ String result = RemoteExec(request);
+ const char *p = result;
+ while(*p)
+ {
+ const char *b = p;
+ while(*p && *p != '\n' && *p != '\t')
+ p++;
+ String fn(b, p);
+ Time time = Time::Low();
+ int size = Null;
+ if(*p == '\t')
+ {
+ int t = ScanInt(p + 1, &p);
+ if(!IsNull(t))
+ time = TimeBase() + t;
+ if(*p == '\t')
+ size = ScanInt(p + 1, &p);
+ }
+ int ifn = out.Find(fn);
+ if(ifn >= 0)
+ {
+ (Time&)out[ifn] = time;
+ out[ifn].length = size;
+ }
+ while(*p && *p++ != '\n')
+ ;
+ }
+ return out.PickValues();
+}
+
+void RemoteHost::DeleteFile(const Vector& path)
+{
+ String request = "-";
+ for(int i = 0; i < path.GetCount(); i++)
+ request << GetHostPath(path[i]) << "\n";
+ String out = RemoteExec(request);
+ if(!IsNull(out) && out != "OK")
+ PutVerbose(out);
+}
+
+void RemoteHost::DeleteFolderDeep(const String& folder)
+{
+ String out = RemoteExec("~" + GetHostPath(folder));
+ if(out != "OK")
+ PutConsole(out);
+}
+
+void RemoteHost::ChDir(const String& path)
+{
+ chdir_path = GetHostPath(path);
+}
+
+void RemoteHost::RealizeDir(const String& path)
+{
+ RemoteExec("*" + GetHostPath(path));
+}
+
+void RemoteHost::SaveFile(const String& path, const String& data)
+{
+ String request;
+ request << ">" << GetHostPath(path)
+ << "\t" << int(GetSysTime() - TimeBase())
+ << "\t" << data.GetLength()
+ << "\t" << ASCII85Encode(BZ2Compress(data))
+ << "\n";
+ String out = RemoteExec(request);
+ if(out != "OK")
+ PutConsole(out);
+}
+
+String RemoteHost::LoadFile(const String& path)
+{
+ String hpath = GetHostPath(path);
+ String request = "^" + hpath;
+ String out = RemoteExec(request);
+ const char *p = out;
+ while(*p && *p != '\n' && *p != '\t')
+ p++;
+ if(*p++ != '\t')
+ return String::GetVoid();
+ int len = ScanInt(p, &p);
+ if(IsNull(len) || len <= 0 || *p++ != '\t')
+ return String::GetVoid();
+ String data = BZ2Decompress(ASCII85Decode(p));
+ if(data.GetLength() != len)
+ {
+ PutConsole(NFormat("%s: decompressed length (%d) doesn't match length in header (%d)",
+ hpath, data.GetLength(), len));
+ return String::GetVoid();
+ }
+ return data;
+}
+
+int RemoteHost::Execute(const char *cmdline)
+{
+ int q = IdeConsoleExecute(StartProcess(cmdline), cmdline);
+ PutVerbose(Format("Exitcode: %d", q));
+ return q;
+}
+
+int RemoteHost::ExecuteWithInput(const char *cmdline)
+{
+ int q = IdeConsoleExecute(StartProcess(cmdline), cmdline);
+ PutVerbose(Format("Exitcode: %d", q));
+ return q;
+}
+
+int RemoteHost::Execute(const char *cmdline, Stream& out)
+{
+ int q = IdeConsoleExecute(StartProcess(cmdline), cmdline, &out, true);
+ PutVerbose(Format("Exitcode: %d", q));
+ return q;
+}
+
+int RemoteHost::AllocSlot()
+{
+ return IdeConsoleAllocSlot();
+}
+
+bool RemoteHost::Run(const char *cmdline, int slot, String key, int blitz_count)
+{
+ return IdeConsoleRun(StartProcess(cmdline), cmdline, NULL, false, slot, key, blitz_count);
+}
+
+bool RemoteHost::Run(const char *cmdline, Stream& out, int slot, String key, int blitz_count)
+{
+ return IdeConsoleRun(StartProcess(cmdline), cmdline, &out, false, slot, key, blitz_count);
+}
+
+bool RemoteHost::Wait()
+{
+ return IdeConsoleWait();
+}
+
+One RemoteHost::StartProcess(const char *cmdline)
+{
+ try {
+ PutVerbose(cmdline);
+ return StartRemoteProcess(host, port, cmdline, environment, REMOTE_TIMEOUT);
+ }
+ catch(...) {
+ return NULL;
+ }
+}
+
+void RemoteHost::Launch(const char *_cmdline, bool)
+{
+}
+
+void RemoteHost::AddFlags(Index& cfg)
+{
+ cfg.Add(os_type);
+}
+#endif
\ No newline at end of file
diff --git a/uppsrc/ide/Core/Host.h b/uppsrc/ide/Core/Host.h
index 090bebc4d..8ba601f5a 100644
--- a/uppsrc/ide/Core/Host.h
+++ b/uppsrc/ide/Core/Host.h
@@ -24,7 +24,7 @@ struct Host {
virtual bool Run(const char *cmdline, int slot, String key, int blitz_count) = 0;
virtual bool Run(const char *cmdline, Stream& out, int slot, String key, int blitz_count) = 0;
virtual bool Wait() = 0;
- virtual One StartProcess(const char *cmdline) = 0;
+ virtual One StartProcess(const char *cmdline) = 0;
virtual void Launch(const char *cmdline, bool console = false) = 0;
virtual void AddFlags(Index& cfg) = 0;
@@ -56,11 +56,12 @@ struct LocalHost : Host {
virtual bool Run(const char *cmdline, int slot, String key, int blitz_count);
virtual bool Run(const char *cmdline, Stream& out, int slot, String key, int blitz_count);
virtual bool Wait();
- virtual One StartProcess(const char *cmdline);
+ virtual One StartProcess(const char *cmdline);
virtual void Launch(const char *cmdline, bool console);
virtual void AddFlags(Index& cfg);
};
+/*
struct RemoteHost : Host {
String host;
int port;
@@ -91,9 +92,10 @@ struct RemoteHost : Host {
virtual bool Run(const char *cmdline, int slot, String key, int blitz_count);
virtual bool Run(const char *cmdline, Stream& out, int slot, String key, int blitz_count);
virtual bool Wait();
- virtual One StartProcess(const char *cmdline);
+ virtual One StartProcess(const char *cmdline);
virtual void Launch(const char *cmdline, bool console);
virtual void AddFlags(Index& cfg);
String RemoteExec(String cmd);
};
+*/
\ No newline at end of file
diff --git a/uppsrc/ide/Debuggers/Debuggers.h b/uppsrc/ide/Debuggers/Debuggers.h
index aae331f2a..a35847ef0 100644
--- a/uppsrc/ide/Debuggers/Debuggers.h
+++ b/uppsrc/ide/Debuggers/Debuggers.h
@@ -69,7 +69,7 @@ struct Dbg : Debugger, ParentCtrl {
virtual bool IsFinished();
One host;
- One dbg;
+ One dbg;
FrameBottom > regs;
diff --git a/uppsrc/ide/Debuggers/Gdb_MI2.h b/uppsrc/ide/Debuggers/Gdb_MI2.h
index edb76f5fc..8a2812452 100644
--- a/uppsrc/ide/Debuggers/Gdb_MI2.h
+++ b/uppsrc/ide/Debuggers/Gdb_MI2.h
@@ -1,242 +1,242 @@
-#ifndef _ide_Debuggers_Gdb_MI2_h_
-#define _ide_Debuggers_Gdb_MI2_h_
-
-#include "MIValue.h"
-
-class WatchEdit : public LineEdit
-{
- virtual void HighlightLine(int line, Vector& h, int pos);
-};
-
-#define LAYOUTFILE
-#include
-
-class Gdb_MI2 : public Debugger, public ParentCtrl
-{
- private:
-
- One host;
- One dbg;
-
- bool firstRun;
-
- // the disassembler window
- DbgDisas disas;
-
- // the registers pane
-#ifdef CPU_64
- FrameBottom > regs;
-#define RPREFIX "r"
-#else
- FrameBottom > regs;
-#define RPREFIX "e"
-#endif
-
- // the quick watch dialog
- WithGdb_MI2QuickwatchLayout quickwatch;
-
- EditString watchedit;
- DropList frame;
- DropList threadSelector;
- TabCtrl tab;
- ArrayCtrl locals;
- ArrayCtrl watches;
- ArrayCtrl autos;
-
- // explorer stuffs -- just starting
- ArrayCtrl explorer;
- EditString explorerExprEdit;
- Button explorerBackBtn, explorerForwardBtn;
- StaticRect explorerPane;
- void onExploreExpr(ArrayCtrl *what = NULL);
- void onExplorerChild();
- void onExplorerBack();
- void onExplorerForward();
- void ExplorerMenu(Bar& bar);
- void doExplore(String const &expr, String var, bool isChild, bool appendHistory);
- Index explorerHistoryExpressions;
- Index explorerHistoryVars;
- Vector explorerHistoryChilds;
- int explorerHistoryPos;
- Vector explorerChildVars;
- String explorerParentExpr;
-
- Label dlock;
-
- Vector regname;
- Vector