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