DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
oks_merge.cxx
Go to the documentation of this file.
1//
2// DUNE DAQ modification notice:
3// This file has been modified from the original ATLAS oks_utils source for the DUNE DAQ project.
4// Fork baseline commit: c2e7dfc7 (2022-03-30).
5// Renamed since fork: yes (from src/bin/oks_merge.cpp to apps/oks_merge.cxx).
6//
7
16
17#include "oks/kernel.hpp"
18
19using namespace dunedaq;
20using namespace dunedaq::oks;
21
23
24#include "ers/ers.hpp"
25
26ERS_DECLARE_ISSUE(oks_merge, BadCommandLine, "Bad command line: \"" << what << '\"', ((const char*)what))
27
28ERS_DECLARE_ISSUE(oks_merge,
30 "Failed to parse query \"" << query << "\" in class \"" << class_name << '\"',
31 ((const char*)query)((const char*)class_name))
32
33ERS_DECLARE_ISSUE(oks_merge, BadClass, "Cannot find class \"" << class_name << '\"', ((const char*)class_name))
34
35
36
37ERS_DECLARE_ISSUE(oks_merge,
38 CaughtException,
39 "Caught " << what << " exception: \'" << text << '\'',
40 ((const char*)what)((const char*)text))
41
42
43
44std::string appTitle;
45
46void
47printUsage(const char* appName, std::ostream& s)
48{
49 s << appTitle
50 << "\n"
51 "Usage: "
52 << appName
53 << "\n"
54 " [--class name-of-class [--query query [--print-references recursion-depth [class-name*] [--]]]\n"
55 " [--version]\n"
56 " [--help]\n"
57 " [--out-data-file data_file] [--out-data-file schema_file] inputfiles*\n"
58 "\n"
59 " Options:\n"
60 " -o | --out-data-file datafilename the out filename to store oks objects from input files\n"
61 " -s | --out-schema-file schemafilename the out filename to store oks classes from input files\n"
62 " -c | --class class_name dump given class (all objects or matching some query)\n"
63 " -q | --query query print objects matching query (can only be used with class)\n"
64 " -r | --print-references N C1 C2 ... CX print objects referenced by found objects (can only be used with "
65 "query), where:\n"
66 " * the parameter N defines recursion depth for referenced objects "
67 "(> 0)\n"
68 " * the optional set of names {C1 .. CX} defines [sub-]classes for "
69 "above objects\n"
70 " -v | --version print version\n"
71 " -h | --help print this text\n"
72 "\n"
73 " Description:\n"
74 " Merges several oks files into single schema and data files.\n"
75 "\n";
76}
77
78enum __OksMergeExitStatus__
79{
80 __Success__ = 0,
81 __NoDataFilesLoaded__,
82 __NoSchemaFilesLoaded__,
84 __NoOutputSchemaFile__,
88};
89
90static void
91no_param(const char* s)
92{
93 Oks::error_msg("oks_merge") << "no parameter(s) for command line argument \'" << s << "\' provided\n\n";
95}
96
97int
98main(int argc, char* argv[])
99{
100 appTitle = "OKS merge. OKS kernel version ";
102
103 const char* appName = "oks_merge";
104
105 std::string out_data_file;
106 std::string out_schema_file;
107
108 const char* class_name = nullptr;
109 const char* query = nullptr;
110 long recursion_depth = 0;
111 std::vector<std::string> ref_classes;
112
113 if (argc == 1) {
114 printUsage(appName, std::cerr);
115 return __BadCommandLine__;
116 }
117
118 OksKernel kernel;
120
121 try {
122
123 for (int i = 1; i < argc; i++) {
124 const char* cp = argv[i];
125
126 if (!strcmp(cp, "-h") || !strcmp(cp, "--help")) {
127 printUsage(appName, std::cout);
128 return __Success__;
129 } else if (!strcmp(cp, "-v") || !strcmp(cp, "--version")) {
130 std::cout << appTitle << std::endl;
131 return __Success__;
132 } else if (!strcmp(cp, "-o") || !strcmp(cp, "--out-data-file")) {
133 if (++i == argc) {
134 no_param(cp);
135 } else {
136 out_data_file = argv[i];
137 }
138 } else if (!strcmp(cp, "-s") || !strcmp(cp, "--out-schema-file")) {
139 if (++i == argc) {
140 no_param(cp);
141 } else {
142 out_schema_file = argv[i];
143 }
144 } else if (!strcmp(cp, "-c") || !strcmp(cp, "--class")) {
145 if (++i == argc) {
146 no_param(cp);
147 } else {
148 class_name = argv[i];
149 }
150 } else if (!strcmp(cp, "-q") || !strcmp(cp, "--query")) {
151 if (++i == argc) {
152 no_param(cp);
153 } else {
154 query = argv[i];
155 }
156 } else if (!strcmp(cp, "-r") || !strcmp(cp, "--print-references")) {
157 if (++i == argc) {
158 no_param(cp);
159 } else {
160 recursion_depth = atol(argv[i]);
161 }
162 int j = 0;
163 for (; j < argc - i - 1; ++j) {
164 if (argv[i + 1 + j][0] != '-') {
165 ref_classes.push_back(argv[i + 1 + j]);
166 } else {
167 break;
168 }
169 }
170 i += j;
171 } else if (strcmp(cp, "--")) {
172 kernel.load_file(cp);
173 }
174 }
175
176 if (!out_data_file.empty() && kernel.data_files().empty()) {
177 ers::fatal(oks_merge::BadCommandLine(ERS_HERE, "There were no data files loaded"));
178 return __NoDataFilesLoaded__;
179 }
180
181 if (!out_schema_file.empty() && kernel.schema_files().empty()) {
182 ers::fatal(oks_merge::BadCommandLine(ERS_HERE, "There were no schema files loaded"));
183 return __NoSchemaFilesLoaded__;
184 }
185
186 if (query && !class_name) {
188 oks_merge::BadCommandLine(ERS_HERE, "Query can only be executed when class name is provided (use -c option)"));
189 return __BadCommandLine__;
190 }
191
192 OksFile* data_file_h = 0;
193 OksFile* schema_file_h = 0;
194
195 if (!out_data_file.empty()) {
196 data_file_h = kernel.new_data(out_data_file);
197 kernel.set_active_data(data_file_h);
198 }
199
200 if (!out_schema_file.empty()) {
201 schema_file_h = kernel.new_schema(out_schema_file);
202 kernel.set_active_schema(schema_file_h);
203 }
204
205 if (!data_file_h && !schema_file_h) {
206 ers::fatal(oks_merge::BadCommandLine(ERS_HERE, "There is no out schema file name defined"));
207 return __NoOutputSchemaFile__;
208 }
209
210 if (schema_file_h) {
211 for (OksClass::Map::const_iterator j = kernel.classes().begin(); j != kernel.classes().end(); ++j) {
212 j->second->set_file(schema_file_h, false);
213 }
214
215 kernel.save_schema(schema_file_h);
216 }
217
218 if (data_file_h) {
219 if (schema_file_h) {
220 data_file_h->add_include_file(out_schema_file);
221 }
222
223 if (class_name && *class_name) {
224 if (OksClass* c = kernel.find_class(class_name)) {
225 if (query && *query) {
226 OksQuery* q = new OksQuery(c, query);
227 if (q->good()) {
228 OksObject::List* objs = c->execute_query(q);
229 size_t num = (objs ? objs->size() : 0);
230 std::cout << "Found " << num << " matching query \"" << query << "\" in class \"" << class_name << "\"";
231 if (num) {
232 OksObject::FSet refs;
233 std::cout << ':' << std::endl;
234 while (!objs->empty()) {
235 OksObject* o = objs->front();
236 objs->pop_front();
237 if (recursion_depth > 0) {
238 oks::ClassSet all_ref_classes;
239 kernel.get_all_classes(ref_classes, all_ref_classes);
240 o->references(refs, recursion_depth, true, &all_ref_classes);
241 std::cout << " - " << o << " references " << refs.size() << " objects" << std::endl;
242 } else {
243 refs.insert(o);
244 }
245 }
246 delete objs;
247 for (OksObject::FSet::iterator i = refs.begin(); i != refs.end(); ++i) {
248 const_cast<OksObject*>(*i)->set_file(data_file_h, false);
249 }
250 } else {
251 std::cout << std::endl;
252 }
253 } else {
254 ers::fatal(oks_merge::BadQuery(ERS_HERE, query, class_name));
255 return __BadQuery__;
256 }
257 delete q;
258 } else {
259 std::cout << *c << std::endl;
260 }
261 } else {
262 ers::fatal(oks_merge::BadClass(ERS_HERE, class_name));
263 return __NoSuchClass__;
264 }
265 } else {
266 for (OksObject::Set::const_iterator j = kernel.objects().begin(); j != kernel.objects().end(); ++j) {
267 (*j)->set_file(data_file_h, false);
268 }
269 }
270
271 kernel.save_data(data_file_h);
272 }
273
274 }
275
276 catch (oks::exception& ex) {
277 ers::fatal(oks_merge::CaughtException(ERS_HERE, "OKS", ex.what()));
278 return __ExceptionCaught__;
279 }
280
281 catch (std::exception& ex) {
282 ers::fatal(oks_merge::CaughtException(ERS_HERE, "Standard C++", ex.what()));
283 return __ExceptionCaught__;
284 }
285
286 catch (...) {
287 ers::fatal(oks_merge::CaughtException(ERS_HERE, "unknown", ""));
288 return __ExceptionCaught__;
289 }
290
291 return __Success__;
292}
#define ERS_HERE
The OKS class.
Definition class.hpp:223
Provides interface to the OKS XML schema and data files.
Definition file.hpp:355
void add_include_file(const std::string &name)
Add include file.
Definition file.cpp:1157
Provides interface to the OKS kernel.
Definition kernel.hpp:615
OksFile * load_file(const std::string &name, bool bind=true)
Load OKS database file.
Definition kernel.cpp:1625
const OksFile::Map & data_files() const
Get all data files.
Definition kernel.hpp:1472
OksFile * new_data(const std::string &name, const std::string &logical_name="", const std::string &type="")
Create OKS data file.
Definition kernel.cpp:3500
void set_active_schema(OksFile *file_h)
Set active OKS schema file.
Definition kernel.cpp:2699
const OksObject::Set & objects() const
Get objects.
Definition kernel.hpp:1732
static void set_use_strict_repository_paths(bool flag)
Set flag to use strict-repository-paths check.
Definition kernel.hpp:1672
const OksClass::Map & classes() const
Get classes.
Definition kernel.hpp:1711
void save_schema(OksFile *file_h, bool force=false, OksFile *true_file_h=0)
Save OKS schema file.
Definition kernel.cpp:2357
void save_data(OksFile *file_h, bool ignore_bad_objects=false, OksFile *true_file_h=nullptr, bool force_defaults=false)
Save OKS data file.
Definition kernel.cpp:3572
OksFile * new_schema(const std::string &name)
Create OKS schema file.
Definition kernel.cpp:2307
static const char * GetVersion()
Get OKS version. The method returns string containing CVS tag and date of OKS build.
Definition kernel.cpp:274
OksClass * find_class(const std::string &class_name) const
Find class by name (C++ string).
Definition kernel.hpp:1754
void set_active_data(OksFile *file_h)
Set active OKS data file.
Definition kernel.cpp:4062
const OksFile::Map & schema_files() const
Get all schema files.
Definition kernel.hpp:1211
void get_all_classes(const std::vector< std::string > &names_in, ClassSet &classes_out) const
The method searches all classes including subclasses for given names.
Definition kernel.cpp:4451
OksObject describes instance of OksClass.
Definition object.hpp:1144
std::unordered_set< OksObject *, oks::hash_obj_ptr, oks::equal_obj_ptr > FSet
Definition object.hpp:1171
std::list< OksObject * > List
Definition object.hpp:1179
void references(OksObject::FSet &refs, unsigned long recursion_depth, bool add_self=false, oks::ClassSet *classes=0) const
Definition object.cpp:3043
void set_file(OksFile *file, bool update_owner=true)
Move object to different file.
Definition object.cpp:1468
OKS query class.
Definition query.hpp:40
bool good() const
Definition query.hpp:57
OksQuery(bool b, OksQueryExpression *q=0)
Definition query.hpp:42
static std::ostream & error_msg(const char *)
Definition kernel.cpp:511
virtual const char * what() const noexcept
int main(int argc, char *argv[])
#define ERS_DECLARE_ISSUE(namespace_name, class_name, message_, attributes)
Definition macro.hpp:71
std::unordered_set< const OksClass *, oks::hash_class_ptr, oks::equal_class_ptr > ClassSet
Definition object.hpp:1129
The DUNE-DAQ namespace.
void fatal(const Issue &issue)
Definition ers.hpp:111
std::string appTitle
@ __BadCommandLine__
@ __Success__
@ __ExceptionCaught__
Definition oks_dump.cxx:37
@ __BadQuery__
Definition oks_dump.cxx:34
@ __NoSuchClass__
Definition oks_dump.cxx:35
BadQuery
Definition oks_merge.cxx:29