LCOV - code coverage report
Current view: top level - oksutils/apps - oks_diff_schema.cxx (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 316 0
Test Date: 2026-10-11 15:05:20 Functions: 0.0 % 6 0

            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 : }
        

Generated by: LCOV version 2.0-1