Line data Source code
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_report_equal_objects.cpp to apps/oks_report_equal_objects.cxx).
6 : //
7 :
8 : /**
9 : * \file oks_diff_data.cpp
10 : *
11 : * This file is part of the OKS package.
12 : * Author: <Igor.Soloviev@cern.ch>
13 : *
14 : * This file contains the implementation of the OKS application to show equal objects.
15 : */
16 :
17 :
18 : #include <iostream>
19 : #include <sstream>
20 :
21 : #include <set>
22 : #include <map>
23 :
24 : #include <boost/program_options.hpp>
25 :
26 : #include "oks/kernel.hpp"
27 : #include "oks/class.hpp"
28 : #include "oks/object.hpp"
29 : #include "oks/attribute.hpp"
30 : #include "oks/relationship.hpp"
31 :
32 : using namespace dunedaq;
33 : using namespace dunedaq::oks;
34 : ////////////////////////////////////////////////////////////////////////////////////////////////////
35 :
36 : struct SortObjById {
37 0 : bool operator() (const OksObject * o1, const OksObject * o2) const {
38 0 : return o1->GetId() < o2->GetId();
39 : }
40 : };
41 :
42 : typedef std::set<const OksObject *, SortObjById> ObjsSet;
43 :
44 : ////////////////////////////////////////////////////////////////////////////////////////////////////
45 :
46 :
47 0 : static void process_class(const OksClass *c, bool verbose)
48 : {
49 0 : bool printed_class(false);
50 :
51 0 : if(verbose) {
52 0 : std::cout << "* processing class \'" << c->get_name() << "\'" << std::endl;
53 : printed_class = true;
54 : }
55 :
56 0 : const OksObject::Map * objects = c->objects();
57 0 : if(!objects || objects->empty()) {
58 0 : if(verbose) {
59 0 : std::cout << " no objects" << std::endl;
60 : }
61 0 : return;
62 : }
63 :
64 0 : std::multimap<std::string, const OksObject *> vals;
65 :
66 0 : const std::list<OksAttribute *> * alist = c->all_attributes();
67 0 : const std::list<OksRelationship *> * rlist = c->all_relationships();
68 :
69 0 : OksDataInfo di(0, (const OksAttribute *)(0));
70 :
71 0 : for(OksObject::Map::const_iterator i = objects->begin(); i != objects->end(); ++i) {
72 0 : const OksObject * o(i->second);
73 0 : std::ostringstream s;
74 0 : OksData * d(o->GetAttributeValue(&di));
75 :
76 0 : if(alist) {
77 0 : for(std::list<OksAttribute *>::const_iterator j = alist->begin(); j != alist->end(); ++j, ++d) {
78 0 : s << (*j)->get_name() << *d << '\n';
79 : }
80 : }
81 :
82 0 : if(rlist) {
83 0 : for(std::list<OksRelationship *>::const_iterator j = rlist->begin(); j != rlist->end(); ++j, ++d) {
84 0 : s << (*j)->get_name() << *d << '\n';
85 : }
86 : }
87 :
88 0 : s << std::ends;
89 :
90 0 : vals.insert(std::make_pair(s.str(), o));
91 0 : }
92 :
93 0 : std::string last;
94 0 : const OksObject * prev(0);
95 :
96 0 : for(std::multimap<std::string, const OksObject *>::iterator i = vals.begin(); i != vals.end(); ) {
97 0 : if(last == i->first) {
98 0 : ObjsSet equal_objs;
99 0 : equal_objs.insert(prev);
100 0 : equal_objs.insert(i->second);
101 0 : ++i;
102 0 : for(; i != vals.end(); ++i) {
103 0 : if(last == i->first) {
104 0 : equal_objs.insert(i->second);
105 : }
106 : else {
107 0 : if(!printed_class) {
108 0 : std::cout << "* found equal objects in class \'" << c->get_name() << "\'" << std::endl;
109 : printed_class = true;
110 : }
111 :
112 0 : std::cout << " # the following " << equal_objs.size() << " objects are equal:\n";
113 0 : for(ObjsSet::const_iterator j = equal_objs.begin(); j != equal_objs.end(); ++j) {
114 0 : std::cout << " - " << (*j) << " from \'" << (*j)->get_file()->get_full_file_name() << "\'\n";
115 : }
116 :
117 0 : last = i->first;
118 0 : prev = i->second;
119 0 : ++i;
120 0 : break;
121 : }
122 : }
123 0 : }
124 : else {
125 0 : last = i->first;
126 0 : prev = i->second;
127 0 : ++i;
128 : }
129 : }
130 0 : }
131 :
132 :
133 :
134 : namespace po = boost::program_options;
135 :
136 : int
137 0 : main(int argc, char **argv)
138 : {
139 0 : std::vector<std::string> files;
140 0 : std::string class_name;
141 0 : bool verbose(false);
142 :
143 0 : try {
144 0 : po::options_description desc("This program is loading OKS data files and searching for equal object.\nUsage: oks_report_equal_objects [options] [-f] file+ ");
145 :
146 0 : desc.add_options()
147 0 : ("class,c" , po::value<std::string>(&class_name) , "If defined, only compare objects of this class")
148 0 : ("files,f" , po::value<std::vector<std::string> >(&files) , "Names of input OKS files")
149 0 : ("verbose,v" , "Run in verbose mode")
150 0 : ("help,h" , "Print help message")
151 : ;
152 :
153 0 : po::positional_options_description p;
154 0 : p.add("files", -1);
155 :
156 0 : po::variables_map vm;
157 0 : po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
158 0 : po::notify(vm);
159 :
160 0 : if(vm.count("help")) { std::cout << desc << std::endl; return EXIT_SUCCESS; }
161 0 : if(vm.count("verbose")) { verbose = true; }
162 :
163 0 : if(files.empty()) { throw std::runtime_error("Missing application name" ); }
164 0 : }
165 0 : catch(std::exception& ex) {
166 0 : std::cerr << "ERROR: " << ex.what() << std::endl;
167 0 : return EXIT_FAILURE;
168 0 : }
169 :
170 0 : try {
171 0 : OksKernel kernel;
172 0 : kernel.set_test_duplicated_objects_via_inheritance_mode(true);
173 0 : kernel.set_silence_mode(!verbose);
174 :
175 0 : for(std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i) {
176 0 : kernel.load_file(*i);
177 : }
178 :
179 0 : if(!class_name.empty()) {
180 0 : if(OksClass * c = kernel.find_class(class_name)) {
181 0 : process_class(c, verbose);
182 : return 0;
183 : }
184 : else {
185 0 : std::cerr << "ERROR: cannot find class \'" << class_name << '\'' << std::endl;
186 : return EXIT_FAILURE;
187 : }
188 : }
189 :
190 0 : for(OksClass::Map::const_iterator i = kernel.classes().begin(); i != kernel.classes().end(); ++i) {
191 0 : process_class(i->second, verbose);
192 : }
193 0 : }
194 0 : catch(oks::exception& ex) {
195 0 : std::cerr << "ERROR: " << ex.what() << std::endl;
196 0 : return EXIT_FAILURE;
197 0 : }
198 :
199 0 : return 0;
200 0 : }
|