153#include "haddCommandLineOptionsHelp.h"
182class NullBuf :
public std::streambuf {
184 int overflow(
int c)
final {
return c; }
187class NullStream :
public std::ostream {
191 NullStream() : std::ostream(&fBuf) {}
202static inline std::ostream &
Err()
204 std::cerr <<
"Error in <hadd>: ";
208static inline std::ostream &
Warn()
211 s <<
"Warning in <hadd>: ";
215static inline std::ostream &
Info(
int minLevel)
218 s <<
"Info in <hadd>: ";
270static std::optional<IntFlag_t>
StrToUInt(
const char *str)
314 Err() <<
"error parsing integer argument '" << arg <<
"'\n";
322 std::stringstream
ss;
325 while (std::getline(
ss,
item,
',')) {
327 Warn() <<
"ignoring unknown feature request: " <<
item <<
"\n";
338 Err() <<
"could not parse the cache size passed after -cachesize: '" << arg <<
"'\n";
342 const char *
munit =
nullptr;
344 Warn() <<
"the cache size passed after -cachesize is too large: " << arg <<
" is greater than " <<
m <<
munit
345 <<
". We will use the maximum value.\n";
348 cacheSize =
"cachesize=";
356 if (
strcmp(arg,
"SkipListed") == 0)
358 if (
strcmp(arg,
"OnlyListed") == 0)
361 Err() <<
"invalid argument for -Ltype: '" << arg <<
"'. Can only be 'SkipListed' or 'OnlyListed' (case matters).\n";
377 const char *
nxtArg =
nullptr;
395 Err() <<
"expected argument after '-" <<
flagStr <<
"' flag.\n";
411 Err() <<
"the argument after '-" <<
flagStr <<
"' flag was not of the expected type.\n";
430 " This behavior is deprecated, please use the full compression settings.\n";
461 const char *
cur = arg + 1;
466 Warn() <<
"duplicate flag: -ff\n";
469 <<
"[err] Cannot specify both -ff and -f[0-9]. Either use the first input compression or specify it.\n";
476 Warn() <<
"duplicate flag: -fk\n";
482 Err() <<
"cannot specify both -ff and -f[0-9]. Either use the first input compression or "
493 Err() << *
compLv <<
" is not a supported compression settings.\n";
497 Err() <<
"failed to parse compression settings '" <<
cur <<
"' as an integer.\n";
501 Err() <<
"cannot specify -f[0-9] multiple times!\n";
505 Err() <<
"invalid flag: " << arg <<
"\n";
533 if (!args.fNoFlagsAfterPositionalArguments &&
argRaw[0] ==
'-' &&
argRaw[1] !=
'\0') {
538 <<
"found `--`, but we've already parsed (or are still parsing) a sequence of positional arguments!"
539 " This is not supported: you must have exactly one sequence of positional arguments, so if you"
540 " need to use `--` make sure to pass *all* positional arguments after it.";
543 args.fNoFlagsAfterPositionalArguments =
true;
550 const char *arg =
argRaw + 1;
553#define PARSE_FLAG(func, ...) \
556 const auto res = func(__VA_ARGS__); \
557 if (res == EFlagResult::kErr) \
559 validFlag = res == EFlagResult::kParsed; \
588 }
else if (!args.fOutputArgIdx) {
590 args.fOutputArgIdx =
argIdx;
596 if (!args.fFirstInputIdx) {
597 args.fFirstInputIdx =
argIdx;
600 Err() <<
"seen a positional argument '" <<
argRaw
601 <<
"' after some flags."
602 " Positional arguments were already parsed at this point (from '"
603 <<
argv[args.fOutputArgIdx]
604 <<
"' onwards), and you can only have one sequence of them, so you cannot pass more."
605 " Please group your positional arguments all together so that hadd works as you expect.\n"
607 for (
int i = 0; i <
argc; ++i)
608 std::cerr <<
argv[i] <<
" ";
634 std::istringstream
ss(
line);
691 Info(2) <<
"parallelizing with " <<
nProcesses <<
" processes.\n";
698 Err() <<
"could not access the directory specified: " << *args.
fWorkingDir <<
".\n";
706 Err() <<
"-L must always be passed along with -Ltype.\n";
712 Err() <<
"missing output file.\n";
717 Err() <<
"missing input file.\n";
726 Info(2) <<
"Using " << cacheSize <<
"\n";
749 Err() <<
"could not open indirect file " << (
argv[
a] + 1) << std::endl;
757 Err() <<
"could not validate the file name \"" <<
line <<
"\" within indirect file "
758 << (
argv[
a] + 1) << std::endl;
762 Err() <<
"file " <<
line <<
" cannot be both the target and an input!\n";
774 Err() <<
"could not validate argument \"" <<
line <<
"\" as input file " << std::endl;
778 Err() <<
"file " <<
line <<
" cannot be both the target and an input!\n";
787 Err() <<
"could not find any valid input file " << std::endl;
807 Info(2) <<
"compression setting for meta data: " <<
newcomp <<
'\n';
809 Info(2) <<
"compression setting for all output: " <<
newcomp <<
'\n';
813 Err() <<
"error opening target file for update :" <<
targetname <<
".\n";
817 std::stringstream
ss;
818 ss <<
"error opening target file (does " <<
targetname <<
" exist?).\n";
820 ss <<
"pass \"-f\" argument to force re-creation of output file.\n";
830 Info(2) <<
"each process should handle at least 3 files for efficiency."
831 " Setting the number of processes to: "
846 for (
auto i = 0; (i * step) <
allSubfiles.size(); i++) {
847 std::stringstream buffer;
860 Warn() <<
"Sources and Target have different compression settings\n"
861 "hadd merging will be slower\n";
888 Err() <<
"exiting due to error in " <<
allSubfiles[i] << std::endl;
904 Err() <<
"error opening target partial file\n";
923 status = std::accumulate(res.begin(), res.end(), 0U) ==
partialFiles.size();
927 Err() <<
"failed at the parallel stage\n";
943 <<
") input (partial) files into " <<
targetname <<
"\n";
947 <<
") input (partial) files into " <<
targetname <<
"\n";
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Boolean (0=false, 1=true) (bool)
int Int_t
Signed integer 4 bytes (int)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
winID h TVirtualViewer3D TVirtualGLPainter p
R__EXTERN TSystem * gSystem
TIOFeatures provides the end-user with the ability to change the IO behavior of data written via a TT...
This class provides a simple interface to execute the same task multiple times in parallel,...
This class provides file copy and merging services.
@ kAll
Merge all type of objects (default)
@ kIncremental
Merge the input file with the content of the output file (if already existing).
@ kSkipListed
Skip objects specified in fObjectNames list.
@ kOnlyListed
Only the objects specified in fObjectNames list.
@ kRegular
Normal merge, overwriting the output file.
@ kFailOnError
The merging process will stop and yield failure when encountering invalid objects.
@ kSkipOnError
The merging process will skip invalid objects and continue.
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
TString & Append(const char *cs)
virtual int GetSysInfo(SysInfo_t *info) const
Returns static system info, like OS type, CPU type, number of CPUs RAM size, etc into the SysInfo_t s...
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
virtual int Unlink(const char *name)
Unlink, i.e.
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
static EFlagResult FlagArg(int argc, char **argv, int &argIdxInOut, const char *flagStr, std::optional< T > &flagOut, std::optional< T > defaultVal=std::nullopt, FlagConvResult< T >(*conv)(const char *)=ConvertArg< T >)
static bool ValidCompressionSettings(int compSettings)
FlagConvResult< IntFlag_t > ConvertArg< IntFlag_t >(const char *arg)
#define PARSE_FLAG(func,...)
static FlagConvResult< Int_t > ConvertFilterType(const char *arg)
static Int_t ParseFilterFile(const std::optional< std::string > &filterFileName, std::optional< Int_t > objectFilterType, TFileMerger &fileMerger)
static FlagConvResult< T > ConvertArg(const char *)
static constexpr int kDefaultHaddVerbosity
static std::ostream & Info(int minLevel)
static std::optional< HAddArgs > ParseArgs(int argc, char **argv)
FlagConvResult< ROOT::TIOFeatures > ConvertArg< ROOT::TIOFeatures >(const char *arg)
static int gHaddVerbosity
static std::ostream & Warn()
static FlagConvResult< TString > ConvertCacheSize(const char *arg)
static std::ostream & Err()
static EFlagResult FlagF(const char *arg, HAddArgs &args)
static EFlagResult FlagToggle(const char *arg, const char *flagStr, bool &flagOut)
static NullStream & GetNullStream()
static std::optional< IntFlag_t > StrToUInt(const char *str)
static constexpr const char kCommandLineOptionsHelp[]
void ToHumanReadableSize(value_type bytes, Bool_t si, Double_t *coeff, const char **units)
Return the size expressed in 'human readable' format.
EFromHumanReadableSize FromHumanReadableSize(std::string_view str, T &value)
Convert strings like the following into byte counts 5MB, 5 MB, 5M, 3.7GB, 123b, 456kB,...
bool fNoFlagsAfterPositionalArguments
bool fKeepCompressionAsIs
std::optional< TString > fCacheSize
std::optional< IntFlag_t > fCompressionSettings
std::optional< Int_t > fObjectFilterType
std::optional< IntFlag_t > fNProcesses
bool fUseFirstInputCompression
std::optional< std::string > fObjectFilterFile
std::optional< IntFlag_t > fVerbosity
std::optional< IntFlag_t > fMaxOpenedFiles
std::optional< std::string > fWorkingDir
std::optional< ROOT::TIOFeatures > fFeatures
@ kUseCompiledDefault
Use the compile-time default setting.