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

Generated by: LCOV version 1.10