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 % 304 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 6 0

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

Generated by: LCOV version 2.0-1