Skip to content
Open
Show file tree
Hide file tree
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
62 changes: 11 additions & 51 deletions main/src/hadd.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
#include <ROOT/TIOFeatures.hxx>

#include "haddCommandLineOptionsHelp.h"
#include "logging.hxx"

#include <climits>
#include <cstdlib>
Expand All @@ -168,56 +169,13 @@

////////////////////////////////////////////////////////////////////////////////

// NOTE: TFileMerger will use PrintLevel = gHaddVerbosity - 1. If PrintLevel is < 1, it will print nothing, otherwise
// NOTE: TFileMerger will use PrintLevel = GetLogVerbosity() - 1. If PrintLevel is < 1, it will print nothing, otherwise
// it will print everything. To give some granularity to hadd, we do the following:
// gHaddVerbosity = 0: only print hadd errors
// gHaddVerbosity = 1: only print hadd errors + warnings
// gHaddVerbosity = 2: print hadd errors + warnings and TFileMerger messages
// gHaddVerbosity > 2: print all hadd and TFileMerger messages.
// LogVerbosity = 0: only print hadd errors
// LogVerbosity = 1: only print hadd errors + warnings
// LogVerbosity = 2: print hadd errors + warnings and TFileMerger messages
// LogVerbosity > 2: print all hadd and TFileMerger messages.
static constexpr int kDefaultHaddVerbosity = 2;
static int gHaddVerbosity = kDefaultHaddVerbosity;

namespace {

class NullBuf : public std::streambuf {
public:
int overflow(int c) final { return c; }
};

class NullStream : public std::ostream {
NullBuf fBuf;

public:
NullStream() : std::ostream(&fBuf) {}
};

} // namespace

static NullStream &GetNullStream()
{
static NullStream nullStream;
return nullStream;
}

static inline std::ostream &Err()
{
std::cerr << "Error in <hadd>: ";
return std::cerr;
}

static inline std::ostream &Warn()
{
std::ostream &s = gHaddVerbosity < 1 ? GetNullStream() : std::cerr;
s << "Warning in <hadd>: ";
return s;
}

static inline std::ostream &Info(int minLevel)
{
std::ostream &s = gHaddVerbosity < minLevel ? GetNullStream() : std::cerr;
s << "Info in <hadd>: ";
return s;
}

using IntFlag_t = uint32_t;

Expand Down Expand Up @@ -658,6 +616,8 @@ static Int_t ParseFilterFile(const std::optional<std::string> &filterFileName,

int main(int argc, char **argv)
{
InitLog("hadd", kDefaultHaddVerbosity);

const auto argsOpt = ParseArgs(argc, argv);
if (!argsOpt)
return 1;
Expand All @@ -670,7 +630,7 @@ int main(int argc, char **argv)

ROOT::TIOFeatures features = args.fFeatures.value_or(ROOT::TIOFeatures{});
Int_t maxopenedfiles = args.fMaxOpenedFiles.value_or(0);
gHaddVerbosity = args.fVerbosity.value_or(kDefaultHaddVerbosity);
SetLogVerbosity(args.fVerbosity.value_or(kDefaultHaddVerbosity));
Int_t newcomp = args.fCompressionSettings.value_or(-1);
TString cacheSize = args.fCacheSize.value_or("");

Expand Down Expand Up @@ -731,7 +691,7 @@ int main(int argc, char **argv)

TFileMerger fileMerger(kFALSE, kFALSE);
fileMerger.SetMsgPrefix("hadd");
fileMerger.SetPrintLevel(gHaddVerbosity - 1);
fileMerger.SetPrintLevel(GetLogVerbosity() - 1);
if (maxopenedfiles > 0) {
fileMerger.SetMaxOpenedFiles(maxopenedfiles);
}
Expand Down Expand Up @@ -896,7 +856,7 @@ int main(int argc, char **argv)
auto parallelMerge = [&](int start) {
TFileMerger mergerP(kFALSE, kFALSE);
mergerP.SetMsgPrefix("hadd");
mergerP.SetPrintLevel(gHaddVerbosity - 1);
mergerP.SetPrintLevel(GetLogVerbosity() - 1);
if (maxopenedfiles > 0) {
mergerP.SetMaxOpenedFiles(maxopenedfiles / nProcesses);
}
Expand Down
75 changes: 75 additions & 0 deletions main/src/logging.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
///
/// Basic logging utilities meant to be used by binaries.
/// Use instead of RLogger for user-facing messages.
///
#ifndef ROOT_Main_Logging
#define ROOT_Main_Logging

#include <iostream>

namespace Detail {

class NullBuf : public std::streambuf {
public:
int overflow(int c) final { return c; }
};

// A stream that discards all input.
class NullStream : public std::ostream {
NullBuf fBuf;

public:
NullStream() : std::ostream(&fBuf) {}
};

inline const char *gLogName = "";
/// Log verbosity works this way:
/// If it's <= 0, all warnings are suppressed.
/// Additionally, when Info(lv) is called, it is only displayed if lv <= LogVerbosity.
inline int gLogVerbosity = 1;

inline NullStream &GetNullStream()
{
static NullStream nullStream;
return nullStream;
}

} // namespace Detail

inline void InitLog(const char *name, int defaultVerbosity = 1)
{
Detail::gLogName = name;
Detail::gLogVerbosity = defaultVerbosity;
}

inline void SetLogVerbosity(int verbosity)
{
Detail::gLogVerbosity = verbosity;
}

inline int GetLogVerbosity()
{
return Detail::gLogVerbosity;
}

inline std::ostream &Err()
{
std::cerr << "Error in <" << Detail::gLogName << ">: ";
return std::cerr;
}

inline std::ostream &Warn()
{
std::ostream &s = Detail::gLogVerbosity < 1 ? Detail::GetNullStream() : std::cerr;
s << "Warning in <" << Detail::gLogName << ">: ";
return s;
}

inline std::ostream &Info(int minLevel)
{
std::ostream &s = Detail::gLogVerbosity < minLevel ? Detail::GetNullStream() : std::cerr;
s << "Info in <" << Detail::gLogName << ">: ";
return s;
}

#endif
12 changes: 5 additions & 7 deletions main/src/rootbrowse.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/// \date 2025-08-21
#include <ROOT/RLogger.hxx>

#include "logging.hxx"
#include "optparse.hxx"

#include <TApplication.h>
Expand Down Expand Up @@ -44,12 +45,6 @@ positional arguments:
Open the ROOT file 'file.root' in a TBrowser
)";

static ROOT::RLogChannel &RootBrowseLog()
{
static ROOT::RLogChannel channel("RootBrowse");
return channel;
}

struct RootBrowseArgs {
enum class EPrintUsage {
kNo,
Expand Down Expand Up @@ -97,6 +92,8 @@ static RootBrowseArgs ParseArgs(const char **args, int nArgs)

int main(int argc, char **argv)
{
InitLog("rootbrowse");

auto args = ParseArgs(const_cast<const char **>(argv) + 1, argc - 1);
if (args.fPrintHelp != RootBrowseArgs::EPrintUsage::kNo) {
std::cerr << kShortHelp;
Expand All @@ -119,7 +116,8 @@ int main(int argc, char **argv)
gErrorIgnoreLevel = kError;
file = std::unique_ptr<TFile>(TFile::Open(std::string(args.fFileName).c_str(), "READ"));
if (!file || file->IsZombie()) {
R__LOG_WARNING(RootBrowseLog()) << "File " << args.fFileName << " does not exist or is unreadable.";
Err() << "File " << args.fFileName << " does not exist or is unreadable.";
return 1;
}
gErrorIgnoreLevel = kUnset;
}
Expand Down
13 changes: 5 additions & 8 deletions main/src/rootls.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <string>
#include <vector>

#include "logging.hxx"
#include "optparse.hxx"
#include "wildcards.hpp"

Expand Down Expand Up @@ -107,12 +108,6 @@ positional arguments:
Display contents of the ROOT file 'example.root', traversing recursively any TDirectory.
)";

static ROOT::RLogChannel &RootLsChannel()
{
static ROOT::RLogChannel sLog("ROOTLS");
return sLog;
}

static bool ClassInheritsFrom(const char *class_, const char *baseClass)
{
const auto *cl = TClass::GetClass(class_);
Expand Down Expand Up @@ -385,7 +380,7 @@ static void PrintNodesDetailed(std::ostream &stream, const RootLsTree &tree,
const auto &desc = reader->GetDescriptor();
PrintRNTuple(stream, desc, indent + 2, desc.GetFieldZero());
} else {
R__LOG_ERROR(RootLsChannel()) << "failed to read RNTuple object: " << child.fName;
Err() << "failed to read RNTuple object: " << child.fName;
}
}
}
Expand Down Expand Up @@ -691,7 +686,7 @@ static RootLsArgs ParseArgs(const char **args, int nArgs)

opts.Parse(args, nArgs);
for (const auto &err : opts.GetErrors())
R__LOG_ERROR(RootLsChannel()) << err;
Err() << err;

if (opts.GetSwitch("help")) {
outArgs.fPrintUsageAndExit = RootLsArgs::EPrintUsage::kLong;
Expand Down Expand Up @@ -745,6 +740,8 @@ int main(int argc, char **argv)
// Ignore diagnostics up to (but excluding) kError to avoid spamming users with TClass::Init warnings.
gErrorIgnoreLevel = kError;

InitLog("rootls");

auto args = ParseArgs(const_cast<const char **>(argv) + 1, argc - 1);
if (args.fPrintUsageAndExit != RootLsArgs::EPrintUsage::kNo) {
std::cerr << "usage: rootls [-1hltr] FILE [FILE ...]\n";
Expand Down
Loading