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

Generated by: LCOV version 2.0-1