LCOV - code coverage report
Current view: top level - unoidl/source - unoidl-check.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 350 748 46.8 %
Date: 2015-06-13 12:38:46 Functions: 15 17 88.2 %
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/character.hxx"
      21             : #include "rtl/process.h"
      22             : #include "rtl/ref.hxx"
      23             : #include "rtl/ustring.hxx"
      24             : #include "sal/main.h"
      25             : #include "sal/types.h"
      26             : #include "unoidl/unoidl.hxx"
      27             : 
      28             : namespace unoidl {
      29             : 
      30        1884 : bool operator ==(ConstantValue const & lhs, ConstantValue const & rhs) {
      31        1884 :     if (lhs.type == rhs.type) {
      32        1884 :         switch (lhs.type) {
      33             :         case ConstantValue::TYPE_BOOLEAN:
      34           0 :             return lhs.booleanValue == rhs.booleanValue;
      35             :         case ConstantValue::TYPE_BYTE:
      36          12 :             return lhs.byteValue == rhs.byteValue;
      37             :         case ConstantValue::TYPE_SHORT:
      38        1170 :             return lhs.shortValue == rhs.shortValue;
      39             :         case ConstantValue::TYPE_UNSIGNED_SHORT:
      40           0 :             return lhs.unsignedShortValue == rhs.unsignedShortValue;
      41             :         case ConstantValue::TYPE_LONG:
      42         653 :             return lhs.longValue == rhs.longValue;
      43             :         case ConstantValue::TYPE_UNSIGNED_LONG:
      44           0 :             return lhs.unsignedLongValue == rhs.unsignedLongValue;
      45             :         case ConstantValue::TYPE_HYPER:
      46          29 :             return lhs.hyperValue == rhs.hyperValue;
      47             :         case ConstantValue::TYPE_UNSIGNED_HYPER:
      48           0 :             return lhs.unsignedHyperValue == rhs.unsignedHyperValue;
      49             :         case ConstantValue::TYPE_FLOAT:
      50          20 :             return lhs.floatValue == rhs.floatValue;
      51             :         case ConstantValue::TYPE_DOUBLE:
      52           0 :             return lhs.doubleValue == rhs.doubleValue;
      53             :         }
      54             :     }
      55           0 :     return false;
      56             : }
      57             : 
      58        1884 : bool operator !=(ConstantValue const & lhs, ConstantValue const & rhs) {
      59        1884 :     return !(lhs == rhs);
      60             : }
      61             : 
      62          31 : bool operator ==(
      63             :     SingleInterfaceBasedServiceEntity::Constructor::Parameter const & lhs,
      64             :     SingleInterfaceBasedServiceEntity::Constructor::Parameter const & rhs)
      65             : {
      66          31 :     return lhs.name == rhs.name && lhs.type == rhs.type && lhs.rest == rhs.rest;
      67             : }
      68             : 
      69             : }
      70             : 
      71             : namespace {
      72             : 
      73           0 : void badUsage() {
      74             :     std::cerr
      75           0 :         << "Usage:" << std::endl << std::endl
      76             :         << ("  unoidl-check [<extra registries A>] <registry A> -- [<extra"
      77           0 :             " registries B>]")
      78           0 :         << std::endl << "    <registry B>" << std::endl << std::endl
      79             :         << ("where each <registry> is either a new- or legacy-format .rdb file,"
      80           0 :             " a single .idl")
      81           0 :         << std::endl
      82             :         << ("file, or a root directory of an .idl file tree.  Check that each"
      83           0 :             " entity from")
      84           0 :         << std::endl
      85           0 :         << "<registry A> is also present in <registry B> in a compatible form."
      86           0 :         << std::endl;
      87           0 :     std::exit(EXIT_FAILURE);
      88             : }
      89             : 
      90           8 : OUString getArgumentUri(sal_uInt32 argument, bool * delimiter) {
      91           8 :     OUString arg;
      92           8 :     rtl_getAppCommandArg(argument, &arg.pData);
      93           8 :     if (arg == "--") {
      94           2 :         if (delimiter == 0) {
      95           0 :             badUsage();
      96             :         }
      97           2 :         *delimiter = true;
      98           2 :         return OUString();
      99             :     }
     100          12 :     OUString url;
     101           6 :     osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
     102           6 :     if (e1 != osl::FileBase::E_None) {
     103             :         std::cerr
     104           0 :             << "Cannot convert \"" << arg << "\" to file URL, error code "
     105           0 :             << +e1 << std::endl;
     106           0 :         std::exit(EXIT_FAILURE);
     107             :     }
     108          12 :     OUString cwd;
     109           6 :     oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
     110           6 :     if (e2 != osl_Process_E_None) {
     111             :         std::cerr
     112           0 :             << "Cannot obtain working directory, error code " << +e2
     113           0 :             << std::endl;
     114           0 :         std::exit(EXIT_FAILURE);
     115             :     }
     116          12 :     OUString abs;
     117           6 :     e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
     118           6 :     if (e1 != osl::FileBase::E_None) {
     119             :         std::cerr
     120           0 :             << "Cannot make \"" << url
     121           0 :             << "\" into an absolute file URL, error code " << +e1 << std::endl;
     122           0 :         std::exit(EXIT_FAILURE);
     123             :     }
     124          14 :     return abs;
     125             : }
     126             : 
     127           0 : OUString showDirection(
     128             :     unoidl::InterfaceTypeEntity::Method::Parameter::Direction direction)
     129             : {
     130           0 :     switch (direction) {
     131             :     case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN:
     132           0 :         return OUString("[in]");
     133             :     case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT:
     134           0 :         return OUString("[out]");
     135             :     case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT:
     136           0 :         return OUString("[inout]");
     137             :     default:
     138           0 :         assert(false && "this cannot happen"); for (;;) { std::abort(); }
     139             :     }
     140             : }
     141             : 
     142         915 : struct EqualsAnnotation {
     143         305 :     explicit EqualsAnnotation(OUString const & name): name_(name) {}
     144             : 
     145         692 :     bool operator ()(unoidl::AnnotatedReference const & ref)
     146         692 :     { return ref.name == name_; }
     147             : 
     148             : private:
     149             :     OUString name_;
     150             : };
     151             : 
     152        2860 : void checkMap(
     153             :     rtl::Reference<unoidl::Provider> const & providerB, OUString const & prefix,
     154             :     rtl::Reference<unoidl::MapCursor> const & cursor)
     155             : {
     156             :     assert(providerB.is());
     157             :     assert(cursor.is());
     158             :     for (;;) {
     159        2860 :         OUString id;
     160        5641 :         rtl::Reference<unoidl::Entity> entA(cursor->getNext(&id));
     161        2860 :         if (!entA.is()) {
     162          79 :             break;
     163             :         }
     164        5562 :         OUString name(prefix + id);
     165        2781 :         if (entA->getSort() == unoidl::Entity::SORT_MODULE) {
     166             :             checkMap(
     167         154 :                 providerB, name + ".",
     168          77 :                 (static_cast<unoidl::ModuleEntity *>(entA.get())
     169         231 :                  ->createCursor()));
     170             :         } else {
     171        2704 :             rtl::Reference<unoidl::Entity> entB(providerB->findEntity(name));
     172        2704 :             if (!entB.is()) {
     173             :                 std::cerr
     174           0 :                     << "A entity " << name << " is not present in B"
     175           0 :                     << std::endl;
     176           0 :                 std::exit(EXIT_FAILURE);
     177             :             }
     178        2704 :             if (entA->getSort() != entB->getSort()) {
     179             :                 std::cerr
     180           0 :                     << "A entity " << name << " is of different sort in B"
     181           0 :                     << std::endl;
     182           0 :                 std::exit(EXIT_FAILURE);
     183             :             }
     184        5408 :             if ((dynamic_cast<unoidl::PublishableEntity &>(*entA.get())
     185        2704 :                  .isPublished())
     186        5395 :                 && (!dynamic_cast<unoidl::PublishableEntity &>(*entB.get())
     187        2691 :                     .isPublished()))
     188             :             {
     189             :                 std::cerr
     190           0 :                     << "A published entity " << name << " is not published in B"
     191           0 :                     << std::endl;
     192           0 :                 std::exit(EXIT_FAILURE);
     193             :             }
     194        2704 :             switch (entA->getSort()) {
     195             :             case unoidl::Entity::SORT_MODULE:
     196             :                 assert(false && "this cannot happen");
     197             :                 //deliberate fall-through anyway
     198             :             case unoidl::Entity::SORT_ENUM_TYPE:
     199             :                 {
     200             :                     rtl::Reference<unoidl::EnumTypeEntity> ent2A(
     201         157 :                         static_cast<unoidl::EnumTypeEntity *>(entA.get()));
     202             :                     rtl::Reference<unoidl::EnumTypeEntity> ent2B(
     203         314 :                         static_cast<unoidl::EnumTypeEntity *>(entB.get()));
     204         314 :                     if (ent2A->getMembers().size()
     205         157 :                         != ent2B->getMembers().size())
     206             :                     {
     207             :                         std::cerr
     208           0 :                             << "enum type " << name
     209           0 :                             << " number of members changed from "
     210           0 :                             << ent2A->getMembers().size() << " to "
     211           0 :                             << ent2B->getMembers().size() << std::endl;
     212           0 :                         std::exit(EXIT_FAILURE);
     213             :                     }
     214        3747 :                     for (std::vector<unoidl::EnumTypeEntity::Member>::const_iterator
     215         157 :                              i(ent2A->getMembers().begin()),
     216         157 :                              j(ent2B->getMembers().begin());
     217        2498 :                          i != ent2A->getMembers().end(); ++i, ++j)
     218             :                     {
     219        1092 :                         if (i->name != j->name || i->value != j->value) {
     220             :                             std::cerr
     221           0 :                                 << "enum type " << name << " member #"
     222           0 :                                 << i - ent2A->getMembers().begin() + 1
     223           0 :                                 << " changed from " << i->name << " = "
     224           0 :                                 << i->value << " to " << j->name << " = "
     225           0 :                                 << j->value << std::endl;
     226           0 :                             std::exit(EXIT_FAILURE);
     227             :                         }
     228             :                     }
     229         314 :                     break;
     230             :                 }
     231             :             case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
     232             :                 {
     233             :                     rtl::Reference<unoidl::PlainStructTypeEntity> ent2A(
     234             :                         static_cast<unoidl::PlainStructTypeEntity *>(
     235         236 :                             entA.get()));
     236             :                     rtl::Reference<unoidl::PlainStructTypeEntity> ent2B(
     237             :                         static_cast<unoidl::PlainStructTypeEntity *>(
     238         472 :                             entB.get()));
     239         236 :                     if (ent2A->getDirectBase() != ent2B->getDirectBase()) {
     240             :                         std::cerr
     241           0 :                             << "plain struct type " << name
     242           0 :                             << " direct base changed from "
     243           0 :                             << (ent2A->getDirectBase().isEmpty()
     244           0 :                                 ? OUString("none") : ent2A->getDirectBase())
     245           0 :                             << " to "
     246           0 :                             << (ent2B->getDirectBase().isEmpty()
     247           0 :                                 ? OUString("none") : ent2B->getDirectBase())
     248           0 :                             << std::endl;
     249           0 :                         std::exit(EXIT_FAILURE);
     250             :                     }
     251         472 :                     if (ent2A->getDirectMembers().size()
     252         236 :                         != ent2B->getDirectMembers().size())
     253             :                     {
     254             :                         std::cerr
     255           0 :                             << "plain struct type " << name
     256           0 :                             << " number of direct members changed from "
     257           0 :                             << ent2A->getDirectMembers().size() << " to "
     258           0 :                             << ent2B->getDirectMembers().size() << std::endl;
     259           0 :                         std::exit(EXIT_FAILURE);
     260             :                     }
     261        3216 :                     for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
     262         236 :                              i(ent2A->getDirectMembers().begin()),
     263         236 :                              j(ent2B->getDirectMembers().begin());
     264        2144 :                          i != ent2A->getDirectMembers().end(); ++i, ++j)
     265             :                     {
     266         836 :                         if (i->name != j->name || i->type != j->type) {
     267             :                             std::cerr
     268           0 :                                 << "plain struct type " << name
     269           0 :                                 << " direct member #"
     270           0 :                                 << i - ent2A->getDirectMembers().begin() + 1
     271           0 :                                 << " changed from " << i->type << " " << i->name
     272           0 :                                 << " to " << j->type << " " << j->name
     273           0 :                                 << std::endl;
     274           0 :                             std::exit(EXIT_FAILURE);
     275             :                         }
     276             :                     }
     277         472 :                     break;
     278             :                 }
     279             :             case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
     280             :                 {
     281             :                     rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
     282             :                         ent2A(
     283             :                             static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
     284           0 :                                 entA.get()));
     285             :                     rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
     286             :                         ent2B(
     287             :                             static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
     288           0 :                                 entB.get()));
     289           0 :                     if (ent2A->getTypeParameters().size()
     290           0 :                         != ent2B->getTypeParameters().size())
     291             :                     {
     292             :                         std::cerr
     293           0 :                             << "polymorphic struct type template " << name
     294           0 :                             << " number of type parameters changed from "
     295           0 :                             << ent2A->getTypeParameters().size() << " to "
     296           0 :                             << ent2B->getTypeParameters().size() << std::endl;
     297           0 :                         std::exit(EXIT_FAILURE);
     298             :                     }
     299           0 :                     for (std::vector<OUString>::const_iterator
     300           0 :                              i(ent2A->getTypeParameters().begin()),
     301           0 :                              j(ent2B->getTypeParameters().begin());
     302           0 :                          i != ent2A->getTypeParameters().end(); ++i, ++j)
     303             :                     {
     304           0 :                         if (*i != *j) {
     305             :                             std::cerr
     306           0 :                                 << "polymorphic struct type template " << name
     307           0 :                                 << " type parameter #"
     308           0 :                                 << i - ent2A->getTypeParameters().begin() + 1
     309           0 :                                 << " changed from " << *i << " to " << *j
     310           0 :                                 << std::endl;
     311           0 :                             std::exit(EXIT_FAILURE);
     312             :                         }
     313             :                     }
     314           0 :                     if (ent2A->getMembers().size()
     315           0 :                         != ent2B->getMembers().size())
     316             :                     {
     317             :                         std::cerr
     318           0 :                             << "polymorphic struct type template " << name
     319           0 :                             << " number of members changed from "
     320           0 :                             << ent2A->getMembers().size() << " to "
     321           0 :                             << ent2B->getMembers().size() << std::endl;
     322           0 :                         std::exit(EXIT_FAILURE);
     323             :                     }
     324           0 :                     for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
     325           0 :                              i(ent2A->getMembers().begin()),
     326           0 :                              j(ent2B->getMembers().begin());
     327           0 :                          i != ent2A->getMembers().end(); ++i, ++j)
     328             :                     {
     329           0 :                         if (i->name != j->name || i->type != j->type
     330           0 :                             || i->parameterized != j->parameterized)
     331             :                         {
     332             :                             std::cerr
     333           0 :                                 << "polymorphic struct type template " << name
     334           0 :                                 << " member #"
     335           0 :                                 << i - ent2A->getMembers().begin() + 1
     336           0 :                                 << " changed from "
     337           0 :                                 << (i->parameterized
     338           0 :                                     ? OUString("parameterized ") : OUString())
     339           0 :                                 << i->type << " " << i->name
     340           0 :                                 << " to "
     341           0 :                                 << (j->parameterized
     342           0 :                                     ? OUString("parameterized ") : OUString())
     343           0 :                                 << j->type << " " << j->name
     344           0 :                                 << std::endl;
     345           0 :                             std::exit(EXIT_FAILURE);
     346             :                         }
     347             :                     }
     348           0 :                     break;
     349             :                 }
     350             :             case unoidl::Entity::SORT_EXCEPTION_TYPE:
     351             :                 {
     352             :                     rtl::Reference<unoidl::ExceptionTypeEntity> ent2A(
     353         172 :                         static_cast<unoidl::ExceptionTypeEntity *>(entA.get()));
     354             :                     rtl::Reference<unoidl::ExceptionTypeEntity> ent2B(
     355         344 :                         static_cast<unoidl::ExceptionTypeEntity *>(entB.get()));
     356         172 :                     if (ent2A->getDirectBase() != ent2B->getDirectBase()) {
     357             :                         std::cerr
     358           0 :                             << "exception type " << name
     359           0 :                             << " direct base changed from "
     360           0 :                             << (ent2A->getDirectBase().isEmpty()
     361           0 :                                 ? OUString("none") : ent2A->getDirectBase())
     362           0 :                             << " to "
     363           0 :                             << (ent2B->getDirectBase().isEmpty()
     364           0 :                                 ? OUString("none") : ent2B->getDirectBase())
     365           0 :                             << std::endl;
     366           0 :                         std::exit(EXIT_FAILURE);
     367             :                     }
     368         344 :                     if (ent2A->getDirectMembers().size()
     369         172 :                         != ent2B->getDirectMembers().size())
     370             :                     {
     371             :                         std::cerr
     372           0 :                             << "exception type " << name
     373           0 :                             << " number of direct members changed from "
     374           0 :                             << ent2A->getDirectMembers().size() << " to "
     375           0 :                             << ent2B->getDirectMembers().size() << std::endl;
     376           0 :                         std::exit(EXIT_FAILURE);
     377             :                     }
     378         822 :                     for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
     379         172 :                              i(ent2A->getDirectMembers().begin()),
     380         172 :                              j(ent2B->getDirectMembers().begin());
     381         548 :                          i != ent2A->getDirectMembers().end(); ++i, ++j)
     382             :                     {
     383         102 :                         if (i->name != j->name || i->type != j->type) {
     384             :                             std::cerr
     385           0 :                                 << "exception type " << name
     386           0 :                                 << " direct member #"
     387           0 :                                 << i - ent2A->getDirectMembers().begin() + 1
     388           0 :                                 << " changed from " << i->type << " " << i->name
     389           0 :                                 << " to " << j->type << " " << j->name
     390           0 :                                 << std::endl;
     391           0 :                             std::exit(EXIT_FAILURE);
     392             :                         }
     393             :                     }
     394         344 :                     break;
     395             :                 }
     396             :             case unoidl::Entity::SORT_INTERFACE_TYPE:
     397             :                 {
     398             :                     rtl::Reference<unoidl::InterfaceTypeEntity> ent2A(
     399        1047 :                         static_cast<unoidl::InterfaceTypeEntity *>(entA.get()));
     400             :                     rtl::Reference<unoidl::InterfaceTypeEntity> ent2B(
     401        2094 :                         static_cast<unoidl::InterfaceTypeEntity *>(entB.get()));
     402        2094 :                     if (ent2A->getDirectMandatoryBases().size()
     403        1047 :                         != ent2B->getDirectMandatoryBases().size())
     404             :                     {
     405             :                         std::cerr
     406           0 :                             << "interface type " << name
     407           0 :                             << " number of direct mandatory bases changed from "
     408           0 :                             << ent2A->getDirectMandatoryBases().size() << " to "
     409           0 :                             << ent2B->getDirectMandatoryBases().size()
     410           0 :                             << std::endl;
     411           0 :                         std::exit(EXIT_FAILURE);
     412             :                     }
     413        6552 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     414        1047 :                              i(ent2A->getDirectMandatoryBases().begin()),
     415        1047 :                              j(ent2B->getDirectMandatoryBases().begin());
     416        4368 :                          i != ent2A->getDirectMandatoryBases().end(); ++i, ++j)
     417             :                     {
     418        1137 :                         if (i->name != j->name) {
     419             :                             std::cerr
     420           0 :                                 << "interface type " << name
     421           0 :                                 << " direct mandatory base #"
     422           0 :                                 << (i - ent2A->getDirectMandatoryBases().begin()
     423           0 :                                     + 1)
     424           0 :                                 << " changed from " << i->name << " to "
     425           0 :                                 << j->name << std::endl;
     426           0 :                             std::exit(EXIT_FAILURE);
     427             :                         }
     428             :                     }
     429        2094 :                     if (ent2A->getDirectOptionalBases().size()
     430        1047 :                         != ent2B->getDirectOptionalBases().size())
     431             :                     {
     432             :                         std::cerr
     433           0 :                             << "interface type " << name
     434           0 :                             << " number of direct optional bases changed from "
     435           0 :                             << ent2A->getDirectOptionalBases().size() << " to "
     436           0 :                             << ent2B->getDirectOptionalBases().size()
     437           0 :                             << std::endl;
     438           0 :                         std::exit(EXIT_FAILURE);
     439             :                     }
     440        3162 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     441        1047 :                              i(ent2A->getDirectOptionalBases().begin()),
     442        1047 :                              j(ent2B->getDirectOptionalBases().begin());
     443        2108 :                          i != ent2A->getDirectOptionalBases().end(); ++i, ++j)
     444             :                     {
     445           7 :                         if (i->name != j->name) {
     446             :                             std::cerr
     447           0 :                                 << "interface type " << name
     448           0 :                                 << " direct optional base #"
     449           0 :                                 << (i - ent2A->getDirectOptionalBases().begin()
     450           0 :                                     + 1)
     451           0 :                                 << " changed from " << i->name << " to "
     452           0 :                                 << j->name << std::endl;
     453           0 :                             std::exit(EXIT_FAILURE);
     454             :                         }
     455             :                     }
     456        2094 :                     if (ent2A->getDirectAttributes().size()
     457        1047 :                         != ent2B->getDirectAttributes().size())
     458             :                     {
     459             :                         std::cerr
     460           0 :                             << "interface type " << name
     461           0 :                             << " number of direct attributes changed from "
     462           0 :                             << ent2A->getDirectAttributes().size() << " to "
     463           0 :                             << ent2B->getDirectAttributes().size() << std::endl;
     464           0 :                         std::exit(EXIT_FAILURE);
     465             :                     }
     466        3483 :                     for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
     467        1047 :                              i(ent2A->getDirectAttributes().begin()),
     468        1047 :                              j(ent2B->getDirectAttributes().begin());
     469        2322 :                          i != ent2A->getDirectAttributes().end(); ++i, ++j)
     470             :                     {
     471         342 :                         if (i->name != j->name || i->type != j->type
     472         114 :                             || i->bound != j->bound
     473         114 :                             || i->readOnly != j->readOnly
     474         114 :                             || i->getExceptions != j->getExceptions
     475         228 :                             || i->setExceptions != j->setExceptions)
     476             :                         {
     477             :                             std::cerr
     478           0 :                                 << "interface type " << name
     479           0 :                                 << " direct attribute #"
     480           0 :                                 << i - ent2A->getDirectAttributes().begin() + 1
     481           0 :                                 << " changed from "
     482           0 :                                 << (i->bound ? OUString("bound ") : OUString())
     483           0 :                                 << (i->readOnly
     484           0 :                                     ? OUString("read-only ") : OUString())
     485           0 :                                 << i->type << " " << i->name //TODO: exceptions
     486           0 :                                 << " to "
     487           0 :                                 << (j->bound ? OUString("bound ") : OUString())
     488           0 :                                 << (j->readOnly
     489           0 :                                     ? OUString("read-only ") : OUString())
     490           0 :                                 << j->type << " " << j->name //TODO: exceptions
     491           0 :                                 << std::endl;
     492           0 :                             std::exit(EXIT_FAILURE);
     493             :                         }
     494             :                     }
     495        2094 :                     if (ent2A->getDirectMethods().size()
     496        1047 :                         != ent2B->getDirectMethods().size())
     497             :                     {
     498             :                         std::cerr
     499           0 :                             << "interface type " << name
     500           0 :                             << " number of direct methods changed from "
     501           0 :                             << ent2A->getDirectMethods().size() << " to "
     502           0 :                             << ent2B->getDirectMethods().size() << std::endl;
     503           0 :                         std::exit(EXIT_FAILURE);
     504             :                     }
     505       13428 :                     for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
     506        1047 :                              i(ent2A->getDirectMethods().begin()),
     507        1047 :                              j(ent2B->getDirectMethods().begin());
     508        8952 :                          i != ent2A->getDirectMethods().end(); ++i, ++j)
     509             :                     {
     510       10287 :                         if (i->name != j->name || i->returnType != j->returnType
     511        6858 :                             || i->exceptions != j->exceptions)
     512             :                         {
     513             :                             std::cerr
     514           0 :                                 << "interface type " << name
     515           0 :                                 << " direct method #"
     516           0 :                                 << i - ent2A->getDirectMethods().begin() + 1
     517           0 :                                 << " changed from "
     518           0 :                                 << i->returnType << " " << i->name //TODO: exceptions
     519           0 :                                 << " to " << j->returnType << " " << j->name //TODO: exceptions
     520           0 :                                 << std::endl;
     521           0 :                             std::exit(EXIT_FAILURE);
     522             :                         }
     523        3429 :                         if (i->parameters.size() != j->parameters.size()) {
     524             :                             std::cerr
     525           0 :                                 << "interface type " << name
     526           0 :                                 << " direct method " << i->name
     527           0 :                                 << " number of parameters changed from "
     528           0 :                                 << i->parameters.size() << " to "
     529           0 :                                 << j->parameters.size() << std::endl;
     530           0 :                             std::exit(EXIT_FAILURE);
     531             :                         }
     532       20544 :                         for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
     533        3429 :                                  k(i->parameters.begin()),
     534        3429 :                                  l(j->parameters.begin());
     535       13696 :                              k != i->parameters.end(); ++k, ++l)
     536             :                         {
     537        3419 :                             if (k->type != l->type || k->direction != l->direction)
     538             :                             {
     539             :                                 std::cerr
     540           0 :                                     << "interface type " << name
     541           0 :                                     << " direct method " << i->name
     542           0 :                                     << " parameter #"
     543           0 :                                     << k - i->parameters.begin() + 1
     544           0 :                                     << " changed from "
     545           0 :                                     << showDirection(k->direction) << " "
     546           0 :                                     << k->type << " to "
     547           0 :                                     << showDirection(l->direction) << " "
     548           0 :                                     << l->type << std::endl;
     549           0 :                                 std::exit(EXIT_FAILURE);
     550             :                             }
     551        3419 :                             if (k->name != l->name) {
     552             :                                 std::cerr
     553           0 :                                     << "interface type " << name
     554           0 :                                     << " direct method " << i->name
     555           0 :                                     << " parameter #"
     556           0 :                                     << k - i->parameters.begin() + 1
     557           0 :                                     << " changed name from " << k->name
     558           0 :                                     << " to " << l->name << std::endl;
     559           0 :                                 std::exit(EXIT_FAILURE);
     560             :                             }
     561             :                         }
     562             :                     }
     563        2094 :                     break;
     564             :                 }
     565             :             case unoidl::Entity::SORT_TYPEDEF:
     566             :                 {
     567             :                     rtl::Reference<unoidl::TypedefEntity> ent2A(
     568          14 :                         static_cast<unoidl::TypedefEntity *>(entA.get()));
     569             :                     rtl::Reference<unoidl::TypedefEntity> ent2B(
     570          28 :                         static_cast<unoidl::TypedefEntity *>(entB.get()));
     571          14 :                     if (ent2A->getType() != ent2B->getType()) {
     572             :                         std::cerr
     573           0 :                             << "typedef " << name << " type changed from "
     574           0 :                             << ent2A->getType() << " to " << ent2B->getType()
     575           0 :                             << std::endl;
     576           0 :                         std::exit(EXIT_FAILURE);
     577             :                     }
     578          28 :                     break;
     579             :                 }
     580             :             case unoidl::Entity::SORT_CONSTANT_GROUP:
     581             :                 {
     582             :                     rtl::Reference<unoidl::ConstantGroupEntity> ent2A(
     583         206 :                         static_cast<unoidl::ConstantGroupEntity *>(entA.get()));
     584             :                     rtl::Reference<unoidl::ConstantGroupEntity> ent2B(
     585         412 :                         static_cast<unoidl::ConstantGroupEntity *>(entB.get()));
     586        6270 :                     for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
     587         206 :                              i(ent2A->getMembers().begin());
     588        4180 :                          i != ent2A->getMembers().end(); ++i)
     589             :                     {
     590        1884 :                         bool found = false;
     591       95967 :                         for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
     592        1884 :                                  j(ent2B->getMembers().begin());
     593       63978 :                              j != ent2B->getMembers().end(); ++j)
     594             :                         {
     595       31989 :                             if (i->name == j->name) {
     596        1884 :                                 if (i->value != j->value) {
     597             :                                     std::cerr
     598           0 :                                         << "constant group " << name
     599           0 :                                         << " member " << i->name
     600           0 :                                         << " changed value" << std::endl;
     601           0 :                                     std::exit(EXIT_FAILURE);
     602             :                                 }
     603        1884 :                                 found = true;
     604        1884 :                                 break;
     605             :                             }
     606             :                         }
     607        1884 :                         if (!found) {
     608             :                             std::cerr
     609           0 :                                 << "A constant group " << name << " member "
     610           0 :                                 << i->name << " is not present in B"
     611           0 :                                 << std::endl;
     612           0 :                             std::exit(EXIT_FAILURE);
     613             :                         }
     614             :                     }
     615         412 :                     break;
     616             :                 }
     617             :             case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
     618             :                 {
     619             :                     rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
     620             :                         ent2A(
     621             :                             static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
     622         127 :                                 entA.get()));
     623             :                     rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
     624             :                         ent2B(
     625             :                             static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
     626         254 :                                 entB.get()));
     627         127 :                     if (ent2A->getBase() != ent2B->getBase()) {
     628             :                         std::cerr
     629           0 :                             << "single-interface--based servcie " << name
     630           0 :                             << " base changed from " << ent2A->getBase()
     631           0 :                             << " to " << ent2B->getBase()
     632           0 :                             << std::endl;
     633           0 :                         std::exit(EXIT_FAILURE);
     634             :                     }
     635         254 :                     if (ent2A->getConstructors().size()
     636         127 :                         != ent2B->getConstructors().size())
     637             :                     {
     638             :                         std::cerr
     639           0 :                             << "single-interface--based service " << name
     640           0 :                             << " number of constructors changed from "
     641           0 :                             << ent2A->getConstructors().size() << " to "
     642           0 :                             << ent2B->getConstructors().size() << std::endl;
     643           0 :                         std::exit(EXIT_FAILURE);
     644             :                     }
     645         771 :                     for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
     646         127 :                              i(ent2A->getConstructors().begin()),
     647         127 :                              j(ent2B->getConstructors().begin());
     648         514 :                          i != ent2A->getConstructors().end(); ++i, ++j)
     649             :                     {
     650         390 :                         if (i->name != j->name || i->parameters != j->parameters
     651         130 :                             || i->exceptions != j->exceptions
     652         260 :                             || i->defaultConstructor != j->defaultConstructor)
     653             :                         {
     654             :                             std::cerr
     655           0 :                                 << "single-interface--based service " << name
     656           0 :                                 << " constructor #"
     657           0 :                                 << i - ent2A->getConstructors().begin() + 1
     658           0 :                                 << " changed from "
     659           0 :                                 << (i->defaultConstructor
     660           0 :                                     ? OUString("default ") : i->name) //TODO: parameters, exceptions
     661           0 :                                 << " to "
     662           0 :                                 << (j->defaultConstructor
     663           0 :                                     ? OUString("default ") : j->name) //TODO: parameters, exceptions
     664           0 :                                 << std::endl;
     665           0 :                             std::exit(EXIT_FAILURE);
     666             :                         }
     667             :                     }
     668         254 :                     break;
     669             :                 }
     670             :             case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
     671             :                 {
     672             :                     rtl::Reference<unoidl::AccumulationBasedServiceEntity>
     673             :                         ent2A(
     674             :                             static_cast<unoidl::AccumulationBasedServiceEntity *>(
     675         738 :                                 entA.get()));
     676             :                     rtl::Reference<unoidl::AccumulationBasedServiceEntity>
     677             :                         ent2B(
     678             :                             static_cast<unoidl::AccumulationBasedServiceEntity *>(
     679        1476 :                                 entB.get()));
     680        1476 :                     if (ent2A->getDirectMandatoryBaseServices().size()
     681         738 :                         != ent2B->getDirectMandatoryBaseServices().size())
     682             :                     {
     683             :                         std::cerr
     684           0 :                             << "accumulation-based service " << name
     685             :                             << (" number of direct mandatory base services"
     686           0 :                                 " changed from ")
     687           0 :                             << ent2A->getDirectMandatoryBaseServices().size()
     688           0 :                             << " to "
     689           0 :                             << ent2B->getDirectMandatoryBaseServices().size()
     690           0 :                             << std::endl;
     691           0 :                         std::exit(EXIT_FAILURE);
     692             :                     }
     693        3933 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     694         738 :                              i(ent2A->getDirectMandatoryBaseServices().begin()),
     695         738 :                              j(ent2B->getDirectMandatoryBaseServices().begin());
     696        2622 :                          i != ent2A->getDirectMandatoryBaseServices().end();
     697             :                          ++i, ++j)
     698             :                     {
     699         573 :                         if (i->name != j->name) {
     700             :                             std::cerr
     701           0 :                                 << "accumulation-based service " << name
     702           0 :                                 << " direct mandatory base service #"
     703             :                                 << (i
     704           0 :                                     - (ent2A->getDirectMandatoryBaseServices()
     705             :                                        .begin())
     706           0 :                                     + 1)
     707           0 :                                 << " changed from " << i->name << " to "
     708           0 :                                 << j->name << std::endl;
     709           0 :                             std::exit(EXIT_FAILURE);
     710             :                         }
     711             :                     }
     712        1476 :                     if (ent2A->getDirectOptionalBaseServices().size()
     713         738 :                         > ent2B->getDirectOptionalBaseServices().size())
     714             :                     {
     715             :                         std::cerr
     716           0 :                             << "accumulation-based service " << name
     717             :                             << (" number of direct optional base services"
     718           0 :                                 " shrank from ")
     719           0 :                             << ent2A->getDirectOptionalBaseServices().size()
     720           0 :                             << " to "
     721           0 :                             << ent2B->getDirectOptionalBaseServices().size()
     722           0 :                             << std::endl;
     723           0 :                         std::exit(EXIT_FAILURE);
     724             :                     }
     725        2388 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     726         738 :                              i(ent2A->getDirectOptionalBaseServices().begin());
     727        1592 :                          i != ent2A->getDirectOptionalBaseServices().end();
     728             :                          ++i)
     729             :                     {
     730         116 :                         if (std::find_if(
     731          58 :                                 ent2B->getDirectOptionalBaseServices().begin(),
     732          58 :                                 ent2B->getDirectOptionalBaseServices().end(),
     733         232 :                                 EqualsAnnotation(i->name))
     734         232 :                             == ent2B->getDirectOptionalBaseServices().end())
     735             :                         {
     736             :                             std::cerr
     737           0 :                                 << "accumulation-based service " << name
     738           0 :                                 << " direct optional base service " << i->name
     739           0 :                                 << " was removed" << std::endl;
     740           0 :                             std::exit(EXIT_FAILURE);
     741             :                         }
     742             :                     }
     743        1476 :                     if (ent2A->getDirectMandatoryBaseInterfaces().size()
     744         738 :                         != ent2B->getDirectMandatoryBaseInterfaces().size())
     745             :                     {
     746             :                         std::cerr
     747           0 :                             << "accumulation-based service " << name
     748             :                             << (" number of direct mandatory base interfaces"
     749           0 :                                 " changed from ")
     750           0 :                             << ent2A->getDirectMandatoryBaseInterfaces().size()
     751           0 :                             << " to "
     752           0 :                             << ent2B->getDirectMandatoryBaseInterfaces().size()
     753           0 :                             << std::endl;
     754           0 :                         std::exit(EXIT_FAILURE);
     755             :                     }
     756        5175 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     757         738 :                              i(ent2A->getDirectMandatoryBaseInterfaces()
     758         738 :                                .begin()),
     759         738 :                              j(ent2B->getDirectMandatoryBaseInterfaces()
     760         738 :                                .begin());
     761        3450 :                          i != ent2A->getDirectMandatoryBaseInterfaces().end();
     762             :                          ++i, ++j)
     763             :                     {
     764         987 :                         if (i->name != j->name) {
     765             :                             std::cerr
     766           0 :                                 << "accumulation-based service " << name
     767           0 :                                 << " direct mandatory base interface #"
     768             :                                 << (i
     769           0 :                                     - (ent2A->getDirectMandatoryBaseInterfaces()
     770             :                                        .begin())
     771           0 :                                     + 1)
     772           0 :                                 << " changed from " << i->name << " to "
     773           0 :                                 << j->name << std::endl;
     774           0 :                             std::exit(EXIT_FAILURE);
     775             :                         }
     776             :                     }
     777        1476 :                     if (ent2A->getDirectOptionalBaseInterfaces().size()
     778         738 :                         > ent2B->getDirectOptionalBaseInterfaces().size())
     779             :                     {
     780             :                         std::cerr
     781           0 :                             << "accumulation-based service " << name
     782             :                             << (" number of direct optional base interfaces"
     783           0 :                                 " shrank from ")
     784           0 :                             << ent2A->getDirectOptionalBaseInterfaces().size()
     785           0 :                             << " to "
     786           0 :                             << ent2B->getDirectOptionalBaseInterfaces().size()
     787           0 :                             << std::endl;
     788           0 :                         std::exit(EXIT_FAILURE);
     789             :                     }
     790        2955 :                     for (std::vector<unoidl::AnnotatedReference>::const_iterator
     791         738 :                              i(ent2A->getDirectOptionalBaseInterfaces()
     792         738 :                                .begin());
     793        1970 :                          i != ent2A->getDirectOptionalBaseInterfaces().end();
     794             :                          ++i)
     795             :                     {
     796         494 :                         if (std::find_if(
     797         247 :                                 (ent2B->getDirectOptionalBaseInterfaces()
     798             :                                  .begin()),
     799         247 :                                 ent2B->getDirectOptionalBaseInterfaces().end(),
     800         988 :                                 EqualsAnnotation(i->name))
     801         988 :                             == ent2B->getDirectOptionalBaseInterfaces().end())
     802             :                         {
     803             :                             std::cerr
     804           0 :                                 << "accumulation-based service " << name
     805           0 :                                 << " direct optional base interface " << i->name
     806           0 :                                 << " was removed" << std::endl;
     807           0 :                             std::exit(EXIT_FAILURE);
     808             :                         }
     809             :                     }
     810        1476 :                     if (ent2A->getDirectProperties().size()
     811         738 :                         > ent2B->getDirectProperties().size())
     812             :                     {
     813             :                         std::cerr
     814           0 :                             << "accumulation-based service " << name
     815           0 :                             << " number of direct properties changed from "
     816           0 :                             << ent2A->getDirectProperties().size() << " to "
     817           0 :                             << ent2B->getDirectProperties().size() << std::endl;
     818           0 :                         std::exit(EXIT_FAILURE);
     819             :                     }
     820       10248 :                     for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
     821         738 :                              i(ent2A->getDirectProperties().begin()),
     822         738 :                              j(ent2B->getDirectProperties().begin());
     823        6832 :                          i != ent2A->getDirectProperties().end(); ++i, ++j)
     824             :                     {
     825        8034 :                         if (i->name != j->name || i->type != j->type
     826        5356 :                             || i->attributes != j->attributes)
     827             :                         {
     828             :                             std::cerr
     829           0 :                                 << "accumulation-based service " << name
     830           0 :                                 << " direct property #"
     831           0 :                                 << i - ent2A->getDirectProperties().begin() + 1
     832           0 :                                 << " changed from "
     833           0 :                                 << i->type << " " << i->name //TODO: attributes
     834           0 :                                 << " to "
     835           0 :                                 << j->type << " " << j->name //TODO: attributes
     836           0 :                                 << std::endl;
     837           0 :                             std::exit(EXIT_FAILURE);
     838             :                         }
     839             :                     }
     840        2223 :                     for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
     841         738 :                              i(ent2B->getDirectProperties().begin()
     842        1476 :                                + ent2A->getDirectProperties().size());
     843        1482 :                          i != ent2B->getDirectProperties().end(); ++i)
     844             :                     {
     845           3 :                         if ((i->attributes & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL) == 0)
     846             :                         {
     847             :                             std::cerr
     848           0 :                                 << "B accumulation-based service " << name
     849           0 :                                 << " additional direct property " << i->name
     850           0 :                                 << " is not optional" << std::endl;
     851           0 :                             std::exit(EXIT_FAILURE);
     852             :                         }
     853             :                     }
     854        1476 :                     break;
     855             :                 }
     856             :             case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
     857             :                 {
     858             :                     rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2A(
     859             :                         static_cast<unoidl::InterfaceBasedSingletonEntity *>(
     860           7 :                             entA.get()));
     861             :                     rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2B(
     862             :                         static_cast<unoidl::InterfaceBasedSingletonEntity *>(
     863          14 :                             entB.get()));
     864           7 :                     if (ent2A->getBase() != ent2B->getBase()) {
     865             :                         std::cerr
     866           0 :                             << "interface-based singleton " << name
     867           0 :                             << " base changed from " << ent2A->getBase()
     868           0 :                             << " to " << ent2B->getBase() << std::endl;
     869           0 :                         std::exit(EXIT_FAILURE);
     870             :                     }
     871          14 :                     break;
     872             :                 }
     873             :             case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
     874             :                 {
     875             :                     rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2A(
     876             :                         static_cast<unoidl::ServiceBasedSingletonEntity *>(
     877           0 :                             entA.get()));
     878             :                     rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2B(
     879             :                         static_cast<unoidl::ServiceBasedSingletonEntity *>(
     880           0 :                             entB.get()));
     881           0 :                     if (ent2A->getBase() != ent2B->getBase()) {
     882             :                         std::cerr
     883           0 :                             << "service-based singleton " << name
     884           0 :                             << " base changed from " << ent2A->getBase()
     885           0 :                             << " to " << ent2B->getBase() << std::endl;
     886           0 :                         std::exit(EXIT_FAILURE);
     887             :                     }
     888           0 :                     break;
     889             :                 }
     890        2704 :             }
     891             :         }
     892        2781 :     }
     893          79 : }
     894             : 
     895        9755 : bool valid(OUString const & identifier) {
     896       10819 :     for (sal_Int32 i = 0;; ++i) {
     897       10819 :         i = identifier.indexOf('_', i);
     898       10819 :         if (i == -1) {
     899        9755 :             return true;
     900             :         }
     901        1064 :         if (!rtl::isAsciiUpperCase(identifier[0]) || identifier[i - 1] == '_') {
     902           0 :             return false;
     903             :         }
     904        1064 :     }
     905             : }
     906             : 
     907        4561 : void checkIds(
     908             :     rtl::Reference<unoidl::Provider> const & providerA, OUString const & prefix,
     909             :     rtl::Reference<unoidl::MapCursor> const & cursor)
     910             : {
     911             :     assert(cursor.is());
     912             :     for (;;) {
     913        4561 :         OUString id;
     914        8988 :         rtl::Reference<unoidl::Entity> entB(cursor->getNext(&id));
     915        4561 :         if (!entB.is()) {
     916         134 :             break;
     917             :         }
     918        8854 :         OUString name(prefix + id);
     919        8854 :         rtl::Reference<unoidl::Entity> entA(providerA->findEntity(name));
     920        4427 :         if (!(entA.is() || valid(id))) {
     921             :             std::cerr
     922           0 :                 << "entity name " << name << " uses an invalid identifier"
     923           0 :                 << std::endl;
     924           0 :             std::exit(EXIT_FAILURE);
     925             :         }
     926        4427 :         switch (entB->getSort()) {
     927             :         case unoidl::Entity::SORT_MODULE:
     928             :             checkIds(
     929         264 :                 providerA, name + ".",
     930         132 :                 (static_cast<unoidl::ModuleEntity *>(entB.get())
     931         396 :                  ->createCursor()));
     932         132 :             break;
     933             :         case unoidl::Entity::SORT_ENUM_TYPE:
     934         192 :             if (!entA.is()) {
     935             :                 rtl::Reference<unoidl::EnumTypeEntity> ent2B(
     936          35 :                     static_cast<unoidl::EnumTypeEntity *>(entB.get()));
     937         795 :                 for (std::vector<unoidl::EnumTypeEntity::Member>::const_iterator
     938          35 :                          i(ent2B->getMembers().begin());
     939         530 :                      i != ent2B->getMembers().end(); ++i)
     940             :                 {
     941         230 :                     if (!valid(i->name)) {
     942             :                         std::cerr
     943           0 :                             << "enum type " << name << " member " << i->name
     944           0 :                             << " uses an invalid identifier" << std::endl;
     945           0 :                         std::exit(EXIT_FAILURE);
     946             :                     }
     947          35 :                 }
     948             :             }
     949         192 :             break;
     950             :         case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
     951         387 :             if (!entA.is()) {
     952             :                 rtl::Reference<unoidl::PlainStructTypeEntity> ent2B(
     953             :                     static_cast<unoidl::PlainStructTypeEntity *>(
     954         151 :                         entB.get()));
     955        2031 :                 for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
     956         151 :                          i(ent2B->getDirectMembers().begin());
     957        1354 :                      i != ent2B->getDirectMembers().end(); ++i)
     958             :                 {
     959         526 :                     if (!valid(i->name)) {
     960             :                         std::cerr
     961           0 :                             << "plain struct type " << name << " direct member "
     962           0 :                             << i->name << " uses an invalid identifier"
     963           0 :                             << std::endl;
     964           0 :                         std::exit(EXIT_FAILURE);
     965             :                     }
     966         151 :                 }
     967             :             }
     968         387 :             break;
     969             :         case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
     970           4 :             if (!entA.is()) {
     971             :                 rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
     972             :                     ent2B(
     973             :                         static_cast<
     974             :                             unoidl::PolymorphicStructTypeTemplateEntity *>(
     975           4 :                                 entB.get()));
     976          27 :                 for (std::vector<OUString>::const_iterator i(
     977           4 :                          ent2B->getTypeParameters().begin());
     978          18 :                      i != ent2B->getTypeParameters().end(); ++i)
     979             :                 {
     980           5 :                     if (!valid(*i)) {
     981             :                         std::cerr
     982           0 :                             << "polymorphic struct type template " << name
     983           0 :                             << " type parameter " << *i
     984           0 :                             << " uses an invalid identifier" << std::endl;
     985           0 :                         std::exit(EXIT_FAILURE);
     986             :                     }
     987             :                 }
     988          36 :                 for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
     989           4 :                          i(ent2B->getMembers().begin());
     990          24 :                      i != ent2B->getMembers().end(); ++i)
     991             :                 {
     992           8 :                     if (!valid(i->name)) {
     993             :                         std::cerr
     994           0 :                             << "polymorphic struct type template " << name
     995           0 :                             << " member " << i->name
     996           0 :                             << " uses an invalid identifier" << std::endl;
     997           0 :                         std::exit(EXIT_FAILURE);
     998             :                     }
     999           4 :                 }
    1000             :             }
    1001           4 :             break;
    1002             :         case unoidl::Entity::SORT_EXCEPTION_TYPE:
    1003         243 :             if (!entA.is()) {
    1004             :                 rtl::Reference<unoidl::ExceptionTypeEntity> ent2B(
    1005          71 :                     static_cast<unoidl::ExceptionTypeEntity *>(entB.get()));
    1006         363 :                 for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
    1007          71 :                          i(ent2B->getDirectMembers().begin());
    1008         242 :                      i != ent2B->getDirectMembers().end(); ++i)
    1009             :                 {
    1010          50 :                     if (!valid(i->name)) {
    1011             :                         std::cerr
    1012           0 :                             << "exception type " << name << " direct member "
    1013           0 :                             << i->name << " uses an invalid identifier"
    1014           0 :                             << std::endl;
    1015           0 :                         std::exit(EXIT_FAILURE);
    1016             :                     }
    1017          71 :                 }
    1018             :             }
    1019         243 :             break;
    1020             :         case unoidl::Entity::SORT_INTERFACE_TYPE:
    1021        1701 :             if (!entA.is()) {
    1022             :                 rtl::Reference<unoidl::InterfaceTypeEntity> ent2B(
    1023         654 :                     static_cast<unoidl::InterfaceTypeEntity *>(entB.get()));
    1024        3399 :                 for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
    1025         654 :                          i(ent2B->getDirectAttributes().begin());
    1026        2266 :                      i != ent2B->getDirectAttributes().end(); ++i)
    1027             :                 {
    1028         479 :                     if (!valid(i->name)) {
    1029             :                         std::cerr
    1030           0 :                             << "interface type " << name << " direct attribute "
    1031           0 :                             << i->name << " uses an invalid identifier"
    1032           0 :                             << std::endl;
    1033           0 :                         std::exit(EXIT_FAILURE);
    1034             :                     }
    1035             :                 }
    1036        8439 :                 for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
    1037         654 :                          i(ent2B->getDirectMethods().begin());
    1038        5626 :                      i != ent2B->getDirectMethods().end(); ++i)
    1039             :                 {
    1040        2159 :                     if (!valid(i->name)) {
    1041             :                         std::cerr
    1042           0 :                             << "interface type " << name << " direct method "
    1043           0 :                             << i->name << " uses an invalid identifier"
    1044           0 :                             << std::endl;
    1045           0 :                         std::exit(EXIT_FAILURE);
    1046             :                     }
    1047       13173 :                     for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
    1048        2159 :                              j(i->parameters.begin());
    1049        8782 :                          j != i->parameters.end(); ++j)
    1050             :                     {
    1051        2232 :                         if (!valid(j->name)) {
    1052             :                             std::cerr
    1053           0 :                                 << "interface type " << name
    1054           0 :                                 << " direct method " << i->name << " parameter "
    1055           0 :                                 << j->name << " uses an invalid identifier"
    1056           0 :                                 << std::endl;
    1057           0 :                             std::exit(EXIT_FAILURE);
    1058             :                         }
    1059             :                     }
    1060         654 :                 }
    1061             :             }
    1062        1701 :             break;
    1063             :         case unoidl::Entity::SORT_TYPEDEF:
    1064             :         case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
    1065             :         case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
    1066          49 :             break;
    1067             :         case unoidl::Entity::SORT_CONSTANT_GROUP:
    1068             :             {
    1069             :                 rtl::Reference<unoidl::ConstantGroupEntity> ent2B(
    1070         356 :                     static_cast<unoidl::ConstantGroupEntity *>(entB.get()));
    1071       11364 :                 for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
    1072         356 :                              i(ent2B->getMembers().begin());
    1073        7576 :                      i != ent2B->getMembers().end(); ++i)
    1074             :                 {
    1075        3432 :                     bool found = false;
    1076        3432 :                     if (entA.is()) {
    1077             :                         rtl::Reference<unoidl::ConstantGroupEntity> ent2A(
    1078             :                             static_cast<unoidl::ConstantGroupEntity *>(
    1079        1884 :                                 entA.get()));
    1080       95967 :                         for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
    1081        1884 :                                  j(ent2A->getMembers().begin());
    1082       63978 :                              j != ent2A->getMembers().end(); ++j)
    1083             :                         {
    1084       31989 :                             if (i->name == j->name) {
    1085        1884 :                                 found = true;
    1086        1884 :                                 break;
    1087             :                             }
    1088        1884 :                         }
    1089             :                     }
    1090        3432 :                     if (!(found || valid(i->name))) {
    1091             :                         std::cerr
    1092           0 :                             << "Constant group " << name << " member "
    1093           0 :                             << i->name << " uses an invalid identifier"
    1094           0 :                             << std::endl;
    1095           0 :                         std::exit(EXIT_FAILURE);
    1096             :                     }
    1097             :                 }
    1098         356 :                 break;
    1099             :             }
    1100             :         case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
    1101         338 :             if (!entA.is()) {
    1102             :                 rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
    1103             :                     ent2B(
    1104             :                         static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
    1105         211 :                             entB.get()));
    1106        1335 :                 for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
    1107         211 :                          i(ent2B->getConstructors().begin());
    1108         890 :                      i != ent2B->getConstructors().end(); ++i)
    1109             :                 {
    1110         234 :                     if (!valid(i->name)) {
    1111             :                         std::cerr
    1112           0 :                             << "single-interface--based service " << name
    1113           0 :                             << " constructor " << i->name
    1114           0 :                             << " uses an invalid identifier" << std::endl;
    1115           0 :                         std::exit(EXIT_FAILURE);
    1116             :                     }
    1117        1158 :                     for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter>::const_iterator
    1118         234 :                              j(i->parameters.begin());
    1119         772 :                          j != i->parameters.end(); ++j)
    1120             :                     {
    1121         152 :                         if (!valid(j->name)) {
    1122             :                             std::cerr
    1123           0 :                                 << "single-interface--based service " << name
    1124           0 :                                 << " constructor " << i->name << " parameter "
    1125           0 :                                 << j->name << " uses an invalid identifier"
    1126           0 :                                 << std::endl;
    1127           0 :                             std::exit(EXIT_FAILURE);
    1128             :                         }
    1129             :                     }
    1130         211 :                 }
    1131             :             }
    1132         338 :             break;
    1133             :         case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
    1134             :             {
    1135             :                 rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2B(
    1136             :                     static_cast<unoidl::AccumulationBasedServiceEntity *>(
    1137        1025 :                         entB.get()));
    1138             :                 std::vector<unoidl::AccumulationBasedServiceEntity::Property>::size_type
    1139        1025 :                     n(entA.is()
    1140             :                       ? (static_cast<unoidl::AccumulationBasedServiceEntity *>(
    1141         738 :                              entA.get())
    1142         738 :                          ->getDirectProperties().size())
    1143        1763 :                       : 0);
    1144             :                 assert(n <= ent2B->getDirectProperties().size());
    1145        4533 :                 for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
    1146        1025 :                          i(ent2B->getDirectProperties().begin() + n);
    1147        3022 :                      i != ent2B->getDirectProperties().end(); ++i)
    1148             :                 {
    1149         486 :                     if (!valid(i->name)) {
    1150             :                         std::cerr
    1151           0 :                             << "accumulation-based service " << name
    1152           0 :                             << " direct property " << i->name
    1153           0 :                             << " uses an invalid identifier" << std::endl;
    1154           0 :                         std::exit(EXIT_FAILURE);
    1155             :                     }
    1156             :                 }
    1157        1025 :                 break;
    1158             :             }
    1159             :         }
    1160        4427 :     }
    1161         134 : }
    1162             : 
    1163             : }
    1164             : 
    1165           4 : SAL_IMPLEMENT_MAIN() {
    1166             :     try {
    1167           2 :         sal_uInt32 args = rtl_getAppCommandArgCount();
    1168           6 :         rtl::Reference<unoidl::Manager> mgr[2];
    1169           2 :         mgr[0] = new unoidl::Manager;
    1170           2 :         mgr[1] = new unoidl::Manager;
    1171           4 :         rtl::Reference<unoidl::Provider> prov[2];
    1172           2 :         int side = 0;
    1173          10 :         for (sal_uInt32 i = 0; i != args; ++i) {
    1174           8 :             bool delimiter = false;
    1175           8 :             OUString uri(getArgumentUri(i, side == 0 ? &delimiter : 0));
    1176           8 :             if (delimiter) {
    1177           2 :                 side = 1;
    1178             :             } else {
    1179             :                 try {
    1180           6 :                     prov[side] = mgr[side]->addProvider(uri);
    1181           0 :                 } catch (unoidl::NoSuchFileException &) {
    1182             :                     std::cerr
    1183           0 :                         << "Input <" << uri << "> does not exist" << std::endl;
    1184           0 :                     std::exit(EXIT_FAILURE);
    1185             :                 }
    1186             :             }
    1187           8 :         }
    1188           2 :         if (side == 0 || !(prov[0].is() && prov[1].is())) {
    1189           0 :             badUsage();
    1190             :         }
    1191           2 :         checkMap(prov[1], "", prov[0]->createRootCursor());
    1192           2 :         checkIds(prov[0], "", prov[1]->createRootCursor());
    1193           8 :         return EXIT_SUCCESS;
    1194           0 :     } catch (unoidl::FileFormatException & e1) {
    1195             :         std::cerr
    1196           0 :             << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
    1197           0 :             << std::endl;
    1198           0 :         std::exit(EXIT_FAILURE);
    1199             :     }
    1200           6 : }
    1201             : 
    1202             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11