summaryrefslogtreecommitdiffstats
path: root/codemaker/source/codemaker
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /codemaker/source/codemaker
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'codemaker/source/codemaker')
-rw-r--r--codemaker/source/codemaker/codemaker.cxx46
-rw-r--r--codemaker/source/codemaker/exceptiontree.cxx93
-rw-r--r--codemaker/source/codemaker/global.cxx367
-rw-r--r--codemaker/source/codemaker/options.cxx41
-rw-r--r--codemaker/source/codemaker/typemanager.cxx258
-rw-r--r--codemaker/source/codemaker/unotype.cxx70
6 files changed, 875 insertions, 0 deletions
diff --git a/codemaker/source/codemaker/codemaker.cxx b/codemaker/source/codemaker/codemaker.cxx
new file mode 100644
index 000000000..cb797533e
--- /dev/null
+++ b/codemaker/source/codemaker/codemaker.cxx
@@ -0,0 +1,46 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <codemaker/codemaker.hxx>
+#include <codemaker/global.hxx>
+#include <rtl/string.hxx>
+#include <rtl/textcvt.h>
+#include <rtl/textenc.h>
+#include <rtl/ustring.hxx>
+
+namespace codemaker {
+
+OString convertString(OUString const & string) {
+ OString s;
+ if (!string.convertToString(
+ &s, RTL_TEXTENCODING_UTF8,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ throw CannotDumpException(
+ "Failure converting string from UTF-16 to UTF-8");
+ }
+ return s;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/codemaker/source/codemaker/exceptiontree.cxx b/codemaker/source/codemaker/exceptiontree.cxx
new file mode 100644
index 000000000..148f017b6
--- /dev/null
+++ b/codemaker/source/codemaker/exceptiontree.cxx
@@ -0,0 +1,93 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <codemaker/exceptiontree.hxx>
+#include <codemaker/typemanager.hxx>
+
+#include <rtl/ref.hxx>
+#include <rtl/string.hxx>
+#include <rtl/textenc.h>
+#include <rtl/ustring.hxx>
+#include <unoidl/unoidl.hxx>
+
+#include <memory>
+#include <vector>
+
+using codemaker::ExceptionTree;
+using codemaker::ExceptionTreeNode;
+
+ExceptionTreeNode * ExceptionTreeNode::add(OString const & theName) {
+ std::unique_ptr< ExceptionTreeNode > node(new ExceptionTreeNode(theName));
+ children.push_back(std::move(node));
+ return children.back().get();
+}
+
+void ExceptionTreeNode::clearChildren() {
+ children.clear();
+}
+
+void ExceptionTree::add(
+ OString const & name, rtl::Reference< TypeManager > const & manager)
+{
+ std::vector< OString > list;
+ bool bRuntimeException = false;
+ for (OString n(name); n != "com.sun.star.uno.Exception";) {
+ if (n == "com.sun.star.uno.RuntimeException") {
+ bRuntimeException = true;
+ break;
+ }
+ list.push_back(n);
+ rtl::Reference< unoidl::Entity > ent;
+ codemaker::UnoType::Sort s = manager->getSort(b2u(n), &ent);
+ (void) s; // WaE: unused variable
+ assert(s == codemaker::UnoType::Sort::Exception);
+ n = u2b(
+ static_cast< unoidl::ExceptionTypeEntity * >(ent.get())->
+ getDirectBase());
+ assert(!n.isEmpty());
+ }
+ if (bRuntimeException)
+ return;
+
+ ExceptionTreeNode * node = &m_root;
+ for (std::vector< OString >::reverse_iterator i(list.rbegin());
+ !node->present; ++i)
+ {
+ if (i == list.rend()) {
+ node->setPresent();
+ break;
+ }
+ for (ExceptionTreeNode::Children::iterator j(
+ node->children.begin());;
+ ++j)
+ {
+ if (j == node->children.end()) {
+ node = node->add(*i);
+ break;
+ }
+ if ((*j)->name == *i) {
+ node = j->get();
+ break;
+ }
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/codemaker/source/codemaker/global.cxx b/codemaker/source/codemaker/global.cxx
new file mode 100644
index 000000000..1310a0b05
--- /dev/null
+++ b/codemaker/source/codemaker/global.cxx
@@ -0,0 +1,367 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <osl/process.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/thread.h>
+#include <osl/file.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <string.h>
+#include <string_view>
+#include <errno.h>
+
+#if defined(_WIN32)
+# include <io.h>
+# include <direct.h>
+#endif
+
+#ifdef UNX
+# include <sys/stat.h>
+# include <unistd.h>
+#endif
+
+#include <codemaker/global.hxx>
+
+#ifdef SAL_UNX
+#define SEPARATOR '/'
+#else
+#define SEPARATOR '\\'
+#endif
+
+using namespace ::osl;
+
+
+OString getTempDir(const OString& sFileName)
+{
+ sal_Int32 index = 0;
+#ifdef SAL_UNX
+ if ((index=sFileName.lastIndexOf('/')) > 0)
+ return sFileName.copy(0, index);
+#else
+ if ((index=sFileName.lastIndexOf('\\')) > 0)
+ return sFileName.copy(0, index);
+#endif
+ return ".";
+}
+
+OString createFileNameFromType( const OString& destination,
+ const OString& typeName,
+ const OString& postfix )
+{
+ OString type(typeName.replace('.', '/'));
+
+ sal_Int32 length = destination.getLength();
+
+ bool bWithPoint = false;
+ if (length == 0)
+ {
+ length++;
+ bWithPoint = true;
+ }
+
+ length += type.getLength() + postfix.getLength();
+
+ bool bWithSeparator = false;
+ if (!(destination.endsWith("\\") || destination.endsWith("/"))
+ && !(type.startsWith("\\") || type.startsWith("/")))
+ {
+ length++;
+ bWithSeparator = true;
+ }
+
+ OStringBuffer fileNameBuf(length);
+
+ if (bWithPoint)
+ fileNameBuf.append('.');
+ else
+ fileNameBuf.append(destination);
+
+ if (bWithSeparator)
+ fileNameBuf.append("/");
+
+ fileNameBuf.append(type);
+ fileNameBuf.append(postfix);
+
+ OString fileName(fileNameBuf.makeStringAndClear());
+
+ char token;
+#ifdef SAL_UNX
+ fileName = fileName.replace('\\', '/');
+ token = '/';
+#else
+ fileName = fileName.replace('/', '\\');
+ token = '\\';
+#endif
+
+ OStringBuffer buffer(length);
+
+ sal_Int32 nIndex = 0;
+ do
+ {
+ buffer.append(o3tl::getToken(fileName, 0, token, nIndex));
+ if( nIndex == -1 )
+ break;
+
+ if (buffer.isEmpty() || std::string_view(".") == buffer)
+ {
+ buffer.append(token);
+ continue;
+ }
+
+#if defined(SAL_UNX)
+ if (mkdir(buffer.getStr(), 0777) == -1)
+#else
+ if (mkdir(buffer.getStr()) == -1)
+#endif
+ {
+ if ( errno == ENOENT )
+ return OString();
+ }
+
+ buffer.append(token);
+ } while(true);
+
+ OUString uSysFileName;
+ OSL_VERIFY( FileBase::getSystemPathFromFileURL(
+ convertToFileUrl(fileName), uSysFileName) == FileBase::E_None );
+ return OUStringToOString(uSysFileName, osl_getThreadTextEncoding());
+}
+
+bool fileExists(const OString& fileName)
+{
+ FILE *f= fopen(fileName.getStr(), "r");
+
+ if (f != nullptr)
+ {
+ fclose(f);
+ return true;
+ }
+
+ return false;
+}
+
+static bool checkFileContent(const OString& targetFileName, const OString& tmpFileName)
+{
+ FILE *target = fopen(targetFileName.getStr(), "r");
+ FILE *tmp = fopen(tmpFileName.getStr(), "r");
+ bool bFindChanges = false;
+
+ if (target != nullptr && tmp != nullptr)
+ {
+ char buffer1[1024+1];
+ char buffer2[1024+1];
+ sal_Int32 n1 = 0;
+ sal_Int32 n2 = 0;
+
+ while ( !bFindChanges && !feof(target) && !feof(tmp))
+ {
+ n1 = fread(buffer1, sizeof(char), 1024, target);
+ n2 = fread(buffer2, sizeof(char), 1024, tmp);
+
+ if ( n1 != n2 )
+ bFindChanges = true;
+ else
+ if ( memcmp(buffer1, buffer2, n2) != 0 )
+ bFindChanges = true;
+ }
+ }
+
+ if (target) fclose(target);
+ if (tmp) fclose(tmp);
+
+ return bFindChanges;
+}
+
+bool makeValidTypeFile(const OString& targetFileName, const OString& tmpFileName,
+ bool bFileCheck)
+{
+ if (bFileCheck) {
+ if (checkFileContent(targetFileName, tmpFileName)) {
+ if ( !unlink(targetFileName.getStr()) )
+ if ( !rename(tmpFileName.getStr(), targetFileName.getStr()) )
+ return true;
+ } else
+ return removeTypeFile(tmpFileName);
+ } else {
+ if (fileExists(targetFileName))
+ if (!removeTypeFile(targetFileName))
+ return false;
+
+ if ( rename(tmpFileName.getStr(), targetFileName.getStr()) ) {
+ if (errno == EEXIST)
+ return true;
+ } else
+ return true;
+ }
+ return false;
+}
+
+bool removeTypeFile(const OString& fileName)
+{
+ return unlink(fileName.getStr()) == 0;
+}
+
+OUString convertToFileUrl(const OString& fileName)
+{
+ if ( fileName.startsWith("file://") )
+ {
+ return OStringToOUString(fileName, osl_getThreadTextEncoding());
+ }
+
+ OUString uUrlFileName;
+ OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
+ if ( fileName.startsWith(".") || fileName.indexOf(SEPARATOR) < 0 )
+ {
+ OUString uWorkingDir;
+ if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None)
+ {
+ OSL_ASSERT(false);
+ }
+ if (FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName)
+ != FileBase::E_None)
+ {
+ OSL_ASSERT(false);
+ }
+ } else
+ {
+ if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName)
+ != FileBase::E_None)
+ {
+ OSL_ASSERT(false);
+ }
+ }
+
+ return uUrlFileName;
+}
+
+
+// FileStream
+
+FileStream::FileStream()
+ : m_file(nullptr)
+{
+}
+
+FileStream::~FileStream()
+{
+ if ( isValid() )
+ osl_closeFile(m_file);
+}
+
+bool FileStream::isValid() const
+{
+ return m_file != nullptr;
+}
+
+void FileStream::createTempFile(const OString& sPath)
+{
+ OString sTmp(".");
+ OUString sTmpPath;
+ OUString sTmpName;
+
+ if (!sPath.isEmpty())
+ sTmp = sPath;
+
+ sTmpPath = convertToFileUrl(sTmp);
+
+ if (osl_createTempFile(sTmpPath.pData, &m_file, &sTmpName.pData) == osl_File_E_None) {
+#ifdef SAL_UNX
+ sal_uInt64 const uAttr = osl_File_Attribute_OwnWrite |
+ osl_File_Attribute_OwnRead |
+ osl_File_Attribute_GrpWrite |
+ osl_File_Attribute_GrpRead |
+ osl_File_Attribute_OthRead;
+ if (osl_setFileAttributes(sTmpName.pData, uAttr) != osl_File_E_None) {
+ m_file = nullptr;
+ return;
+ }
+#endif
+ OUString sSysTmpName;
+ FileBase::getSystemPathFromFileURL(sTmpName, sSysTmpName);
+ m_name = OUStringToOString(sSysTmpName, osl_getThreadTextEncoding());
+ } else
+ m_file = nullptr;
+}
+
+void FileStream::close()
+{
+ if ( isValid() )
+ {
+ osl_closeFile(m_file);
+ m_file = nullptr;
+ m_name.clear();
+ }
+}
+
+bool FileStream::write(void const * buffer, sal_uInt64 size) {
+ while (size > 0) {
+ sal_uInt64 written;
+ if (osl_writeFile(m_file, buffer, size, &written) != osl_File_E_None) {
+ return false;
+ }
+ OSL_ASSERT(written <= size);
+ size -= written;
+ buffer = static_cast< char const * >(buffer) + written;
+ }
+ return true;
+}
+
+FileStream &operator<<(FileStream& o, sal_uInt32 i) {
+ sal_uInt64 writtenBytes;
+ OString s = OString::number(static_cast<sal_Int32>(i));
+ osl_writeFile(o.m_file, s.getStr(), s.getLength() * sizeof(char), &writtenBytes);
+ return o;
+}
+FileStream &operator<<(FileStream& o, char const * s) {
+ sal_uInt64 writtenBytes;
+ osl_writeFile(o.m_file, s, strlen(s), &writtenBytes);
+ return o;
+}
+FileStream &operator<<(FileStream& o, OString const * s) {
+ sal_uInt64 writtenBytes;
+ osl_writeFile(o.m_file, s->getStr(), s->getLength() * sizeof(char), &writtenBytes);
+ return o;
+}
+FileStream &operator<<(FileStream& o, const OString& s) {
+ sal_uInt64 writtenBytes;
+ osl_writeFile(o.m_file, s.getStr(), s.getLength() * sizeof(char), &writtenBytes);
+ return o;
+
+}
+FileStream &operator<<(FileStream& o, OStringBuffer const * s) {
+ sal_uInt64 writtenBytes;
+ osl_writeFile(o.m_file, s->getStr(), s->getLength() * sizeof(char), &writtenBytes);
+ return o;
+}
+FileStream &operator<<(FileStream& o, const OStringBuffer& s) {
+ sal_uInt64 writtenBytes;
+ osl_writeFile(
+ o.m_file, s.getStr(), s.getLength() * sizeof(char), &writtenBytes);
+ return o;
+}
+
+FileStream & operator <<(FileStream & out, std::u16string_view s) {
+ return out << OUStringToOString(s, RTL_TEXTENCODING_UTF8);
+}
+
+CannotDumpException::~CannotDumpException() noexcept {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/codemaker/source/codemaker/options.cxx b/codemaker/source/codemaker/options.cxx
new file mode 100644
index 000000000..2d85b35a9
--- /dev/null
+++ b/codemaker/source/codemaker/options.cxx
@@ -0,0 +1,41 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <codemaker/options.hxx>
+
+Options::Options() {}
+
+Options::~Options() {}
+
+bool Options::isValid(const OString& option) const
+{
+ return m_options.find(option) != m_options.end();
+}
+
+const OString& Options::getOption(const OString& option) const
+{
+ OptionMap::const_iterator i(m_options.find(option));
+ if (i == m_options.end())
+ {
+ throw IllegalArgument("Option is not valid or currently not set.");
+ }
+ return i->second;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/codemaker/source/codemaker/typemanager.cxx b/codemaker/source/codemaker/typemanager.cxx
new file mode 100644
index 000000000..194840ca9
--- /dev/null
+++ b/codemaker/source/codemaker/typemanager.cxx
@@ -0,0 +1,258 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <cstdlib>
+#include <cstring>
+#include <vector>
+
+#include <codemaker/global.hxx>
+#include <codemaker/typemanager.hxx>
+#include <rtl/ref.hxx>
+#include <rtl/ustring.hxx>
+#include <unoidl/unoidl.hxx>
+
+TypeManager::TypeManager(): manager_(new unoidl::Manager) {}
+
+TypeManager::~TypeManager() {}
+
+void TypeManager::loadProvider(OUString const & uri, bool primary) {
+ rtl::Reference< unoidl::Provider > prov(manager_->addProvider(uri));
+ if (primary) {
+ primaryProviders_.push_back(prov);
+ }
+}
+
+bool TypeManager::foundAtPrimaryProvider(OUString const & name) const {
+ if (name.isEmpty()) {
+ return !primaryProviders_.empty();
+ }
+ for (const rtl::Reference< unoidl::Provider >& xProvider : primaryProviders_)
+ {
+ if (xProvider->findEntity(name).is()) {
+ return true;
+ }
+ }
+ if (!manager_->findEntity(name).is()) {
+ throw CannotDumpException("Unknown entity '" + name + "'");
+ }
+ return false;
+}
+
+codemaker::UnoType::Sort TypeManager::getSort(
+ OUString const & name, rtl::Reference< unoidl::Entity > * entity,
+ rtl::Reference< unoidl::MapCursor > * cursor) const
+{
+ if (name.isEmpty()) {
+ if (cursor != nullptr) {
+ *cursor = manager_->createCursor("");
+ }
+ return codemaker::UnoType::Sort::Module;
+ }
+ if (name == "void") {
+ return codemaker::UnoType::Sort::Void;
+ }
+ if (name == "boolean") {
+ return codemaker::UnoType::Sort::Boolean;
+ }
+ if (name == "byte") {
+ return codemaker::UnoType::Sort::Byte;
+ }
+ if (name == "short") {
+ return codemaker::UnoType::Sort::Short;
+ }
+ if (name == "unsigned short") {
+ return codemaker::UnoType::Sort::UnsignedShort;
+ }
+ if (name == "long") {
+ return codemaker::UnoType::Sort::Long;
+ }
+ if (name == "unsigned long") {
+ return codemaker::UnoType::Sort::UnsignedLong;
+ }
+ if (name == "hyper") {
+ return codemaker::UnoType::Sort::Hyper;
+ }
+ if (name == "unsigned hyper") {
+ return codemaker::UnoType::Sort::UnsignedHyper;
+ }
+ if (name == "float") {
+ return codemaker::UnoType::Sort::Float;
+ }
+ if (name == "double") {
+ return codemaker::UnoType::Sort::Double;
+ }
+ if (name == "char") {
+ return codemaker::UnoType::Sort::Char;
+ }
+ if (name == "string") {
+ return codemaker::UnoType::Sort::String;
+ }
+ if (name == "type") {
+ return codemaker::UnoType::Sort::Type;
+ }
+ if (name == "any") {
+ return codemaker::UnoType::Sort::Any;
+ }
+ if (name.startsWith("[")) {
+ return codemaker::UnoType::Sort::Sequence;
+ }
+ if (name.indexOf('<') != -1) {
+ return codemaker::UnoType::Sort::InstantiatedPolymorphicStruct;
+ }
+ rtl::Reference< unoidl::Entity > ent(manager_->findEntity(name));
+ if (!ent.is()) {
+ throw CannotDumpException("Unknown entity '" + name + "'");
+ }
+ if (entity != nullptr) {
+ *entity = ent;
+ }
+ switch (ent->getSort()) {
+ case unoidl::Entity::SORT_MODULE:
+ if (cursor != nullptr) {
+ *cursor = manager_->createCursor(name);
+ }
+ return codemaker::UnoType::Sort::Module;
+ case unoidl::Entity::SORT_ENUM_TYPE:
+ return codemaker::UnoType::Sort::Enum;
+ case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
+ return codemaker::UnoType::Sort::PlainStruct;
+ case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
+ return codemaker::UnoType::Sort::PolymorphicStructTemplate;
+ case unoidl::Entity::SORT_EXCEPTION_TYPE:
+ return codemaker::UnoType::Sort::Exception;
+ case unoidl::Entity::SORT_INTERFACE_TYPE:
+ return codemaker::UnoType::Sort::Interface;
+ case unoidl::Entity::SORT_TYPEDEF:
+ return codemaker::UnoType::Sort::Typedef;
+ case unoidl::Entity::SORT_CONSTANT_GROUP:
+ return codemaker::UnoType::Sort::ConstantGroup;
+ case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
+ return codemaker::UnoType::Sort::SingleInterfaceBasedService;
+ case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
+ return codemaker::UnoType::Sort::AccumulationBasedService;
+ case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
+ return codemaker::UnoType::Sort::InterfaceBasedSingleton;
+ case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
+ return codemaker::UnoType::Sort::ServiceBasedSingleton;
+ default:
+ for (;;) { std::abort(); } // this cannot happen
+ }
+}
+
+codemaker::UnoType::Sort TypeManager::decompose(
+ std::u16string_view name, bool resolveTypedefs, OUString * nucleus,
+ sal_Int32 * rank, std::vector< OUString > * arguments,
+ rtl::Reference< unoidl::Entity > * entity) const
+{
+ sal_Int32 k;
+ std::vector< OString > args;
+ OUString n = b2u(codemaker::UnoType::decompose(u2b(name), &k, &args));
+ for (;;) {
+ rtl::Reference< unoidl::Entity > ent;
+ codemaker::UnoType::Sort s = getSort(n, &ent);
+ if (args.empty()
+ != (s != codemaker::UnoType::Sort::PolymorphicStructTemplate))
+ {
+ throw CannotDumpException(
+ "template arguments mismatch for \"" + n
+ + "\" resolved from \"" + name + "\"");
+ }
+ switch (s) {
+ case codemaker::UnoType::Sort::Typedef:
+ if (resolveTypedefs) {
+ n = dynamic_cast<unoidl::TypedefEntity&>(*ent).getType();
+ while (n.startsWith("[]")) {
+ ++k; //TODO: overflow
+ n = n.copy(std::strlen("[]"));
+ }
+ break;
+ }
+ [[fallthrough]];
+ case codemaker::UnoType::Sort::Void:
+ case codemaker::UnoType::Sort::Boolean:
+ case codemaker::UnoType::Sort::Byte:
+ case codemaker::UnoType::Sort::Short:
+ case codemaker::UnoType::Sort::UnsignedShort:
+ case codemaker::UnoType::Sort::Long:
+ case codemaker::UnoType::Sort::UnsignedLong:
+ case codemaker::UnoType::Sort::Hyper:
+ case codemaker::UnoType::Sort::UnsignedHyper:
+ case codemaker::UnoType::Sort::Float:
+ case codemaker::UnoType::Sort::Double:
+ case codemaker::UnoType::Sort::Char:
+ case codemaker::UnoType::Sort::String:
+ case codemaker::UnoType::Sort::Type:
+ case codemaker::UnoType::Sort::Any:
+ case codemaker::UnoType::Sort::Enum:
+ case codemaker::UnoType::Sort::PlainStruct:
+ case codemaker::UnoType::Sort::Exception:
+ case codemaker::UnoType::Sort::Interface:
+ if (nucleus != nullptr) {
+ *nucleus = n;
+ }
+ if (rank != nullptr) {
+ *rank = k;
+ }
+ if (arguments != nullptr) {
+ arguments->clear();
+ }
+ if (entity != nullptr) {
+ *entity = ent;
+ }
+ return s;
+ case codemaker::UnoType::Sort::PolymorphicStructTemplate:
+ if (args.size()
+ != (dynamic_cast<unoidl::PolymorphicStructTypeTemplateEntity&>(*ent).
+ getTypeParameters().size()))
+ {
+ throw CannotDumpException(
+ "bad number of template arguments for \"" + n
+ + "\" resolved from \"" + name + "\"");
+ }
+ if (nucleus != nullptr) {
+ *nucleus = n;
+ }
+ if (rank != nullptr) {
+ *rank = k;
+ }
+ if (arguments != nullptr) {
+ arguments->clear();
+ for (const OString& rArg : args)
+ {
+ arguments->push_back(b2u(rArg));
+ }
+ }
+ if (entity != nullptr) {
+ *entity = ent;
+ }
+ return
+ codemaker::UnoType::Sort::InstantiatedPolymorphicStruct;
+ case codemaker::UnoType::Sort::Sequence:
+ for (;;) std::abort(); // this cannot happen
+ default:
+ throw CannotDumpException(
+ "unexpected \"" + n + "\" resolved from \"" + name
+ + "\"in call to TypeManager::decompose");
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/codemaker/source/codemaker/unotype.cxx b/codemaker/source/codemaker/unotype.cxx
new file mode 100644
index 000000000..8c25ac8ae
--- /dev/null
+++ b/codemaker/source/codemaker/unotype.cxx
@@ -0,0 +1,70 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <codemaker/unotype.hxx>
+
+#include <osl/diagnose.h>
+#include <rtl/string.hxx>
+#include <sal/types.h>
+
+
+OString codemaker::UnoType::decompose(
+ OString const & type, sal_Int32 * rank,
+ std::vector< OString > * arguments)
+{
+ sal_Int32 len = type.getLength();
+ sal_Int32 i = 0;
+ while (len - i > 1 && type[i + 1] == ']') {
+ i += 2;
+ }
+ if (rank != nullptr) {
+ *rank = i / 2;
+ }
+ sal_Int32 j = arguments == nullptr ? -1 : type.indexOf('<', i);
+ if (j < 0) {
+ return type.copy(i);
+ }
+ sal_Int32 k = j;
+ do {
+ ++k; // skip '<' or ','
+ sal_Int32 l = k;
+ for (sal_Int32 level = 0; l != len; ++l) {
+ char c = type[l];
+ if (c == ',') {
+ if (level == 0) {
+ break;
+ }
+ } else if (c == '<') {
+ ++level;
+ } else if (c == '>') {
+ if (level == 0) {
+ break;
+ }
+ --level;
+ }
+ }
+ arguments->push_back(type.copy(k, l - k));
+ k = l;
+ } while (k != len && type[k] != '>');
+ OSL_ASSERT(k == len - 1 && type[k] == '>');
+ return type.copy(i, j - i);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */