Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 151 additions & 37 deletions tutorials/legacy/rootalias.C
Original file line number Diff line number Diff line change
Expand Up @@ -11,71 +11,185 @@
///
/// \author Rene Brun

#include <TSystem.h>
#include <TROOT.h>
#include <TCanvas.h>
#include <TPaveText.h>
#include <TText.h>

#include <string>
#include <cstdlib> // std::getenv
#include <cstring> // std::strcmp
#include <algorithm> // std::replace
#include <cstdio> // std::printf

namespace {
inline bool IsWindows()
{
return std::strcmp(gSystem->GetName(), "WinNT") == 0;
}
inline bool IsMac()
{
return std::strcmp(gSystem->GetName(), "Macosx") == 0;
}

// Minimal, pragmatic shell quoting for filenames/paths.
// Good enough for normal paths; not a full shell-escaping library.
std::string QuoteForShell(const std::string &s)
{
if (s.empty())
return "''";

if (IsWindows()) {
// Wrap in double quotes; replace embedded " with ' (rare in paths)
std::string q = s;
std::replace(q.begin(), q.end(), '"', '\'');
return "\"" + q + "\"";
} else {
// POSIX: single-quote, escape internal single quotes with '"'"'
std::string out;
out.reserve(s.size() + 2);
out.push_back('\'');
for (char c : s) {
if (c == '\'')
out += "'\"'\"'";
else
out.push_back(c);
}
out.push_back('\'');
return out;
}
}

std::string GetEnvOrEmpty(const char *name)
{
if (const char *v = std::getenv(name))
return std::string(v);
return {};
}

// Build a command that (on POSIX) returns immediately to keep the ROOT prompt usable.
std::string MaybeBackground(std::string cmd)
{
if (!IsWindows())
cmd += " &";
return cmd;
}
} // namespace

//______________________________________________________________________________
void edit(char *file)
// Open a file in the user's editor, with robust cross-platform fallbacks.
void edit(const char *file)
{
char s[64], *e;
if (!strcmp(gSystem->GetName(), "WinNT")) {
if ((e = std::getenv("EDITOR")))
sprintf(s, "start %s %s", e, file);
const std::string f = (file ? file : "");
const std::string qf = QuoteForShell(f);
const std::string editor = GetEnvOrEmpty("EDITOR");

std::string cmd;

if (IsWindows()) {
// Use "start" to detach a new window (cmd.exe builtin).
if (!editor.empty())
cmd = "start " + editor + " " + qf;
else
cmd = "start notepad " + qf;
} else if (IsMac()) {
// macOS: prefer $EDITOR, else TextEdit
if (!editor.empty())
cmd = MaybeBackground(editor + " " + qf);
else
sprintf(s, "start notepad %s", file);
cmd = MaybeBackground("open -e " + qf);
} else {
if ((e = std::getenv("EDITOR")))
sprintf(s, "%s %s", e, file);
// Linux/Unix: $EDITOR if set; else xdg-open; else xterm+vi
if (!editor.empty())
cmd = MaybeBackground(editor + " " + qf);
else
sprintf(s, "xterm -e vi %s &", file);
cmd =
MaybeBackground("(command -v xdg-open >/dev/null 2>&1 && xdg-open " + qf + ") || (xterm -e vi " + qf + ")");
}
gSystem->Exec(s);

gSystem->Exec(cmd.c_str());
}

//______________________________________________________________________________
void ls(char *path=0)
// List a directory in a compact, friendly way.
void ls(const char *path = nullptr)
{
char s[256];
strcpy(s, (!strcmp(gSystem->GetName(), "WinNT")) ? "dir /w " : "ls ");
if (path) strcat(s,path);
gSystem->Exec(s);
std::string cmd = IsWindows() ? "dir /w" : "ls";
if (path && *path) {
cmd += " ";
cmd += QuoteForShell(path);
}
gSystem->Exec(cmd.c_str());
}

//______________________________________________________________________________
void dir(char *path=0)
// More verbose directory view (traditional Unix-y default).
void dir(const char *path = nullptr)
{
char s[256];
strcpy(s,(!strcmp(gSystem->GetName(), "WinNT")) ? "dir " : "ls -l ");
if (path) strcat(s,path);
gSystem->Exec(s);
std::string cmd = IsWindows() ? "dir" : "ls -alF";
if (path && *path) {
cmd += " ";
cmd += QuoteForShell(path);
}
gSystem->Exec(cmd.c_str());
}

//______________________________________________________________________________
// Return current working directory (keeps macro API stable: returns const char*).
const char *pwd()
{
return gSystem->WorkingDirectory();
static std::string wd; // static so c_str() stays valid after return
wd = gSystem->WorkingDirectory();
return wd.c_str();
}

//______________________________________________________________________________
const char *cd(char *path=0)
// Change directory; if no path is given, just report where we are.
const char *cd(const char *path = nullptr)
{
if (path)
gSystem->ChangeDirectory(path);
return pwd();
if (path && *path)
gSystem->ChangeDirectory(path);
return pwd();
}

TCanvas *bench = 0;
// ===
// The following benchmark helper (seen in your file) is kept as-is in spirit,
// just minor cleanups for clarity. If you have more helpers in your local copy,
// you can apply the same style: std::string, const-correctness, early returns.
// ===

TCanvas *bench = nullptr;

//______________________________________________________________________________
void bexec2(char *macro)
// Colorize a macro name in the summary before/after execution and run it.
void bexec2(const char *macro)
{
printf("in bexec dir=%s\n",pwd());
if (gROOT->IsBatch()) printf("Processing benchmark: %s\n",macro);
TPaveText *summary = (TPaveText*)bench->GetPrimitive("TPave");
TText *tmacro = summary->GetLineWith(macro);
if (tmacro) tmacro->SetTextColor(4);
bench->Modified(); bench->Update();
std::printf("in bexec dir=%s\n", pwd());
if (gROOT->IsBatch())
std::printf("Processing benchmark: %s\n", macro);

if (!bench) {
// If bench isn't prepared yet, just run the macro.
gROOT->Macro(macro);
return;
}

auto *summary = dynamic_cast<TPaveText *>(bench->GetPrimitive("TPave"));
if (summary) {
if (auto *tmacro = summary->GetLineWith(macro))
tmacro->SetTextColor(4);
bench->Modified();
bench->Update();
}

gROOT->Macro(macro);

TPaveText *summary2 = (TPaveText*)bench->GetPrimitive("TPave");
TText *tmacro2 = summary2->GetLineWith(macro);
if (tmacro2) tmacro2->SetTextColor(2);
bench->Modified(); bench->Update();
auto *summary2 = dynamic_cast<TPaveText *>(bench->GetPrimitive("TPave"));
if (summary2) {
if (auto *tmacro2 = summary2->GetLineWith(macro))
tmacro2->SetTextColor(2);
bench->Modified();
bench->Update();
}
}
Loading