[Libreoffice-commits] core.git: 3 commits - unoidl/source

Stephan Bergmann sbergman at redhat.com
Tue Nov 18 23:50:56 PST 2014


 unoidl/source/unoidl-check.cxx   | 1442 ++++++++++++++++++---------------------
 unoidl/source/unoidlprovider.cxx |  337 ++++++---
 unoidl/source/unoidlprovider.hxx |   15 
 3 files changed, 960 insertions(+), 834 deletions(-)

New commits:
commit 333c6c114b0f21acf0f2525d61850a5f86d84aa7
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Tue Nov 18 18:34:56 2014 +0100

    Check entity and type name syntax
    
    (For types, only checks their syntax, but not whether they semantically fit in a
    certain situation, e.g., "boolean" cannot be used as a base interface.)
    
    Change-Id: I12f617e74ca13ce2afcec8f611bfdb4912c62960

diff --git a/unoidl/source/unoidlprovider.cxx b/unoidl/source/unoidlprovider.cxx
index 9b37e78..23de040 100644
--- a/unoidl/source/unoidlprovider.cxx
+++ b/unoidl/source/unoidlprovider.cxx
@@ -17,6 +17,7 @@
 
 #include "osl/endian.h"
 #include "osl/file.h"
+#include "rtl/character.hxx"
 #include "rtl/ref.hxx"
 #include "rtl/textenc.h"
 #include "rtl/textcvt.h"
@@ -30,6 +31,54 @@
 
 namespace unoidl { namespace detail {
 
+class MappedFile: public salhelper::SimpleReferenceObject {
+public:
+    explicit MappedFile(OUString const & fileUrl);
+
+    sal_uInt8 read8(sal_uInt32 offset) const;
+
+    sal_uInt16 read16(sal_uInt32 offset) const;
+
+    sal_uInt32 read32(sal_uInt32 offset) const;
+
+    sal_uInt64 read64(sal_uInt32 offset) const;
+
+    float readIso60599Binary32(sal_uInt32 offset) const;
+
+    double readIso60599Binary64(sal_uInt32 offset) const;
+
+    OUString readNulName(sal_uInt32 offset) /*const*/;
+
+    OUString readIdxName(sal_uInt32 * offset) const
+    { return readIdxString(offset, RTL_TEXTENCODING_ASCII_US); }
+
+    OUString readIdxString(sal_uInt32 * offset) const
+    { return readIdxString(offset, RTL_TEXTENCODING_UTF8); }
+
+    OUString uri;
+    oslFileHandle handle;
+    sal_uInt64 size;
+    void * address;
+
+private:
+    virtual ~MappedFile();
+
+    sal_uInt8 get8(sal_uInt32 offset) const;
+
+    sal_uInt16 get16(sal_uInt32 offset) const;
+
+    sal_uInt32 get32(sal_uInt32 offset) const;
+
+    sal_uInt64 get64(sal_uInt32 offset) const;
+
+    float getIso60599Binary32(sal_uInt32 offset) const;
+
+    double getIso60599Binary64(sal_uInt32 offset) const;
+
+    OUString readIdxString(sal_uInt32 * offset, rtl_TextEncoding encoding)
+        const;
+};
+
 namespace {
 
 // sizeof (Memory16) == 2
@@ -116,55 +165,96 @@ struct Memory64 {
     }
 };
 
+bool isSimpleType(OUString const & type) {
+    return type == "void" || type == "boolean" || type == "byte"
+        || type == "short" || type == "unsigned short" || type == "long"
+        || type == "unsigned long" || type == "hyper"
+        || type == "unsigned hyper" || type == "float" || type == "double"
+        || type == "char" || type == "string" || type == "type"
+        || type == "any";
 }
 
-class MappedFile: public salhelper::SimpleReferenceObject {
-public:
-    explicit MappedFile(OUString const & fileUrl);
-
-    sal_uInt8 read8(sal_uInt32 offset) const;
-
-    sal_uInt16 read16(sal_uInt32 offset) const;
-
-    sal_uInt32 read32(sal_uInt32 offset) const;
-
-    sal_uInt64 read64(sal_uInt32 offset) const;
-
-    float readIso60599Binary32(sal_uInt32 offset) const;
-
-    double readIso60599Binary64(sal_uInt32 offset) const;
-
-    OUString readNulName(sal_uInt32 offset) const;
-
-    OUString readIdxName(sal_uInt32 * offset) const
-    { return readIdxString(offset, RTL_TEXTENCODING_ASCII_US); }
-
-    OUString readIdxString(sal_uInt32 * offset) const
-    { return readIdxString(offset, RTL_TEXTENCODING_UTF8); }
-
-    OUString uri;
-    oslFileHandle handle;
-    sal_uInt64 size;
-    void * address;
-
-private:
-    virtual ~MappedFile();
-
-    sal_uInt8 get8(sal_uInt32 offset) const;
-
-    sal_uInt16 get16(sal_uInt32 offset) const;
-
-    sal_uInt32 get32(sal_uInt32 offset) const;
-
-    sal_uInt64 get64(sal_uInt32 offset) const;
+// For backwards compatibility, does not strictly check segments to match
+//
+//  <segment> ::= <blocks> | <block>
+//  <blocks> ::= <capital> <other>* ("_" <block>)*
+//  <block> ::= <other>+
+//  <other> ::= <capital> | "a"--"z" | "0"--"9"
+//  <capital> ::= "A"--"Z"
+//
+bool isIdentifier(OUString const & type, bool scoped) {
+    if (type.isEmpty()) {
+        return false;
+    }
+    for (sal_Int32 i = 0; i != type.getLength(); ++i) {
+        sal_Unicode c = type[i];
+        if (c == '.') {
+            if (!scoped || i == 0 || i == type.getLength() - 1
+                || type[i - 1] == '.')
+            {
+                return false;
+            }
+        } else if (!rtl::isAsciiAlphanumeric(c) && c != '_') {
+            return false;
+        }
+    }
+    return true;
+}
 
-    float getIso60599Binary32(sal_uInt32 offset) const;
+void checkTypeName(
+    rtl::Reference< MappedFile > const & file, OUString const & type)
+{
+    OUString nucl(type);
+    bool args = false;
+    while (nucl.startsWith("[]", &nucl)) {}
+    sal_Int32 i = nucl.indexOf('<');
+    if (i != -1) {
+        OUString tmpl(nucl.copy(0, i));
+        do {
+            ++i; // skip '<' or ','
+            sal_Int32 j = i;
+            for (sal_Int32 level = 0; j != nucl.getLength(); ++j) {
+                sal_Unicode c = nucl[j];
+                if (c == ',') {
+                    if (level == 0) {
+                        break;
+                    }
+                } else if (c == '<') {
+                    ++level;
+                } else if (c == '>') {
+                    if (level == 0) {
+                        break;
+                    }
+                    --level;
+                }
+            }
+            if (j != nucl.getLength()) {
+                checkTypeName(file, nucl.copy(i, j - i));
+                args = true;
+            }
+            i = j;
+        } while (i != nucl.getLength() && nucl[i] != '>');
+        if (i != nucl.getLength() - 1 || nucl[i] != '>' || !args) {
+            tmpl.clear(); // bad input
+        }
+        nucl = tmpl;
+    }
+    if (isSimpleType(nucl) ? args : !isIdentifier(nucl, true)) {
+        throw FileFormatException(
+            file->uri, "UNOIDL format: bad type \"" + type + "\"");
+    }
+}
 
-    double getIso60599Binary64(sal_uInt32 offset) const;
+void checkEntityName(
+    rtl::Reference< MappedFile > const & file, OUString const & name)
+{
+    if (isSimpleType(name) || !isIdentifier(name, false)) {
+        throw FileFormatException(
+            file->uri, "UNOIDL format: bad entity name \"" + name + "\"");
+    }
+}
 
-    OUString readIdxString(sal_uInt32 * offset, rtl_TextEncoding encoding)
-        const;
-};
+}
 
 MappedFile::MappedFile(OUString const & fileUrl): uri(fileUrl), handle(0) {
     oslFileError e = osl_openFile(uri.pData, &handle, osl_File_OpenFlag_Read);
@@ -244,7 +334,7 @@ double MappedFile::readIso60599Binary64(sal_uInt32 offset) const {
     return getIso60599Binary64(offset);
 }
 
-OUString MappedFile::readNulName(sal_uInt32 offset) const {
+OUString MappedFile::readNulName(sal_uInt32 offset) {
     if (offset > size) {
         throw FileFormatException(
             uri, "UNOIDL format: offset for string too large");
@@ -272,6 +362,7 @@ OUString MappedFile::readNulName(sal_uInt32 offset) const {
     {
         throw FileFormatException(uri, "UNOIDL format: name is not ASCII");
     }
+    checkEntityName(this, name);
     return name;
 }
 
@@ -679,6 +770,7 @@ rtl::Reference< Entity > readEntity(
             std::vector< EnumTypeEntity::Member > mems;
             for (sal_uInt32 i = 0; i != n; ++i) {
                 OUString memName(file->readIdxName(&offset));
+                checkEntityName(file, memName);
                 sal_Int32 memValue = static_cast< sal_Int32 >(
                     file->read32(offset));
                     //TODO: implementation-defined behavior of conversion from
@@ -706,6 +798,7 @@ rtl::Reference< Entity > readEntity(
                         ("UNOIDL format: empty base type name of plain struct"
                          " type"));
                 }
+                checkTypeName(file, base);
             }
             sal_uInt32 n = file->read32(offset);
             if (n > SAL_MAX_INT32) {
@@ -718,7 +811,9 @@ rtl::Reference< Entity > readEntity(
             std::vector< PlainStructTypeEntity::Member > mems;
             for (sal_uInt32 i = 0; i != n; ++i) {
                 OUString memName(file->readIdxName(&offset));
+                checkEntityName(file, memName);
                 OUString memType(file->readIdxName(&offset));
+                checkTypeName(file, memType);
                 mems.push_back(
                     PlainStructTypeEntity::Member(
                         memName, memType,
@@ -740,7 +835,9 @@ rtl::Reference< Entity > readEntity(
             offset += 5;
             std::vector< OUString > params;
             for (sal_uInt32 i = 0; i != n; ++i) {
-                params.push_back(file->readIdxName(&offset));
+                OUString param(file->readIdxName(&offset));
+                checkEntityName(file, param);
+                params.push_back(param);
             }
             n = file->read32(offset);
             if (n > SAL_MAX_INT32) {
@@ -755,7 +852,9 @@ rtl::Reference< Entity > readEntity(
                 v = file->read8(offset);
                 ++offset;
                 OUString memName(file->readIdxName(&offset));
+                checkEntityName(file, memName);
                 OUString memType(file->readIdxName(&offset));
+                checkTypeName(file, memType);
                 if (v > 1) {
                     throw FileFormatException(
                         file->uri,
@@ -785,6 +884,7 @@ rtl::Reference< Entity > readEntity(
                         ("UNOIDL format: empty base type name of exception"
                          " type"));
                 }
+                checkTypeName(file, base);
             }
             sal_uInt32 n = file->read32(offset);
             if (n > SAL_MAX_INT32) {
@@ -796,7 +896,9 @@ rtl::Reference< Entity > readEntity(
             std::vector< ExceptionTypeEntity::Member > mems;
             for (sal_uInt32 i = 0; i != n; ++i) {
                 OUString memName(file->readIdxName(&offset));
+                checkEntityName(file, memName);
                 OUString memType(file->readIdxName(&offset));
+                checkTypeName(file, memType);
                 mems.push_back(
                     ExceptionTypeEntity::Member(
                         memName, memType,
@@ -819,6 +921,7 @@ rtl::Reference< Entity > readEntity(
             std::vector< AnnotatedReference > mandBases;
             for (sal_uInt32 i = 0; i != n; ++i) {
                 OUString base(file->readIdxName(&offset));
+                checkTypeName(file, base);
                 mandBases.push_back(
                     AnnotatedReference(
                         base,
@@ -835,6 +938,7 @@ rtl::Reference< Entity > readEntity(
             std::vector< AnnotatedReference > optBases;
             for (sal_uInt32 i = 0; i != n; ++i) {
                 OUString base(file->readIdxName(&offset));
+                checkTypeName(file, base);
                 optBases.push_back(
                     AnnotatedReference(
                         base,
@@ -853,7 +957,9 @@ rtl::Reference< Entity > readEntity(
                 v = file->read8(offset);
                 ++offset;
                 OUString attrName(file->readIdxName(&offset));
+                checkEntityName(file, attrName);
                 OUString attrType(file->readIdxName(&offset));
+                checkTypeName(file, attrType);
                 if (v > 0x03) {
                     throw FileFormatException(
                         file->uri,
@@ -870,7 +976,9 @@ rtl::Reference< Entity > readEntity(
                 }
                 offset += 4;
                 for (sal_uInt32 j = 0; j != m; ++j) {
-                    getExcs.push_back(file->readIdxName(&offset));
+                    OUString exc(file->readIdxName(&offset));
+                    checkTypeName(file, exc);
+                    getExcs.push_back(exc);
                 }
                 std::vector< OUString > setExcs;
                 if ((v & 0x02) == 0) {
@@ -884,7 +992,9 @@ rtl::Reference< Entity > readEntity(
                     }
                     offset += 4;
                     for (sal_uInt32 j = 0; j != m; ++j) {
-                        setExcs.push_back(file->readIdxName(&offset));
+                        OUString exc(file->readIdxName(&offset));
+                        checkTypeName(file, exc);
+                        setExcs.push_back(exc);
                     }
                 }
                 attrs.push_back(
@@ -904,7 +1014,9 @@ rtl::Reference< Entity > readEntity(
             std::vector< InterfaceTypeEntity::Method > meths;
             for (sal_uInt32 i = 0; i != nMeths; ++i) {
                 OUString methName(file->readIdxName(&offset));
+                checkEntityName(file, methName);
                 OUString methType(file->readIdxName(&offset));
+                checkTypeName(file, methType);
                 sal_uInt32 m = file->read32(offset);
                 if (m > SAL_MAX_INT32) {
                     throw FileFormatException(
@@ -918,7 +1030,9 @@ rtl::Reference< Entity > readEntity(
                     v = file->read8(offset);
                     ++offset;
                     OUString paramName(file->readIdxName(&offset));
+                    checkEntityName(file, paramName);
                     OUString paramType(file->readIdxName(&offset));
+                    checkTypeName(file, paramType);
                     InterfaceTypeEntity::Method::Parameter::Direction dir;
                     switch (v) {
                     case 0:
@@ -955,7 +1069,9 @@ rtl::Reference< Entity > readEntity(
                 }
                 offset += 4;
                 for (sal_uInt32 j = 0; j != m; ++j) {
-                    excs.push_back(file->readIdxName(&offset));
+                    OUString exc(file->readIdxName(&offset));
+                    checkTypeName(file, exc);
+                    excs.push_back(exc);
                 }
                 meths.push_back(
                     InterfaceTypeEntity::Method(
@@ -970,6 +1086,7 @@ rtl::Reference< Entity > readEntity(
         {
             ++offset;
             OUString base(file->readIdxName(&offset));
+            checkTypeName(file, base);
             return new TypedefEntity(
                 published, base, readAnnotations(annotated, file, offset));
         }
@@ -1010,6 +1127,7 @@ rtl::Reference< Entity > readEntity(
         {
             ++offset;
             OUString base(file->readIdxName(&offset));
+            checkTypeName(file, base);
             std::vector< SingleInterfaceBasedServiceEntity::Constructor > ctors;
             if (flag) {
                 ctors.push_back(
@@ -1025,6 +1143,7 @@ rtl::Reference< Entity > readEntity(
                 offset += 4;
                 for (sal_uInt32 i = 0; i != n; ++i) {
                     OUString ctorName(file->readIdxName(&offset));
+                    checkEntityName(file, ctorName);
                     sal_uInt32 m = file->read32(offset);
                     if (m > SAL_MAX_INT32) {
                         throw FileFormatException(
@@ -1041,7 +1160,9 @@ rtl::Reference< Entity > readEntity(
                         v = file->read8(offset);
                         ++offset;
                         OUString paramName(file->readIdxName(&offset));
+                        checkEntityName(file, paramName);
                         OUString paramType(file->readIdxName(&offset));
+                        checkTypeName(file, paramType);
                         bool rest;
                         switch (v) {
                         case 0:
@@ -1074,7 +1195,9 @@ rtl::Reference< Entity > readEntity(
                     }
                     offset += 4;
                     for (sal_uInt32 j = 0; j != m; ++j) {
-                        excs.push_back(file->readIdxName(&offset));
+                        OUString exc(file->readIdxName(&offset));
+                        checkTypeName(file, exc);
+                        excs.push_back(exc);
                     }
                     ctors.push_back(
                         SingleInterfaceBasedServiceEntity::Constructor(
@@ -1099,6 +1222,7 @@ rtl::Reference< Entity > readEntity(
             std::vector< AnnotatedReference > mandServs;
             for (sal_uInt32 i = 0; i != n; ++i) {
                 OUString base(file->readIdxName(&offset));
+                checkTypeName(file, base);
                 mandServs.push_back(
                     AnnotatedReference(
                         base,
@@ -1115,6 +1239,7 @@ rtl::Reference< Entity > readEntity(
             std::vector< AnnotatedReference > optServs;
             for (sal_uInt32 i = 0; i != n; ++i) {
                 OUString base(file->readIdxName(&offset));
+                checkTypeName(file, base);
                 optServs.push_back(
                     AnnotatedReference(
                         base,
@@ -1131,6 +1256,7 @@ rtl::Reference< Entity > readEntity(
             std::vector< AnnotatedReference > mandIfcs;
             for (sal_uInt32 i = 0; i != n; ++i) {
                 OUString base(file->readIdxName(&offset));
+                checkTypeName(file, base);
                 mandIfcs.push_back(
                     AnnotatedReference(
                         base,
@@ -1147,6 +1273,7 @@ rtl::Reference< Entity > readEntity(
             std::vector< AnnotatedReference > optIfcs;
             for (sal_uInt32 i = 0; i != n; ++i) {
                 OUString base(file->readIdxName(&offset));
+                checkTypeName(file, base);
                 optIfcs.push_back(
                     AnnotatedReference(
                         base,
@@ -1165,7 +1292,9 @@ rtl::Reference< Entity > readEntity(
                 sal_uInt16 attrs = file->read16(offset);
                 offset += 2;
                 OUString propName(file->readIdxName(&offset));
+                checkEntityName(file, propName);
                 OUString propType(file->readIdxName(&offset));
+                checkTypeName(file, propType);
                 if (attrs > 0x01FF) { // see css.beans.PropertyAttribute
                     throw FileFormatException(
                         file->uri,
@@ -1190,6 +1319,7 @@ rtl::Reference< Entity > readEntity(
         {
             ++offset;
             OUString base(file->readIdxName(&offset));
+            checkTypeName(file, base);
             return new InterfaceBasedSingletonEntity(
                 published, base, readAnnotations(annotated, file, offset));
         }
@@ -1197,6 +1327,7 @@ rtl::Reference< Entity > readEntity(
         {
             ++offset;
             OUString base(file->readIdxName(&offset));
+            checkTypeName(file, base);
             return new ServiceBasedSingletonEntity(
                 published, base, readAnnotations(annotated, file, offset));
         }
commit e7da382244481ad0b2dfb67e5ffde85aac220c2b
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Tue Nov 18 17:49:22 2014 +0100

    Check for recursive maps
    
    Change-Id: I50227c41c5b4c5c410939ddfa078b996b5804965

diff --git a/unoidl/source/unoidlprovider.cxx b/unoidl/source/unoidlprovider.cxx
index aef380d..9b37e78 100644
--- a/unoidl/source/unoidlprovider.cxx
+++ b/unoidl/source/unoidlprovider.cxx
@@ -12,6 +12,7 @@
 #include <algorithm>
 #include <cassert>
 #include <cstring>
+#include <set>
 #include <vector>
 
 #include "osl/endian.h"
@@ -364,6 +365,11 @@ struct MapEntry {
     Memory32 data;
 };
 
+bool operator <(Map const map1, Map const map2) {
+    return map1.begin < map2.begin
+        || (map1.begin == map2.begin && map1.size < map2.size);
+}
+
 namespace {
 
 enum Compare { COMPARE_LESS, COMPARE_GREATER, COMPARE_EQUAL };
@@ -543,14 +549,20 @@ ConstantValue readConstant(
 }
 
 rtl::Reference< Entity > readEntity(
-    rtl::Reference< MappedFile > const & file, sal_uInt32 offset);
+    rtl::Reference< MappedFile > const & file, sal_uInt32 offset,
+    std::set<Map> const & trace);
+
+class UnoidlModuleEntity;
 
 class UnoidlCursor: public MapCursor {
 public:
     UnoidlCursor(
-        rtl::Reference< MappedFile > file, MapEntry const * mapBegin,
-        sal_uInt32 mapSize):
-        file_(file), mapIndex_(mapBegin), mapEnd_(mapBegin + mapSize)
+        rtl::Reference< MappedFile > file,
+        rtl::Reference<UnoidlProvider> const & reference1,
+        rtl::Reference<UnoidlModuleEntity> const & reference2,
+        NestedMap const & map):
+        file_(file), reference1_(reference1), reference2_(reference2),
+        map_(map), index_(0)
     {}
 
 private:
@@ -559,17 +571,20 @@ private:
     virtual rtl::Reference< Entity > getNext(OUString * name) SAL_OVERRIDE;
 
     rtl::Reference< MappedFile > file_;
-    MapEntry const * mapIndex_;
-    MapEntry const * mapEnd_;
+    rtl::Reference<UnoidlProvider> reference1_; // HACK to keep alive whatever
+    rtl::Reference<UnoidlModuleEntity> reference2_;           // owner of map_
+    NestedMap const & map_;
+    sal_uInt32 index_;
 };
 
 rtl::Reference< Entity > UnoidlCursor::getNext(OUString * name) {
     assert(name != 0);
     rtl::Reference< Entity > ent;
-    if (mapIndex_ != mapEnd_) {
-        *name = file_->readNulName(mapIndex_->name.getUnsigned32());
-        ent = readEntity(file_, mapIndex_->data.getUnsigned32());
-        ++mapIndex_;
+    if (index_ != map_.map.size) {
+        *name = file_->readNulName(map_.map.begin[index_].name.getUnsigned32());
+        ent = readEntity(
+            file_, map_.map.begin[index_].data.getUnsigned32(), map_.trace);
+        ++index_;
     }
     return ent;
 }
@@ -578,37 +593,47 @@ class UnoidlModuleEntity: public ModuleEntity {
 public:
     UnoidlModuleEntity(
         rtl::Reference< MappedFile > const & file, sal_uInt32 mapOffset,
-        sal_uInt32 mapSize):
-        file_(file),
-        mapBegin_(
-            reinterpret_cast< MapEntry const * >(
-                static_cast< char const * >(file_->address) + mapOffset)),
-        mapSize_(mapSize)
-    { assert(file.is()); }
+        sal_uInt32 mapSize, std::set<Map> const & trace):
+        file_(file)
+    {
+        assert(file.is());
+        map_.map.begin = reinterpret_cast<MapEntry const *>(
+            static_cast<char const *>(file_->address) + mapOffset);
+        map_.map.size = mapSize;
+        map_.trace = trace;
+        if (!map_.trace.insert(map_.map).second) {
+            throw FileFormatException(
+                file_->uri, "UNOIDL format: recursive map");
+        }
+    }
 
 private:
     virtual ~UnoidlModuleEntity() throw () {}
 
     virtual std::vector< OUString > getMemberNames() const SAL_OVERRIDE;
 
-    virtual rtl::Reference< MapCursor > createCursor() const SAL_OVERRIDE
-    { return new UnoidlCursor(file_, mapBegin_, mapSize_); }
+    virtual rtl::Reference< MapCursor > createCursor() const SAL_OVERRIDE {
+        return new UnoidlCursor(
+            file_, rtl::Reference<UnoidlProvider>(),
+            const_cast<UnoidlModuleEntity *>(this), map_);
+    }
 
     rtl::Reference< MappedFile > file_;
-    MapEntry const * mapBegin_;
-    sal_uInt32 mapSize_;
+    NestedMap map_;
 };
 
 std::vector< OUString > UnoidlModuleEntity::getMemberNames() const {
     std::vector< OUString > names;
-    for (sal_uInt32 i = 0; i != mapSize_; ++i) {
-        names.push_back(file_->readNulName(mapBegin_[i].name.getUnsigned32()));
+    for (sal_uInt32 i = 0; i != map_.map.size; ++i) {
+        names.push_back(
+            file_->readNulName(map_.map.begin[i].name.getUnsigned32()));
     }
     return names;
 }
 
 rtl::Reference< Entity > readEntity(
-    rtl::Reference< MappedFile > const & file, sal_uInt32 offset)
+    rtl::Reference< MappedFile > const & file, sal_uInt32 offset,
+    std::set<Map> const & trace)
 {
     assert(file.is());
     int v = file->read8(offset);
@@ -637,7 +662,7 @@ rtl::Reference< Entity > readEntity(
                     file->uri,
                     "UNOIDL format: module map offset + size too large");
             }
-            return new UnoidlModuleEntity(file, offset + 5, n);
+            return new UnoidlModuleEntity(file, offset + 5, n, trace);
         }
     case 1: // enum type
         {
@@ -1193,35 +1218,40 @@ UnoidlProvider::UnoidlProvider(OUString const & uri): file_(new MappedFile(uri))
             " 0");
     }
     sal_uInt32 off = file_->read32(8);
-    mapSize_ = file_->read32(12);
-    if (off + 8 * sal_uInt64(mapSize_) > file_->size) { // cannot overflow
+    map_.map.size = file_->read32(12);
+    if (off + 8 * sal_uInt64(map_.map.size) > file_->size) { // cannot overflow
         throw FileFormatException(
             file_->uri, "UNOIDL format: root map offset + size too large");
     }
-    mapBegin_ = reinterpret_cast< MapEntry const * >(
+    map_.map.begin = reinterpret_cast< MapEntry const * >(
         static_cast< char const * >(file_->address) + off);
+    map_.trace.insert(map_.map);
 }
 
 rtl::Reference< MapCursor > UnoidlProvider::createRootCursor() const {
-    return new UnoidlCursor(file_, mapBegin_, mapSize_);
+    return new UnoidlCursor(
+        file_, const_cast<UnoidlProvider *>(this),
+        rtl::Reference<UnoidlModuleEntity>(), map_);
 }
 
 rtl::Reference< Entity > UnoidlProvider::findEntity(OUString const & name) const
 {
-    MapEntry const * mapBegin = mapBegin_;
-    sal_uInt32 mapSize = mapSize_;
+    NestedMap map(map_);
     bool cgroup = false;
     for (sal_Int32 i = 0;;) {
         sal_Int32 j = name.indexOf('.', i);
         if (j == -1) {
             j = name.getLength();
         }
-        sal_Int32 off = findInMap(file_, mapBegin, mapSize, name, i, j - i);
+        sal_Int32 off = findInMap(
+            file_, map.map.begin, map.map.size, name, i, j - i);
         if (off == 0) {
             return rtl::Reference< Entity >();
         }
         if (j == name.getLength()) {
-            return cgroup ? rtl::Reference< Entity >() : readEntity(file_, off);
+            return cgroup
+                ? rtl::Reference< Entity >()
+                : readEntity(file_, off, map.trace);
         }
         if (cgroup) {
             return rtl::Reference< Entity >();
@@ -1240,15 +1270,19 @@ rtl::Reference< Entity > UnoidlProvider::findEntity(OUString const & name) const
                     // prefix of the requested name's segments?
             }
         }
-        mapSize = file_->read32(off + 1);
-        if (sal_uInt64(off) + 5 + 8 * sal_uInt64(mapSize) > file_->size)
+        map.map.size = file_->read32(off + 1);
+        if (sal_uInt64(off) + 5 + 8 * sal_uInt64(map.map.size) > file_->size)
             // cannot overflow
         {
             throw FileFormatException(
                 file_->uri, "UNOIDL format: map offset + size too large");
         }
-        mapBegin = reinterpret_cast< MapEntry const * >(
+        map.map.begin = reinterpret_cast< MapEntry const * >(
             static_cast< char const * >(file_->address) + off + 5);
+        if (!map.trace.insert(map.map).second) {
+            throw FileFormatException(
+                file_->uri, "UNOIDL format: recursive map");
+        }
         i = j + 1;
     }
 }
diff --git a/unoidl/source/unoidlprovider.hxx b/unoidl/source/unoidlprovider.hxx
index 2f0728a..9eacfb5 100644
--- a/unoidl/source/unoidlprovider.hxx
+++ b/unoidl/source/unoidlprovider.hxx
@@ -12,6 +12,8 @@
 
 #include "sal/config.h"
 
+#include <set>
+
 #include "rtl/ref.hxx"
 #include "sal/types.h"
 #include "unoidl/unoidl.hxx"
@@ -21,6 +23,16 @@ namespace unoidl { namespace detail {
 class MappedFile;
 struct MapEntry;
 
+struct Map {
+    MapEntry const * begin;
+    sal_uInt32 size;
+};
+
+struct NestedMap {
+    Map map;
+    std::set<Map> trace;
+};
+
 class UnoidlProvider: public Provider {
 public:
     // throws FileFormatException, NoSuchFileException:
@@ -37,8 +49,7 @@ private:
     virtual ~UnoidlProvider() throw ();
 
     rtl::Reference< detail::MappedFile > file_;
-    detail::MapEntry const * mapBegin_;
-    sal_uInt32 mapSize_;
+    NestedMap map_;
 };
 
 } }
commit b0583c57efc253e4e2f9c86e7900eb02e0e22173
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Tue Nov 18 16:48:35 2014 +0100

    Revert "cosmetic 'en-passant'...."
    
    This reverts commit d4810a814c7c7f3db2df15b62367bd1edc7040f6.
    
    Change-Id: Ia062e070c7d7dac5cc4388d1c8e812fb97851d52

diff --git a/unoidl/source/unoidl-check.cxx b/unoidl/source/unoidl-check.cxx
index c314b86..22dff88 100644
--- a/unoidl/source/unoidl-check.cxx
+++ b/unoidl/source/unoidl-check.cxx
@@ -27,12 +27,9 @@
 
 namespace unoidl {
 
-bool operator ==(ConstantValue const & lhs, ConstantValue const & rhs)
-{
-    if (lhs.type == rhs.type)
-    {
-        switch (lhs.type)
-        {
+bool operator ==(ConstantValue const & lhs, ConstantValue const & rhs) {
+    if (lhs.type == rhs.type) {
+        switch (lhs.type) {
         case ConstantValue::TYPE_BOOLEAN:
             return lhs.booleanValue == rhs.booleanValue;
         case ConstantValue::TYPE_BYTE:
@@ -58,13 +55,13 @@ bool operator ==(ConstantValue const & lhs, ConstantValue const & rhs)
     return false;
 }
 
-bool operator !=(ConstantValue const & lhs, ConstantValue const & rhs)
-{
+bool operator !=(ConstantValue const & lhs, ConstantValue const & rhs) {
     return !(lhs == rhs);
 }
 
-bool operator ==( SingleInterfaceBasedServiceEntity::Constructor::Parameter const & lhs,
-                  SingleInterfaceBasedServiceEntity::Constructor::Parameter const & rhs)
+bool operator ==(
+    SingleInterfaceBasedServiceEntity::Constructor::Parameter const & lhs,
+    SingleInterfaceBasedServiceEntity::Constructor::Parameter const & rhs)
 {
     return lhs.name == rhs.name && lhs.type == rhs.type && lhs.rest == rhs.rest;
 }
@@ -73,18 +70,12 @@ bool operator ==( SingleInterfaceBasedServiceEntity::Constructor::Parameter cons
 
 namespace {
 
-void badUsage()
-{
+void badUsage() {
     std::cerr
-        << "Usage:"
-        << std::endl
-        << std::endl
+        << "Usage:" << std::endl << std::endl
         << ("  unoidl-check [<extra registries A>] <registry A> -- [<extra"
             " registries B>]")
-        << std::endl
-        << "    <registry B>"
-        << std::endl
-        << std::endl
+        << std::endl << "    <registry B>" << std::endl << std::endl
         << ("where each <registry> is either a new- or legacy-format .rdb file,"
             " a single .idl")
         << std::endl
@@ -96,14 +87,11 @@ void badUsage()
     std::exit(EXIT_FAILURE);
 }
 
-OUString getArgumentUri(sal_uInt32 argument, bool * delimiter)
-{
+OUString getArgumentUri(sal_uInt32 argument, bool * delimiter) {
     OUString arg;
     rtl_getAppCommandArg(argument, &arg.pData);
-    if (arg == "--")
-    {
-        if (delimiter == 0)
-        {
+    if (arg == "--") {
+        if (delimiter == 0) {
             badUsage();
         }
         *delimiter = true;
@@ -111,18 +99,15 @@ OUString getArgumentUri(sal_uInt32 argument, bool * delimiter)
     }
     OUString url;
     osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
-    if (e1 != osl::FileBase::E_None)
-    {
+    if (e1 != osl::FileBase::E_None) {
         std::cerr
             << "Cannot convert \"" << arg << "\" to file URL, error code "
-            << +e1
-            << std::endl;
+            << +e1 << std::endl;
         std::exit(EXIT_FAILURE);
     }
     OUString cwd;
     oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
-    if (e2 != osl_Process_E_None)
-    {
+    if (e2 != osl_Process_E_None) {
         std::cerr
             << "Cannot obtain working directory, error code " << +e2
             << std::endl;
@@ -130,21 +115,19 @@ OUString getArgumentUri(sal_uInt32 argument, bool * delimiter)
     }
     OUString abs;
     e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
-    if (e1 != osl::FileBase::E_None)
-    {
+    if (e1 != osl::FileBase::E_None) {
         std::cerr
             << "Cannot make \"" << url
-            << "\" into an absolute file URL, error code " << +e1
-            << std::endl;
+            << "\" into an absolute file URL, error code " << +e1 << std::endl;
         std::exit(EXIT_FAILURE);
     }
     return abs;
 }
 
-OUString showDirection( unoidl::InterfaceTypeEntity::Method::Parameter::Direction direction)
+OUString showDirection(
+    unoidl::InterfaceTypeEntity::Method::Parameter::Direction direction)
 {
-    switch (direction)
-    {
+    switch (direction) {
     case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN:
         return OUString("[in]");
     case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT:
@@ -156,828 +139,824 @@ OUString showDirection( unoidl::InterfaceTypeEntity::Method::Parameter::Directio
     }
 }
 
-struct EqualsAnnotation
-{
+struct EqualsAnnotation {
     EqualsAnnotation(OUString const & name): name_(name) {}
 
     bool operator ()(unoidl::AnnotatedReference const & ref)
-        { return ref.name == name_; }
+    { return ref.name == name_; }
 
 private:
     OUString name_;
 };
 
-void checkMap( rtl::Reference<unoidl::Provider> const & providerB, OUString const & prefix,
-               rtl::Reference<unoidl::MapCursor> const & cursor)
+void checkMap(
+    rtl::Reference<unoidl::Provider> const & providerB, OUString const & prefix,
+    rtl::Reference<unoidl::MapCursor> const & cursor)
 {
     assert(providerB.is());
     assert(cursor.is());
-    for (;;)
-    {
+    for (;;) {
         OUString id;
         rtl::Reference<unoidl::Entity> entA(cursor->getNext(&id));
-        if (!entA.is())
-        {
+        if (!entA.is()) {
             break;
         }
         OUString name(prefix + id);
-        if (entA->getSort() == unoidl::Entity::SORT_MODULE)
-        {
-            checkMap( providerB, name + ".",
-                      (static_cast<unoidl::ModuleEntity *>(entA.get())->createCursor()));
-        }
-        else
-        {
+        if (entA->getSort() == unoidl::Entity::SORT_MODULE) {
+            checkMap(
+                providerB, name + ".",
+                (static_cast<unoidl::ModuleEntity *>(entA.get())
+                 ->createCursor()));
+        } else {
             rtl::Reference<unoidl::Entity> entB(providerB->findEntity(name));
-            if (!entB.is())
-            {
+            if (!entB.is()) {
                 std::cerr
                     << "A entity " << name << " is not present in B"
                     << std::endl;
                 std::exit(EXIT_FAILURE);
             }
-            if (entA->getSort() != entB->getSort())
-            {
+            if (entA->getSort() != entB->getSort()) {
                 std::cerr
                     << "A entity " << name << " is of different sort in B"
                     << std::endl;
                 std::exit(EXIT_FAILURE);
             }
-            if ((dynamic_cast<unoidl::PublishableEntity&>(*entA.get()).isPublished()) &&
-                (!dynamic_cast<unoidl::PublishableEntity&>(*entB.get()).isPublished()))
+            if ((dynamic_cast<unoidl::PublishableEntity &>(*entA.get())
+                 .isPublished())
+                && (!dynamic_cast<unoidl::PublishableEntity &>(*entB.get())
+                    .isPublished()))
             {
                 std::cerr
                     << "A published entity " << name << " is not published in B"
                     << std::endl;
                 std::exit(EXIT_FAILURE);
             }
-            switch (entA->getSort())
-            {
+            switch (entA->getSort()) {
             case unoidl::Entity::SORT_MODULE:
                 assert(false && "this cannot happen");
                 //deliberate fall-through anyway
             case unoidl::Entity::SORT_ENUM_TYPE:
-            {
-                rtl::Reference<unoidl::EnumTypeEntity> ent2A(
+                {
+                    rtl::Reference<unoidl::EnumTypeEntity> ent2A(
                         static_cast<unoidl::EnumTypeEntity *>(entA.get()));
-                rtl::Reference<unoidl::EnumTypeEntity> ent2B(
+                    rtl::Reference<unoidl::EnumTypeEntity> ent2B(
                         static_cast<unoidl::EnumTypeEntity *>(entB.get()));
-
-                if (ent2A->getMembers().size() != ent2B->getMembers().size())
-                {
-                    std::cerr
-                        << "enum type " << name
-                        << " number of members changed from "
-                        << ent2A->getMembers().size() << " to "
-                        << ent2B->getMembers().size()
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::EnumTypeEntity::Member>::const_iterator
-                         i(ent2A->getMembers().begin()),
-                         j(ent2B->getMembers().begin());
-                     i != ent2A->getMembers().end(); ++i, ++j)
-                {
-                    if (i->name != j->name ||
-                        i->value != j->value)
+                    if (ent2A->getMembers().size()
+                        != ent2B->getMembers().size())
                     {
                         std::cerr
-                            << "enum type " << name << " member #"
-                            << i - ent2A->getMembers().begin() + 1
-                            << " changed from " << i->name << " = "
-                            << i->value << " to " << j->name << " = "
-                            << j->value
-                            << std::endl;
+                            << "enum type " << name
+                            << " number of members changed from "
+                            << ent2A->getMembers().size() << " to "
+                            << ent2B->getMembers().size() << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
+                    for (std::vector<unoidl::EnumTypeEntity::Member>::const_iterator
+                             i(ent2A->getMembers().begin()),
+                             j(ent2B->getMembers().begin());
+                         i != ent2A->getMembers().end(); ++i, ++j)
+                    {
+                        if (i->name != j->name || i->value != j->value) {
+                            std::cerr
+                                << "enum type " << name << " member #"
+                                << i - ent2A->getMembers().begin() + 1
+                                << " changed from " << i->name << " = "
+                                << i->value << " to " << j->name << " = "
+                                << j->value << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    break;
                 }
-                break;
-            }
             case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
-            {
-                rtl::Reference<unoidl::PlainStructTypeEntity> ent2A(
-                        static_cast<unoidl::PlainStructTypeEntity *>(entA.get()));
-                rtl::Reference<unoidl::PlainStructTypeEntity> ent2B(
-                        static_cast<unoidl::PlainStructTypeEntity *>(entB.get()));
-
-                if (ent2A->getDirectBase() != ent2B->getDirectBase())
-                {
-                    std::cerr
-                        << "plain struct type " << name
-                        << " direct base changed from "
-                        << (ent2A->getDirectBase().isEmpty() ? OUString("none") : ent2A->getDirectBase())
-                        << " to "
-                        << (ent2B->getDirectBase().isEmpty() ? OUString("none") : ent2B->getDirectBase())
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                if (ent2A->getDirectMembers().size()
-                    != ent2B->getDirectMembers().size())
                 {
-                    std::cerr
-                        << "plain struct type " << name
-                        << " number of direct members changed from "
-                        << ent2A->getDirectMembers().size() << " to "
-                        << ent2B->getDirectMembers().size() << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
-                         i(ent2A->getDirectMembers().begin()),
-                         j(ent2B->getDirectMembers().begin());
-                     i != ent2A->getDirectMembers().end(); ++i, ++j)
-                {
-                    if (i->name != j->name ||
-                        i->type != j->type)
-                    {
+                    rtl::Reference<unoidl::PlainStructTypeEntity> ent2A(
+                        static_cast<unoidl::PlainStructTypeEntity *>(
+                            entA.get()));
+                    rtl::Reference<unoidl::PlainStructTypeEntity> ent2B(
+                        static_cast<unoidl::PlainStructTypeEntity *>(
+                            entB.get()));
+                    if (ent2A->getDirectBase() != ent2B->getDirectBase()) {
                         std::cerr
                             << "plain struct type " << name
-                            << " direct member #"
-                            << i - ent2A->getDirectMembers().begin() + 1
-                            << " changed from " << i->type << " " << i->name
-                            << " to " << j->type << " " << j->name
+                            << " direct base changed from "
+                            << (ent2A->getDirectBase().isEmpty()
+                                ? OUString("none") : ent2A->getDirectBase())
+                            << " to "
+                            << (ent2B->getDirectBase().isEmpty()
+                                ? OUString("none") : ent2B->getDirectBase())
                             << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
+                    if (ent2A->getDirectMembers().size()
+                        != ent2B->getDirectMembers().size())
+                    {
+                        std::cerr
+                            << "plain struct type " << name
+                            << " number of direct members changed from "
+                            << ent2A->getDirectMembers().size() << " to "
+                            << ent2B->getDirectMembers().size() << std::endl;
+                        std::exit(EXIT_FAILURE);
+                    }
+                    for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
+                             i(ent2A->getDirectMembers().begin()),
+                             j(ent2B->getDirectMembers().begin());
+                         i != ent2A->getDirectMembers().end(); ++i, ++j)
+                    {
+                        if (i->name != j->name || i->type != j->type) {
+                            std::cerr
+                                << "plain struct type " << name
+                                << " direct member #"
+                                << i - ent2A->getDirectMembers().begin() + 1
+                                << " changed from " << i->type << " " << i->name
+                                << " to " << j->type << " " << j->name
+                                << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    break;
                 }
-                break;
-            }
             case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
-            {
-                rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
-                    ent2A(static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(entA.get()));
-                rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
-                    ent2B(static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(entB.get()));
-
-                if (ent2A->getTypeParameters().size() != ent2B->getTypeParameters().size())
-                {
-                    std::cerr
-                        << "polymorphic struct type template " << name
-                        << " number of type parameters changed from "
-                        << ent2A->getTypeParameters().size() << " to "
-                        << ent2B->getTypeParameters().size()
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<OUString>::const_iterator
-                         i(ent2A->getTypeParameters().begin()),
-                         j(ent2B->getTypeParameters().begin());
-                     i != ent2A->getTypeParameters().end(); ++i, ++j)
                 {
-                    if (*i != *j)
+                    rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
+                        ent2A(
+                            static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
+                                entA.get()));
+                    rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
+                        ent2B(
+                            static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
+                                entB.get()));
+                    if (ent2A->getTypeParameters().size()
+                        != ent2B->getTypeParameters().size())
                     {
                         std::cerr
                             << "polymorphic struct type template " << name
-                            << " type parameter #"
-                            << i - ent2A->getTypeParameters().begin() + 1
-                            << " changed from " << *i << " to " << *j
-                            << std::endl;
+                            << " number of type parameters changed from "
+                            << ent2A->getTypeParameters().size() << " to "
+                            << ent2B->getTypeParameters().size() << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
-                }
-                if (ent2A->getMembers().size() != ent2B->getMembers().size())
-                {
-                    std::cerr
-                        << "polymorphic struct type template " << name
-                        << " number of members changed from "
-                        << ent2A->getMembers().size() << " to "
-                        << ent2B->getMembers().size() << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
-                         i(ent2A->getMembers().begin()),
-                         j(ent2B->getMembers().begin());
-                     i != ent2A->getMembers().end(); ++i, ++j)
-                {
-                    if (i->name != j->name ||
-                        i->type != j->type ||
-                        i->parameterized != j->parameterized)
+                    for (std::vector<OUString>::const_iterator
+                             i(ent2A->getTypeParameters().begin()),
+                             j(ent2B->getTypeParameters().begin());
+                         i != ent2A->getTypeParameters().end(); ++i, ++j)
+                    {
+                        if (*i != *j) {
+                            std::cerr
+                                << "polymorphic struct type template " << name
+                                << " type parameter #"
+                                << i - ent2A->getTypeParameters().begin() + 1
+                                << " changed from " << *i << " to " << *j
+                                << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    if (ent2A->getMembers().size()
+                        != ent2B->getMembers().size())
                     {
                         std::cerr
                             << "polymorphic struct type template " << name
-                            << " member #"
-                            << i - ent2A->getMembers().begin() + 1
-                            << " changed from "
-                            << (i->parameterized ? OUString("parameterized ") : OUString())
-                            << i->type << " " << i->name
-                            << " to "
-                            << (j->parameterized ? OUString("parameterized ") : OUString())
-                            << j->type << " " << j->name
-                            << std::endl;
+                            << " number of members changed from "
+                            << ent2A->getMembers().size() << " to "
+                            << ent2B->getMembers().size() << std::endl;
+                        std::exit(EXIT_FAILURE);
+                    }
+                    for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
+                             i(ent2A->getMembers().begin()),
+                             j(ent2B->getMembers().begin());
+                         i != ent2A->getMembers().end(); ++i, ++j)
+                    {
+                        if (i->name != j->name || i->type != j->type
+                            || i->parameterized != j->parameterized)
+                        {
+                            std::cerr
+                                << "polymorphic struct type template " << name
+                                << " member #"
+                                << i - ent2A->getMembers().begin() + 1
+                                << " changed from "
+                                << (i->parameterized
+                                    ? OUString("parameterized ") : OUString())
+                                << i->type << " " << i->name
+                                << " to "
+                                << (j->parameterized
+                                    ? OUString("parameterized ") : OUString())
+                                << j->type << " " << j->name
+                                << std::endl;
                             std::exit(EXIT_FAILURE);
+                        }
                     }
+                    break;
                 }
-                break;
-            }
             case unoidl::Entity::SORT_EXCEPTION_TYPE:
-            {
-                rtl::Reference<unoidl::ExceptionTypeEntity> ent2A(
+                {
+                    rtl::Reference<unoidl::ExceptionTypeEntity> ent2A(
                         static_cast<unoidl::ExceptionTypeEntity *>(entA.get()));
-                rtl::Reference<unoidl::ExceptionTypeEntity> ent2B(
+                    rtl::Reference<unoidl::ExceptionTypeEntity> ent2B(
                         static_cast<unoidl::ExceptionTypeEntity *>(entB.get()));
-                if (ent2A->getDirectBase() != ent2B->getDirectBase())
-                {
-                    std::cerr
-                        << "exception type " << name
-                        << " direct base changed from "
-                        << (ent2A->getDirectBase().isEmpty() ? OUString("none") : ent2A->getDirectBase())
-                        << " to "
-                        << (ent2B->getDirectBase().isEmpty() ? OUString("none") : ent2B->getDirectBase())
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                if (ent2A->getDirectMembers().size() != ent2B->getDirectMembers().size())
-                {
-                    std::cerr
-                        << "exception type " << name
-                        << " number of direct members changed from "
-                        << ent2A->getDirectMembers().size() << " to "
-                        << ent2B->getDirectMembers().size() << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
-                         i(ent2A->getDirectMembers().begin()),
-                         j(ent2B->getDirectMembers().begin());
-                     i != ent2A->getDirectMembers().end(); ++i, ++j)
-                {
-                    if (i->name != j->name || i->type != j->type)
-                    {
+                    if (ent2A->getDirectBase() != ent2B->getDirectBase()) {
                         std::cerr
                             << "exception type " << name
-                            << " direct member #"
-                            << i - ent2A->getDirectMembers().begin() + 1
-                            << " changed from " << i->type << " " << i->name
-                            << " to " << j->type << " " << j->name
+                            << " direct base changed from "
+                            << (ent2A->getDirectBase().isEmpty()
+                                ? OUString("none") : ent2A->getDirectBase())
+                            << " to "
+                            << (ent2B->getDirectBase().isEmpty()
+                                ? OUString("none") : ent2B->getDirectBase())
                             << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
-                }
-                break;
-            }
-            case unoidl::Entity::SORT_INTERFACE_TYPE:
-            {
-                rtl::Reference<unoidl::InterfaceTypeEntity> ent2A(
-                        static_cast<unoidl::InterfaceTypeEntity *>(entA.get()));
-                rtl::Reference<unoidl::InterfaceTypeEntity> ent2B(
-                        static_cast<unoidl::InterfaceTypeEntity *>(entB.get()));
-                if (ent2A->getDirectMandatoryBases().size() != ent2B->getDirectMandatoryBases().size())
-                {
-                    std::cerr
-                        << "interface type " << name
-                        << " number of direct mandatory bases changed from "
-                        << ent2A->getDirectMandatoryBases().size() << " to "
-                        << ent2B->getDirectMandatoryBases().size()
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::AnnotatedReference>::const_iterator
-                         i(ent2A->getDirectMandatoryBases().begin()),
-                         j(ent2B->getDirectMandatoryBases().begin());
-                     i != ent2A->getDirectMandatoryBases().end(); ++i, ++j)
-                {
-                    if (i->name != j->name)
+                    if (ent2A->getDirectMembers().size()
+                        != ent2B->getDirectMembers().size())
                     {
                         std::cerr
-                            << "interface type " << name
-                            << " direct mandatory base #"
-                            << (i - ent2A->getDirectMandatoryBases().begin()
-                                + 1)
-                            << " changed from " << i->name << " to "
-                            << j->name
-                            << std::endl;
+                            << "exception type " << name
+                            << " number of direct members changed from "
+                            << ent2A->getDirectMembers().size() << " to "
+                            << ent2B->getDirectMembers().size() << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
+                    for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
+                             i(ent2A->getDirectMembers().begin()),
+                             j(ent2B->getDirectMembers().begin());
+                         i != ent2A->getDirectMembers().end(); ++i, ++j)
+                    {
+                        if (i->name != j->name || i->type != j->type) {
+                            std::cerr
+                                << "exception type " << name
+                                << " direct member #"
+                                << i - ent2A->getDirectMembers().begin() + 1
+                                << " changed from " << i->type << " " << i->name
+                                << " to " << j->type << " " << j->name
+                                << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    break;
                 }
-                if (ent2A->getDirectOptionalBases().size() != ent2B->getDirectOptionalBases().size())
-                {
-                    std::cerr
-                        << "interface type " << name
-                        << " number of direct optional bases changed from "
-                        << ent2A->getDirectOptionalBases().size() << " to "
-                        << ent2B->getDirectOptionalBases().size()
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::AnnotatedReference>::const_iterator
-                         i(ent2A->getDirectOptionalBases().begin()),
-                         j(ent2B->getDirectOptionalBases().begin());
-                     i != ent2A->getDirectOptionalBases().end(); ++i, ++j)
+            case unoidl::Entity::SORT_INTERFACE_TYPE:
                 {
-                    if (i->name != j->name)
+                    rtl::Reference<unoidl::InterfaceTypeEntity> ent2A(
+                        static_cast<unoidl::InterfaceTypeEntity *>(entA.get()));
+                    rtl::Reference<unoidl::InterfaceTypeEntity> ent2B(
+                        static_cast<unoidl::InterfaceTypeEntity *>(entB.get()));
+                    if (ent2A->getDirectMandatoryBases().size()
+                        != ent2B->getDirectMandatoryBases().size())
                     {
                         std::cerr
                             << "interface type " << name
-                            << " direct optional base #"
-                            << (i - ent2A->getDirectOptionalBases().begin() + 1)
-                            << " changed from " << i->name << " to "
-                            << j->name
+                            << " number of direct mandatory bases changed from "
+                            << ent2A->getDirectMandatoryBases().size() << " to "
+                            << ent2B->getDirectMandatoryBases().size()
                             << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
-                }
-                if (ent2A->getDirectAttributes().size()
-                    != ent2B->getDirectAttributes().size())
-                {
-                    std::cerr
-                        << "interface type " << name
-                        << " number of direct attributes changed from "
-                        << ent2A->getDirectAttributes().size() << " to "
-                        << ent2B->getDirectAttributes().size() << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
-                         i(ent2A->getDirectAttributes().begin()),
-                         j(ent2B->getDirectAttributes().begin());
-                     i != ent2A->getDirectAttributes().end(); ++i, ++j)
-                {
-                    if (i->name != j->name ||
-                        i->type != j->type ||
-                        i->bound != j->bound ||
-                        i->readOnly != j->readOnly ||
-                        i->getExceptions != j->getExceptions ||
-                        i->setExceptions != j->setExceptions)
+                    for (std::vector<unoidl::AnnotatedReference>::const_iterator
+                             i(ent2A->getDirectMandatoryBases().begin()),
+                             j(ent2B->getDirectMandatoryBases().begin());
+                         i != ent2A->getDirectMandatoryBases().end(); ++i, ++j)
+                    {
+                        if (i->name != j->name) {
+                            std::cerr
+                                << "interface type " << name
+                                << " direct mandatory base #"
+                                << (i - ent2A->getDirectMandatoryBases().begin()
+                                    + 1)
+                                << " changed from " << i->name << " to "
+                                << j->name << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    if (ent2A->getDirectOptionalBases().size()
+                        != ent2B->getDirectOptionalBases().size())
                     {
                         std::cerr
                             << "interface type " << name
-                            << " direct attribute #"
-                            << i - ent2A->getDirectAttributes().begin() + 1
-                            << " changed from "
-                            << (i->bound ? OUString("bound ") : OUString())
-                            << (i->readOnly ? OUString("read-only ") : OUString())
-                            << i->type << " " << i->name //TODO: exceptions
-                            << " to "
-                            << (j->bound ? OUString("bound ") : OUString())
-                            << (j->readOnly ? OUString("read-only ") : OUString())
-                            << j->type << " " << j->name //TODO: exceptions
+                            << " number of direct optional bases changed from "
+                            << ent2A->getDirectOptionalBases().size() << " to "
+                            << ent2B->getDirectOptionalBases().size()
                             << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
-                }
-                if (ent2A->getDirectMethods().size()
-                    != ent2B->getDirectMethods().size())
-                {
-                    std::cerr
-                        << "interface type " << name
-                        << " number of direct methods changed from "
-                        << ent2A->getDirectMethods().size() << " to "
-                        << ent2B->getDirectMethods().size() << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
-                         i(ent2A->getDirectMethods().begin()),
-                         j(ent2B->getDirectMethods().begin());
-                     i != ent2A->getDirectMethods().end(); ++i, ++j)
-                {
-                    if (i->name != j->name ||
-                        i->returnType != j->returnType ||
-                        i->exceptions != j->exceptions)
+                    for (std::vector<unoidl::AnnotatedReference>::const_iterator
+                             i(ent2A->getDirectOptionalBases().begin()),
+                             j(ent2B->getDirectOptionalBases().begin());
+                         i != ent2A->getDirectOptionalBases().end(); ++i, ++j)
+                    {
+                        if (i->name != j->name) {
+                            std::cerr
+                                << "interface type " << name
+                                << " direct optional base #"
+                                << (i - ent2A->getDirectOptionalBases().begin()
+                                    + 1)
+                                << " changed from " << i->name << " to "
+                                << j->name << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    if (ent2A->getDirectAttributes().size()
+                        != ent2B->getDirectAttributes().size())
                     {
                         std::cerr
                             << "interface type " << name
-                            << " direct method #"
-                            << i - ent2A->getDirectMethods().begin() + 1
-                            << " changed from "
-                            << i->returnType << " " << i->name //TODO: exceptions
-                            << " to " << j->returnType << " " << j->name //TODO: exceptions
-                            << std::endl;
+                            << " number of direct attributes changed from "
+                            << ent2A->getDirectAttributes().size() << " to "
+                            << ent2B->getDirectAttributes().size() << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
-                    if (i->parameters.size() != j->parameters.size())
+                    for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
+                             i(ent2A->getDirectAttributes().begin()),
+                             j(ent2B->getDirectAttributes().begin());
+                         i != ent2A->getDirectAttributes().end(); ++i, ++j)
+                    {
+                        if (i->name != j->name || i->type != j->type
+                            || i->bound != j->bound
+                            || i->readOnly != j->readOnly
+                            || i->getExceptions != j->getExceptions
+                            || i->setExceptions != j->setExceptions)
+                        {
+                            std::cerr
+                                << "interface type " << name
+                                << " direct attribute #"
+                                << i - ent2A->getDirectAttributes().begin() + 1
+                                << " changed from "
+                                << (i->bound ? OUString("bound ") : OUString())
+                                << (i->readOnly
+                                    ? OUString("read-only ") : OUString())
+                                << i->type << " " << i->name //TODO: exceptions
+                                << " to "
+                                << (j->bound ? OUString("bound ") : OUString())
+                                << (j->readOnly
+                                    ? OUString("read-only ") : OUString())
+                                << j->type << " " << j->name //TODO: exceptions
+                                << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    if (ent2A->getDirectMethods().size()
+                        != ent2B->getDirectMethods().size())
                     {
                         std::cerr
                             << "interface type " << name
-                            << " direct method " << i->name
-                            << " number of parameters changed from "
-                            << i->parameters.size() << " to "
-                            << j->parameters.size()
-                            << std::endl;
+                            << " number of direct methods changed from "
+                            << ent2A->getDirectMethods().size() << " to "
+                            << ent2B->getDirectMethods().size() << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
-                    for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
-                             k(i->parameters.begin()),
-                             l(j->parameters.begin());
-                         k != i->parameters.end(); ++k, ++l)
+                    for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
+                             i(ent2A->getDirectMethods().begin()),
+                             j(ent2B->getDirectMethods().begin());
+                         i != ent2A->getDirectMethods().end(); ++i, ++j)
                     {
-                        if (k->type != l->type || k->direction != l->direction)
+                        if (i->name != j->name || i->returnType != j->returnType
+                            || i->exceptions != j->exceptions)
                         {
                             std::cerr
                                 << "interface type " << name
-                                << " direct method " << i->name
-                                << " parameter #"
-                                << k - i->parameters.begin() + 1
+                                << " direct method #"
+                                << i - ent2A->getDirectMethods().begin() + 1
                                 << " changed from "
-                                << showDirection(k->direction) << " "
-                                << k->type << " to "
-                                << showDirection(l->direction) << " "
-                                << l->type
+                                << i->returnType << " " << i->name //TODO: exceptions
+                                << " to " << j->returnType << " " << j->name //TODO: exceptions
                                 << std::endl;
                             std::exit(EXIT_FAILURE);
                         }
-                        if (k->name != l->name)
-                        {
+                        if (i->parameters.size() != j->parameters.size()) {
                             std::cerr
                                 << "interface type " << name
                                 << " direct method " << i->name
-                                << " parameter #"
-                                << k - i->parameters.begin() + 1
-                                << " changed name from " << k->name
-                                << " to " << l->name
-                                << std::endl;
+                                << " number of parameters changed from "
+                                << i->parameters.size() << " to "
+                                << j->parameters.size() << std::endl;
                             std::exit(EXIT_FAILURE);
                         }
+                        for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
+                                 k(i->parameters.begin()),
+                                 l(j->parameters.begin());
+                             k != i->parameters.end(); ++k, ++l)
+                        {
+                            if (k->type != l->type || k->direction != l->direction)
+                            {
+                                std::cerr
+                                    << "interface type " << name
+                                    << " direct method " << i->name
+                                    << " parameter #"
+                                    << k - i->parameters.begin() + 1
+                                    << " changed from "
+                                    << showDirection(k->direction) << " "
+                                    << k->type << " to "
+                                    << showDirection(l->direction) << " "
+                                    << l->type << std::endl;
+                                std::exit(EXIT_FAILURE);
+                            }
+                            if (k->name != l->name) {
+                                std::cerr
+                                    << "interface type " << name
+                                    << " direct method " << i->name
+                                    << " parameter #"
+                                    << k - i->parameters.begin() + 1
+                                    << " changed name from " << k->name
+                                    << " to " << l->name << std::endl;
+                                std::exit(EXIT_FAILURE);
+                            }
+                        }
                     }
+                    break;
                 }
-                break;
-            }
             case unoidl::Entity::SORT_TYPEDEF:
-            {
-                rtl::Reference<unoidl::TypedefEntity> ent2A(
+                {
+                    rtl::Reference<unoidl::TypedefEntity> ent2A(
                         static_cast<unoidl::TypedefEntity *>(entA.get()));
-                rtl::Reference<unoidl::TypedefEntity> ent2B(
+                    rtl::Reference<unoidl::TypedefEntity> ent2B(
                         static_cast<unoidl::TypedefEntity *>(entB.get()));
-                if (ent2A->getType() != ent2B->getType())
-                {
-                    std::cerr
-                        << "typedef " << name << " type changed from "
-                        << ent2A->getType() << " to " << ent2B->getType()
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
+                    if (ent2A->getType() != ent2B->getType()) {
+                        std::cerr
+                            << "typedef " << name << " type changed from "
+                            << ent2A->getType() << " to " << ent2B->getType()
+                            << std::endl;
+                        std::exit(EXIT_FAILURE);
+                    }
+                    break;
                 }
-                break;
-            }
             case unoidl::Entity::SORT_CONSTANT_GROUP:
-            {
-                rtl::Reference<unoidl::ConstantGroupEntity> ent2A(
+                {
+                    rtl::Reference<unoidl::ConstantGroupEntity> ent2A(
                         static_cast<unoidl::ConstantGroupEntity *>(entA.get()));
-                rtl::Reference<unoidl::ConstantGroupEntity> ent2B(
+                    rtl::Reference<unoidl::ConstantGroupEntity> ent2B(
                         static_cast<unoidl::ConstantGroupEntity *>(entB.get()));
-                for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
-                         i(ent2A->getMembers().begin());
-                     i != ent2A->getMembers().end(); ++i)
-                {
-                    bool found = false;
                     for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
-                             j(ent2B->getMembers().begin());
-                         j != ent2B->getMembers().end(); ++j)
+                             i(ent2A->getMembers().begin());
+                         i != ent2A->getMembers().end(); ++i)
                     {
-                        if (i->name == j->name)
+                        bool found = false;
+                        for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
+                                 j(ent2B->getMembers().begin());
+                             j != ent2B->getMembers().end(); ++j)
                         {
-                            if (i->value != j->value)
-                            {
-                                std::cerr
-                                    << "constant group " << name
-                                    << " member " << i->name
-                                    << " changed value"
-                                    << std::endl;
-                                std::exit(EXIT_FAILURE);
+                            if (i->name == j->name) {
+                                if (i->value != j->value) {
+                                    std::cerr
+                                        << "constant group " << name
+                                        << " member " << i->name
+                                        << " changed value" << std::endl;
+                                    std::exit(EXIT_FAILURE);
+                                }
+                                found = true;
+                                break;
                             }
-                            found = true;
-                            break;
+                        }
+                        if (!found) {
+                            std::cerr
+                                << "A constant group " << name << " member "
+                                << i->name << " is not present in B"
+                                << std::endl;
+                            std::exit(EXIT_FAILURE);
                         }
                     }
-                    if (!found)
-                    {
+                    break;
+                }
+            case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
+                {
+                    rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
+                        ent2A(
+                            static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
+                                entA.get()));
+                    rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
+                        ent2B(
+                            static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
+                                entB.get()));
+                    if (ent2A->getBase() != ent2B->getBase()) {
                         std::cerr
-                            << "A constant group " << name << " member "
-                            << i->name << " is not present in B"
+                            << "single-interface--based servcie " << name
+                            << " base changed from " << ent2A->getBase()
+                            << " to " << ent2B->getBase()
                             << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
-                }
-                break;
-            }
-            case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
-            {
-                rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
-                    ent2A( static_cast<unoidl::SingleInterfaceBasedServiceEntity *>( entA.get()));
-                rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
-                    ent2B( static_cast<unoidl::SingleInterfaceBasedServiceEntity *>( entB.get()));
-                if (ent2A->getBase() != ent2B->getBase())
-                {
-                    std::cerr
-                        << "single-interface--based servcie " << name
-                        << " base changed from " << ent2A->getBase()
-                        << " to " << ent2B->getBase()
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                if (ent2A->getConstructors().size() != ent2B->getConstructors().size())
-                {
-                    std::cerr
-                        << "single-interface--based service " << name
-                        << " number of constructors changed from "
-                        << ent2A->getConstructors().size() << " to "
-                        << ent2B->getConstructors().size() << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
-                         i(ent2A->getConstructors().begin()),
-                         j(ent2B->getConstructors().begin());
-                     i != ent2A->getConstructors().end(); ++i, ++j)
-                {
-                    if (i->name != j->name ||
-                        i->parameters != j->parameters ||
-                        i->exceptions != j->exceptions ||
-                        i->defaultConstructor != j->defaultConstructor)
+                    if (ent2A->getConstructors().size()
+                        != ent2B->getConstructors().size())
                     {
                         std::cerr
                             << "single-interface--based service " << name
-                            << " constructor #"
-                            << i - ent2A->getConstructors().begin() + 1
-                            << " changed from "
-                            << (i->defaultConstructor ? OUString("default ") : i->name) //TODO: parameters, exceptions
-                            << " to "
-                            << (j->defaultConstructor ? OUString("default ") : j->name) //TODO: parameters, exceptions
-                            << std::endl;
+                            << " number of constructors changed from "
+                            << ent2A->getConstructors().size() << " to "
+                            << ent2B->getConstructors().size() << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
+                    for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
+                             i(ent2A->getConstructors().begin()),
+                             j(ent2B->getConstructors().begin());
+                         i != ent2A->getConstructors().end(); ++i, ++j)
+                    {
+                        if (i->name != j->name || i->parameters != j->parameters
+                            || i->exceptions != j->exceptions
+                            || i->defaultConstructor != j->defaultConstructor)
+                        {
+                            std::cerr
+                                << "single-interface--based service " << name
+                                << " constructor #"
+                                << i - ent2A->getConstructors().begin() + 1
+                                << " changed from "
+                                << (i->defaultConstructor
+                                    ? OUString("default ") : i->name) //TODO: parameters, exceptions
+                                << " to "
+                                << (j->defaultConstructor
+                                    ? OUString("default ") : j->name) //TODO: parameters, exceptions
+                                << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    break;
                 }
-                break;
-            }
             case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
-            {
-                rtl::Reference<unoidl::AccumulationBasedServiceEntity>
-                    ent2A( static_cast<unoidl::AccumulationBasedServiceEntity *>( entA.get()));
-                rtl::Reference<unoidl::AccumulationBasedServiceEntity>
-                    ent2B( static_cast<unoidl::AccumulationBasedServiceEntity *>( entB.get()));
-
-                if (ent2A->getDirectMandatoryBaseServices().size() != ent2B->getDirectMandatoryBaseServices().size())
                 {
-                    std::cerr
-                        << "accumulation-based service " << name
-                        << " number of direct mandatory base services changed from "
-                        << ent2A->getDirectMandatoryBaseServices().size()
-                        << " to "
-                        << ent2B->getDirectMandatoryBaseServices().size()
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::AnnotatedReference>::const_iterator
-                         i(ent2A->getDirectMandatoryBaseServices().begin()),
-                         j(ent2B->getDirectMandatoryBaseServices().begin());
-                     i != ent2A->getDirectMandatoryBaseServices().end();
-                     ++i, ++j)
-                {
-                    if (i->name != j->name)
+                    rtl::Reference<unoidl::AccumulationBasedServiceEntity>
+                        ent2A(
+                            static_cast<unoidl::AccumulationBasedServiceEntity *>(
+                                entA.get()));
+                    rtl::Reference<unoidl::AccumulationBasedServiceEntity>
+                        ent2B(
+                            static_cast<unoidl::AccumulationBasedServiceEntity *>(
+                                entB.get()));
+                    if (ent2A->getDirectMandatoryBaseServices().size()
+                        != ent2B->getDirectMandatoryBaseServices().size())
                     {
                         std::cerr
                             << "accumulation-based service " << name
-                            << " direct mandatory base service #"
-                            << (i - (ent2A->getDirectMandatoryBaseServices().begin()) + 1)
-                            << " changed from " << i->name << " to "
-                            << j->name << std::endl;
+                            << (" number of direct mandatory base services"
+                                " changed from ")
+                            << ent2A->getDirectMandatoryBaseServices().size()
+                            << " to "
+                            << ent2B->getDirectMandatoryBaseServices().size()
+                            << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
-                }
-                if (ent2A->getDirectOptionalBaseServices().size() > ent2B->getDirectOptionalBaseServices().size())
-                {
-                    std::cerr
-                        << "accumulation-based service " << name
-                        << " number of direct optional base services  shrank from "
-                        << ent2A->getDirectOptionalBaseServices().size()
-                        << " to "
-                        << ent2B->getDirectOptionalBaseServices().size()
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::AnnotatedReference>::const_iterator
-                         i(ent2A->getDirectOptionalBaseServices().begin());
-                     i != ent2A->getDirectOptionalBaseServices().end();
-                     ++i)
-                {
-                    if (std::find_if(
-                                ent2B->getDirectOptionalBaseServices().begin(),
-                                ent2B->getDirectOptionalBaseServices().end(),
-                                EqualsAnnotation(i->name))
-                        == ent2B->getDirectOptionalBaseServices().end())
+                    for (std::vector<unoidl::AnnotatedReference>::const_iterator
+                             i(ent2A->getDirectMandatoryBaseServices().begin()),
+                             j(ent2B->getDirectMandatoryBaseServices().begin());
+                         i != ent2A->getDirectMandatoryBaseServices().end();
+                         ++i, ++j)
                     {
-                        std::cerr
-                            << "accumulation-based service " << name
-                            << " direct optional base service " << i->name
-                            << " was removed" << std::endl;
-                        std::exit(EXIT_FAILURE);
+                        if (i->name != j->name) {
+                            std::cerr
+                                << "accumulation-based service " << name
+                                << " direct mandatory base service #"
+                                << (i
+                                    - (ent2A->getDirectMandatoryBaseServices()
+                                       .begin())
+                                    + 1)
+                                << " changed from " << i->name << " to "
+                                << j->name << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
                     }
-                }
-                if (ent2A->getDirectMandatoryBaseInterfaces().size()
-                    != ent2B->getDirectMandatoryBaseInterfaces().size())
-                {
-                    std::cerr
-                        << "accumulation-based service " << name
-                        << (" number of direct mandatory base interfaces"
-                            " changed from ")
-                        << ent2A->getDirectMandatoryBaseInterfaces().size()
-                        << " to "
-                        << ent2B->getDirectMandatoryBaseInterfaces().size()
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::AnnotatedReference>::const_iterator
-                         i(ent2A->getDirectMandatoryBaseInterfaces().begin()),
-                         j(ent2B->getDirectMandatoryBaseInterfaces().begin());
-                     i != ent2A->getDirectMandatoryBaseInterfaces().end();
-                     ++i, ++j)
-                {
-                    if (i->name != j->name)
+                    if (ent2A->getDirectOptionalBaseServices().size()
+                        > ent2B->getDirectOptionalBaseServices().size())
                     {
                         std::cerr
                             << "accumulation-based service " << name
-                            << " direct mandatory base interface #"
-                            << (i - (ent2A->getDirectMandatoryBaseInterfaces().begin()) + 1)
-                            << " changed from " << i->name << " to "
-                            << j->name << std::endl;
+                            << (" number of direct optional base services"
+                                " shrank from ")
+                            << ent2A->getDirectOptionalBaseServices().size()
+                            << " to "
+                            << ent2B->getDirectOptionalBaseServices().size()
+                            << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
-                }
-                if (ent2A->getDirectOptionalBaseInterfaces().size() > ent2B->getDirectOptionalBaseInterfaces().size())
-                {
-                    std::cerr
-                        << "accumulation-based service " << name
-                        << (" number of direct optional base interfaces"
-                            " shrank from ")
-                        << ent2A->getDirectOptionalBaseInterfaces().size()
-                        << " to "
-                        << ent2B->getDirectOptionalBaseInterfaces().size()
-                        << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::AnnotatedReference>::const_iterator
-                         i(ent2A->getDirectOptionalBaseInterfaces().begin());
-                     i != ent2A->getDirectOptionalBaseInterfaces().end();
-                     ++i)
-                {
-                    if (std::find_if(
-                                (ent2B->getDirectOptionalBaseInterfaces().begin()),
-                                ent2B->getDirectOptionalBaseInterfaces().end(),
+                    for (std::vector<unoidl::AnnotatedReference>::const_iterator
+                             i(ent2A->getDirectOptionalBaseServices().begin());
+                         i != ent2A->getDirectOptionalBaseServices().end();
+                         ++i)
+                    {
+                        if (std::find_if(
+                                ent2B->getDirectOptionalBaseServices().begin(),
+                                ent2B->getDirectOptionalBaseServices().end(),
                                 EqualsAnnotation(i->name))
-                        == ent2B->getDirectOptionalBaseInterfaces().end())
+                            == ent2B->getDirectOptionalBaseServices().end())
+                        {
+                            std::cerr
+                                << "accumulation-based service " << name
+                                << " direct optional base service " << i->name
+                                << " was removed" << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    if (ent2A->getDirectMandatoryBaseInterfaces().size()
+                        != ent2B->getDirectMandatoryBaseInterfaces().size())
                     {
                         std::cerr
                             << "accumulation-based service " << name
-                            << " direct optional base interface " << i->name
-                            << " was removed" << std::endl;
+                            << (" number of direct mandatory base interfaces"
+                                " changed from ")
+                            << ent2A->getDirectMandatoryBaseInterfaces().size()
+                            << " to "
+                            << ent2B->getDirectMandatoryBaseInterfaces().size()
+                            << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
-                }
-                if (ent2A->getDirectProperties().size() > ent2B->getDirectProperties().size())
-                {
-                    std::cerr
-                        << "accumulation-based service " << name
-                        << " number of direct properties changed from "
-                        << ent2A->getDirectProperties().size() << " to "
-                        << ent2B->getDirectProperties().size() << std::endl;
-                    std::exit(EXIT_FAILURE);
-                }
-                for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
-                         i(ent2A->getDirectProperties().begin()),
-                         j(ent2B->getDirectProperties().begin());
-                     i != ent2A->getDirectProperties().end(); ++i, ++j)
-                {
-                    if (i->name != j->name ||
-                        i->type != j->type ||
-                        i->attributes != j->attributes)
+                    for (std::vector<unoidl::AnnotatedReference>::const_iterator
+                             i(ent2A->getDirectMandatoryBaseInterfaces()
+                               .begin()),
+                             j(ent2B->getDirectMandatoryBaseInterfaces()
+                               .begin());
+                         i != ent2A->getDirectMandatoryBaseInterfaces().end();
+                         ++i, ++j)
+                    {
+                        if (i->name != j->name) {
+                            std::cerr
+                                << "accumulation-based service " << name
+                                << " direct mandatory base interface #"
+                                << (i
+                                    - (ent2A->getDirectMandatoryBaseInterfaces()
+                                       .begin())
+                                    + 1)
+                                << " changed from " << i->name << " to "
+                                << j->name << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    if (ent2A->getDirectOptionalBaseInterfaces().size()
+                        > ent2B->getDirectOptionalBaseInterfaces().size())
                     {
                         std::cerr
                             << "accumulation-based service " << name
-                            << " direct property #"
-                            << i - ent2A->getDirectProperties().begin() + 1
-                            << " changed from "
-                            << i->type << " " << i->name //TODO: attributes
+                            << (" number of direct optional base interfaces"
+                                " shrank from ")
+                            << ent2A->getDirectOptionalBaseInterfaces().size()
                             << " to "
-                            << j->type << " " << j->name //TODO: attributes
+                            << ent2B->getDirectOptionalBaseInterfaces().size()
                             << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
-                }
-                for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
-                         i(ent2B->getDirectProperties().begin()
-                           + ent2A->getDirectProperties().size());
-                     i != ent2B->getDirectProperties().end(); ++i)
-                {
-                    if ((i->attributes & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL) == 0)
+                    for (std::vector<unoidl::AnnotatedReference>::const_iterator
+                             i(ent2A->getDirectOptionalBaseInterfaces()
+                               .begin());
+                         i != ent2A->getDirectOptionalBaseInterfaces().end();
+                         ++i)
+                    {
+                        if (std::find_if(
+                                (ent2B->getDirectOptionalBaseInterfaces()
+                                 .begin()),
+                                ent2B->getDirectOptionalBaseInterfaces().end(),
+                                EqualsAnnotation(i->name))
+                            == ent2B->getDirectOptionalBaseInterfaces().end())
+                        {
+                            std::cerr
+                                << "accumulation-based service " << name
+                                << " direct optional base interface " << i->name
+                                << " was removed" << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    if (ent2A->getDirectProperties().size()
+                        > ent2B->getDirectProperties().size())
                     {
                         std::cerr
-                            << "B accumulation-based service " << name
-                            << " additional direct property " << i->name
-                            << " is not optional" << std::endl;
+                            << "accumulation-based service " << name
+                            << " number of direct properties changed from "
+                            << ent2A->getDirectProperties().size() << " to "
+                            << ent2B->getDirectProperties().size() << std::endl;
                         std::exit(EXIT_FAILURE);
                     }
+                    for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
+                             i(ent2A->getDirectProperties().begin()),
+                             j(ent2B->getDirectProperties().begin());
+                         i != ent2A->getDirectProperties().end(); ++i, ++j)
+                    {
+                        if (i->name != j->name || i->type != j->type
+                            || i->attributes != j->attributes)
+                        {
+                            std::cerr
+                                << "accumulation-based service " << name
+                                << " direct property #"
+                                << i - ent2A->getDirectProperties().begin() + 1
+                                << " changed from "
+                                << i->type << " " << i->name //TODO: attributes
+                                << " to "
+                                << j->type << " " << j->name //TODO: attributes
+                                << std::endl;
+                            std::exit(EXIT_FAILURE);
+                        }
+                    }
+                    for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
+                             i(ent2B->getDirectProperties().begin()

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list