LCOV - code coverage report
Current view: top level - unoidl/source - unoidl-check.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 237 582 40.7 %
Date: 2014-04-11 Functions: 13 15 86.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include "sal/config.h"
      11             : 
      12             : #include <algorithm>
      13             : #include <cassert>
      14             : #include <cstdlib>
      15             : #include <iostream>
      16             : #include <vector>
      17             : 
      18             : #include "osl/file.hxx"
      19             : #include "osl/process.h"
      20             : #include "rtl/process.h"
      21             : #include "rtl/ref.hxx"
      22             : #include "rtl/ustring.hxx"
      23             : #include "sal/main.h"
      24             : #include "sal/types.h"
      25             : #include "unoidl/unoidl.hxx"
      26             : 
      27             : namespace unoidl {
      28             : 
      29        1882 : bool operator ==(ConstantValue const & lhs, ConstantValue const & rhs) {
      30        1882 :     if (lhs.type == rhs.type) {
      31        1882 :         switch (lhs.type) {
      32             :         case ConstantValue::TYPE_BOOLEAN:
      33           0 :             return lhs.booleanValue == rhs.booleanValue;
      34             :         case ConstantValue::TYPE_BYTE:
      35          12 :             return lhs.byteValue == rhs.byteValue;
      36             :         case ConstantValue::TYPE_SHORT:
      37        1168 :             return lhs.shortValue == rhs.shortValue;
      38             :         case ConstantValue::TYPE_UNSIGNED_SHORT:
      39           0 :             return lhs.unsignedShortValue == rhs.unsignedShortValue;
      40             :         case ConstantValue::TYPE_LONG:
      41         653 :             return lhs.longValue == rhs.longValue;
      42             :         case ConstantValue::TYPE_UNSIGNED_LONG:
      43           0 :             return lhs.unsignedLongValue == rhs.unsignedLongValue;
      44             :         case ConstantValue::TYPE_HYPER:
      45          29 :             return lhs.hyperValue == rhs.hyperValue;
      46             :         case ConstantValue::TYPE_UNSIGNED_HYPER:
      47           0 :             return lhs.unsignedHyperValue == rhs.unsignedHyperValue;
      48             :         case ConstantValue::TYPE_FLOAT:
      49          20 :             return lhs.floatValue == rhs.floatValue;
      50             :         case ConstantValue::TYPE_DOUBLE:
      51           0 :             return lhs.doubleValue == rhs.doubleValue;
      52             :         }
      53             :     }
      54           0 :     return false;
      55             : }
      56             : 
      57        1882 : bool operator !=(ConstantValue const & lhs, ConstantValue const & rhs) {
      58        1882 :     return !(lhs == rhs);
      59             : }
      60             : 
      61          31 : bool operator ==(
      62             :     SingleInterfaceBasedServiceEntity::Constructor::Parameter const & lhs,
      63             :     SingleInterfaceBasedServiceEntity::Constructor::Parameter const & rhs)
      64             : {
      65          31 :     return lhs.name == rhs.name && lhs.type == rhs.type && lhs.rest == rhs.rest;
      66             : }
      67             : 
      68             : }
      69             : 
      70             : namespace {
      71             : 
      72           0 : void badUsage() {
      73             :     std::cerr
      74           0 :         << "Usage:" << std::endl << std::endl
      75             :         << ("  unoidl-check [<extra registries A>] <registry A> -- [<extra"
      76           0 :             " registries B>]")
      77           0 :         << std::endl << "    <registry B>" << std::endl << std::endl
      78             :         << ("where each <registry> is either a new- or legacy-format .rdb file,"
      79           0 :             " a single .idl")
      80           0 :         << std::endl
      81             :         << ("file, or a root directory of an .idl file tree.  Check that each"
      82           0 :             " entity from")
      83           0 :         << std::endl
      84           0 :         << "<registry A> is also present in <registry B> in a compatible form."
      85           0 :         << std::endl;
      86           0 :     std::exit(EXIT_FAILURE);
      87             : }
      88             : 
      89           8 : OUString getArgumentUri(sal_uInt32 argument, bool * delimiter) {
      90           8 :     OUString arg;
      91           8 :     rtl_getAppCommandArg(argument, &arg.pData);
      92           8 :     if (arg == "--") {
      93           2 :         if (delimiter == 0) {
      94           0 :             badUsage();
      95             :         }
      96           2 :         *delimiter = true;
      97           2 :         return OUString();
      98             :     }
      99          12 :     OUString url;
     100           6 :     osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
     101           6 :     if (e1 != osl::FileBase::E_None) {
     102             :         std::cerr
     103           0 :             << "Cannot convert \"" << arg << "\" to file URL, error code "
     104           0 :             << +e1 << std::endl;
     105           0 :         std::exit(EXIT_FAILURE);
     106             :     }
     107          12 :     OUString cwd;
     108           6 :     oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
     109           6 :     if (e2 != osl_Process_E_None) {
     110             :         std::cerr
     111           0 :             << "Cannot obtain working directory, error code " << +e2
     112           0 :             << std::endl;
     113           0 :         std::exit(EXIT_FAILURE);
     114             :     }
     115          12 :     OUString abs;
     116           6 :     e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
     117           6 :     if (e1 != osl::FileBase::E_None) {
     118             :         std::cerr
     119           0 :             << "Cannot make \"" << url
     120           0 :             << "\" into an absolute file URL, error code " << +e1 << std::endl;
     121           0 :         std::exit(EXIT_FAILURE);
     122             :     }
     123          14 :     return abs;
     124             : }
     125             : 
     126           0 : OUString showDirection(
     127             :     unoidl::InterfaceTypeEntity::Method::Parameter::Direction direction)
     128             : {
     129           0 :     switch (direction) {
     130             :     case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN:
     131           0 :         return OUString("[in]");
     132             :     case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT:
     133           0 :         return OUString("[out]");
     134             :     case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT:
     135           0 :         return OUString("[inout]");
     136             :     default:
     137           0 :         assert(false); for (;;) { std::abort(); } // this cannot happen
     138             :     }
     139             : }
     140             : 
     141         912 : struct EqualsAnnotation {
     142         304 :     EqualsAnnotation(OUString const & name): name_(name) {}
     143             : 
     144         674 :     bool operator ()(unoidl::AnnotatedReference const & ref)
     145         674 :     { return ref.name == name_; }
     146             : 
     147             : private:
     148             :     OUString name_;
     149             : };
     150             : 
     151        2856 : void checkMap(
     152             :     rtl::Reference<unoidl::Provider> const & providerB, OUString const & prefix,
     153             :     rtl::Reference<unoidl::MapCursor> const & cursor)
     154             : {
     155             :     assert(providerB.is());
     156             :     assert(cursor.is());
     157             :     for (;;) {
     158        2856 :         OUString id;
     159        5633 :         rtl::Reference<unoidl::Entity> entA(cursor->getNext(&id));
     160        2856 :         if (!entA.is()) {
     161          79 :             break;
     162             :         }
     163        5554 :         OUString name(prefix + id);
     164        2777 :         if (entA->getSort() == unoidl::Entity::SORT_MODULE) {
     165             :             checkMap(
     166         154 :                 providerB, name + ".",
     167          77 :                 (static_cast<unoidl::ModuleEntity *>(entA.get())
     168         231 :                  ->createCursor()));
     169             :         } else {
     170        2700 :             rtl::Reference<unoidl::Entity> entB(providerB->findEntity(name));
     171        2700 :             if (!entB.is()) {
     172             :                 std::cerr
     173           0 :                     << "A entity " << name << " is not present in B"
     174           0 :                     << std::endl;
     175           0 :                 std::exit(EXIT_FAILURE);
     176             :             }
     177        2700 :             if (entA->getSort() != entB->getSort()) {
     178             :                 std::cerr
     179           0 :                     << "A entity " << name << " is of different sort in B"
     180           0 :                     << std::endl;
     181           0 :                 std::exit(EXIT_FAILURE);
     182             :             }
     183        5400 :             if ((dynamic_cast<unoidl::PublishableEntity *>(entA.get())
     184        2700 :                  ->isPublished())
     185        5387 :                 && (!dynamic_cast<unoidl::PublishableEntity *>(entB.get())
     186        2687 :                     ->isPublished()))
     187             :             {
     188             :                 std::cerr
     189           0 :                     << "A published entity " << name << " is not published in B"
     190           0 :                     << std::endl;
     191           0 :                 std::exit(EXIT_FAILURE);
     192             :             }
     193        2700 :             switch (entA->getSort()) {
     194             :             case unoidl::Entity::SORT_MODULE:
     195             :                 assert(false); // this cannot happen
     196             :             case unoidl::Entity::SORT_ENUM_TYPE:
     197             :                 {
     198             :                     rtl::Reference<unoidl::EnumTypeEntity> ent2A(
     199         157 :                         static_cast<unoidl::EnumTypeEntity *>(entA.get()));
     200             :                     rtl::Reference<unoidl::EnumTypeEntity> ent2B(
     201         314 :                         static_cast<unoidl::EnumTypeEntity *>(entB.get()));
     202         314 :                     if (ent2A->getMembers().size()
     203         157 :                         != ent2B->getMembers().size())
     204             :                     {
     205             :                         std::cerr
     206           0 :                             << "enum type " << name
     207           0 :                             << " number of members changed from "
     208           0 :                             << ent2A->getMembers().size() << " to "
     209           0 :                             << ent2B->getMembers().size() << std::endl;
     210           0 :                         std::exit(EXIT_FAILURE);
     211             :                     }
     212        3747 :                     for (std::vector<unoidl::EnumTypeEntity::Member>::const_iterator
     213         157 :                              i(ent2A->getMembers().begin()),
     214         157 :                              j(ent2B->getMembers().begin());
     215        2498 :                          i != ent2A->getMembers().end(); ++i, ++j)
     216             :                     {
     217        1092 :                         if (i->name != j->name || i->value != j->value) {
     218             :                             std::cerr
     219           0 :                                 << "enum type " << name << " member #"
     220           0 :                                 << i - ent2A->getMembers().begin() + 1
     221           0 :                                 << " changed from " << i->name << " = "
     222           0 :                                 << i->value << " to " << j->name << " = "
     223           0 :                                 << j->value << std::endl;
     224           0 :                             std::exit(EXIT_FAILURE);
     225             :                         }
     226             :                     }
     227         314 :                     break;
     228             :                 }
     229             :             case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
     230             :                 {
     231             :                     rtl::Reference<unoidl::PlainStructTypeEntity> ent2A(
     232             :                         static_cast<unoidl::PlainStructTypeEntity *>(
     233         236 :                             entA.get()));
     234             :                     rtl::Reference<unoidl::PlainStructTypeEntity> ent2B(
     235             :                         static_cast<unoidl::PlainStructTypeEntity *>(
     236         472 :                             entB.get()));
     237         236 :                     if (ent2A->getDirectBase() != ent2B->getDirectBase()) {
     238             :                         std::cerr
     239           0 :                             << "plain struct type " << name
     240           0 :                             << " direct base changed from "
     241           0 :                             << (ent2A->getDirectBase().isEmpty()
     242           0 :                                 ? OUString("none") : ent2A->getDirectBase())
     243           0 :                             << " to "
     244           0 :                             << (ent2B->getDirectBase().isEmpty()
     245           0 :                                 ? OUString("none") : ent2B->getDirectBase())
     246           0 :                             << std::endl;
     247           0 :                         std::exit(EXIT_FAILURE);
     248             :                     }
     249         472 :                     if (ent2A->getDirectMembers().size()
     250         236 :                         != ent2B->getDirectMembers().size())
     251             :                     {
     252             :                         std::cerr
     253           0 :                             << "plain struct type " << name
     254           0 :                             << " number of direct members changed from "
     255           0 :                             << ent2A->getDirectMembers().size() << " to "
     256           0 :                             << ent2B->getDirectMembers().size() << std::endl;
     257           0 :                         std::exit(EXIT_FAILURE);
     258             :                     }
     259        3216 :                     for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
     260         236 :                              i(ent2A->getDirectMembers().begin()),
     261         236 :                              j(ent2B->getDirectMembers().begin());
     262        2144 :                          i != ent2A->getDirectMembers().end(); ++i, ++j)
     263             :                     {
     264         836 :                         if (i->name != j->name || i->type != j->type) {
     265             :                             std::cerr
     266           0 :                                 << "plain struct type " << name
     267           0 :                                 << " direct member #"
     268           0 :                                 << i - ent2A->getDirectMembers().begin() + 1
     269           0 :                                 << " changed from " << i->type << " " << i->name
     270           0 :                                 << " to " << j->type << " " << j->name
     271           0 :                                 << std::endl;
     272           0 :                             std::exit(EXIT_FAILURE);
     273             :                         }
     274             :                     }
     275         472 :                     break;
     276             :                 }
     277             :             case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
     278             :                 {
     279             :                     rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
     280             :                         ent2A(
     281             :                             static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
     282           0 :                                 entA.get()));
     283             :                     rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
     284             :                         ent2B(
     285             :                             static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
     286           0 :                                 entB.get()));
     287           0 :                     if (ent2A->getTypeParameters().size()
     288           0 :                         != ent2B->getTypeParameters().size())
     289             :                     {
     290             :                         std::cerr
     291           0 :                             << "polymorphic struct type template " << name
     292           0 :                             << " number of type parameters changed from "
     293           0 :                             << ent2A->getTypeParameters().size() << " to "
     294           0 :                             << ent2B->getTypeParameters().size() << std::endl;
     295           0 :                         std::exit(EXIT_FAILURE);
     296             :                     }
     297           0 :                     for (std::vector<OUString>::const_iterator
     298           0 :                              i(ent2A->getTypeParameters().begin()),
     299           0 :                              j(ent2B->getTypeParameters().begin());
     300           0 :                          i != ent2A->getTypeParameters().end(); ++i, ++j)
     301             :                     {
     302           0 :                         if (*i != *j) {
     303             :                             std::cerr
     304           0 :                                 << "polymorphic struct type template " << name
     305           0 :                                 << " type parameter #"
     306           0 :                                 << i - ent2A->getTypeParameters().begin() + 1
     307           0 :                                 << " changed from " << *i << " to " << *j
     308           0 :                                 << std::endl;
     309           0 :                             std::exit(EXIT_FAILURE);
     310             :                         }
     311             :                     }
     312           0 :                     if (ent2A->getMembers().size()
     313           0 :                         != ent2B->getMembers().size())
     314             :                     {
     315             :                         std::cerr
     316           0 :                             << "polymorphic struct type template " << name
     317           0 :                             << " number of members changed from "
     318           0 :                             << ent2A->getMembers().size() << " to "
     319           0 :                             << ent2B->getMembers().size() << std::endl;
     320           0 :                         std::exit(EXIT_FAILURE);
     321             :                     }
     322           0 :                     for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
     323           0 :                              i(ent2A->getMembers().begin()),
     324           0 :                              j(ent2B->getMembers().begin());
     325           0 :                          i != ent2A->getMembers().end(); ++i, ++j)
     326             :                     {
     327           0 :                         if (i->name != j->name || i->type != j->type
     328           0 :                             || i->parameterized != j->parameterized)
     329             :                         {
     330             :                             std::cerr
     331           0 :                                 << "polymorphic struct type template " << name
     332           0 :                                 << " member #"
     333           0 :                                 << i - ent2A->getMembers().begin() + 1
     334           0 :                                 << " changed from "
     335           0 :                                 << (i->parameterized
     336           0 :                                     ? OUString("parameterized ") : OUString())
     337           0 :                                 << i->type << " " << i->name
     338           0 :                                 << " to "
     339           0 :                                 << (j->parameterized
     340           0 :                                     ? OUString("parameterized ") : OUString())
     341           0 :                                 << j->type << " " << j->name
     342           0 :                                 << std::endl;
     343           0 :                             std::exit(EXIT_FAILURE);
     344             :                         }
     345             :                     }
     346           0 :                     break;
     347             :                 }
     348             :             case unoidl::Entity::SORT_EXCEPTION_TYPE:
     349             :                 {
     350             :                     rtl::Reference<unoidl::ExceptionTypeEntity> ent2A(
     351         172 :                         static_cast<unoidl::ExceptionTypeEntity *>(entA.get()));
     352             :                     rtl::Reference<unoidl::ExceptionTypeEntity> ent2B(
     353         344 :                         static_cast<unoidl::ExceptionTypeEntity *>(entB.get()));
     354         172 :                     if (ent2A->getDirectBase() != ent2B->getDirectBase()) {
     355             :                         std::cerr
     356           0 :                             << "exception type " << name
     357           0 :                             << " direct base changed from "
     358           0 :                             << (ent2A->getDirectBase().isEmpty()
     359           0 :                                 ? OUString("none") : ent2A->getDirectBase())
     360           0 :                             << " to "
     361           0 :                             << (ent2B->getDirectBase().isEmpty()
     362           0 :                                 ? OUString("none") : ent2B->getDirectBase())
     363           0 :                             << std::endl;
     364           0 :                         std::exit(EXIT_FAILURE);
     365             :                     }
     366         344 :                     if (ent2A->getDirectMembers().size()
     367         172 :                         != ent2B->getDirectMembers().size())
     368             :                     {
     369             :                         std::cerr
     370           0 :                             << "exception type " << name
     371           0 :                             << " number of direct members changed from "
     372           0 :                             << ent2A->getDirectMembers().size() << " to "
     373           0 :                             << ent2B->getDirectMembers().size() << std::endl;
     374           0 :                         std::exit(EXIT_FAILURE);
     375             :                     }
     376         822 :                     for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
     377         172 :                              i(ent2A->getDirectMembers().begin()),
     378         172 :                              j(ent2B->getDirectMembers().begin());
     379         548 :                          i != ent2A->getDirectMembers().end(); ++i, ++j)
     380             :                     {
     381         102 :                         if (i->name != j->name || i->type != j->type) {
     382             :                             std::cerr
     383           0 :                                 << "exception type " << name
     384           0 :                                 << " direct member #"
     385           0 :                                 << i - ent2A->getDirectMembers().begin() + 1
     386           0 :                                 << " changed from " << i->type << " " << i->name
     387           0 :                                 << " to " << j->type << " " << j->name
     388           0 :                                 << std::endl;
     389           0 :                             std::exit(EXIT_FAILURE);
     390             :                         }
     391             :                     }
     392         344 :                     break;
     393             :                 }
     394             :             case unoidl::Entity::SORT_INTERFACE_TYPE:
     395             :                 {
     396             :                     rtl::Reference<unoidl::InterfaceTypeEntity> ent2A(
     397        1047 :                         static_cast<unoidl::InterfaceTypeEntity *>(entA.get()));
     398             :                     rtl::Reference<unoidl::InterfaceTypeEntity> ent2B(
     399        2094 :                         static_cast<unoidl::InterfaceTypeEntity *>(entB.get()));
     400        2094 :                     if (ent2A->getDirectMandatoryBases().size()
     401        1047 :                         != ent2B->getDirectMandatoryBases().size())
     402             :                     {
     403             :                         std::cerr
     404           0 :                             << "interface type " << name
     405           0 :                             << " number of direct mandatory bases changed from "
     406           0 :                             << ent2A->getDirectMandatoryBases().size() << " to "
     407           0 :                             << ent2B->getDirectMandatoryBases().size()
     408           0 :                             << std::endl;
     409           0 :                         std::exit(EXIT_FAILURE);
     410             :                     }
     411        6552 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     412        1047 :                              i(ent2A->getDirectMandatoryBases().begin()),
     413        1047 :                              j(ent2B->getDirectMandatoryBases().begin());
     414        4368 :                          i != ent2A->getDirectMandatoryBases().end(); ++i, ++j)
     415             :                     {
     416        1137 :                         if (i->name != j->name) {
     417             :                             std::cerr
     418           0 :                                 << "interface type " << name
     419           0 :                                 << " direct mandatory base #"
     420           0 :                                 << (i - ent2A->getDirectMandatoryBases().begin()
     421           0 :                                     + 1)
     422           0 :                                 << " changed from " << i->name << " to "
     423           0 :                                 << j->name << std::endl;
     424           0 :                             std::exit(EXIT_FAILURE);
     425             :                         }
     426             :                     }
     427        2094 :                     if (ent2A->getDirectOptionalBases().size()
     428        1047 :                         != ent2B->getDirectOptionalBases().size())
     429             :                     {
     430             :                         std::cerr
     431           0 :                             << "interface type " << name
     432           0 :                             << " number of direct optional bases changed from "
     433           0 :                             << ent2A->getDirectOptionalBases().size() << " to "
     434           0 :                             << ent2B->getDirectOptionalBases().size()
     435           0 :                             << std::endl;
     436           0 :                         std::exit(EXIT_FAILURE);
     437             :                     }
     438        3162 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     439        1047 :                              i(ent2A->getDirectOptionalBases().begin()),
     440        1047 :                              j(ent2B->getDirectOptionalBases().begin());
     441        2108 :                          i != ent2A->getDirectOptionalBases().end(); ++i, ++j)
     442             :                     {
     443           7 :                         if (i->name != j->name) {
     444             :                             std::cerr
     445           0 :                                 << "interface type " << name
     446           0 :                                 << " direct optional base #"
     447           0 :                                 << (i - ent2A->getDirectOptionalBases().begin()
     448           0 :                                     + 1)
     449           0 :                                 << " changed from " << i->name << " to "
     450           0 :                                 << j->name << std::endl;
     451           0 :                             std::exit(EXIT_FAILURE);
     452             :                         }
     453             :                     }
     454        2094 :                     if (ent2A->getDirectAttributes().size()
     455        1047 :                         != ent2B->getDirectAttributes().size())
     456             :                     {
     457             :                         std::cerr
     458           0 :                             << "interface type " << name
     459           0 :                             << " number of direct attributes changed from "
     460           0 :                             << ent2A->getDirectAttributes().size() << " to "
     461           0 :                             << ent2B->getDirectAttributes().size() << std::endl;
     462           0 :                         std::exit(EXIT_FAILURE);
     463             :                     }
     464        3483 :                     for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
     465        1047 :                              i(ent2A->getDirectAttributes().begin()),
     466        1047 :                              j(ent2B->getDirectAttributes().begin());
     467        2322 :                          i != ent2A->getDirectAttributes().end(); ++i, ++j)
     468             :                     {
     469         342 :                         if (i->name != j->name || i->type != j->type
     470         114 :                             || i->bound != j->bound
     471         114 :                             || i->readOnly != j->readOnly
     472         114 :                             || i->getExceptions != j->getExceptions
     473         228 :                             || i->setExceptions != j->setExceptions)
     474             :                         {
     475             :                             std::cerr
     476           0 :                                 << "interface type " << name
     477           0 :                                 << " direct attribute #"
     478           0 :                                 << i - ent2A->getDirectAttributes().begin() + 1
     479           0 :                                 << " changed from "
     480           0 :                                 << (i->bound ? OUString("bound ") : OUString())
     481           0 :                                 << (i->readOnly
     482           0 :                                     ? OUString("read-only ") : OUString())
     483           0 :                                 << i->type << " " << i->name //TODO: exceptions
     484           0 :                                 << " to "
     485           0 :                                 << (j->bound ? OUString("bound ") : OUString())
     486           0 :                                 << (j->readOnly
     487           0 :                                     ? OUString("read-only ") : OUString())
     488           0 :                                 << j->type << " " << j->name //TODO: exceptions
     489           0 :                                 << std::endl;
     490           0 :                             std::exit(EXIT_FAILURE);
     491             :                         }
     492             :                     }
     493        2094 :                     if (ent2A->getDirectMethods().size()
     494        1047 :                         != ent2B->getDirectMethods().size())
     495             :                     {
     496             :                         std::cerr
     497           0 :                             << "interface type " << name
     498           0 :                             << " number of direct methods changed from "
     499           0 :                             << ent2A->getDirectMethods().size() << " to "
     500           0 :                             << ent2B->getDirectMethods().size() << std::endl;
     501           0 :                         std::exit(EXIT_FAILURE);
     502             :                     }
     503       13428 :                     for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
     504        1047 :                              i(ent2A->getDirectMethods().begin()),
     505        1047 :                              j(ent2B->getDirectMethods().begin());
     506        8952 :                          i != ent2A->getDirectMethods().end(); ++i, ++j)
     507             :                     {
     508       10287 :                         if (i->name != j->name || i->returnType != j->returnType
     509        6858 :                             || i->exceptions != j->exceptions)
     510             :                         {
     511             :                             std::cerr
     512           0 :                                 << "interface type " << name
     513           0 :                                 << " direct method #"
     514           0 :                                 << i - ent2A->getDirectMethods().begin() + 1
     515           0 :                                 << " changed from "
     516           0 :                                 << i->returnType << " " << i->name //TODO: exceptions
     517           0 :                                 << " to " << j->returnType << " " << j->name //TODO: exceptions
     518           0 :                                 << std::endl;
     519           0 :                             std::exit(EXIT_FAILURE);
     520             :                         }
     521        3429 :                         if (i->parameters.size() != j->parameters.size()) {
     522             :                             std::cerr
     523           0 :                                 << "interface type " << name
     524           0 :                                 << " direct method " << i->name
     525           0 :                                 << " number of parameters changed from "
     526           0 :                                 << i->parameters.size() << " to "
     527           0 :                                 << j->parameters.size() << std::endl;
     528           0 :                             std::exit(EXIT_FAILURE);
     529             :                         }
     530       20544 :                         for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
     531        3429 :                                  k(i->parameters.begin()),
     532        3429 :                                  l(j->parameters.begin());
     533       13696 :                              k != i->parameters.end(); ++k, ++l)
     534             :                         {
     535        3419 :                             if (k->type != l->type || k->direction != l->direction)
     536             :                             {
     537             :                                 std::cerr
     538           0 :                                     << "interface type " << name
     539           0 :                                     << " direct method " << i->name
     540           0 :                                     << " parameter #"
     541           0 :                                     << k - i->parameters.begin() + 1
     542           0 :                                     << " changed from "
     543           0 :                                     << showDirection(k->direction) << " "
     544           0 :                                     << k->type << " to "
     545           0 :                                     << showDirection(l->direction) << " "
     546           0 :                                     << l->type << std::endl;
     547           0 :                                 std::exit(EXIT_FAILURE);
     548             :                             }
     549        3419 :                             if (k->name != l->name) {
     550             :                                 std::cerr
     551           0 :                                     << "interface type " << name
     552           0 :                                     << " direct method " << i->name
     553           0 :                                     << " parameter #"
     554           0 :                                     << k - i->parameters.begin() + 1
     555           0 :                                     << " changed name from " << k->name
     556           0 :                                     << " to " << l->name << std::endl;
     557           0 :                                 std::exit(EXIT_FAILURE);
     558             :                             }
     559             :                         }
     560             :                     }
     561        2094 :                     break;
     562             :                 }
     563             :             case unoidl::Entity::SORT_TYPEDEF:
     564             :                 {
     565             :                     rtl::Reference<unoidl::TypedefEntity> ent2A(
     566          14 :                         static_cast<unoidl::TypedefEntity *>(entA.get()));
     567             :                     rtl::Reference<unoidl::TypedefEntity> ent2B(
     568          28 :                         static_cast<unoidl::TypedefEntity *>(entB.get()));
     569          14 :                     if (ent2A->getType() != ent2B->getType()) {
     570             :                         std::cerr
     571           0 :                             << "typedef " << name << " type changed from "
     572           0 :                             << ent2A->getType() << " to " << ent2B->getType()
     573           0 :                             << std::endl;
     574           0 :                         std::exit(EXIT_FAILURE);
     575             :                     }
     576          28 :                     break;
     577             :                 }
     578             :             case unoidl::Entity::SORT_CONSTANT_GROUP:
     579             :                 {
     580             :                     rtl::Reference<unoidl::ConstantGroupEntity> ent2A(
     581         206 :                         static_cast<unoidl::ConstantGroupEntity *>(entA.get()));
     582             :                     rtl::Reference<unoidl::ConstantGroupEntity> ent2B(
     583         412 :                         static_cast<unoidl::ConstantGroupEntity *>(entB.get()));
     584        6264 :                     for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
     585         206 :                              i(ent2A->getMembers().begin());
     586        4176 :                          i != ent2A->getMembers().end(); ++i)
     587             :                     {
     588        1882 :                         bool found = false;
     589       95538 :                         for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
     590        1882 :                                  j(ent2B->getMembers().begin());
     591       63692 :                              j != ent2B->getMembers().end(); ++j)
     592             :                         {
     593       31846 :                             if (i->name == j->name) {
     594        1882 :                                 if (i->value != j->value) {
     595             :                                     std::cerr
     596           0 :                                         << "constant group " << name
     597           0 :                                         << " member " << i->name
     598           0 :                                         << " changed value" << std::endl;
     599           0 :                                     std::exit(EXIT_FAILURE);
     600             :                                 }
     601        1882 :                                 found = true;
     602        1882 :                                 break;
     603             :                             }
     604             :                         }
     605        1882 :                         if (!found) {
     606             :                             std::cerr
     607           0 :                                 << "A constant group " << name << " member "
     608           0 :                                 << i->name << " is not present in B"
     609           0 :                                 << std::endl;
     610           0 :                             std::exit(EXIT_FAILURE);
     611             :                         }
     612             :                     }
     613         412 :                     break;
     614             :                 }
     615             :             case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
     616             :                 {
     617             :                     rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
     618             :                         ent2A(
     619             :                             static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
     620         127 :                                 entA.get()));
     621             :                     rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
     622             :                         ent2B(
     623             :                             static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
     624         254 :                                 entB.get()));
     625         127 :                     if (ent2A->getBase() != ent2B->getBase()) {
     626             :                         std::cerr
     627           0 :                             << "single-interface--based servcie " << name
     628           0 :                             << " base changed from " << ent2A->getBase()
     629           0 :                             << " to " << ent2B->getBase()
     630           0 :                             << std::endl;
     631           0 :                         std::exit(EXIT_FAILURE);
     632             :                     }
     633         254 :                     if (ent2A->getConstructors().size()
     634         127 :                         != ent2B->getConstructors().size())
     635             :                     {
     636             :                         std::cerr
     637           0 :                             << "single-interface--based service " << name
     638           0 :                             << " number of constructors changed from "
     639           0 :                             << ent2A->getConstructors().size() << " to "
     640           0 :                             << ent2B->getConstructors().size() << std::endl;
     641           0 :                         std::exit(EXIT_FAILURE);
     642             :                     }
     643         771 :                     for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
     644         127 :                              i(ent2A->getConstructors().begin()),
     645         127 :                              j(ent2B->getConstructors().begin());
     646         514 :                          i != ent2A->getConstructors().end(); ++i, ++j)
     647             :                     {
     648         390 :                         if (i->name != j->name || i->parameters != j->parameters
     649         130 :                             || i->exceptions != j->exceptions
     650         260 :                             || i->defaultConstructor != j->defaultConstructor)
     651             :                         {
     652             :                             std::cerr
     653           0 :                                 << "single-interface--based service " << name
     654           0 :                                 << " constructor #"
     655           0 :                                 << i - ent2A->getConstructors().begin() + 1
     656           0 :                                 << " changed from "
     657           0 :                                 << (i->defaultConstructor
     658           0 :                                     ? OUString("default ") : i->name) //TODO: parameters, exceptions
     659           0 :                                 << " to "
     660           0 :                                 << (j->defaultConstructor
     661           0 :                                     ? OUString("default ") : j->name) //TODO: parameters, exceptions
     662           0 :                                 << std::endl;
     663           0 :                             std::exit(EXIT_FAILURE);
     664             :                         }
     665             :                     }
     666         254 :                     break;
     667             :                 }
     668             :             case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
     669             :                 {
     670             :                     rtl::Reference<unoidl::AccumulationBasedServiceEntity>
     671             :                         ent2A(
     672             :                             static_cast<unoidl::AccumulationBasedServiceEntity *>(
     673         738 :                                 entA.get()));
     674             :                     rtl::Reference<unoidl::AccumulationBasedServiceEntity>
     675             :                         ent2B(
     676             :                             static_cast<unoidl::AccumulationBasedServiceEntity *>(
     677        1476 :                                 entB.get()));
     678        1476 :                     if (ent2A->getDirectMandatoryBaseServices().size()
     679         738 :                         != ent2B->getDirectMandatoryBaseServices().size())
     680             :                     {
     681             :                         std::cerr
     682           0 :                             << "accumulation-based service " << name
     683             :                             << (" number of direct mandatory base services"
     684           0 :                                 " changed from ")
     685           0 :                             << ent2A->getDirectMandatoryBaseServices().size()
     686           0 :                             << " to "
     687           0 :                             << ent2B->getDirectMandatoryBaseServices().size()
     688           0 :                             << std::endl;
     689           0 :                         std::exit(EXIT_FAILURE);
     690             :                     }
     691        3933 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     692         738 :                              i(ent2A->getDirectMandatoryBaseServices().begin()),
     693         738 :                              j(ent2B->getDirectMandatoryBaseServices().begin());
     694        2622 :                          i != ent2A->getDirectMandatoryBaseServices().end();
     695             :                          ++i, ++j)
     696             :                     {
     697         573 :                         if (i->name != j->name) {
     698             :                             std::cerr
     699           0 :                                 << "accumulation-based service " << name
     700           0 :                                 << " direct mandatory base service #"
     701             :                                 << (i
     702           0 :                                     - (ent2A->getDirectMandatoryBaseServices()
     703             :                                        .begin())
     704           0 :                                     + 1)
     705           0 :                                 << " changed from " << i->name << " to "
     706           0 :                                 << j->name << std::endl;
     707           0 :                             std::exit(EXIT_FAILURE);
     708             :                         }
     709             :                     }
     710        1476 :                     if (ent2A->getDirectOptionalBaseServices().size()
     711         738 :                         > ent2B->getDirectOptionalBaseServices().size())
     712             :                     {
     713             :                         std::cerr
     714           0 :                             << "accumulation-based service " << name
     715             :                             << (" number of direct optional base services"
     716           0 :                                 " shrank from ")
     717           0 :                             << ent2A->getDirectOptionalBaseServices().size()
     718           0 :                             << " to "
     719           0 :                             << ent2B->getDirectOptionalBaseServices().size()
     720           0 :                             << std::endl;
     721           0 :                         std::exit(EXIT_FAILURE);
     722             :                     }
     723        2388 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     724         738 :                              i(ent2A->getDirectOptionalBaseServices().begin());
     725        1592 :                          i != ent2A->getDirectOptionalBaseServices().end();
     726             :                          ++i)
     727             :                     {
     728         116 :                         if (std::find_if(
     729          58 :                                 ent2B->getDirectOptionalBaseServices().begin(),
     730          58 :                                 ent2B->getDirectOptionalBaseServices().end(),
     731         232 :                                 EqualsAnnotation(i->name))
     732         232 :                             == ent2B->getDirectOptionalBaseServices().end())
     733             :                         {
     734             :                             std::cerr
     735           0 :                                 << "accumulation-based service " << name
     736           0 :                                 << " direct optional base service " << i->name
     737           0 :                                 << " was removed" << std::endl;
     738           0 :                             std::exit(EXIT_FAILURE);
     739             :                         }
     740             :                     }
     741        1476 :                     if (ent2A->getDirectMandatoryBaseInterfaces().size()
     742         738 :                         != ent2B->getDirectMandatoryBaseInterfaces().size())
     743             :                     {
     744             :                         std::cerr
     745           0 :                             << "accumulation-based service " << name
     746             :                             << (" number of direct mandatory base interfaces"
     747           0 :                                 " changed from ")
     748           0 :                             << ent2A->getDirectMandatoryBaseInterfaces().size()
     749           0 :                             << " to "
     750           0 :                             << ent2B->getDirectMandatoryBaseInterfaces().size()
     751           0 :                             << std::endl;
     752           0 :                         std::exit(EXIT_FAILURE);
     753             :                     }
     754        5175 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     755         738 :                              i(ent2A->getDirectMandatoryBaseInterfaces()
     756         738 :                                .begin()),
     757         738 :                              j(ent2B->getDirectMandatoryBaseInterfaces()
     758         738 :                                .begin());
     759        3450 :                          i != ent2A->getDirectMandatoryBaseInterfaces().end();
     760             :                          ++i, ++j)
     761             :                     {
     762         987 :                         if (i->name != j->name) {
     763             :                             std::cerr
     764           0 :                                 << "accumulation-based service " << name
     765           0 :                                 << " direct mandatory base interface #"
     766             :                                 << (i
     767           0 :                                     - (ent2A->getDirectMandatoryBaseInterfaces()
     768             :                                        .begin())
     769           0 :                                     + 1)
     770           0 :                                 << " changed from " << i->name << " to "
     771           0 :                                 << j->name << std::endl;
     772           0 :                             std::exit(EXIT_FAILURE);
     773             :                         }
     774             :                     }
     775        1476 :                     if (ent2A->getDirectOptionalBaseInterfaces().size()
     776         738 :                         > ent2B->getDirectOptionalBaseInterfaces().size())
     777             :                     {
     778             :                         std::cerr
     779           0 :                             << "accumulation-based service " << name
     780             :                             << (" number of direct optional base interfaces"
     781           0 :                                 " shrank from ")
     782           0 :                             << ent2A->getDirectOptionalBaseInterfaces().size()
     783           0 :                             << " to "
     784           0 :                             << ent2B->getDirectOptionalBaseInterfaces().size()
     785           0 :                             << std::endl;
     786           0 :                         std::exit(EXIT_FAILURE);
     787             :                     }
     788        2952 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     789         738 :                              i(ent2A->getDirectOptionalBaseInterfaces()
     790         738 :                                .begin());
     791        1968 :                          i != ent2A->getDirectOptionalBaseInterfaces().end();
     792             :                          ++i)
     793             :                     {
     794         492 :                         if (std::find_if(
     795         246 :                                 (ent2B->getDirectOptionalBaseInterfaces()
     796             :                                  .begin()),
     797         246 :                                 ent2B->getDirectOptionalBaseInterfaces().end(),
     798         984 :                                 EqualsAnnotation(i->name))
     799         984 :                             == ent2B->getDirectOptionalBaseInterfaces().end())
     800             :                         {
     801             :                             std::cerr
     802           0 :                                 << "accumulation-based service " << name
     803           0 :                                 << " direct optional base interface " << i->name
     804           0 :                                 << " was removed" << std::endl;
     805           0 :                             std::exit(EXIT_FAILURE);
     806             :                         }
     807             :                     }
     808        1476 :                     if (ent2A->getDirectProperties().size()
     809         738 :                         > ent2B->getDirectProperties().size())
     810             :                     {
     811             :                         std::cerr
     812           0 :                             << "accumulation-based service " << name
     813           0 :                             << " number of direct properties changed from "
     814           0 :                             << ent2A->getDirectProperties().size() << " to "
     815           0 :                             << ent2B->getDirectProperties().size() << std::endl;
     816           0 :                         std::exit(EXIT_FAILURE);
     817             :                     }
     818       10197 :                     for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
     819         738 :                              i(ent2A->getDirectProperties().begin()),
     820         738 :                              j(ent2B->getDirectProperties().begin());
     821        6798 :                          i != ent2A->getDirectProperties().end(); ++i, ++j)
     822             :                     {
     823        7983 :                         if (i->name != j->name || i->type != j->type
     824        5322 :                             || i->attributes != j->attributes)
     825             :                         {
     826             :                             std::cerr
     827           0 :                                 << "accumulation-based service " << name
     828           0 :                                 << " direct property #"
     829           0 :                                 << i - ent2A->getDirectProperties().begin() + 1
     830           0 :                                 << " changed from "
     831           0 :                                 << i->type << " " << i->name //TODO: attributes
     832           0 :                                 << " to "
     833           0 :                                 << j->type << " " << j->name //TODO: attributes
     834           0 :                                 << std::endl;
     835           0 :                             std::exit(EXIT_FAILURE);
     836             :                         }
     837             :                     }
     838        2262 :                     for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
     839         738 :                              i(ent2B->getDirectProperties().begin()
     840        1476 :                                + ent2A->getDirectProperties().size());
     841        1508 :                          i != ent2B->getDirectProperties().end(); ++i)
     842             :                     {
     843          16 :                         if ((i->attributes & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL) == 0)
     844             :                         {
     845             :                             std::cerr
     846           0 :                                 << "B accumulation-based service " << name
     847           0 :                                 << " additional direct property " << i->name
     848           0 :                                 << " is not optional" << std::endl;
     849           0 :                             std::exit(EXIT_FAILURE);
     850             :                         }
     851             :                     }
     852        1476 :                     break;
     853             :                 }
     854             :             case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
     855             :                 {
     856             :                     rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2A(
     857             :                         static_cast<unoidl::InterfaceBasedSingletonEntity *>(
     858           3 :                             entA.get()));
     859             :                     rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2B(
     860             :                         static_cast<unoidl::InterfaceBasedSingletonEntity *>(
     861           6 :                             entB.get()));
     862           3 :                     if (ent2A->getBase() != ent2B->getBase()) {
     863             :                         std::cerr
     864           0 :                             << "interface-based singleton " << name
     865           0 :                             << " base changed from " << ent2A->getBase()
     866           0 :                             << " to " << ent2B->getBase() << std::endl;
     867           0 :                         std::exit(EXIT_FAILURE);
     868             :                     }
     869           6 :                     break;
     870             :                 }
     871             :             case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
     872             :                 {
     873             :                     rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2A(
     874             :                         static_cast<unoidl::ServiceBasedSingletonEntity *>(
     875           0 :                             entA.get()));
     876             :                     rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2B(
     877             :                         static_cast<unoidl::ServiceBasedSingletonEntity *>(
     878           0 :                             entB.get()));
     879           0 :                     if (ent2A->getBase() != ent2B->getBase()) {
     880             :                         std::cerr
     881           0 :                             << "service-based singleton " << name
     882           0 :                             << " base changed from " << ent2A->getBase()
     883           0 :                             << " to " << ent2B->getBase() << std::endl;
     884           0 :                         std::exit(EXIT_FAILURE);
     885             :                     }
     886           0 :                     break;
     887             :                 }
     888        2700 :             }
     889             :         }
     890        2777 :     }
     891          79 : }
     892             : 
     893             : }
     894             : 
     895           4 : SAL_IMPLEMENT_MAIN() {
     896             :     try {
     897           2 :         sal_uInt32 args = rtl_getAppCommandArgCount();
     898           6 :         rtl::Reference<unoidl::Manager> mgr[2];
     899           2 :         mgr[0] = new unoidl::Manager;
     900           2 :         mgr[1] = new unoidl::Manager;
     901           4 :         rtl::Reference<unoidl::Provider> prov[2];
     902           2 :         int side = 0;
     903          10 :         for (sal_uInt32 i = 0; i != args; ++i) {
     904           8 :             bool delimiter = false;
     905           8 :             OUString uri(getArgumentUri(i, side == 0 ? &delimiter : 0));
     906           8 :             if (delimiter) {
     907           2 :                 side = 1;
     908             :             } else {
     909             :                 try {
     910           6 :                     prov[side] = unoidl::loadProvider(mgr[side], uri);
     911           0 :                 } catch (unoidl::NoSuchFileException &) {
     912             :                     std::cerr
     913           0 :                         << "Input <" << uri << "> does not exist" << std::endl;
     914           0 :                     std::exit(EXIT_FAILURE);
     915             :                 }
     916           6 :                 mgr[side]->addProvider(prov[side]);
     917             :             }
     918           8 :         }
     919           2 :         if (side == 0 || !(prov[0].is() && prov[1].is())) {
     920           0 :             badUsage();
     921             :         }
     922           2 :         checkMap(prov[1], "", prov[0]->createRootCursor());
     923           8 :         return EXIT_SUCCESS;
     924           0 :     } catch (unoidl::FileFormatException & e1) {
     925             :         std::cerr
     926           0 :             << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
     927           0 :             << std::endl;
     928           0 :         std::exit(EXIT_FAILURE);
     929             :     }
     930           6 : }
     931             : 
     932             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10