#include "ide.h" UrepoConsole::UrepoConsole() { CtrlLayoutExit(*this, "System Console"); list.NoHeader().NoGrid().NoCursor().AddColumn(); font = Courier(Ctrl::VertLayoutZoom(12)); list.SetLineCy(max(font.GetCy(), font().Bold().GetCy(), font().Bold().Italic().GetCy())); exit.Hide(); cancel.Hide(); cancel << [=] { canceled = true; }; } void UrepoConsole::AddResult(const String& out) { const char *s = out; const char *b = s; auto Add = [&] { String txt(b, int(s - b)); list.Add(AttrText(" " + txt).SetFont(font), txt); b = ++s; }; while(*s) { if(*s == '\r') { if(s[1] == '\n') { Add(); s++; b++; } else if(list.GetCount() == 0) Add(); else { list.SetCount(list.GetCount() - 1); Add(); } } else if(*s == '\n') Add(); else s++; } list.GoEnd(); } void UrepoConsole::Log(const Value& s, Color ink) { list.Add(AttrText(s).SetFont(font).NormalInk(ink), s); } int UrepoConsole::System(const char *cmd) { if(!IsOpen()) Open(); if(hide_password_to > hide_password_from) { String w = cmd; w = w.Mid(0, hide_password_from) + String('*', hide_password_to - hide_password_from) + w.Mid(hide_password_to); hide_password_to = hide_password_from = 0; list.Add(AttrText(w).SetFont(font().Bold()).Ink(SLtBlue())); } else list.Add(AttrText(cmd).SetFont(font().Bold()).Ink(SLtBlue())); int ii = list.GetCount(); Ide *ide = (Ide *)TheIde(); if(!ide) return -1; Host host; ide->CreateHost(host, false, false); LocalProcess p; if(!host.StartProcess(p, cmd)) { list.Add(AttrText("Failed to start the executable").SetFont(font().Bold()).Ink(SLtRed())); return -1; } String out; canceled = false; cancel.Show(); while(p.IsRunning() && IsOpen()) { String h = p.Get(); out.Cat(h); int lf = out.ReverseFind('\n'); if(lf >= 0) { AddResult(out.Mid(0, lf + 1)); out = out.Mid(lf + 1); } int cr = out.ReverseFind('\r'); if(cr >= 0) { AddResult(out.Mid(0, cr + 1)); out = out.Mid(cr + 1); } ProcessEvents(); Sleep(h.GetCount() == 0); // p.Wait would be much better here! if(canceled) break; } cancel.Hide(); out.Cat(p.Get()); AddResult(out); ProcessEvents(); int code = canceled ? -1 : p.GetExitCode(); if(code) while(ii < list.GetCount()) { list.Set(ii, 0, AttrText((String)list.Get(ii, 1)).SetFont(font).Ink(SLtRed())); ii++; } return code; } int UrepoConsole::CheckSystem(const char *s) { int exitcode = System(s); if(exitcode) { if(exitcode < 0) AddResult("Error running " + String(s)); else AddResult("exitcode = " + FormatInt(exitcode)); } return exitcode; }