6 #include "boost/program_options.hpp" 34 namespace bpo = boost::program_options;
39 using std::back_inserter;
58 if (value[0] ==
'[' || value[0] ==
'{' ||
68 char const* entval = value.c_str();
69 char* endptr =
const_cast<char*
>(entval);
70 strtold(entval, &endptr);
71 if (endptr == entval + value.size()) {
85 size_t const longestName,
89 constexpr
size_t maxIDdigits{5};
90 constexpr
size_t maxNameSpacing{20};
93 auto const maxIDspace =
std::min(idLen, maxIDdigits);
94 int nspaces = maxIDspace - 1;
96 auto id =
static_cast<int>(ent.
SMDid);
97 for (
int i{}; (nspaces > 0) && (
id > 0); ++
i) {
105 output << indent << ent.
SMDid <<
": " <<
name;
108 auto const nameSpacing =
std::min(maxNameSpacing, longestName);
109 nspaces =
static_cast<int>(nameSpacing - name.size());
110 while (nspaces > 0) {
121 vector<FileCatalogMetadataEntry>
const& entries,
128 size_t longestName{1};
129 for (
auto const& entry : entries) {
130 maxID =
std::max(entry.SMDid, maxID);
131 longestName =
std::max(entry.name.size(), longestName);
134 for (
int i{}; (i < 5) && (maxID > 0); ++
i) {
139 for (
auto const& entry : entries) {
154 vector<FileCatalogMetadataEntry>
const& entries,
158 std::ostringstream buf;
160 for (
auto const& entry : entries) {
176 vector<FileCatalogMetadataEntry>& all_metadata_entries,
183 sqlite3_stmt* stmt =
nullptr;
184 sqlite3_prepare_v2(sqliteDB,
185 "SELECT rowid, Name, Value from FileCatalog_metadata;",
189 bool row_found =
false;
190 int sqlite_status = SQLITE_OK;
191 while ((sqlite_status = sqlite3_step(stmt)) == SQLITE_ROW) {
193 ent.
SMDid = sqlite3_column_int(stmt, 0);
198 all_metadata_entries.push_back(ent);
200 if (sqlite_status != SQLITE_DONE) {
201 errors <<
"Unexpected status from table read: " << sqlite3_errmsg(sqliteDB)
202 <<
" (0x" << sqlite_status <<
").\n";
204 int const finalize_status = sqlite3_finalize(stmt);
205 if (finalize_status != SQLITE_OK) {
206 errors <<
"Unexpected status (" << finalize_status
207 <<
") from DB status cleanup:\n" 208 << sqlite3_errmsg(sqliteDB) <<
'\n';
212 <<
"No file catalog Metadata rows found - table is missing or empty\n";
234 vector<FileCatalogMetadataEntry> all_metadata_entries;
236 errors <<
"Unable to to read metadata entries.\n";
242 std::string const& baseName = path.substr(path.find_last_of(
"/") + 1u);
246 output <<
"\nFile catalog metadata from file " << file.GetName() <<
":\n\n";
248 output <<
"-------------------------------\n";
263 bool const want_json)
267 bool printed_opening{
false};
268 for (
auto const& fn : file_names) {
269 std::unique_ptr<TFile> current_file(TFile::Open(fn.c_str(),
"READ"));
270 if (!current_file || current_file->IsZombie()) {
272 errors <<
"Unable to open file '" << fn <<
"' for reading." 273 <<
"\nSkipping file.\n";
277 auto* key_ptr = current_file->GetKey(
"RootFileDB");
278 if (key_ptr ==
nullptr) {
280 errors <<
"\nRequested DB, \"RootFileDB\" of type, \"tkeyvfs\", not " 281 "present in file: \"" 283 <<
"Either this is not an art/ROOT file, it is a corrupt art/ROOT " 285 <<
"or it is an art/ROOT file produced with a version older than " 294 printed_opening =
true;
296 }
else if (want_json) {
301 if (printed_opening) {
311 if (level == kWarning && (!die) && strcmp(location,
"TClass::TClass") == 0 &&
312 std::string{message}.find(
"no dictionary") != std::string::npos) {
316 DefaultErrorHandler(level, die, location, message);
326 std::ostringstream descstr;
327 descstr << argv[0] <<
" <options> [<source-file>]+";
328 bpo::options_description desc(descstr.str());
329 desc.add_options()(
"help,h",
"produce help message")(
330 "hr,H",
"produce human-readable output (default is JSON)")(
331 "human-readable",
"produce human-readable output (default is JSON)")(
332 "source,s", bpo::value<stringvec>(),
"source data file (multiple OK)");
333 bpo::options_description all_opts(
"All Options");
337 bpo::positional_options_description pd;
338 pd.add(
"source", -1);
340 bpo::variables_map vm;
342 bpo::store(bpo::command_line_parser(argc, argv)
350 std::cerr <<
"Exception from command line processing in " << argv[0] <<
": " 354 if (vm.count(
"help")) {
355 std::cout << desc << std::endl;
358 bool const want_json =
359 (!vm.count(
"hr")) && (!vm.count(
"human-readable"));
363 size_t const file_count = vm.count(
"source");
364 if (file_count < 1) {
365 cerr <<
"One or more input files must be specified;" 366 <<
" supply filenames as program arguments\n" 367 <<
"For usage and options list, please do 'sam_metadata_dumper " 371 file_names.reserve(file_count);
372 cet::copy_all(vm[
"source"].as<stringvec>(), std::back_inserter(file_names));
std::vector< std::string > stringvec
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
bool is_double_quoted_string(std::string const &str)
std::string indent(std::size_t const i)
auto copy_all(FwdCont &, FwdIter)
bool canonical_string(std::string const &str, std::string &result)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
std::map< fhicl::ParameterSetID, ParameterSetBlob > ParameterSetMap