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_diff_schema.cpp to apps/oks_diff_schema.cxx).
6 : //
7 :
8 : /**
9 : * \file oks_diff_schema.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
15 : * differences between two schema files.
16 : *
17 : * Usage:
18 : *
19 : * oks_diff_schema [-a] [-r] [-m] [-sb] [-all] [-h] [--help] [-v]
20 : * schema_file1 schema_file2
21 : *
22 : * Options (if two classes differed):
23 : * \param -a produce a listing of detail differences for attributes
24 : * \param -r produce a listing of detail differences for relationships
25 : * \param -m produce a listing of detail differences for methods
26 : * \param -sb produce a listing of all sub classes
27 : * \param -all the same as -a -r -m -sb
28 : *
29 : * General options:
30 : * \param -v print version
31 : * \param -h print this text
32 : *
33 : */
34 :
35 : #include <fstream>
36 :
37 : #include "oks/attribute.hpp"
38 : #include "oks/class.hpp"
39 : #include "oks/kernel.hpp"
40 : #include "oks/method.hpp"
41 : #include "oks/relationship.hpp"
42 :
43 : using namespace dunedaq;
44 : using namespace dunedaq::oks;
45 :
46 : int localDiffsCount;
47 : int classDiffsCount;
48 : char* schemaFile1 = 0;
49 : char* schemaFile2 = 0;
50 :
51 : static void
52 0 : ReportSubClasses(OksClass* c)
53 : {
54 0 : const OksClass::FList* clist = c->all_sub_classes();
55 :
56 0 : if (clist && !clist->empty()) {
57 0 : for (OksClass::FList::const_iterator i = clist->begin(); i != clist->end(); ++i)
58 0 : std::cout << " " << (*i)->get_name() << std::endl;
59 : } else
60 0 : std::cout << " no subclasses\n";
61 0 : }
62 :
63 : enum
64 : {
65 : __Success__ = 0,
66 : __StartOfBadStatus__ = 252,
67 : __BadCommandLine__,
68 : __CannotReadFile__,
69 : __ThereAreNoClasses__
70 : };
71 :
72 : static void
73 0 : printUsage(std::ostream& s)
74 : {
75 0 : s << "Usage: oks_diff_schema [-a] [-r] [-m] [-sb] [-all] [-h | --help] [-v] schema_file1 schema_file2\n"
76 : "Options:\n"
77 : " -a print details of attribute differences\n"
78 : " -r print details of relationship differences\n"
79 : " -m print details of method differences\n"
80 : " -sb print all sub classes\n"
81 : " -all the same as -a -r -m -sb\n"
82 : " -v print version\n"
83 : " -h | --help print this text\n"
84 : "\n"
85 : "Description:\n"
86 : " Print out differences between two schema files.\n"
87 : "\n"
88 : "Return Status:\n"
89 : " 0 - there are no differences between two schema files\n"
90 0 : " "
91 : << __BadCommandLine__
92 : << " - bad command line\n"
93 0 : " "
94 : << __CannotReadFile__
95 : << " - cannot load database file(s)\n"
96 0 : " "
97 : << __ThereAreNoClasses__
98 : << " - loaded file has no any class\n"
99 0 : " 1.."
100 0 : << __StartOfBadStatus__ << " - number of differences (is limited by the max possible value)\n";
101 0 : }
102 :
103 : static void
104 0 : attributesTest(bool printAttributeDifferences, OksClass* c1, OksClass* c2)
105 : {
106 0 : const std::list<OksAttribute*>* alist = c1->direct_attributes();
107 0 : OksAttribute *a1, *a2;
108 :
109 0 : if (alist) {
110 0 : for (std::list<OksAttribute*>::const_iterator ai = alist->begin(); ai != alist->end(); ++ai) {
111 0 : OksAttribute* a1 = *ai;
112 0 : const std::string& attributeName = a1->get_name();
113 :
114 0 : if (!(a2 = c2->find_attribute(attributeName))) {
115 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " There is no attribute \""
116 0 : << attributeName << "\" defined in the \"" << schemaFile2 << "\" database file.\n";
117 :
118 0 : continue;
119 : }
120 :
121 0 : if (!(*a1 == *a2)) {
122 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " The ATTRIBUTE \"" << attributeName
123 0 : << "\" differed";
124 :
125 0 : if (!printAttributeDifferences)
126 0 : std::cout << ".\n";
127 : else {
128 0 : int localAttrCount = 0;
129 :
130 0 : const char* szTheAttribute = " The Attribute ";
131 0 : const char* szMultiValues = "multi-values";
132 0 : const char* szSingleValues = "single-value";
133 0 : const char* szItCan = "\" it can ";
134 0 : const char* szNot = "not ";
135 0 : const char* szBeNull = "be null\n";
136 :
137 0 : std::cout << ":\n";
138 :
139 0 : if (a1->get_type() != a2->get_type())
140 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
141 : << szTheAttribute << "Types differed: \n"
142 0 : << " in the FILE \"" << schemaFile1 << "\" it is: \"" << a1->get_type() << "\"\n"
143 0 : << " in the FILE \"" << schemaFile2 << "\" it is: \"" << a2->get_type() << "\"\n";
144 :
145 0 : if (a1->get_range() != a2->get_range())
146 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
147 : << szTheAttribute << "Ranges differed: \n"
148 : << " in the FILE \"" << schemaFile1 << "\" it is: \"" << a1->get_range() << "\"\n"
149 0 : << " in the FILE \"" << schemaFile2 << "\" it is: \"" << a2->get_range() << "\"\n";
150 :
151 0 : if (a1->get_is_multi_values() != a2->get_is_multi_values())
152 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
153 : << szTheAttribute << "Cardinality differed: \n"
154 : << " in the FILE \"" << schemaFile1 << "\" it is: \""
155 0 : << (a1->get_is_multi_values() ? szMultiValues : szSingleValues) << "\"\n"
156 : << " in the FILE \"" << schemaFile2 << "\" it is: \""
157 0 : << (a2->get_is_multi_values() ? szMultiValues : szSingleValues) << "\"\n";
158 :
159 0 : if (a1->get_init_value() != a2->get_init_value())
160 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
161 : << szTheAttribute << "Initial Values differed: \n"
162 : << " in the FILE \"" << schemaFile1 << "\" it is: \"" << a1->get_init_value() << "\"\n"
163 0 : << " in the FILE \"" << schemaFile2 << "\" it is: \"" << a2->get_init_value() << "\"\n";
164 :
165 0 : if (a1->get_description() != a2->get_description())
166 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
167 : << szTheAttribute << "Descriptions differed: \n"
168 : << " in the FILE \"" << schemaFile1 << "\" it is: \"" << a1->get_description() << "\"\n"
169 0 : << " in the FILE \"" << schemaFile2 << "\" it is: \"" << a2->get_description() << "\"\n";
170 :
171 0 : if (a1->get_is_no_null() != a2->get_is_no_null())
172 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
173 : << szTheAttribute << "Constraints differed: \n"
174 0 : << " in the FILE \"" << schemaFile1 << szItCan << (a1->get_is_no_null() ? szNot : "")
175 : << szBeNull << " in the FILE \"" << schemaFile2 << szItCan
176 0 : << (a2->get_is_no_null() ? szNot : "") << szBeNull;
177 : }
178 : }
179 : }
180 : }
181 :
182 0 : alist = c2->direct_attributes();
183 :
184 0 : if (alist) {
185 0 : for (std::list<OksAttribute*>::const_iterator ai = alist->begin(); ai != alist->end(); ++ai) {
186 0 : OksAttribute* a2 = *ai;
187 0 : const std::string& attributeName = a2->get_name();
188 0 : if (!(a1 = c1->find_attribute(attributeName))) {
189 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " There is no attribute \""
190 0 : << attributeName << "\" defined in the \"" << schemaFile1 << "\" database file.\n";
191 0 : continue;
192 : }
193 : }
194 : }
195 0 : }
196 :
197 : static void
198 0 : relationshipsTest(bool printRelationshipDifferences, OksClass* c1, OksClass* c2)
199 : {
200 0 : const char* szRELATIONSHIP = "RELATIONSHIP ";
201 :
202 0 : const std::list<OksRelationship*>* rlist = c1->direct_relationships();
203 0 : OksRelationship *r1, *r2;
204 :
205 0 : if (rlist) {
206 0 : for (std::list<OksRelationship*>::const_iterator ri = rlist->begin(); ri != rlist->end(); ++ri) {
207 0 : OksRelationship* r1 = *ri;
208 0 : const std::string& relationshipName = r1->get_name();
209 :
210 0 : if (!(r2 = c2->find_relationship(relationshipName))) {
211 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " There is no " << szRELATIONSHIP << "\""
212 0 : << relationshipName << "\" defined in the \"" << schemaFile2 << "\" database file.\n";
213 :
214 0 : continue;
215 : }
216 :
217 0 : if (!(*r1 == *r2)) {
218 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " The " << szRELATIONSHIP << "\""
219 0 : << relationshipName << "\" differed";
220 0 : if (!printRelationshipDifferences)
221 0 : std::cout << ".\n";
222 : else {
223 0 : int localAttrCount = 0;
224 :
225 0 : const char* szTheRelationship = " The Relationship ";
226 0 : const char* szReference = " reference\n";
227 0 : const char* szZero = "Zero";
228 0 : const char* szOne = "One";
229 0 : const char* szMany = "Many";
230 0 : const char* szComposite = "composite";
231 0 : const char* szWeak = "weak";
232 0 : const char* szExclusive = "exclusive";
233 0 : const char* szShared = "shared";
234 0 : const char* szDependent = "dependent";
235 0 : const char* szIndependent = "independent";
236 :
237 0 : std::cout << ":\n";
238 :
239 0 : if (r1->get_type() != r2->get_type())
240 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
241 : << szTheRelationship << "Class Types differed: \n"
242 : << " in the FILE \"" << schemaFile1 << "\" it is: \"" << r1->get_type() << "\"\n"
243 0 : << " in the FILE \"" << schemaFile2 << "\" it is: \"" << r2->get_type() << "\"\n";
244 :
245 0 : if (r1->get_description() != r2->get_description())
246 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
247 : << szTheRelationship << "Descriptions differed: \n"
248 : << " in the FILE \"" << schemaFile1 << "\" it is: \"" << r1->get_description() << "\"\n"
249 0 : << " in the FILE \"" << schemaFile2 << "\" it is: \"" << r2->get_description() << "\"\n";
250 :
251 0 : if (r1->get_low_cardinality_constraint() != r2->get_low_cardinality_constraint())
252 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
253 : << szTheRelationship << "Low Cardinality Constraint differed: \n"
254 : << " in the FILE \"" << schemaFile1 << "\" it is: \""
255 0 : << (r1->get_low_cardinality_constraint() == OksRelationship::Zero
256 : ? szZero
257 0 : : (r1->get_low_cardinality_constraint() == OksRelationship::One ? szOne : szMany))
258 : << "\"\n"
259 : << " in the FILE \"" << schemaFile2 << "\" it is: \""
260 0 : << (r2->get_low_cardinality_constraint() == OksRelationship::Zero
261 : ? szZero
262 0 : : (r2->get_low_cardinality_constraint() == OksRelationship::One ? szOne : szMany))
263 0 : << "\"\n";
264 :
265 0 : if (r1->get_high_cardinality_constraint() != r2->get_high_cardinality_constraint())
266 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
267 : << szTheRelationship << "High Cardinality Constraint differed: \n"
268 : << " in the FILE \"" << schemaFile1 << "\" it is: \""
269 0 : << (r1->get_high_cardinality_constraint() == OksRelationship::Zero
270 : ? szZero
271 0 : : (r1->get_high_cardinality_constraint() == OksRelationship::One ? szOne : szMany))
272 : << "\"\n"
273 : << " in the FILE \"" << schemaFile2 << "\" it is: \""
274 0 : << (r2->get_high_cardinality_constraint() == OksRelationship::Zero
275 : ? szZero
276 0 : : (r2->get_high_cardinality_constraint() == OksRelationship::One ? szOne : szMany))
277 0 : << "\"\n";
278 :
279 0 : if (r1->get_is_composite() != r2->get_is_composite())
280 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
281 : << szTheRelationship << "Composite Types differed: \n"
282 : << " in the FILE \"" << schemaFile1 << "\" it is "
283 0 : << (r1->get_is_composite() ? szComposite : szWeak) << szReference << " in the FILE \""
284 0 : << schemaFile2 << "\" it is " << (r2->get_is_composite() ? szComposite : szWeak) << szReference;
285 :
286 0 : if (r1->get_is_exclusive() != r2->get_is_exclusive())
287 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
288 : << szTheRelationship << "Composite Exclusive Types differed: \n"
289 : << " in the FILE \"" << schemaFile1 << "\" it is "
290 0 : << (r1->get_is_exclusive() ? szExclusive : szShared) << szReference << " in the FILE \""
291 0 : << schemaFile2 << "\" it is " << (r2->get_is_exclusive() ? szExclusive : szShared) << szReference;
292 :
293 0 : if (r1->get_is_dependent() != r2->get_is_dependent())
294 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
295 : << szTheRelationship << "Composite Dependent Types differed: \n"
296 : << " in the FILE \"" << schemaFile1 << "\" it is "
297 0 : << (r1->get_is_dependent() ? szDependent : szIndependent) << szReference << " in the FILE \""
298 0 : << schemaFile2 << "\" it is " << (r2->get_is_dependent() ? szDependent : szIndependent)
299 0 : << szReference;
300 : }
301 : }
302 : }
303 : }
304 :
305 0 : rlist = c2->direct_relationships();
306 :
307 0 : if (rlist) {
308 0 : for (std::list<OksRelationship*>::const_iterator ri = rlist->begin(); ri != rlist->end(); ++ri) {
309 0 : OksRelationship* r2 = *ri;
310 0 : const std::string& relationshipName = r2->get_name();
311 :
312 0 : if (!(r1 = c1->find_relationship(relationshipName))) {
313 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " There is no " << szRELATIONSHIP << "\""
314 0 : << relationshipName << "\" defined in the \"" << schemaFile1 << "\" database file.\n";
315 :
316 0 : continue;
317 : }
318 : }
319 : }
320 0 : }
321 :
322 : static void
323 0 : methodsTest(bool printMethodDifferences, OksClass* c1, OksClass* c2)
324 : {
325 0 : const std::list<OksMethod*>* mlist = c1->direct_methods();
326 0 : OksMethod *m1, *m2;
327 :
328 0 : if (mlist) {
329 0 : for (std::list<OksMethod*>::const_iterator mi = mlist->begin(); mi != mlist->end(); ++mi) {
330 0 : OksMethod* m1 = *mi;
331 0 : const std::string& methodName = m1->get_name();
332 :
333 0 : if (!(m2 = c2->find_method(methodName))) {
334 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " There is no METHOD \"" << methodName
335 0 : << "\" defined in the \"" << schemaFile2 << "\" database file.\n";
336 :
337 0 : continue;
338 : }
339 :
340 0 : if (!(*m1 == *m2)) {
341 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " The METHOD \"" << methodName
342 0 : << "\" differed";
343 :
344 0 : if (!printMethodDifferences)
345 0 : std::cout << ".\n";
346 : else {
347 0 : int localAttrCount = 0;
348 0 : const char* szTheMethod = " The Method ";
349 :
350 0 : std::cout << ":\n";
351 :
352 0 : if (m1->get_description() != m2->get_description())
353 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount << szTheMethod
354 : << "Description differed: \n"
355 : << " in the FILE \"" << schemaFile1 << "\" it is: \"" << m1->get_description() << "\"\n"
356 0 : << " in the FILE \"" << schemaFile2 << "\" it is: \"" << m2->get_description() << "\"\n";
357 :
358 0 : const std::list<OksMethodImplementation*>* m1i = m1->implementations();
359 0 : const std::list<OksMethodImplementation*>* m2i = m2->implementations();
360 :
361 0 : if (m1i || m2i) {
362 0 : if (m2i == 0) {
363 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount << szTheMethod
364 : << "Implementations differed: \n"
365 : << " in the FILE \"" << schemaFile1 << "\" it has implementations\n"
366 0 : << " in the FILE \"" << schemaFile2 << "\" it has no implementations\n";
367 0 : } else if (m1i == 0) {
368 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount << szTheMethod
369 : << "Implementations differed: \n"
370 : << " in the FILE \"" << schemaFile1 << "\" it has no implementations\n"
371 0 : << " in the FILE \"" << schemaFile2 << "\" it has implementations\n";
372 0 : } else if (m1i->size() != m2i->size()) {
373 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount << szTheMethod
374 : << "Implementations differed: \n"
375 0 : << " in the FILE \"" << schemaFile1 << "\" it has " << m1i->size() << " implementations\n"
376 0 : << " in the FILE \"" << schemaFile2 << "\" it has " << m2i->size() << " implementations\n";
377 : } else {
378 0 : std::list<OksMethodImplementation*>::const_iterator m1it = m1i->begin();
379 0 : std::list<OksMethodImplementation*>::const_iterator m2it = m2i->begin();
380 0 : unsigned int icount = 0;
381 0 : for (; m1it != m1i->end(); ++m1it, ++m2it) {
382 0 : icount++;
383 0 : OksMethodImplementation* i1 = *m1it;
384 0 : OksMethodImplementation* i2 = *m2it;
385 :
386 0 : if (i1->get_language() != i2->get_language()) {
387 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
388 0 : << szTheMethod << "Implementations " << icount << " differed: \n"
389 : << " in the FILE \"" << schemaFile1 << "\" it's language is \"" << i1->get_language()
390 : << "\"\n"
391 : << " in the FILE \"" << schemaFile2 << "\" it's language is \"" << i2->get_language()
392 0 : << "\"\n";
393 : }
394 :
395 0 : if (i1->get_prototype() != i2->get_prototype()) {
396 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
397 0 : << szTheMethod << "Implementations " << icount << " differed: \n"
398 : << " in the FILE \"" << schemaFile1 << "\" it's prototype is \"" << i1->get_prototype()
399 : << "\"\n"
400 : << " in the FILE \"" << schemaFile2 << "\" it's prototype is \"" << i2->get_prototype()
401 0 : << "\"\n";
402 : }
403 :
404 0 : if (i1->get_body() != i2->get_body()) {
405 0 : std::cout << " " << classDiffsCount << '.' << localDiffsCount << '.' << ++localAttrCount
406 0 : << szTheMethod << "Implementations " << icount << " differed: \n"
407 : << " in the FILE \"" << schemaFile1 << "\" it's body is \"" << i1->get_body() << "\"\n"
408 : << " in the FILE \"" << schemaFile2 << "\" it's body is \"" << i2->get_body()
409 0 : << "\"\n";
410 : }
411 : }
412 : }
413 : }
414 : }
415 : }
416 : }
417 : }
418 :
419 0 : mlist = c2->direct_methods();
420 :
421 0 : if (mlist) {
422 0 : for (std::list<OksMethod*>::const_iterator mi = mlist->begin(); mi != mlist->end(); ++mi) {
423 0 : OksMethod* m2 = *mi;
424 0 : const std::string& methodName = m2->get_name();
425 0 : if (!(m1 = c1->find_method(methodName))) {
426 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " There is no METHOD \"" << methodName
427 0 : << "\" defined in the \"" << schemaFile1 << "\" database file.\n";
428 :
429 0 : continue;
430 : }
431 : }
432 : }
433 0 : }
434 :
435 : int
436 0 : main(int argc, char** argv)
437 : {
438 0 : bool printAttributeDifferences = false;
439 0 : bool printRelationshipDifferences = false;
440 0 : bool printMethodDifferences = false;
441 0 : bool printSubClasses = false;
442 :
443 0 : if (argc == 1) {
444 0 : printUsage(std::cerr);
445 0 : return __BadCommandLine__;
446 : }
447 :
448 0 : for (int i = 1; i < argc; i++) {
449 0 : if (!strcmp(argv[i], "-a"))
450 : printAttributeDifferences = true;
451 0 : else if (!strcmp(argv[i], "-r"))
452 : printRelationshipDifferences = true;
453 0 : else if (!strcmp(argv[i], "-m"))
454 : printMethodDifferences = true;
455 0 : else if (!strcmp(argv[i], "-sb"))
456 : printSubClasses = true;
457 0 : else if (!strcmp(argv[i], "-all")) {
458 : printAttributeDifferences = true;
459 : printRelationshipDifferences = true;
460 : printMethodDifferences = true;
461 : printSubClasses = true;
462 0 : } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
463 0 : printUsage(std::cout);
464 0 : return __Success__;
465 0 : } else if (!strcmp(argv[i], "-v")) {
466 0 : std::cout << "OKS kernel version " << OksKernel::GetVersion() << std::endl;
467 0 : return __Success__;
468 0 : } else if (argc == (i + 2) && argv[i][0] != '-' && argv[i + 1][0] != '-') {
469 0 : schemaFile1 = argv[i++];
470 0 : schemaFile2 = argv[i++];
471 : } else {
472 0 : std::cerr << "Unknown parameter: \"" << argv[i] << "\"\n\n";
473 :
474 0 : printUsage(std::cerr);
475 0 : return __BadCommandLine__;
476 : }
477 : }
478 :
479 0 : OksKernel kernel1;
480 0 : OksKernel kernel2;
481 :
482 0 : try {
483 :
484 0 : const char* szNoClasses = " No classes were found in \"";
485 0 : const char* szExiting = ", exiting ...\n";
486 :
487 0 : kernel1.load_file(schemaFile1);
488 0 : kernel2.load_file(schemaFile2);
489 :
490 0 : const OksClass::Map& classes1 = kernel1.classes();
491 0 : const OksClass::Map& classes2 = kernel2.classes();
492 :
493 0 : if (classes1.empty()) {
494 0 : std::cerr << "ERROR:" << szNoClasses << schemaFile1 << "\" database file" << szExiting;
495 0 : return __ThereAreNoClasses__;
496 : }
497 :
498 0 : if (classes2.empty()) {
499 0 : std::cerr << "ERROR:" << szNoClasses << schemaFile2 << "\" database file" << szExiting;
500 : return __ThereAreNoClasses__;
501 : }
502 :
503 0 : OksClass::Map::const_iterator class_iterator1 = classes1.begin();
504 0 : OksClass::Map::const_iterator class_iterator2 = classes2.begin();
505 :
506 0 : std::cout << std::endl;
507 :
508 0 : classDiffsCount = 0;
509 :
510 0 : OksClass *c1, *c2;
511 :
512 0 : for (; class_iterator1 != classes1.end(); ++class_iterator1) {
513 0 : c1 = class_iterator1->second;
514 0 : const std::string& className = c1->get_name();
515 :
516 0 : if (!(c2 = kernel2.find_class(className))) {
517 0 : std::cout << "\n DIFFERENCE " << ++classDiffsCount << ". There is no class \"" << className << "\" in the \""
518 0 : << schemaFile2 << "\" database file.\n";
519 :
520 0 : continue;
521 : }
522 :
523 0 : std::cout << "TESTING IN CLASSES \"" << className << "\"... ";
524 0 : std::cout.flush();
525 :
526 : //
527 : // Operators '==' and '!=' have completly different implementation:
528 : // - operator== is optimised for performance and
529 : // checks addresses of classes and their names only
530 : // - operator!= checks all class properties
531 : //
532 :
533 0 : if ((*c1 != *c2) == false) {
534 0 : std::cout << " no differences were found\n";
535 0 : continue;
536 : }
537 :
538 0 : std::cout << std::endl
539 0 : << " DIFFERENCE " << ++classDiffsCount << '.' << " The CLASSES \"" << className << "\" differed:\n";
540 :
541 0 : localDiffsCount = 0;
542 :
543 0 : attributesTest(printAttributeDifferences, c1, c2);
544 0 : relationshipsTest(printRelationshipDifferences, c1, c2);
545 0 : methodsTest(printMethodDifferences, c1, c2);
546 :
547 0 : if (c1->get_description() != c2->get_description()) {
548 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " The Class Descriptions differed: \n"
549 : << " in the FILE \"" << schemaFile1 << "\" it is: \"" << c1->get_description() << "\"\n"
550 0 : << " in the FILE \"" << schemaFile2 << "\" it is: \"" << c2->get_description() << "\"\n";
551 : }
552 :
553 0 : if (c1->get_is_abstract() != c2->get_is_abstract()) {
554 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " The Class Abstraction differed: \n"
555 : << " in the FILE \"" << schemaFile1 << "\" it is: \""
556 0 : << (c1->get_is_abstract() ? "abstract" : "not abstract") << "\"\n"
557 : << " in the FILE \"" << schemaFile2 << "\" it is: \""
558 0 : << (c2->get_is_abstract() ? "abstract" : "not abstract") << "\"\n";
559 : }
560 :
561 0 : { /* DIRECT SUPERCLASSES TEST */
562 :
563 0 : const std::list<std::string*>* slist = c1->direct_super_classes();
564 0 : const std::string* spn;
565 :
566 0 : if (slist) {
567 0 : for (std::list<std::string*>::const_iterator spi = slist->begin(); spi != slist->end(); ++spi) {
568 0 : spn = *spi;
569 0 : if (!c2->find_super_class(*spn)) {
570 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " There is no SUPERCLASS \"" << *spn
571 0 : << "\" defined in the \"" << schemaFile2 << "\" database file.\n";
572 :
573 0 : continue;
574 : }
575 : }
576 : }
577 :
578 0 : slist = c2->direct_super_classes();
579 :
580 0 : if (slist) {
581 0 : for (std::list<std::string*>::const_iterator spi = slist->begin(); spi != slist->end(); ++spi) {
582 0 : spn = *spi;
583 0 : if (!c1->find_super_class(*spn)) {
584 0 : std::cout << " " << classDiffsCount << '.' << ++localDiffsCount << " There is no SUPERCLASS \"" << *spn
585 0 : << "\" defined in the \"" << schemaFile1 << "\" database file.\n";
586 :
587 0 : continue;
588 : }
589 : }
590 : }
591 : } /* END OF DIRECT SUPERCLASSES TEST */
592 :
593 0 : if (printSubClasses) {
594 0 : std::cout << " ALL SUBCLASS(ES) of the CLASS \"" << className << "\"\n";
595 0 : std::cout << " in the FILE \"" << schemaFile1 << "\"\n";
596 0 : ReportSubClasses(c1);
597 0 : std::cout << " in the FILE \"" << schemaFile2 << "\"\n";
598 0 : ReportSubClasses(c2);
599 : }
600 : }
601 :
602 0 : for (; class_iterator2 != classes2.end(); ++class_iterator2) {
603 0 : if (!kernel1.find_class(class_iterator2->second->get_name())) {
604 0 : std::cout << "\n DIFFERENCE " << ++classDiffsCount << ". There is no class \""
605 0 : << class_iterator2->second->get_name() << "\" in the \"" << schemaFile1 << "\" database file.\n";
606 : }
607 : }
608 :
609 0 : std::cout << "\nFound " << classDiffsCount << " differences, exiting...\n";
610 : }
611 :
612 0 : catch (oks::exception& ex) {
613 0 : std::cerr << "Caught oks exception:\n" << ex << std::endl;
614 0 : return __CannotReadFile__;
615 0 : }
616 :
617 0 : catch (std::exception& e) {
618 0 : std::cerr << "Caught standard C++ exception: " << e.what() << std::endl;
619 0 : return __CannotReadFile__;
620 0 : }
621 :
622 0 : return (classDiffsCount > __StartOfBadStatus__ ? __StartOfBadStatus__ : classDiffsCount);
623 0 : }
|