142#include "haddCommandLineOptionsHelp.h"
161 std::cerr <<
"Error in <hadd>: ";
167 std::cerr <<
"Warning in <hadd>: ";
173 std::cerr <<
"Info in <hadd>: ";
224static std::optional<IntFlag_t>
StrToUInt(
const char *str)
268 Err() <<
"error parsing integer argument '" << arg <<
"'\n";
276 std::stringstream
ss;
279 while (std::getline(
ss, item,
',')) {
281 Warn() <<
"ignoring unknown feature request: " << item <<
"\n";
292 Err() <<
"could not parse the cache size passed after -cachesize: '" << arg <<
"'\n";
296 const char *
munit =
nullptr;
298 Warn() <<
"the cache size passed after -cachesize is too large: " << arg <<
" is greater than " <<
m <<
munit
299 <<
". We will use the maximum value.\n";
302 cacheSize =
"cachesize=";
310 if (
strcmp(arg,
"SkipListed") == 0)
312 if (
strcmp(arg,
"OnlyListed") == 0)
315 Err() <<
"invalid argument for -Ltype: '" << arg <<
"'. Can only be 'SkipListed' or 'OnlyListed' (case matters).\n";
331 const char *
nxtArg =
nullptr;
349 Err() <<
"expected argument after '-" <<
flagStr <<
"' flag.\n";
365 Err() <<
"the argument after '-" <<
flagStr <<
"' flag was not of the expected type.\n";
384 " This behavior is deprecated, please use the full compression settings.\n";
415 const char *
cur = arg + 1;
420 Warn() <<
"duplicate flag: -ff\n";
423 <<
"[err] Cannot specify both -ff and -f[0-9]. Either use the first input compression or specify it.\n";
430 Warn() <<
"duplicate flag: -fk\n";
436 Err() <<
"cannot specify both -ff and -f[0-9]. Either use the first input compression or "
447 Err() << *
compLv <<
" is not a supported compression settings.\n";
451 Err() <<
"failed to parse compression settings '" <<
cur <<
"' as an integer.\n";
455 Err() <<
"cannot specify -f[0-9] multiple times!\n";
459 Err() <<
"invalid flag: " << arg <<
"\n";
487 if (!args.fNoFlagsAfterPositionalArguments &&
argRaw[0] ==
'-' &&
argRaw[1] !=
'\0') {
492 <<
"found `--`, but we've already parsed (or are still parsing) a sequence of positional arguments!"
493 " This is not supported: you must have exactly one sequence of positional arguments, so if you"
494 " need to use `--` make sure to pass *all* positional arguments after it.";
497 args.fNoFlagsAfterPositionalArguments =
true;
504 const char *arg =
argRaw + 1;
507#define PARSE_FLAG(func, ...) \
510 const auto res = func(__VA_ARGS__); \
511 if (res == EFlagResult::kErr) \
513 validFlag = res == EFlagResult::kParsed; \
538 }
else if (!args.fOutputArgIdx) {
540 args.fOutputArgIdx =
argIdx;
546 if (!args.fFirstInputIdx) {
547 args.fFirstInputIdx =
argIdx;
550 Err() <<
"seen a positional argument '" <<
argRaw
551 <<
"' after some flags."
552 " Positional arguments were already parsed at this point (from '"
553 <<
argv[args.fOutputArgIdx]
554 <<
"' onwards), and you can only have one sequence of them, so you cannot pass more."
555 " Please group your positional arguments all together so that hadd works as you expect.\n"
557 for (
int i = 0; i <
argc; ++i)
558 std::cerr <<
argv[i] <<
" ";
584 std::istringstream
ss(
line);
611 if (
argc < 3 ||
"-h" == std::string(
argv[1]) ||
"--help" == std::string(
argv[1])) {
613 return (
argc == 2 && (
"-h" == std::string(
argv[1]) ||
"--help" == std::string(
argv[1]))) ? 0 : 1;
648 Err() <<
"could not access the directory specified: " << *args.
fWorkingDir <<
".\n";
656 Err() <<
"-L must always be passed along with -Ltype.\n";
662 Err() <<
"missing output file.\n";
666 Err() <<
"missing input file.\n";
675 Info() <<
"Using " << cacheSize <<
"\n";
698 Err() <<
"could not open indirect file " << (
argv[
a] + 1) << std::endl;
706 Err() <<
"could not validate the file name \"" <<
line <<
"\" within indirect file "
707 << (
argv[
a] + 1) << std::endl;
711 Err() <<
"file " <<
line <<
" cannot be both the target and an input!\n";
723 Err() <<
"could not validate argument \"" <<
line <<
"\" as input file " << std::endl;
727 Err() <<
"file " <<
line <<
" cannot be both the target and an input!\n";
736 Err() <<
"could not find any valid input file " << std::endl;
757 Info() <<
"compression setting for meta data: " <<
newcomp <<
'\n';
759 Info() <<
"compression setting for all output: " <<
newcomp <<
'\n';
763 Err() <<
"error opening target file for update :" <<
targetname <<
".\n";
767 Err() <<
"error opening target file (does " <<
targetname <<
" exist?).\n";
769 Info() <<
"pass \"-f\" argument to force re-creation of output file.\n";
778 Info() <<
"each process should handle at least 3 files for efficiency."
779 " Setting the number of processes to: "
794 for (
auto i = 0; (i * step) <
allSubfiles.size(); i++) {
795 std::stringstream buffer;
808 Warn() <<
"Sources and Target have different compression settings\n"
809 "hadd merging will be slower\n";
834 Err() <<
"exiting due to error in " <<
allSubfiles[i] << std::endl;
839 return mergeFiles(
merger);
850 Err() <<
"error opening target partial file\n";
869 status = std::accumulate(res.begin(), res.end(), 0U) ==
partialFiles.size();
873 Err() <<
"failed at the parallel stage\n";
890 <<
") input (partial) files into " <<
targetname <<
".\n";
895 Err() <<
"failure during the merge of " <<
allSubfiles.size() <<
" ("
896 <<
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.