148#include "haddCommandLineOptionsHelp.h"
167 std::cerr <<
"Error in <hadd>: ";
173 std::cerr <<
"Warning in <hadd>: ";
179 std::cerr <<
"Info in <hadd>: ";
230static std::optional<IntFlag_t>
StrToUInt(
const char *str)
274 Err() <<
"error parsing integer argument '" << arg <<
"'\n";
282 std::stringstream
ss;
285 while (std::getline(
ss,
item,
',')) {
287 Warn() <<
"ignoring unknown feature request: " <<
item <<
"\n";
298 Err() <<
"could not parse the cache size passed after -cachesize: '" << arg <<
"'\n";
302 const char *
munit =
nullptr;
304 Warn() <<
"the cache size passed after -cachesize is too large: " << arg <<
" is greater than " <<
m <<
munit
305 <<
". We will use the maximum value.\n";
308 cacheSize =
"cachesize=";
316 if (
strcmp(arg,
"SkipListed") == 0)
318 if (
strcmp(arg,
"OnlyListed") == 0)
321 Err() <<
"invalid argument for -Ltype: '" << arg <<
"'. Can only be 'SkipListed' or 'OnlyListed' (case matters).\n";
337 const char *
nxtArg =
nullptr;
355 Err() <<
"expected argument after '-" <<
flagStr <<
"' flag.\n";
371 Err() <<
"the argument after '-" <<
flagStr <<
"' flag was not of the expected type.\n";
390 " This behavior is deprecated, please use the full compression settings.\n";
421 const char *
cur = arg + 1;
426 Warn() <<
"duplicate flag: -ff\n";
429 <<
"[err] Cannot specify both -ff and -f[0-9]. Either use the first input compression or specify it.\n";
436 Warn() <<
"duplicate flag: -fk\n";
442 Err() <<
"cannot specify both -ff and -f[0-9]. Either use the first input compression or "
453 Err() << *
compLv <<
" is not a supported compression settings.\n";
457 Err() <<
"failed to parse compression settings '" <<
cur <<
"' as an integer.\n";
461 Err() <<
"cannot specify -f[0-9] multiple times!\n";
465 Err() <<
"invalid flag: " << arg <<
"\n";
493 if (!args.fNoFlagsAfterPositionalArguments &&
argRaw[0] ==
'-' &&
argRaw[1] !=
'\0') {
498 <<
"found `--`, but we've already parsed (or are still parsing) a sequence of positional arguments!"
499 " This is not supported: you must have exactly one sequence of positional arguments, so if you"
500 " need to use `--` make sure to pass *all* positional arguments after it.";
503 args.fNoFlagsAfterPositionalArguments =
true;
510 const char *arg =
argRaw + 1;
513#define PARSE_FLAG(func, ...) \
516 const auto res = func(__VA_ARGS__); \
517 if (res == EFlagResult::kErr) \
519 validFlag = res == EFlagResult::kParsed; \
544 }
else if (!args.fOutputArgIdx) {
546 args.fOutputArgIdx =
argIdx;
552 if (!args.fFirstInputIdx) {
553 args.fFirstInputIdx =
argIdx;
556 Err() <<
"seen a positional argument '" <<
argRaw
557 <<
"' after some flags."
558 " Positional arguments were already parsed at this point (from '"
559 <<
argv[args.fOutputArgIdx]
560 <<
"' onwards), and you can only have one sequence of them, so you cannot pass more."
561 " Please group your positional arguments all together so that hadd works as you expect.\n"
563 for (
int i = 0; i <
argc; ++i)
564 std::cerr <<
argv[i] <<
" ";
590 std::istringstream
ss(
line);
617 if (
argc < 3 ||
"-h" == std::string(
argv[1]) ||
"--help" == std::string(
argv[1])) {
619 return (
argc == 2 && (
"-h" == std::string(
argv[1]) ||
"--help" == std::string(
argv[1]))) ? 0 : 1;
654 Err() <<
"could not access the directory specified: " << *args.
fWorkingDir <<
".\n";
662 Err() <<
"-L must always be passed along with -Ltype.\n";
668 Err() <<
"missing output file.\n";
672 Err() <<
"missing input file.\n";
681 Info() <<
"Using " << cacheSize <<
"\n";
704 Err() <<
"could not open indirect file " << (
argv[
a] + 1) << std::endl;
712 Err() <<
"could not validate the file name \"" <<
line <<
"\" within indirect file "
713 << (
argv[
a] + 1) << std::endl;
717 Err() <<
"file " <<
line <<
" cannot be both the target and an input!\n";
729 Err() <<
"could not validate argument \"" <<
line <<
"\" as input file " << std::endl;
733 Err() <<
"file " <<
line <<
" cannot be both the target and an input!\n";
742 Err() <<
"could not find any valid input file " << std::endl;
763 Info() <<
"compression setting for meta data: " <<
newcomp <<
'\n';
765 Info() <<
"compression setting for all output: " <<
newcomp <<
'\n';
769 Err() <<
"error opening target file for update :" <<
targetname <<
".\n";
773 Err() <<
"error opening target file (does " <<
targetname <<
" exist?).\n";
775 Info() <<
"pass \"-f\" argument to force re-creation of output file.\n";
784 Info() <<
"each process should handle at least 3 files for efficiency."
785 " Setting the number of processes to: "
800 for (
auto i = 0; (i * step) <
allSubfiles.size(); i++) {
801 std::stringstream buffer;
814 Warn() <<
"Sources and Target have different compression settings\n"
815 "hadd merging will be slower\n";
840 Err() <<
"exiting due to error in " <<
allSubfiles[i] << std::endl;
856 Err() <<
"error opening target partial file\n";
875 status = std::accumulate(res.begin(), res.end(), 0U) ==
partialFiles.size();
879 Err() <<
"failed at the parallel stage\n";
896 <<
") input (partial) files into " <<
targetname <<
".\n";
901 Err() <<
"failure during the merge of " <<
allSubfiles.size() <<
" ("
902 <<
fileMerger.GetMergeList()->GetEntries() <<
") input (partial) files into " <<
targetname <<
".\n";
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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.
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 std::optional< HAddArgs > ParseArgs(int argc, char **argv)
FlagConvResult< ROOT::TIOFeatures > ConvertArg< ROOT::TIOFeatures >(const char *arg)
static FlagConvResult< TString > ConvertCacheSize(const char *arg)
static EFlagResult FlagF(const char *arg, HAddArgs &args)
static EFlagResult FlagToggle(const char *arg, const char *flagStr, bool &flagOut)
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.