[Libreoffice-commits] core.git: 5 commits - codemaker/source unoidl/Library_unoidl.mk unoidl/source

Stephan Bergmann sbergman at redhat.com
Mon Sep 16 21:56:04 PDT 2013


 codemaker/source/codemaker/typemanager.cxx       |    3 
 unoidl/Library_unoidl.mk                         |    3 
 unoidl/source/sourcefileprovider.cxx             |  142 +++++++++++++
 unoidl/source/sourcefileprovider.hxx             |   44 ++++
 unoidl/source/sourceprovider-parser-requires.hxx |    2 
 unoidl/source/sourceprovider-parser.y            |  122 +++++++++++
 unoidl/source/sourceprovider-scanner.hxx         |   25 +-
 unoidl/source/sourceprovider.cxx                 |  235 -----------------------
 unoidl/source/sourceprovider.hxx                 |   46 ----
 unoidl/source/sourcetreeprovider.cxx             |  152 ++++++++++++++
 unoidl/source/sourcetreeprovider.hxx             |   46 ++++
 unoidl/source/unoidl.cxx                         |    8 
 12 files changed, 531 insertions(+), 297 deletions(-)

New commits:
commit 14bc5fc0ec652650deb9a41505e97c3b4d3854b2
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Mon Sep 16 23:25:43 2013 +0200

    WIP: additional unoidl::Provider that directly reads a single .idl file
    
    Change-Id: Iab795a34a657cb36ced24a1a05f6c21a6c1637aa

diff --git a/unoidl/Library_unoidl.mk b/unoidl/Library_unoidl.mk
index 411e0a9..c98fc69 100644
--- a/unoidl/Library_unoidl.mk
+++ b/unoidl/Library_unoidl.mk
@@ -13,6 +13,7 @@ $(eval $(call gb_Library_add_defs,unoidl,-DLO_DLLIMPLEMENTATION_UNOIDL))
 
 $(eval $(call gb_Library_add_exception_objects,unoidl, \
     unoidl/source/legacyprovider \
+    unoidl/source/sourcefileprovider \
     unoidl/source/sourcetreeprovider \
     unoidl/source/unoidl \
     unoidl/source/unoidlprovider \
diff --git a/unoidl/source/sourcefileprovider.cxx b/unoidl/source/sourcefileprovider.cxx
new file mode 100644
index 0000000..4c522e8
--- /dev/null
+++ b/unoidl/source/sourcefileprovider.cxx
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "sal/config.h"
+
+#include <map>
+#include <utility>
+#include <vector>
+
+#include "sourcefileprovider.hxx"
+#include "sourceprovider-scanner.hxx"
+
+namespace unoidl { namespace detail {
+
+namespace {
+
+class Cursor: public MapCursor {
+public:
+    explicit Cursor(std::map< OUString, rtl::Reference<Entity> > const & map):
+        map_(map), iterator_(map_.begin())
+    {}
+
+private:
+    virtual ~Cursor() throw () {}
+
+    virtual rtl::Reference< Entity > getNext(OUString * name);
+
+    std::map< OUString, rtl::Reference<Entity> > const & map_; //TODO: extent
+    std::map< OUString, rtl::Reference<Entity> >::const_iterator iterator_;
+};
+
+rtl::Reference< Entity > Cursor::getNext(OUString * name) {
+    assert(name != 0);
+    rtl::Reference< Entity > ent;
+    if (iterator_ != map_.end()) {
+        *name = iterator_->first;
+        ent = iterator_->second;
+        ++iterator_;
+    }
+    return ent;
+}
+
+class Module: public ModuleEntity {
+public:
+    Module() {}
+
+    std::map< OUString, rtl::Reference<Entity> > map;
+
+private:
+    virtual ~Module() throw () {}
+
+    virtual std::vector<rtl::OUString> getMemberNames() const;
+
+    virtual rtl::Reference<MapCursor> createCursor() const
+    { return new Cursor(map); }
+};
+
+std::vector<rtl::OUString> Module::getMemberNames() const {
+    std::vector<rtl::OUString> names;
+    for (std::map< OUString, rtl::Reference<Entity> >::const_iterator i(
+             map.begin());
+         i != map.end(); ++i)
+    {
+        names.push_back(i->first);
+    }
+    return names;
+}
+
+}
+
+SourceFileProvider::SourceFileProvider(
+    rtl::Reference<Manager> const & manager, OUString const & uri)
+{
+    SourceProviderScannerData data(manager);
+    if (!parse(uri, &data)) {
+        throw NoSuchFileException(uri);
+    }
+    for (std::map<OUString, SourceProviderEntity>::iterator i(
+             data.entities.begin());
+         i != data.entities.end(); ++i)
+    {
+        if (i->second.kind == SourceProviderEntity::KIND_LOCAL) {
+            assert(i->second.entity.is());
+            assert(i->second.entity->getSort() != Entity::SORT_MODULE);
+            std::map< OUString, rtl::Reference<Entity> > * map = &rootMap_;
+            for (sal_Int32 j = 0;;) {
+                OUString id(i->first.getToken(0, '.', j));
+                if (j == -1) {
+                    map->insert(std::make_pair(id, i->second.entity));
+                    break;
+                }
+                std::map< OUString, rtl::Reference<Entity> >::const_iterator k(
+                    map->find(id));
+                if (k == map->end()) {
+                    k = map->insert(std::make_pair(id, new Module)).first;
+                }
+                Module * mod = dynamic_cast< Module * >(k->second.get());
+                assert(mod != 0);
+                map = &mod->map;
+            }
+        }
+    }
+}
+
+rtl::Reference<MapCursor> SourceFileProvider::createRootCursor() const {
+    return new Cursor(rootMap_);
+}
+
+rtl::Reference<Entity> SourceFileProvider::findEntity(OUString const & name)
+    const
+{
+    std::map< OUString, rtl::Reference<Entity> > const * map = &rootMap_;
+    for (sal_Int32 i = 0;;) {
+        OUString id(name.getToken(0, '.', i));
+        std::map< OUString, rtl::Reference<Entity> >::const_iterator j(
+            map->find(id));
+        if (j == map->end()) {
+            return rtl::Reference<Entity>();
+        }
+        if (i == -1) {
+            return j->second;
+        }
+        if (j->second->getSort() != Entity::SORT_MODULE) {
+            return rtl::Reference<Entity>();
+        }
+        Module * mod = dynamic_cast< Module * >(j->second.get());
+        assert(mod != 0);
+        map = &mod->map;
+    }
+}
+
+SourceFileProvider::~SourceFileProvider() throw () {}
+
+} }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/unoidl/source/sourcefileprovider.hxx b/unoidl/source/sourcefileprovider.hxx
new file mode 100644
index 0000000..672f0d6
--- /dev/null
+++ b/unoidl/source/sourcefileprovider.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_UNOIDL_SOURCEFILEPROVIDER_HXX
+#define INCLUDED_UNOIDL_SOURCEFILEPROVIDER_HXX
+
+#include "sal/config.h"
+
+#include <map>
+
+#include "rtl/ref.hxx"
+#include "unoidl/unoidl.hxx"
+
+namespace unoidl { namespace detail {
+
+class SourceFileProvider: public Provider {
+public:
+    // throws FileFormatException, NoSuchFileException:
+    SourceFileProvider(
+        rtl::Reference<Manager> const & manager, OUString const & uri);
+
+    // throws FileFormatException:
+    virtual rtl::Reference<MapCursor> createRootCursor() const;
+
+    // throws FileFormatException:
+    virtual rtl::Reference<Entity> findEntity(OUString const & name) const;
+
+private:
+    virtual ~SourceFileProvider() throw ();
+
+    std::map< OUString, rtl::Reference<Entity> > rootMap_;
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/unoidl/source/unoidl.cxx b/unoidl/source/unoidl.cxx
index 19b8a9c..7c3e2e5 100644
--- a/unoidl/source/unoidl.cxx
+++ b/unoidl/source/unoidl.cxx
@@ -20,6 +20,7 @@
 #include "unoidl/unoidl.hxx"
 
 #include "legacyprovider.hxx"
+#include "sourcefileprovider.hxx"
 #include "sourcetreeprovider.hxx"
 #include "unoidlprovider.hxx"
 
@@ -117,6 +118,9 @@ rtl::Reference< Provider > loadProvider(
             return new detail::SourceTreeProvider(manager, uri);
         }
     }
+    if (uri.endsWith(".idl")) {
+        return new detail::SourceFileProvider(manager, uri);
+    }
     try {
         return new detail::UnoidlProvider(uri);
     } catch (FileFormatException & e) {
commit 6292bba6debaeb5c1bbbabfb77606296c894ec28
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Mon Sep 16 22:30:31 2013 +0200

    Rename SourceProvider -> SourceTreeProvider
    
    Change-Id: Ic864f9c6f3dbbe9f75bdae76818c00f62825182d

diff --git a/unoidl/Library_unoidl.mk b/unoidl/Library_unoidl.mk
index 5cffa49..411e0a9 100644
--- a/unoidl/Library_unoidl.mk
+++ b/unoidl/Library_unoidl.mk
@@ -13,7 +13,7 @@ $(eval $(call gb_Library_add_defs,unoidl,-DLO_DLLIMPLEMENTATION_UNOIDL))
 
 $(eval $(call gb_Library_add_exception_objects,unoidl, \
     unoidl/source/legacyprovider \
-    unoidl/source/sourceprovider \
+    unoidl/source/sourcetreeprovider \
     unoidl/source/unoidl \
     unoidl/source/unoidlprovider \
 ))
diff --git a/unoidl/source/sourceprovider.cxx b/unoidl/source/sourcetreeprovider.cxx
similarity index 93%
rename from unoidl/source/sourceprovider.cxx
rename to unoidl/source/sourcetreeprovider.cxx
index 64428eb..d389f0c 100755
--- a/unoidl/source/sourceprovider.cxx
+++ b/unoidl/source/sourcetreeprovider.cxx
@@ -23,7 +23,7 @@
 #include "sourceprovider-parser-requires.hxx"
 #include "sourceprovider-parser.hxx"
 #include "sourceprovider-scanner.hxx"
-#include "sourceprovider.hxx"
+#include "sourcetreeprovider.hxx"
 
 namespace unoidl { namespace detail {
 
@@ -56,16 +56,18 @@ private:
 
 }
 
-SourceProvider::SourceProvider(
+SourceTreeProvider::SourceTreeProvider(
     rtl::Reference<Manager> const & manager, OUString const & uri):
     manager_(manager), uri_(uri.endsWith("/") ? uri : uri + "/")
 {}
 
-rtl::Reference<MapCursor> SourceProvider::createRootCursor() const {
+rtl::Reference<MapCursor> SourceTreeProvider::createRootCursor() const {
     return new Cursor;
 }
 
-rtl::Reference<Entity> SourceProvider::findEntity(OUString const & name) const {
+rtl::Reference<Entity> SourceTreeProvider::findEntity(OUString const & name)
+    const
+{
     std::map< OUString, rtl::Reference<Entity> >::iterator ci(
         cache_.find(name));
     if (ci != cache_.end()) {
@@ -143,7 +145,7 @@ rtl::Reference<Entity> SourceProvider::findEntity(OUString const & name) const {
     return ent;
 }
 
-SourceProvider::~SourceProvider() throw () {}
+SourceTreeProvider::~SourceTreeProvider() throw () {}
 
 } }
 
diff --git a/unoidl/source/sourceprovider.hxx b/unoidl/source/sourcetreeprovider.hxx
similarity index 83%
rename from unoidl/source/sourceprovider.hxx
rename to unoidl/source/sourcetreeprovider.hxx
index e7ee92f..1bacad8 100644
--- a/unoidl/source/sourceprovider.hxx
+++ b/unoidl/source/sourcetreeprovider.hxx
@@ -7,8 +7,8 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#ifndef INCLUDED_UNOIDL_SOURCEPROVIDER_HXX
-#define INCLUDED_UNOIDL_SOURCEPROVIDER_HXX
+#ifndef INCLUDED_UNOIDL_SOURCETREEPROVIDER_HXX
+#define INCLUDED_UNOIDL_SOURCETREEPROVIDER_HXX
 
 #include "sal/config.h"
 
@@ -19,10 +19,10 @@
 
 namespace unoidl { namespace detail {
 
-class SourceProvider: public Provider {
+class SourceTreeProvider: public Provider {
 public:
     // throws FileFormatException, NoSuchFileException:
-    SourceProvider(
+    SourceTreeProvider(
         rtl::Reference<Manager> const & manager, OUString const & uri);
 
     // throws FileFormatException:
@@ -32,7 +32,7 @@ public:
     virtual rtl::Reference<Entity> findEntity(OUString const & name) const;
 
 private:
-    virtual ~SourceProvider() throw ();
+    virtual ~SourceTreeProvider() throw ();
 
     rtl::Reference<Manager> manager_;
     OUString uri_;
diff --git a/unoidl/source/unoidl.cxx b/unoidl/source/unoidl.cxx
index e5c3c43..19b8a9c 100644
--- a/unoidl/source/unoidl.cxx
+++ b/unoidl/source/unoidl.cxx
@@ -20,7 +20,7 @@
 #include "unoidl/unoidl.hxx"
 
 #include "legacyprovider.hxx"
-#include "sourceprovider.hxx"
+#include "sourcetreeprovider.hxx"
 #include "unoidlprovider.hxx"
 
 namespace unoidl {
@@ -114,7 +114,7 @@ rtl::Reference< Provider > loadProvider(
         if (item.getFileStatus(status) == osl::FileBase::E_None
             && status.getFileType() == osl::FileStatus::Directory)
         {
-            return new detail::SourceProvider(manager, uri);
+            return new detail::SourceTreeProvider(manager, uri);
         }
     }
     try {
commit d11592ad8e21970e80f6a87a9ae43d380f1c3eef
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Mon Sep 16 22:25:30 2013 +0200

    Move full file parsing logic to sourceprovider-parser.y
    
    ...in preparation of SourceFile- vs. -TreeProvider.
    
    Change-Id: I4c8f37ade1ba26cb7b38f63211711613d1b98a73

diff --git a/unoidl/source/sourceprovider-parser-requires.hxx b/unoidl/source/sourceprovider-parser-requires.hxx
index 0c52b3d..fc84c5d 100644
--- a/unoidl/source/sourceprovider-parser-requires.hxx
+++ b/unoidl/source/sourceprovider-parser-requires.hxx
@@ -23,8 +23,6 @@
 
 typedef void * yyscan_t;
 
-int yyparse(yyscan_t yyscanner);
-
 namespace unoidl { namespace detail {
 
 struct SourceProviderEntity;
diff --git a/unoidl/source/sourceprovider-parser.y b/unoidl/source/sourceprovider-parser.y
index cc18854..92deb23 100644
--- a/unoidl/source/sourceprovider-parser.y
+++ b/unoidl/source/sourceprovider-parser.y
@@ -19,10 +19,13 @@
 
 #include <algorithm>
 #include <cassert>
+#include <cerrno>
 #include <cstddef>
 #include <cstdlib>
 #include <limits>
+#include <new>
 #include <utility>
+#include <vector>
 
 #include <sourceprovider-parser-requires.hxx>
 
@@ -50,6 +53,9 @@
 
 %{
 
+#include "osl/file.h"
+#include "osl/thread.h"
+
 #include "sourceprovider-scanner.hxx"
 
 #define YYLLOC_DEFAULT(Current, Rhs, N) \
@@ -3657,6 +3663,87 @@ OUString SourceProviderType::getName() const {
     }
 }
 
+bool parse(OUString const & uri, SourceProviderScannerData * data) {
+    assert(data != 0);
+    oslFileHandle handle;
+    oslFileError e = osl_openFile(uri.pData, &handle, osl_File_OpenFlag_Read);
+    switch (e) {
+    case osl_File_E_None:
+        break;
+    case osl_File_E_NOENT:
+        return false;
+    default:
+        throw FileFormatException(uri, "cannot open: " + OUString::number(e));
+    }
+    sal_uInt64 size;
+    e = osl_getFileSize(handle, &size);
+    if (e != osl_File_E_None) {
+        oslFileError e2 = osl_closeFile(handle);
+        SAL_WARN_IF(
+            e2 != osl_File_E_None, "unoidl",
+            "cannot close " << uri << ": " << +e2);
+        throw FileFormatException(
+            uri, "cannot get size: " + OUString::number(e));
+    }
+    void * address;
+    e = osl_mapFile(handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
+    if (e != osl_File_E_None) {
+        oslFileError e2 = osl_closeFile(handle);
+        SAL_WARN_IF(
+            e2 != osl_File_E_None, "unoidl",
+            "cannot close " << uri << ": " << +e2);
+        throw FileFormatException(uri, "cannot mmap: " + OUString::number(e));
+    }
+    try {
+        data->setSource(address, size);
+        yyscan_t yyscanner;
+        if (yylex_init_extra(data, &yyscanner) != 0) {
+            // Checking errno for the specific EINVAL, ENOMEM documented for
+            // yylex_init_extra would not work as those values are not defined
+            // by the C++ Standard:
+            int e = errno;
+            throw FileFormatException(
+                uri,
+                "yylex_init_extra failed with errno " + OUString::number(e));
+        }
+        int e2 = yyparse(yyscanner);
+        yylex_destroy(yyscanner);
+        switch (e2) {
+        case 0:
+            break;
+        default:
+            assert(false);
+            // fall through
+        case 1:
+            throw FileFormatException(
+                uri,
+                ("cannot parse"
+                 + (data->errorLine == 0
+                    ? OUString() : " line " + OUString::number(data->errorLine))
+                 + (data->parserError.isEmpty()
+                    ? OUString()
+                    : (", "
+                       + OStringToOUString(
+                           data->parserError, osl_getThreadTextEncoding())))
+                 + (data->errorMessage.isEmpty()
+                    ? OUString() : ": \"" + data->errorMessage + "\"")));
+        case 2:
+            throw std::bad_alloc();
+        }
+    } catch (...) {
+        e = osl_unmapMappedFile(handle, address, size);
+        SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
+        e = osl_closeFile(handle);
+        SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
+        throw;
+    }
+    e = osl_unmapMappedFile(handle, address, size);
+    SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
+    e = osl_closeFile(handle);
+    SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
+    return true;
+}
+
 } }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/unoidl/source/sourceprovider-scanner.hxx b/unoidl/source/sourceprovider-scanner.hxx
index 5190058..8a79d31 100644
--- a/unoidl/source/sourceprovider-scanner.hxx
+++ b/unoidl/source/sourceprovider-scanner.hxx
@@ -213,17 +213,19 @@ struct SourceProviderEntity {
 
 struct SourceProviderScannerData {
     SourceProviderScannerData(
-        rtl::Reference<unoidl::Manager> const & theManager,
-        void const * sourceAddress, sal_uInt64 sourceSize):
-        manager(theManager),
-        sourcePosition(static_cast<char const *>(sourceAddress)),
-        sourceEnd(sourcePosition + sourceSize), errorLine(0)
+        rtl::Reference<unoidl::Manager> const & theManager):
+        manager(theManager), errorLine(0)
     { assert(manager.is()); }
 
+    void setSource(void const * address, sal_uInt64 size) {
+        sourcePosition = static_cast<char const *>(address);
+        sourceEnd = sourcePosition + size;
+    }
+
     rtl::Reference<unoidl::Manager> manager;
 
     char const * sourcePosition;
-    char const * const sourceEnd;
+    char const * sourceEnd;
     YYLTYPE errorLine;
     OString parserError;
     OUString errorMessage;
@@ -233,6 +235,8 @@ struct SourceProviderScannerData {
     OUString currentName;
 };
 
+bool parse(OUString const & uri, SourceProviderScannerData * data);
+
 } }
 
 int yylex_init_extra(
diff --git a/unoidl/source/sourceprovider.cxx b/unoidl/source/sourceprovider.cxx
index 429f68f..64428eb 100755
--- a/unoidl/source/sourceprovider.cxx
+++ b/unoidl/source/sourceprovider.cxx
@@ -9,13 +9,11 @@
 
 #include "sal/config.h"
 
-#include <cerrno>
 #include <map>
-#include <new>
+#include <vector>
 
 #include "osl/file.h"
 #include "osl/file.hxx"
-#include "osl/thread.h"
 #include "rtl/character.hxx"
 #include "rtl/ref.hxx"
 #include "rtl/ustrbuf.hxx"
@@ -31,51 +29,6 @@ namespace unoidl { namespace detail {
 
 namespace {
 
-rtl::Reference<Entity> parse(
-    rtl::Reference<Manager> const & manager, OUString const & name,
-    OUString const & uri, void const * address, sal_uInt64 size)
-{
-    SourceProviderScannerData data(manager, address, size);
-    yyscan_t yyscanner;
-    if (yylex_init_extra(&data, &yyscanner) != 0) {
-        // Checking errno for the specific EINVAL, ENOMEM documented for
-        // yylex_init_extra would not work as those values are not defined by
-        // the C++ Standard:
-        int e = errno;
-        throw FileFormatException(
-            uri, "yylex_init_extra failed with errno " + OUString::number(e));
-    }
-    int e = yyparse(yyscanner);
-    yylex_destroy(yyscanner);
-    switch (e) {
-    case 0:
-        {
-            std::map<OUString, SourceProviderEntity>::const_iterator i(
-                data.entities.find(name));
-            return i == data.entities.end()
-                ? rtl::Reference<Entity>() : i->second.entity;
-        }
-    default:
-        assert(false);
-        // fall through
-    case 1:
-        throw FileFormatException(
-            uri,
-            ("cannot parse"
-             + (data.errorLine == 0
-                ? OUString() : " line " + OUString::number(data.errorLine))
-             + (data.parserError.isEmpty()
-                ? OUString()
-                : (", "
-                   + OStringToOUString(
-                       data.parserError, osl_getThreadTextEncoding())))
-             + (data.errorMessage.isEmpty()
-                ? OUString() : ": \"" + data.errorMessage + "\"")));
-    case 2:
-        throw std::bad_alloc();
-    }
-}
-
 class Cursor: public MapCursor {
 public:
     Cursor() {}
@@ -173,55 +126,17 @@ rtl::Reference<Entity> SourceProvider::findEntity(OUString const & name) const {
         ent = new SourceModuleEntity;
     } else {
         uri += ".idl";
-        oslFileHandle handle;
-        oslFileError e = osl_openFile(
-            uri.pData, &handle, osl_File_OpenFlag_Read);
-        switch (e) {
-        case osl_File_E_None:
-            break;
-        case osl_File_E_NOENT:
-            cache_.insert(
-                std::map< OUString, rtl::Reference<Entity> >::value_type(
-                    name, rtl::Reference<Entity>()));
-            return rtl::Reference<Entity>();
-        default:
-            throw FileFormatException(
-                uri, "cannot open: " + OUString::number(e));
-        }
-        sal_uInt64 size;
-        e = osl_getFileSize(handle, &size);
-        if (e != osl_File_E_None) {
-            oslFileError e2 = osl_closeFile(handle);
-            SAL_WARN_IF(
-                e2 != osl_File_E_None, "unoidl",
-                "cannot close " << uri << ": " << +e2);
-            throw FileFormatException(
-                uri, "cannot get size: " + OUString::number(e));
-        }
-        void * address;
-        e = osl_mapFile(
-            handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
-        if (e != osl_File_E_None) {
-            oslFileError e2 = osl_closeFile(handle);
+        SourceProviderScannerData data(manager_);
+        if (parse(uri, &data)) {
+            std::map<OUString, SourceProviderEntity>::const_iterator i(
+                data.entities.find(name));
+            if (i != data.entities.end()) {
+                ent = i->second.entity;
+            }
             SAL_WARN_IF(
-                e2 != osl_File_E_None, "unoidl",
-                "cannot close " << uri << ": " << +e2);
-            throw FileFormatException(
-                uri, "cannot mmap: " + OUString::number(e));
-        }
-        try {
-            ent = parse(manager_, name, uri, address, size);
-        } catch (...) {
-            e = osl_unmapMappedFile(handle, address, size);
-            SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
-            e = osl_closeFile(handle);
-            SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
-            throw;
+                !ent.is(), "unoidl",
+                "<" << uri << "> does not define entity " << name);
         }
-        e = osl_unmapMappedFile(handle, address, size);
-        SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
-        e = osl_closeFile(handle);
-        SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
     }
     cache_.insert(
         std::map< OUString, rtl::Reference<Entity> >::value_type(name, ent));
commit 65a1f81a70e4268801a09106df54fcb2497c6d7d
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Mon Sep 16 21:53:14 2013 +0200

    Detect reuse of module names for other entities
    
    Change-Id: Ifc8d95b4b15a7dd91195e6f727fdb7fa2a267be9

diff --git a/unoidl/source/sourceprovider-parser.y b/unoidl/source/sourceprovider-parser.y
index 7d5f108..cc18854 100644
--- a/unoidl/source/sourceprovider-parser.y
+++ b/unoidl/source/sourceprovider-parser.y
@@ -460,6 +460,8 @@ Found findEntity(
                                         case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
                                             argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
                                             break;
+                                        case unoidl::detail::SourceProviderEntity::KIND_MODULE:
+                                            assert(false); // this cannot happen
                                         }
                                         argType
                                             = unoidl::detail::SourceProviderType(
@@ -546,6 +548,11 @@ Found findEntity(
                     e->entity = ent;
                 }
                 break;
+            case unoidl::detail::SourceProviderEntity::KIND_MODULE:
+                error(
+                    location, yyscanner,
+                    *name + " is based on module entity " + n);
+                return FOUND_ERROR;
             }
         }
         if (!typeNucleus.isEmpty() || rank != 0 || !args.empty()) {
@@ -696,6 +703,8 @@ Found findEntity(
                             unoidl::detail::SourceProviderType::TYPE_INTERFACE,
                             n, e);
                         break;
+                    case unoidl::detail::SourceProviderEntity::KIND_MODULE:
+                        assert(false); // this cannot happen
                     }
                 }
             } else {
@@ -757,6 +766,8 @@ Found findEntity(
                          + n
                          + " that is not a polymorphic struct type template"));
                     return FOUND_ERROR;
+                case unoidl::detail::SourceProviderEntity::KIND_MODULE:
+                    assert(false); // this cannot happen
                 }
             }
             if (typedefedType != 0) {
@@ -904,7 +915,21 @@ moduleDecl:
   TOK_MODULE identifier
   {
       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
-      data->modules.push_back(convertToFullName(data, $2));
+      OUString name(convertToFullName(data, $2));
+      data->modules.push_back(name);
+      std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p(
+          data->entities.insert(
+              std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
+                  name,
+                  unoidl::detail::SourceProviderEntity(
+                      unoidl::detail::SourceProviderEntity::KIND_MODULE))));
+      if (!p.second
+          && (p.first->second.kind
+              != unoidl::detail::SourceProviderEntity::KIND_MODULE))
+      {
+          error(@2, yyscanner, "multiple entities named " + name);
+          YYERROR;
+      }
   }
   '{' definitions '}' ';' { yyget_extra(yyscanner)->modules.pop_back(); }
 ;
@@ -2671,7 +2696,9 @@ interfaceDecl:
       std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p(
           data->entities.insert(
               std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
-                  name, unoidl::detail::SourceProviderEntity())));
+                  name,
+                  unoidl::detail::SourceProviderEntity(
+                      unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL))));
       if (!p.second
           && (p.first->second.kind
               != unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL))
@@ -3468,6 +3495,8 @@ type:
                       ent);
                   ok = true;
                   break;
+              case unoidl::detail::SourceProviderEntity::KIND_MODULE:
+                  assert(false); // this cannot happen
               }
               if (!ok) {
                   error(@1, yyscanner, "non-type entity " + name);
@@ -3533,6 +3562,8 @@ type:
           break;
       case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
           break;
+      case unoidl::detail::SourceProviderEntity::KIND_MODULE:
+          assert(false); // this cannot happen
       }
       if (!ok) {
           error(@1, yyscanner, "non-type entity " + name);
diff --git a/unoidl/source/sourceprovider-scanner.hxx b/unoidl/source/sourceprovider-scanner.hxx
index 152b9cf..5190058 100644
--- a/unoidl/source/sourceprovider-scanner.hxx
+++ b/unoidl/source/sourceprovider-scanner.hxx
@@ -189,19 +189,22 @@ private:
 };
 
 struct SourceProviderEntity {
-    enum Kind { KIND_EXTERNAL, KIND_LOCAL, KIND_INTERFACE_DECL };
+    enum Kind { KIND_EXTERNAL, KIND_LOCAL, KIND_INTERFACE_DECL, KIND_MODULE };
 
     explicit SourceProviderEntity(
         Kind theKind, rtl::Reference<unoidl::Entity> const & externalEntity):
         kind(theKind), entity(externalEntity)
-    { assert(theKind != KIND_INTERFACE_DECL); assert(externalEntity.is()); }
+    { assert(theKind <= KIND_LOCAL); assert(externalEntity.is()); }
 
     explicit SourceProviderEntity(
         rtl::Reference<SourceProviderEntityPad> const & localPad):
         kind(KIND_LOCAL), pad(localPad)
     { assert(localPad.is()); }
 
-    SourceProviderEntity(): kind(KIND_INTERFACE_DECL) {}
+    explicit SourceProviderEntity(Kind theKind): kind(theKind)
+    { assert(theKind >= KIND_INTERFACE_DECL); }
+
+    SourceProviderEntity() {} // needed for std::map::operator []
 
     Kind kind;
     rtl::Reference<unoidl::Entity> entity;
commit 04a002491b149bee6ba972e8288f867c791db19e
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Mon Sep 16 21:51:59 2013 +0200

    Fail for unkonwn entities
    
    Change-Id: I13d668e92ea762e9888f8c1c4615eccad6a1ff1b

diff --git a/codemaker/source/codemaker/typemanager.cxx b/codemaker/source/codemaker/typemanager.cxx
index ff0e6f9..7779704 100644
--- a/codemaker/source/codemaker/typemanager.cxx
+++ b/codemaker/source/codemaker/typemanager.cxx
@@ -54,6 +54,9 @@ bool TypeManager::foundAtPrimaryProvider(OUString const & name) const {
             return true;
         }
     }
+    if (!manager_->findEntity(name).is()) {
+        throw CannotDumpException("Unknown entity '" + name + "'");
+    }
     return false;
 }
 


More information about the Libreoffice-commits mailing list