[Libreoffice-commits] core.git: 2 commits - Repository.mk unoidl/Executable_unoidl-read.mk unoidl/Module_unoidl.mk unoidl/source

Stephan Bergmann sbergman at redhat.com
Tue Sep 17 09:30:49 PDT 2013


 Repository.mk                    |    1 
 unoidl/Executable_unoidl-read.mk |   22 
 unoidl/Module_unoidl.mk          |    1 
 unoidl/source/unoidl-read.cxx    | 1112 +++++++++++++++++++++++++++++++++++++++
 unoidl/source/unoidl-write.cxx   |   18 
 5 files changed, 1145 insertions(+), 9 deletions(-)

New commits:
commit 78dde8745e6fbc9ca73378d0ef093f3159d25d16
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Tue Sep 17 18:29:58 2013 +0200

    New unoidl-read tool to translate registries into readable .idl files
    
    Change-Id: Ibd6ce23d2698280105469fb75c4afa225dc237ee

diff --git a/Repository.mk b/Repository.mk
index b3111fb..d91c021 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -59,6 +59,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \
 	treex \
 	uiex \
 	ulfex \
+	unoidl-read \
 	unoidl-write \
 	xrmex \
 ))
diff --git a/unoidl/Executable_unoidl-read.mk b/unoidl/Executable_unoidl-read.mk
new file mode 100644
index 0000000..af9c5fd
--- /dev/null
+++ b/unoidl/Executable_unoidl-read.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Executable_Executable,unoidl-read))
+
+$(eval $(call gb_Executable_add_exception_objects,unoidl-read, \
+    unoidl/source/unoidl-read \
+))
+
+$(eval $(call gb_Executable_use_libraries,unoidl-read, \
+    sal \
+    salhelper \
+    unoidl \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/unoidl/Module_unoidl.mk b/unoidl/Module_unoidl.mk
index c035257..308ccf1 100644
--- a/unoidl/Module_unoidl.mk
+++ b/unoidl/Module_unoidl.mk
@@ -10,6 +10,7 @@
 $(eval $(call gb_Module_Module,unoidl))
 
 $(eval $(call gb_Module_add_targets,unoidl, \
+    Executable_unoidl-read \
     Library_unoidl \
 ))
 
diff --git a/unoidl/source/unoidl-read.cxx b/unoidl/source/unoidl-read.cxx
new file mode 100644
index 0000000..aaab9a8
--- /dev/null
+++ b/unoidl/source/unoidl-read.cxx
@@ -0,0 +1,1112 @@
+/* -*- 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 <cassert>
+#include <cstddef>
+#include <iostream>
+#include <map>
+#include <set>
+#include <utility>
+#include <vector>
+
+#include "config_version.h"
+#include "osl/endian.h"
+#include "osl/file.h"
+#include "osl/file.hxx"
+#include "osl/process.h"
+#include "rtl/process.h"
+#include "rtl/string.h"
+#include "rtl/string.hxx"
+#include "rtl/textenc.h"
+#include "rtl/textcvt.h"
+#include "rtl/ustring.hxx"
+#include "sal/macros.h"
+#include "sal/main.h"
+#include "unoidl/unoidl.hxx"
+
+namespace {
+
+void badUsage() {
+    std::cerr
+        << "Usage:" << std::endl << std::endl
+        << "  unoidl-read [--published] [<extra registries>] <registry>"
+        << std::endl << std::endl
+        << ("where each <registry> is either a new- or legacy-format .rdb file,"
+            " a single .idl")
+        << std::endl
+        << ("file, or a root directory of an .idl file tree.  The complete"
+            " content of the")
+        << std::endl
+        << ("last <registry> is written to stdout; if --published is specified,"
+            " only the")
+        << std::endl << "published entities are written out." << std::endl;
+    std::exit(EXIT_FAILURE);
+}
+
+OUString getArgumentUri(sal_uInt32 argument) {
+    OUString arg;
+    rtl_getAppCommandArg(argument, &arg.pData);
+    OUString url;
+    osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
+    if (e1 != osl::FileBase::E_None) {
+        std::cerr
+            << "Cannot convert \"" << arg << "\" to file URL, error code "
+            << +e1 << std::endl;
+        std::exit(EXIT_FAILURE);
+    }
+    OUString cwd;
+    oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
+    if (e2 != osl_Process_E_None) {
+        std::cerr
+            << "Cannot obtain working directory, error code " << +e2
+            << std::endl;
+        std::exit(EXIT_FAILURE);
+    }
+    OUString abs;
+    e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
+    if (e1 != osl::FileBase::E_None) {
+        std::cerr
+            << "Cannot make \"" << url
+            << "\" into an absolute file URL, error code " << +e1 << std::endl;
+        std::exit(EXIT_FAILURE);
+    }
+    return abs;
+}
+
+OUString decomposeType(
+    OUString const & type, std::size_t * rank,
+    std::vector<OUString> * typeArguments, bool * entity)
+{
+    assert(rank != 0);
+    assert(typeArguments != 0);
+    assert(entity != 0);
+    OUString nucl(type);
+    *rank = 0;
+    typeArguments->clear();
+    while (nucl.startsWith("[]")) {
+        ++*rank;
+        nucl = nucl.copy(2);
+    }
+    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()) {
+                typeArguments->push_back(nucl.copy(i, j - i));
+            }
+            i = j;
+        } while (i != nucl.getLength() && nucl[i] != '>');
+        assert(i == nucl.getLength() - 1 && nucl[i] == '>');
+        assert(!typeArguments->empty());
+        nucl = tmpl;
+    }
+    assert(!nucl.isEmpty());
+    *entity = nucl != "void" && nucl != "boolean" && nucl != "byte"
+        && nucl != "short" && nucl != "unsigned short" && nucl != "long"
+        && nucl != "unsigned long" && nucl != "hyper"
+        && nucl != "unsigned hyper" && nucl != "float" && nucl != "double"
+        && nucl != "char" && nucl != "string" && nucl != "type"
+        && nucl != "any";
+    assert(*entity || typeArguments->empty());
+    return nucl;
+}
+
+struct Entity {
+    explicit Entity(rtl::Reference<unoidl::Entity> const & theEntity):
+        entity(theEntity), sorted(false), written(false)
+    {}
+
+    rtl::Reference<unoidl::Entity> const entity;
+    std::set<OUString> dependencies;
+    std::set<OUString> interfaceDependencies;
+    bool sorted;
+    bool written;
+};
+
+void insertEntityDependency(
+    rtl::Reference<unoidl::Manager> const & manager,
+    std::map<OUString, Entity>::iterator const & iterator,
+    OUString const & name, bool weakInterfaceDependency = false)
+{
+    assert(manager.is());
+    if (name != iterator->first) {
+        bool ifc = false;
+        if (weakInterfaceDependency) {
+            rtl::Reference<unoidl::Entity> ent(manager->findEntity(name));
+            if (!ent.is()) {
+                std::cerr << "unknown entity " << name << std::endl;
+                std::exit(EXIT_FAILURE);
+            }
+            ifc = ent->getSort() == unoidl::Entity::SORT_INTERFACE_TYPE;
+        }
+        (ifc
+         ? iterator->second.interfaceDependencies
+         : iterator->second.dependencies)
+            .insert(name);
+    }
+}
+
+void insertEntityDependencies(
+    rtl::Reference<unoidl::Manager> const & manager,
+    std::map<OUString, Entity>::iterator const & iterator,
+    std::vector<OUString> const & names)
+{
+    for (std::vector<OUString>::const_iterator i(names.begin());
+         i != names.end(); ++i)
+    {
+        insertEntityDependency(manager, iterator, *i);
+    }
+}
+
+void insertEntityDependencies(
+    rtl::Reference<unoidl::Manager> const & manager,
+    std::map<OUString, Entity>::iterator const & iterator,
+    std::vector<unoidl::AnnotatedReference> const & references)
+{
+    for (std::vector<unoidl::AnnotatedReference>::const_iterator i(
+             references.begin());
+         i != references.end(); ++i)
+    {
+        insertEntityDependency(manager, iterator, i->name);
+    }
+}
+
+void insertTypeDependency(
+    rtl::Reference<unoidl::Manager> const & manager,
+    std::map<OUString, Entity>::iterator const & iterator,
+    OUString const & type)
+{
+    std::size_t rank;
+    std::vector<OUString> args;
+    bool entity;
+    OUString nucl(decomposeType(type, &rank, &args, &entity));
+    if (entity) {
+        insertEntityDependency(manager, iterator, nucl, true);
+        for (std::vector<OUString>::iterator i(args.begin()); i != args.end();
+             ++i)
+        {
+            insertTypeDependency(manager, iterator, *i);
+        }
+    }
+}
+
+void scanMap(
+    rtl::Reference<unoidl::Manager> const & manager,
+    rtl::Reference<unoidl::MapCursor> const & cursor, bool published,
+    OUString const & prefix, std::map<OUString, Entity> & entities)
+{
+    assert(cursor.is());
+    for (;;) {
+        OUString id;
+        rtl::Reference<unoidl::Entity> ent(cursor->getNext(&id));
+        if (!ent.is()) {
+            break;
+        }
+        OUString name(prefix + id);
+        if (ent->getSort() == unoidl::Entity::SORT_MODULE) {
+            scanMap(
+                manager,
+                static_cast<unoidl::ModuleEntity *>(ent.get())->createCursor(),
+                published, name + ".", entities);
+        } else if (!published
+                   || (static_cast<unoidl::PublishableEntity *>(ent.get())
+                       ->isPublished()))
+        {
+            std::map<OUString, Entity>::iterator i(
+                entities.insert(std::make_pair(name, Entity(ent))).first);
+            switch (ent->getSort()) {
+            case unoidl::Entity::SORT_MODULE:
+                assert(false); // this cannot happen
+            case unoidl::Entity::SORT_ENUM_TYPE:
+            case unoidl::Entity::SORT_CONSTANT_GROUP:
+                break;
+            case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
+                {
+                    rtl::Reference<unoidl::PlainStructTypeEntity> ent2(
+                        static_cast<unoidl::PlainStructTypeEntity *>(
+                            ent.get()));
+                    if (!ent2->getDirectBase().isEmpty()) {
+                        insertEntityDependency(
+                            manager, i, ent2->getDirectBase());
+                    }
+                    for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
+                             j(ent2->getDirectMembers().begin());
+                         j != ent2->getDirectMembers().end(); ++j)
+                    {
+                        insertTypeDependency(manager, i, j->type);
+                    }
+                    break;
+                }
+            case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
+                {
+                    rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
+                        ent2(
+                            static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
+                                ent.get()));
+                    for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
+                             j(ent2->getMembers().begin());
+                         j != ent2->getMembers().end(); ++j)
+                    {
+                        if (!j->parameterized) {
+                            insertTypeDependency(manager, i, j->type);
+                        }
+                    }
+                    break;
+                }
+            case unoidl::Entity::SORT_EXCEPTION_TYPE:
+                {
+                    rtl::Reference<unoidl::ExceptionTypeEntity> ent2(
+                        static_cast<unoidl::ExceptionTypeEntity *>(ent.get()));
+                    if (!ent2->getDirectBase().isEmpty()) {
+                        insertEntityDependency(
+                            manager, i, ent2->getDirectBase());
+                    }
+                    for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
+                             j(ent2->getDirectMembers().begin());
+                         j != ent2->getDirectMembers().end(); ++j)
+                    {
+                        insertTypeDependency(manager, i, j->type);
+                    }
+                    break;
+                }
+            case unoidl::Entity::SORT_INTERFACE_TYPE:
+                {
+                    rtl::Reference<unoidl::InterfaceTypeEntity> ent2(
+                        static_cast<unoidl::InterfaceTypeEntity *>(
+                            ent.get()));
+                    insertEntityDependencies(
+                        manager, i, ent2->getDirectMandatoryBases());
+                    insertEntityDependencies(
+                        manager, i, ent2->getDirectOptionalBases());
+                    for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
+                             j(ent2->getDirectAttributes().begin());
+                         j != ent2->getDirectAttributes().end(); ++j)
+                    {
+                        insertTypeDependency(manager, i, j->type);
+                    }
+                    for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
+                             j(ent2->getDirectMethods().begin());
+                         j != ent2->getDirectMethods().end(); ++j)
+                    {
+                        insertTypeDependency(manager, i, j->returnType);
+                        for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
+                                 k(j->parameters.begin());
+                             k != j->parameters.end(); ++k)
+                        {
+                            insertTypeDependency(manager, i, k->type);
+                        }
+                        insertEntityDependencies(manager, i, j->exceptions);
+                    }
+                    break;
+                }
+            case unoidl::Entity::SORT_TYPEDEF:
+                {
+                    rtl::Reference<unoidl::TypedefEntity> ent2(
+                        static_cast<unoidl::TypedefEntity *>(ent.get()));
+                    insertTypeDependency(manager, i, ent2->getType());
+                    break;
+                }
+            case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
+                {
+                    rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
+                        ent2(
+                            static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
+                                ent.get()));
+                    insertEntityDependency(manager, i, ent2->getBase());
+                    for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
+                             j(ent2->getConstructors().begin());
+                         j != ent2->getConstructors().end(); ++j)
+                    {
+                        for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter>::const_iterator
+                                 k(j->parameters.begin());
+                             k != j->parameters.end(); ++k)
+                        {
+                            insertTypeDependency(manager, i, k->type);
+                        }
+                        insertEntityDependencies(manager, i, j->exceptions);
+                    }
+                    break;
+                }
+            case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
+                {
+                    rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2(
+                        static_cast<unoidl::AccumulationBasedServiceEntity *>(
+                            ent.get()));
+                    insertEntityDependencies(
+                        manager, i, ent2->getDirectMandatoryBaseServices());
+                    insertEntityDependencies(
+                        manager, i, ent2->getDirectOptionalBaseServices());
+                    insertEntityDependencies(
+                        manager, i, ent2->getDirectMandatoryBaseInterfaces());
+                    insertEntityDependencies(
+                        manager, i, ent2->getDirectOptionalBaseInterfaces());
+                    for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
+                             j(ent2->getDirectProperties().begin());
+                         j != ent2->getDirectProperties().end(); ++j)
+                    {
+                        insertTypeDependency(manager, i, j->type);
+                    }
+                    break;
+                }
+            case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
+                {
+                    rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2(
+                        static_cast<unoidl::InterfaceBasedSingletonEntity *>(
+                            ent.get()));
+                    insertEntityDependency(manager, i, ent2->getBase());
+                    break;
+                }
+            case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
+                {
+                    rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2(
+                        static_cast<unoidl::ServiceBasedSingletonEntity *>(
+                            ent.get()));
+                    insertEntityDependency(manager, i, ent2->getBase());
+                    break;
+                }
+            }
+        }
+    }
+}
+
+void visit(
+    std::map<OUString, Entity> & entities,
+    std::map<OUString, Entity>::iterator const & iterator,
+    std::vector<OUString> & result)
+{
+    if (!iterator->second.sorted) {
+        // Doesn't bother to verify the graph is acyclic (which it is guaranteed
+        // to be for a consistent set of entities); a non-DAG will lead to
+        // infinite recursion/stack overflow:
+        for (std::set<OUString>::iterator i(
+                 iterator->second.dependencies.begin());
+             i != iterator->second.dependencies.end(); ++i)
+        {
+            std::map<OUString, Entity>::iterator j(entities.find(*i));
+            if (j != entities.end()) {
+                visit(entities, j, result);
+            }
+        }
+        iterator->second.sorted = true;
+        result.push_back(iterator->first);
+    }
+}
+
+std::vector<OUString> sort(std::map<OUString, Entity> & entities) {
+    std::vector<OUString> res;
+    for (std::map<OUString, Entity>::iterator i(entities.begin());
+         i != entities.end(); ++i)
+    {
+        visit(entities, i, res);
+    }
+    return res;
+}
+
+void indent(std::vector<OUString> const & modules, unsigned int extra = 0) {
+    for (std::vector<OUString>::size_type i = 0; i != modules.size(); ++i) {
+        std::cout << ' ';
+    }
+    for (unsigned int i = 0; i != extra; ++i) {
+        std::cout << ' ';
+    }
+}
+
+void closeModule(std::vector<OUString> & modules) {
+    assert(!modules.empty());
+    modules.pop_back();
+    indent(modules);
+    std::cout << "};\n";
+}
+
+OUString openModulesFor(std::vector<OUString> & modules, OUString const & name)
+{
+    std::vector<OUString>::iterator i(modules.begin());
+    for (sal_Int32 j = 0;;) {
+        OUString id(name.getToken(0, '.', j));
+        if (j == -1) {
+            indent(modules);
+            return id;
+        }
+        if (i != modules.end()) {
+            if (id == *i) {
+                ++i;
+                continue;
+            }
+            std::vector<OUString>::difference_type n = modules.end() - i;
+            assert(n > 0);
+            for (std::vector<OUString>::difference_type k = 0; k != n; ++k) {
+                closeModule(modules);
+            }
+            i = modules.end();
+        }
+        indent(modules);
+        std::cout << "module " << id << " {\n";
+        modules.push_back(id);
+        i = modules.end();
+    }
+}
+
+void writeName(OUString const & name) {
+    std::cout << "::" << name.replaceAll(".", "::");
+}
+
+void writeAnnotations(std::vector<OUString> const & annotations) {
+    if (!annotations.empty()) {
+        std::cout << "/**";
+        for (std::vector<OUString>::const_iterator i(annotations.begin());
+             i != annotations.end(); ++i)
+        {
+            //TODO: i->indexOf("*/") == -1
+            std::cout << " @" << *i;
+        }
+        std::cout << " */ ";
+    }
+}
+
+void writePublished(rtl::Reference<unoidl::PublishableEntity> const & entity) {
+    assert(entity.is());
+    if (entity->isPublished()) {
+        std::cout << "published ";
+    }
+}
+
+void writeAnnotationsPublished(
+    rtl::Reference<unoidl::PublishableEntity> const & entity)
+{
+    assert(entity.is());
+    writeAnnotations(entity->getAnnotations());
+    writePublished(entity);
+}
+
+void writeType(OUString const & type) {
+    std::size_t rank;
+    std::vector<OUString> args;
+    bool entity;
+    OUString nucl(decomposeType(type, &rank, &args, &entity));
+    for (std::size_t i = 0; i != rank; ++i) {
+        std::cout << "sequence< ";
+    }
+    if (entity) {
+        writeName(nucl);
+    } else {
+        std::cout << nucl;
+    }
+    if (!args.empty()) {
+        std::cout << "< ";
+        for (std::vector<OUString>::iterator i(args.begin()); i != args.end();
+             ++i)
+        {
+            if (i != args.begin()) {
+                std::cout << ", ";
+            }
+            writeType(*i);
+        }
+        std::cout << " >";
+    }
+    for (std::size_t i = 0; i != rank; ++i) {
+        std::cout << " >";
+    }
+}
+
+void writeExceptionSpecification(std::vector<OUString> const & exceptions) {
+    if (!exceptions.empty()) {
+        std::cout << " raises (";
+        for (std::vector<OUString>::const_iterator i(exceptions.begin());
+             i != exceptions.end(); ++i)
+        {
+            if (i != exceptions.begin()) {
+                std::cout << ", ";
+            }
+            writeName(*i);
+        }
+        std::cout << ')';
+    }
+}
+
+void writeEntity(
+    std::map<OUString, Entity> & entities, std::vector<OUString> & modules,
+    OUString const & name)
+{
+    std::map<OUString, Entity>::iterator i(entities.find(name));
+    if (i != entities.end()) {
+        assert(!i->second.written);
+        i->second.written = true;
+        for (std::set<OUString>::iterator j(
+                 i->second.interfaceDependencies.begin());
+             j != i->second.interfaceDependencies.end(); ++j)
+        {
+            std::map<OUString, Entity>::iterator k(entities.find(*j));
+            if (k != entities.end() && !k->second.written) {
+                OUString id(openModulesFor(modules, *j));
+                assert(
+                    k->second.entity->getSort()
+                    == unoidl::Entity::SORT_INTERFACE_TYPE);
+                writePublished(
+                    static_cast<unoidl::PublishableEntity *>(
+                        k->second.entity.get()));
+                std::cout << "interface " << id << ";\n";
+            }
+        }
+        OUString id(openModulesFor(modules, name));
+        rtl::Reference<unoidl::PublishableEntity> ent(
+            static_cast<unoidl::PublishableEntity *>(i->second.entity.get()));
+        switch (ent->getSort()) {
+        case unoidl::Entity::SORT_MODULE:
+            assert(false); // this cannot happen
+        case unoidl::Entity::SORT_ENUM_TYPE:
+            {
+                rtl::Reference<unoidl::EnumTypeEntity> ent2(
+                    static_cast<unoidl::EnumTypeEntity *>(ent.get()));
+                writeAnnotationsPublished(ent);
+                std::cout << "enum " << id << " {\n";
+                for (std::vector<unoidl::EnumTypeEntity::Member>::const_iterator
+                         j(ent2->getMembers().begin());
+                     j != ent2->getMembers().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    std::cout << j->name << " = " << j->value;
+                    if (j + 1 != ent2->getMembers().end()) {
+                        std::cout << ',';
+                    }
+                    std::cout << '\n';
+                }
+                indent(modules);
+                std::cout << "};\n";
+                break;
+            }
+        case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
+            {
+                rtl::Reference<unoidl::PlainStructTypeEntity> ent2(
+                    static_cast<unoidl::PlainStructTypeEntity *>(ent.get()));
+                writeAnnotationsPublished(ent);
+                std::cout << "struct " << id;
+                if (!ent2->getDirectBase().isEmpty()) {
+                    std::cout << ": ";
+                    writeName(ent2->getDirectBase());
+                }
+                std::cout << " {\n";
+                for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
+                         j(ent2->getDirectMembers().begin());
+                     j != ent2->getDirectMembers().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    writeType(j->type);
+                    std::cout << ' ' << j->name << ";\n";
+                }
+                indent(modules);
+                std::cout << "};\n";
+                break;
+            }
+        case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
+            {
+                rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
+                    ent2(
+                        static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
+                            ent.get()));
+                writeAnnotationsPublished(ent);
+                std::cout << "struct " << id << '<';
+                for (std::vector<OUString>::const_iterator j(
+                         ent2->getTypeParameters().begin());
+                     j != ent2->getTypeParameters().end(); ++j)
+                {
+                    if (j != ent2->getTypeParameters().begin()) {
+                        std::cout << ", ";
+                    }
+                    std::cout << *j;
+                }
+                std::cout << ">  {\n";
+                for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
+                         j(ent2->getMembers().begin());
+                     j != ent2->getMembers().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    if (j->parameterized) {
+                        std::cout << j->type;
+                    } else {
+                        writeType(j->type);
+                    }
+                    std::cout << ' ' << j->name << ";\n";
+                }
+                indent(modules);
+                std::cout << "};\n";
+                break;
+            }
+        case unoidl::Entity::SORT_EXCEPTION_TYPE:
+            {
+                rtl::Reference<unoidl::ExceptionTypeEntity> ent2(
+                    static_cast<unoidl::ExceptionTypeEntity *>(ent.get()));
+                writeAnnotationsPublished(ent);
+                std::cout << "exception " << id;
+                if (!ent2->getDirectBase().isEmpty()) {
+                    std::cout << ": ";
+                    writeName(ent2->getDirectBase());
+                }
+                std::cout << " {\n";
+                for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
+                         j(ent2->getDirectMembers().begin());
+                     j != ent2->getDirectMembers().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    writeType(j->type);
+                    std::cout << ' ' << j->name << ";\n";
+                }
+                indent(modules);
+                std::cout << "};\n";
+                break;
+            }
+        case unoidl::Entity::SORT_INTERFACE_TYPE:
+            {
+                rtl::Reference<unoidl::InterfaceTypeEntity> ent2(
+                    static_cast<unoidl::InterfaceTypeEntity *>(
+                        ent.get()));
+                writeAnnotationsPublished(ent);
+                std::cout << "interface " << id << " {\n";
+                for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
+                         ent2->getDirectMandatoryBases().begin());
+                     j != ent2->getDirectMandatoryBases().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    std::cout << "interface ";
+                    writeName(j->name);
+                    std::cout << ";\n";
+                }
+                for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
+                         ent2->getDirectOptionalBases().begin());
+                     j != ent2->getDirectOptionalBases().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    std::cout << "[optional] interface ";
+                    writeName(j->name);
+                    std::cout << ";\n";
+                }
+                for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
+                         j(ent2->getDirectAttributes().begin());
+                     j != ent2->getDirectAttributes().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    std::cout << "[attribute";
+                    if (j->bound) {
+                        std::cout << ", bound";
+                    }
+                    if (j->readOnly) {
+                        std::cout << ", readonly";
+                    }
+                    std::cout << "] ";
+                    writeType(j->type);
+                    std::cout << ' ' << j->name;
+                    if (!(j->getExceptions.empty() && j->setExceptions.empty()))
+                    {
+                        std::cout << " {\n";
+                        if (!j->getExceptions.empty()) {
+                            indent(modules, 2);
+                            std::cout << "get";
+                            writeExceptionSpecification(j->getExceptions);
+                            std::cout << ";\n";
+                        }
+                        if (!j->setExceptions.empty()) {
+                            indent(modules, 2);
+                            std::cout << "set";
+                            writeExceptionSpecification(j->setExceptions);
+                            std::cout << ";\n";
+                        }
+                        std::cout << " }";
+                    }
+                    std::cout << ";\n";
+                }
+                for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
+                         j(ent2->getDirectMethods().begin());
+                     j != ent2->getDirectMethods().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    writeType(j->returnType);
+                    std::cout << ' ' << j->name << '(';
+                    for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
+                             k(j->parameters.begin());
+                         k != j->parameters.end(); ++k)
+                    {
+                        if (k != j->parameters.begin()) {
+                            std::cout << ", ";
+                        }
+                        switch (k->direction) {
+                        case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN:
+                            std::cout << "[in] ";
+                            break;
+                        case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT:
+                            std::cout << "[out] ";
+                            break;
+                        case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT:
+                            std::cout << "[inout] ";
+                            break;
+                        }
+                        writeType(k->type);
+                        std::cout << ' ' << k->name;
+                    }
+                    std::cout << ')';
+                    writeExceptionSpecification(j->exceptions);
+                    std::cout << ";\n";
+                }
+                indent(modules);
+                std::cout << "};\n";
+                break;
+            }
+        case unoidl::Entity::SORT_TYPEDEF:
+            {
+                rtl::Reference<unoidl::TypedefEntity> ent2(
+                    static_cast<unoidl::TypedefEntity *>(ent.get()));
+                writeAnnotationsPublished(ent);
+                std::cout << "typedef ";
+                writeType(ent2->getType());
+                std::cout << id << ";\n";
+                break;
+            }
+        case unoidl::Entity::SORT_CONSTANT_GROUP:
+            {
+                rtl::Reference<unoidl::ConstantGroupEntity> ent2(
+                    static_cast<unoidl::ConstantGroupEntity *>(ent.get()));
+                writeAnnotationsPublished(ent);
+                std::cout << "constants " << id << " {\n";
+                for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
+                         j(ent2->getMembers().begin());
+                     j != ent2->getMembers().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    std::cout << "const ";
+                    switch (j->value.type) {
+                    case unoidl::ConstantValue::TYPE_BOOLEAN:
+                        std::cout << "boolean";
+                        break;
+                    case unoidl::ConstantValue::TYPE_BYTE:
+                        std::cout << "byte";
+                        break;
+                    case unoidl::ConstantValue::TYPE_SHORT:
+                        std::cout << "short";
+                        break;
+                    case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
+                        std::cout << "unsigned short";
+                        break;
+                    case unoidl::ConstantValue::TYPE_LONG:
+                        std::cout << "long";
+                        break;
+                    case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
+                        std::cout << "unsigned long";
+                        break;
+                    case unoidl::ConstantValue::TYPE_HYPER:
+                        std::cout << "hyper";
+                        break;
+                    case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
+                        std::cout << "unsigned hyper";
+                        break;
+                    case unoidl::ConstantValue::TYPE_FLOAT:
+                        std::cout << "float";
+                        break;
+                    case unoidl::ConstantValue::TYPE_DOUBLE:
+                        std::cout << "double";
+                        break;
+                    }
+                    std::cout << ' ' << j->name << " = ";
+                    switch (j->value.type) {
+                    case unoidl::ConstantValue::TYPE_BOOLEAN:
+                        std::cout << (j->value.booleanValue ? "TRUE" : "FALSE");
+                        break;
+                    case unoidl::ConstantValue::TYPE_BYTE:
+                        std::cout << j->value.byteValue;
+                        break;
+                    case unoidl::ConstantValue::TYPE_SHORT:
+                        std::cout << j->value.shortValue;
+                        break;
+                    case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
+                        std::cout << j->value.unsignedShortValue;
+                        break;
+                    case unoidl::ConstantValue::TYPE_LONG:
+                        std::cout << j->value.longValue;
+                        break;
+                    case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
+                        std::cout << j->value.unsignedLongValue;
+                        break;
+                    case unoidl::ConstantValue::TYPE_HYPER:
+                        std::cout << j->value.hyperValue;
+                        break;
+                    case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
+                        std::cout << j->value.unsignedHyperValue;
+                        break;
+                    case unoidl::ConstantValue::TYPE_FLOAT:
+                        std::cout << j->value.floatValue;
+                        break;
+                    case unoidl::ConstantValue::TYPE_DOUBLE:
+                        std::cout << j->value.doubleValue;
+                        break;
+                    }
+                    std::cout << ";\n";
+                }
+                indent(modules);
+                std::cout << "};\n";
+                break;
+            }
+        case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
+            {
+                rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity> ent2(
+                    static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
+                        ent.get()));
+                writeAnnotationsPublished(ent);
+                std::cout << "service " << id << ": ";
+                writeName(ent2->getBase());
+                if (ent2->getConstructors().size() != 1
+                    || !ent2->getConstructors().front().defaultConstructor)
+                {
+                    std::cout << " {\n";
+                    for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
+                             j(ent2->getConstructors().begin());
+                         j != ent2->getConstructors().end(); ++j)
+                    {
+                        indent(modules, 1);
+                        writeAnnotations(j->annotations);
+                        std::cout << j->name << '(';
+                        for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter>::const_iterator
+                                 k(j->parameters.begin());
+                             k != j->parameters.end(); ++k)
+                        {
+                            if (k != j->parameters.begin()) {
+                                std::cout << ", ";
+                            }
+                            std::cout << "[in] ";
+                            writeType(k->type);
+                            if (k->rest) {
+                                std::cout << "...";
+                            }
+                            std::cout << ' ' << k->name;
+                        }
+                        std::cout << ')';
+                        writeExceptionSpecification(j->exceptions);
+                        std::cout << ";\n";
+                    }
+                    indent(modules);
+                    std::cout << '}';
+                }
+                std::cout << ";\n";
+                break;
+            }
+        case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
+            {
+                rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2(
+                    static_cast<unoidl::AccumulationBasedServiceEntity *>(
+                        ent.get()));
+                writeAnnotationsPublished(ent);
+                std::cout << "service " << id << " {\n";
+                for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
+                         ent2->getDirectMandatoryBaseServices().begin());
+                     j != ent2->getDirectMandatoryBaseServices().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    std::cout << "service ";
+                    writeName(j->name);
+                    std::cout << ";\n";
+                }
+                for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
+                         ent2->getDirectOptionalBaseServices().begin());
+                     j != ent2->getDirectOptionalBaseServices().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    std::cout << "[optional] service ";
+                    writeName(j->name);
+                    std::cout << ";\n";
+                }
+                for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
+                         ent2->getDirectMandatoryBaseInterfaces().begin());
+                     j != ent2->getDirectMandatoryBaseInterfaces().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    std::cout << "interface ";
+                    writeName(j->name);
+                    std::cout << ";\n";
+                }
+                for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
+                         ent2->getDirectOptionalBaseInterfaces().begin());
+                     j != ent2->getDirectOptionalBaseInterfaces().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    std::cout << "[optional] interface ";
+                    writeName(j->name);
+                    std::cout << ";\n";
+                }
+                for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
+                         j(ent2->getDirectProperties().begin());
+                     j != ent2->getDirectProperties().end(); ++j)
+                {
+                    indent(modules, 1);
+                    writeAnnotations(j->annotations);
+                    std::cout << "[property";
+                    if ((j->attributes
+                         & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND)
+                        != 0)
+                    {
+                        std::cout << ", bound";
+                    }
+                    if ((j->attributes
+                         & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED)
+                        != 0)
+                    {
+                        std::cout << ", constrained";
+                    }
+                    if ((j->attributes
+                         & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS)
+                        != 0)
+                    {
+                        std::cout << ", maybeambiguous";
+                    }
+                    if ((j->attributes
+                         & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT)
+                        != 0)
+                    {
+                        std::cout << ", maybedefault";
+                    }
+                    if ((j->attributes
+                         & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID)
+                        != 0)
+                    {
+                        std::cout << ", maybevoid";
+                    }
+                    if ((j->attributes
+                         & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL)
+                        != 0)
+                    {
+                        std::cout << ", optional";
+                    }
+                    if ((j->attributes
+                         & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY)
+                        != 0)
+                    {
+                        std::cout << ", readonly";
+                    }
+                    if ((j->attributes
+                         & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE)
+                        != 0)
+                    {
+                        std::cout << ", removable";
+                    }
+                    if ((j->attributes
+                         & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT)
+                        != 0)
+                    {
+                        std::cout << ", transient";
+                    }
+                    std::cout << "] ";
+                    writeType(j->type);
+                    std::cout << ' ' << j->name << ";\n";
+                }
+                indent(modules);
+                std::cout << "};\n";
+                break;
+            }
+        case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
+            {
+                rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2(
+                    static_cast<unoidl::InterfaceBasedSingletonEntity *>(
+                        ent.get()));
+                writeAnnotationsPublished(ent);
+                std::cout << "singleton " << id << ": ";
+                writeName(ent2->getBase());
+                std::cout << ";\n";
+                break;
+            }
+        case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
+            {
+                rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2(
+                    static_cast<unoidl::ServiceBasedSingletonEntity *>(
+                        ent.get()));
+                writeAnnotationsPublished(ent);
+                std::cout << "singleton " << id << " { service ";
+                writeName(ent2->getBase());
+                std::cout << "; };";
+                break;
+            }
+        }
+    }
+}
+
+}
+
+SAL_IMPLEMENT_MAIN() {
+    try {
+        sal_uInt32 args = rtl_getAppCommandArgCount();
+        if (args == 0) {
+            badUsage();
+        }
+        OUString arg;
+        rtl_getAppCommandArg(0, &arg.pData);
+        bool published = arg == "--published";
+        if (published && args == 1) {
+            badUsage();
+        }
+        rtl::Reference<unoidl::Manager> mgr(new unoidl::Manager);
+        rtl::Reference<unoidl::Provider> prov;
+        for (sal_uInt32 i = (published ? 1 : 0); i != args; ++i) {
+            OUString uri(getArgumentUri(i));
+            try {
+                prov = unoidl::loadProvider(mgr, uri);
+            } catch (unoidl::NoSuchFileException &) {
+                std::cerr
+                    << "Input <" << uri << "> does not exist" << std::endl;
+                std::exit(EXIT_FAILURE);
+            }
+            mgr->addProvider(prov);
+        }
+        std::map<OUString, Entity> ents;
+        scanMap(mgr, prov->createRootCursor(), published, "", ents);
+        std::vector<OUString> sorted(sort(ents));
+        std::vector<OUString> mods;
+        for (std::vector<OUString>::iterator i(sorted.begin());
+             i != sorted.end(); ++i)
+        {
+            writeEntity(ents, mods, *i);
+        }
+        while (!mods.empty()) {
+            closeModule(mods);
+        }
+        return EXIT_SUCCESS;
+    } catch (unoidl::FileFormatException & e1) {
+        std::cerr
+            << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
+            << std::endl;
+        std::exit(EXIT_FAILURE);
+    }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 3a576e36604dcd8027dc134febd6677af90ef237
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Tue Sep 17 18:25:17 2013 +0200

    Fix usage message
    
    Change-Id: I7d8b196d047b1e0075acdbf380a9b3ed750a7b90

diff --git a/unoidl/source/unoidl-write.cxx b/unoidl/source/unoidl-write.cxx
index dbb3ef7..ad9268e 100644
--- a/unoidl/source/unoidl-write.cxx
+++ b/unoidl/source/unoidl-write.cxx
@@ -39,18 +39,18 @@ void badUsage() {
         << "Usage:" << std::endl << std::endl
         << "  unoidl-write [<registries>] [@<entities file>] <unoidl file>"
         << std::endl << std::endl
-        << ("where each <registry> is either a new- or legacy-format .rdb"
-            " file or a")
+        << ("where each <registry> is either a new- or legacy-format .rdb file,"
+            " a single .idl")
         << std::endl
-        << ("root directory of an .idl file tree, and the UTF-8 encoded"
-            " <entities file>")
+        << ("file, or a root directory of an .idl file tree; and the UTF-8"
+            " encoded <entities")
         << std::endl
-        << ("contains zero or more space-separated names of (non-module)"
-            " entities to include")
+        << ("file> contains zero or more space-separated names of (non-module)"
+            " entities to")
         << std::endl
-        << ("in the output, and, if omitted, defaults to the complete content"
-            " of the final")
-        << std::endl << "<registry>, if any." << std::endl;
+        << ("include in the output, and, if omitted, defaults to the complete"
+            " content of the")
+        << std::endl << "last <registry>, if any." << std::endl;
     std::exit(EXIT_FAILURE);
 }
 


More information about the Libreoffice-commits mailing list