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