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