diff options
Diffstat (limited to 'codemaker/source/codemaker')
-rw-r--r-- | codemaker/source/codemaker/codemaker.cxx | 188 | ||||
-rw-r--r-- | codemaker/source/codemaker/dependencies.cxx | 281 | ||||
-rw-r--r-- | codemaker/source/codemaker/exceptiontree.cxx | 106 | ||||
-rw-r--r-- | codemaker/source/codemaker/global.cxx | 449 | ||||
-rw-r--r-- | codemaker/source/codemaker/makefile.mk | 51 | ||||
-rw-r--r-- | codemaker/source/codemaker/options.cxx | 99 | ||||
-rw-r--r-- | codemaker/source/codemaker/typemanager.cxx | 403 | ||||
-rw-r--r-- | codemaker/source/codemaker/unotype.cxx | 103 |
8 files changed, 1680 insertions, 0 deletions
diff --git a/codemaker/source/codemaker/codemaker.cxx b/codemaker/source/codemaker/codemaker.cxx new file mode 100644 index 000000000000..d31b4762f235 --- /dev/null +++ b/codemaker/source/codemaker/codemaker.cxx @@ -0,0 +1,188 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_codemaker.hxx" + +#include "sal/config.h" + +#include "codemaker/codemaker.hxx" + +#include "codemaker/options.hxx" +#include "codemaker/typemanager.hxx" +#include "codemaker/unotype.hxx" + +#include "osl/diagnose.h" +#include "registry/reader.hxx" +#include "registry/types.h" +#include "rtl/strbuf.h" +#include "rtl/string.h" +#include "rtl/string.hxx" +#include "rtl/ustring.hxx" +#include "sal/types.h" + +#include <vector> + +namespace { + +void checkNoTypeArguments(std::vector< rtl::OString > const & arguments) { + if (!arguments.empty()) { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } +} + +} + +namespace codemaker { + +rtl::OString convertString(rtl::OUString const & string) { + rtl::OString s; + if (!string.convertToString( + &s, RTL_TEXTENCODING_UTF8, + (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR + | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Failure converting string from UTF-16 to UTF-8"))); + } + return s; +} + +rtl::OString errorMsg(rtl::OString const & desc, rtl::OString const & type) { + rtl::OStringBuffer msg(128); + msg.append(desc); + msg.append(type); + return msg.makeStringAndClear(); +} + +codemaker::UnoType::Sort decomposeAndResolve( + TypeManager const & manager, rtl::OString const & type, + bool resolveTypedefs, bool allowVoid, bool allowExtraEntities, + RTTypeClass * typeClass, rtl::OString * name, sal_Int32 * rank, + std::vector< rtl::OString > * arguments) +{ + OSL_ASSERT(typeClass != 0 && name != 0 && rank != 0 && arguments != 0); + *rank = 0; + for (rtl::OString t(type);;) { + sal_Int32 n = 0; + *name = codemaker::UnoType::decompose(t, &n, arguments); + if (n > SAL_MAX_INT32 - *rank) { + throw CannotDumpException( + errorMsg(rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information: ")), + type)); + //TODO + } + *rank += n; + if (n > 0) { + allowVoid = false; + allowExtraEntities = false; + } + codemaker::UnoType::Sort sort = codemaker::UnoType::getSort(*name); + switch (sort) { + case codemaker::UnoType::SORT_VOID: + if (!allowVoid) { + throw CannotDumpException( + errorMsg(rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information: ")), + type)); + //TODO + } + default: + checkNoTypeArguments(*arguments); + *typeClass = RT_TYPE_INVALID; + return sort; + + case codemaker::UnoType::SORT_COMPLEX: + typereg::Reader reader(manager.getTypeReader(*name)); + *typeClass = reader.getTypeClass(); + switch (*typeClass) { + case RT_TYPE_ENUM: + case RT_TYPE_INTERFACE: + checkNoTypeArguments(*arguments); + return sort; + + case RT_TYPE_STRUCT: + if (!(allowExtraEntities && arguments->empty()) + && (arguments->size() > SAL_MAX_UINT16 + || (static_cast< sal_uInt16 >(arguments->size()) + != reader.getReferenceCount()))) + { + throw CannotDumpException( + errorMsg(rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information: ")), + type)); + //TODO + } + return sort; + + case RT_TYPE_MODULE: + case RT_TYPE_EXCEPTION: + case RT_TYPE_SERVICE: + case RT_TYPE_SINGLETON: + case RT_TYPE_CONSTANTS: + if (!allowExtraEntities) { + throw CannotDumpException( + errorMsg(rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information: ")), + type)); + //TODO + } + checkNoTypeArguments(*arguments); + //TODO: check reader for consistency + return sort; + + case RT_TYPE_TYPEDEF: + checkNoTypeArguments(*arguments); + if (reader.getSuperTypeCount() == 1 + && reader.getFieldCount() == 0 + && reader.getMethodCount() == 0 + && reader.getReferenceCount() == 0) + { + if (resolveTypedefs) { + t = convertString(reader.getSuperTypeName(0)); + continue; + } else { + return sort; + } + } + default: + throw CannotDumpException( + errorMsg(rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information: ")), + type)); + //TODO + } + } + } +} + +} diff --git a/codemaker/source/codemaker/dependencies.cxx b/codemaker/source/codemaker/dependencies.cxx new file mode 100644 index 000000000000..a005c07ec4fe --- /dev/null +++ b/codemaker/source/codemaker/dependencies.cxx @@ -0,0 +1,281 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_codemaker.hxx" + +#include "codemaker/dependencies.hxx" + +#include "codemaker/typemanager.hxx" +#include "codemaker/unotype.hxx" + +#include "osl/diagnose.h" +#include "registry/reader.hxx" +#include "rtl/string.hxx" +#include "rtl/textcvt.h" +#include "rtl/textenc.h" +#include "rtl/ustring.hxx" +#include "sal/types.h" + +#include <vector> + +using codemaker::Dependencies; + +namespace { + +struct Bad {}; + +} + +Dependencies::Dependencies( + TypeManager const & manager, rtl::OString const & type): + m_voidDependency(false), m_booleanDependency(false), + m_byteDependency(false), m_shortDependency(false), + m_unsignedShortDependency(false), m_longDependency(false), + m_unsignedLongDependency(false), m_hyperDependency(false), + m_unsignedHyperDependency(false), m_floatDependency(false), + m_doubleDependency(false), m_charDependency(false), + m_stringDependency(false), m_typeDependency(false), m_anyDependency(false), + m_sequenceDependency(false) +{ + typereg::Reader reader(manager.getTypeReader(type)); + m_valid = reader.isValid(); + if (m_valid) { + // Not everything is checked for consistency, just things that are cheap + // to test: + try { + RTTypeClass tc = reader.getTypeClass(); + if (tc != RT_TYPE_SERVICE) { + for (sal_Int16 i = 0; i < reader.getSuperTypeCount(); ++i) { + insert(reader.getSuperTypeName(i), true); + } + } + if (tc != RT_TYPE_ENUM) { + {for (sal_Int16 i = 0; i < reader.getFieldCount(); ++i) { + if ((reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) + == 0) + { + insert(reader.getFieldTypeName(i), false); + } + }} + } + for (sal_Int16 i = 0; i < reader.getMethodCount(); ++i) { + insert(reader.getMethodReturnTypeName(i), false); + for (sal_Int16 j = 0; j < reader.getMethodParameterCount(i); + ++j) + { + if ((reader.getMethodParameterFlags(i, j) & RT_PARAM_REST) + != 0) + { + m_sequenceDependency = true; + } + insert(reader.getMethodParameterTypeName(i, j), false); + } + for (sal_Int16 j = 0; j < reader.getMethodExceptionCount(i); + ++j) + { + insert(reader.getMethodExceptionTypeName(i, j), false); + } + } + for (sal_Int16 i = 0; i < reader.getReferenceCount(); ++i) { + if (reader.getReferenceSort(i) != RT_REF_TYPE_PARAMETER) { + insert(reader.getReferenceTypeName(i), false); + } + } + } catch (Bad &) { + m_map.clear(); + m_valid = false; + m_voidDependency = false; + m_booleanDependency = false; + m_byteDependency = false; + m_shortDependency = false; + m_unsignedShortDependency = false; + m_longDependency = false; + m_unsignedLongDependency = false; + m_hyperDependency = false; + m_unsignedHyperDependency = false; + m_floatDependency = false; + m_doubleDependency = false; + m_charDependency = false; + m_stringDependency = false; + m_typeDependency = false; + m_anyDependency = false; + m_sequenceDependency = false; + } + } +} + +Dependencies::~Dependencies() +{} + +void Dependencies::insert(rtl::OUString const & type, bool base) { + rtl::OString t; + if (!type.convertToString( + &t, RTL_TEXTENCODING_UTF8, + (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR + | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))) + { + throw Bad(); + } + insert(t, base); +} + +void Dependencies::insert(rtl::OString const & type, bool base) { + sal_Int32 rank; + std::vector< rtl::OString > args; + rtl::OString t(UnoType::decompose(type, &rank, &args)); + if (rank > 0) { + m_sequenceDependency = true; + } + switch (UnoType::getSort(t)) { + case UnoType::SORT_VOID: + if (rank != 0 || !args.empty()) { + throw Bad(); + } + m_voidDependency = true; + break; + + case UnoType::SORT_BOOLEAN: + if (!args.empty()) { + throw Bad(); + } + m_booleanDependency = true; + break; + + case UnoType::SORT_BYTE: + if (!args.empty()) { + throw Bad(); + } + m_byteDependency = true; + break; + + case UnoType::SORT_SHORT: + if (!args.empty()) { + throw Bad(); + } + m_shortDependency = true; + break; + + case UnoType::SORT_UNSIGNED_SHORT: + if (!args.empty()) { + throw Bad(); + } + m_unsignedShortDependency = true; + break; + + case UnoType::SORT_LONG: + if (!args.empty()) { + throw Bad(); + } + m_longDependency = true; + break; + + case UnoType::SORT_UNSIGNED_LONG: + if (!args.empty()) { + throw Bad(); + } + m_unsignedLongDependency = true; + break; + + case UnoType::SORT_HYPER: + if (!args.empty()) { + throw Bad(); + } + m_hyperDependency = true; + break; + + case UnoType::SORT_UNSIGNED_HYPER: + if (!args.empty()) { + throw Bad(); + } + m_unsignedHyperDependency = true; + break; + + case UnoType::SORT_FLOAT: + if (!args.empty()) { + throw Bad(); + } + m_floatDependency = true; + break; + + case UnoType::SORT_DOUBLE: + if (!args.empty()) { + throw Bad(); + } + m_doubleDependency = true; + break; + + case UnoType::SORT_CHAR: + if (!args.empty()) { + throw Bad(); + } + m_charDependency = true; + break; + + case UnoType::SORT_STRING: + if (!args.empty()) { + throw Bad(); + } + m_stringDependency = true; + break; + + case UnoType::SORT_TYPE: + if (!args.empty()) { + throw Bad(); + } + m_typeDependency = true; + break; + + case UnoType::SORT_ANY: + if (!args.empty()) { + throw Bad(); + } + m_anyDependency = true; + break; + + case UnoType::SORT_COMPLEX: + { + {for (std::vector< rtl::OString >::iterator i(args.begin()); + i != args.end(); ++i) + { + insert(*i, false); + }} + Map::iterator i(m_map.find(t)); + if (i == m_map.end()) { + m_map.insert( + Map::value_type(t, base ? KIND_BASE : KIND_NO_BASE)); + } else if (base) { + i->second = KIND_BASE; + } + break; + } + + default: + OSL_ASSERT(false); + break; + } +} diff --git a/codemaker/source/codemaker/exceptiontree.cxx b/codemaker/source/codemaker/exceptiontree.cxx new file mode 100644 index 000000000000..3fd581651ba3 --- /dev/null +++ b/codemaker/source/codemaker/exceptiontree.cxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_codemaker.hxx" + +#include "codemaker/exceptiontree.hxx" +#include "codemaker/typemanager.hxx" + +#include "osl/diagnose.h" +#include "registry/reader.hxx" +#include "registry/types.h" +#include "rtl/string.hxx" +#include "rtl/textenc.h" +#include "rtl/ustring.hxx" + +#include <memory> +#include <vector> + +using codemaker::ExceptionTree; +using codemaker::ExceptionTreeNode; + +ExceptionTreeNode * ExceptionTreeNode::add(rtl::OString const & theName) { + std::auto_ptr< ExceptionTreeNode > node(new ExceptionTreeNode(theName)); + children.push_back(node.get()); + return node.release(); +} + +void ExceptionTreeNode::clearChildren() { + for (Children::iterator i(children.begin()); i != children.end(); ++i) { + delete *i; + } + children.clear(); +} + +void ExceptionTree::add(rtl::OString const & name, TypeManager const & manager) + throw( CannotDumpException ) +{ + typedef std::vector< rtl::OString > List; + List list; + bool runtimeException = false; + for (rtl::OString n(name); n != "com/sun/star/uno/Exception";) { + if (n == "com/sun/star/uno/RuntimeException") { + runtimeException = true; + break; + } + list.push_back(n); + typereg::Reader reader(manager.getTypeReader(n)); + if (!reader.isValid()) + throw CannotDumpException( + ::rtl::OString("Unknown type '" + n.replace('/', '.') + + "', incomplete type library.")); + + OSL_ASSERT( + reader.getTypeClass() == RT_TYPE_EXCEPTION + && reader.getSuperTypeCount() == 1); + n = rtl::OUStringToOString( + reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); + } + if (!runtimeException) { + ExceptionTreeNode * node = &m_root; + for (List::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; + break; + } + } + } + } +} diff --git a/codemaker/source/codemaker/global.cxx b/codemaker/source/codemaker/global.cxx new file mode 100644 index 000000000000..a83116635afc --- /dev/null +++ b/codemaker/source/codemaker/global.cxx @@ -0,0 +1,449 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_codemaker.hxx" +#include "osl/process.h" +#include "rtl/strbuf.hxx" +#include "rtl/ustring.hxx" +#include "osl/thread.h" +#include "osl/file.hxx" + +#include <string.h> +#if defined(SAL_W32) || defined(SAL_OS2) +#include <io.h> + +#include <direct.h> +#include <errno.h> +#endif + +#ifdef UNX +#include <sys/stat.h> +#include <errno.h> +#include <unistd.h> +#endif + +#include "codemaker/global.hxx" + +#ifdef SAL_UNX +#define SEPARATOR '/' +#else +#define SEPARATOR '\\' +#endif + +using namespace ::rtl; +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, + sal_Bool bLowerCase, + const OString prefix ) +{ + OString type(typeName); + + if (bLowerCase) + { + type = typeName.toAsciiLowerCase(); + } + + sal_uInt32 length = destination.getLength(); + + sal_Bool withPoint = sal_False; + if (length == 0) + { + length++; + withPoint = sal_True; + } + + length += prefix.getLength() + type.getLength() + postfix.getLength(); + + sal_Bool withSeperator = sal_False; + if (destination.getStr()[destination.getLength()] != '\\' && + destination.getStr()[destination.getLength()] != '/' && + type.getStr()[0] != '\\' && + type.getStr()[0] != '/') + { + length++; + withSeperator = sal_True; + } + + OStringBuffer nameBuffer(length); + + if (withPoint) + nameBuffer.append('.'); + else + nameBuffer.append(destination.getStr(), destination.getLength()); + + if (withSeperator) + nameBuffer.append("/", 1); + + OString tmpStr(type); + if (prefix.getLength() > 0) + { + tmpStr = type.replaceAt(type.lastIndexOf('/')+1, 0, prefix); + } + + nameBuffer.append(tmpStr.getStr(), tmpStr.getLength()); + nameBuffer.append(postfix.getStr(), postfix.getLength()); + + OString fileName(nameBuffer); + + sal_Char token; +#ifdef SAL_UNX + fileName = fileName.replace('\\', '/'); + token = '/'; +#else + fileName = fileName.replace('/', '\\'); + token = '\\'; +#endif + + nameBuffer = OStringBuffer(length); + + sal_Int32 nIndex = 0; + do + { + nameBuffer.append(fileName.getToken(0, token, nIndex).getStr()); + if( nIndex == -1 ) + break; + + if (nameBuffer.getLength() == 0 || OString(".") == nameBuffer.getStr()) + { + nameBuffer.append(token); + continue; + } + +#if defined(SAL_UNX) || defined(SAL_OS2) + if (mkdir((char*)nameBuffer.getStr(), 0777) == -1) +#else + if (mkdir((char*)nameBuffer.getStr()) == -1) +#endif + { + if ( errno == ENOENT ) + return OString(); + } + + nameBuffer.append(token); + } while( nIndex != -1 ); + + OUString uSysFileName; + OSL_VERIFY( FileBase::getSystemPathFromFileURL( + convertToFileUrl(fileName), uSysFileName) == FileBase::E_None ); + return OUStringToOString(uSysFileName, osl_getThreadTextEncoding());; +} + +sal_Bool fileExists(const OString& fileName) +{ + FILE *f= fopen(fileName.getStr(), "r"); + + if (f != NULL) + { + fclose(f); + return sal_True; + } + + return sal_False; +} + +sal_Bool checkFileContent(const OString& targetFileName, const OString& tmpFileName) +{ + FILE *target = fopen(targetFileName.getStr(), "r"); + FILE *tmp = fopen(tmpFileName.getStr(), "r"); + sal_Bool bFindChanges = sal_False; + + if (target != NULL && tmp != NULL) + { + sal_Char buffer1[1024+1]; + sal_Char buffer2[1024+1]; + sal_Int32 n1 = 0; + sal_Int32 n2 = 0; + + while ( !bFindChanges && !feof(target) && !feof(tmp)) + { + n1 = fread(buffer1, sizeof(sal_Char), 1024, target); + n2 = fread(buffer2, sizeof(sal_Char), 1024, tmp); + + if ( n1 != n2 ) + bFindChanges = sal_True; + else + if ( rtl_compareMemory(buffer1, buffer2, n2) != 0 ) + bFindChanges = sal_True; + } + } + + if (target) fclose(target); + if (tmp) fclose(tmp); + + return bFindChanges; +} + +sal_Bool makeValidTypeFile(const OString& targetFileName, const OString& tmpFileName, + sal_Bool bFileCheck) +{ + if (bFileCheck) { + if (checkFileContent(targetFileName, tmpFileName)) { + if ( !unlink(targetFileName.getStr()) ) + if ( !rename(tmpFileName.getStr(), targetFileName.getStr()) ) + return sal_True; + } else + return removeTypeFile(tmpFileName); + } else { + if (fileExists(targetFileName)) + if (!removeTypeFile(targetFileName)) + return sal_False; + + if ( rename(tmpFileName.getStr(), targetFileName.getStr()) ) { + if (errno == EEXIST) + return sal_True; + } else + return sal_True; + } + return sal_False; +} + +sal_Bool removeTypeFile(const OString& fileName) +{ + if ( !unlink(fileName.getStr()) ) + return sal_True; + + return sal_False; +} + +static sal_Bool isFileUrl(const OString& fileName) +{ + if (fileName.indexOf("file://") == 0 ) + return sal_True; + return sal_False; +} + +OUString convertToFileUrl(const OString& fileName) +{ + if ( isFileUrl(fileName) ) + { + return OStringToOUString(fileName, osl_getThreadTextEncoding()); + } + + OUString uUrlFileName; + OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding()); + if ( fileName.indexOf('.') == 0 || 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(NULL) +{ +} + +FileStream::FileStream(const OString& name, FileAccessMode mode) + : m_file(NULL) +{ + if ( name.getLength() > 0 ) + { + OUString sUrl(convertToFileUrl(name)); +#ifdef SAL_UNX + sal_uInt64 uAttr = osl_File_Attribute_OwnWrite | + osl_File_Attribute_OwnRead | + osl_File_Attribute_GrpWrite | + osl_File_Attribute_GrpRead | + osl_File_Attribute_OthRead; + if (osl_openFile(sUrl.pData, &m_file, checkAccessMode(mode)) == osl_File_E_None && + osl_setFileAttributes(sUrl.pData, uAttr) == osl_File_E_None) +#else + if (osl_openFile(sUrl.pData, &m_file, checkAccessMode(mode)) == osl_File_E_None) +#endif + m_name = name; + else + m_file = NULL; + } +} + +FileStream::~FileStream() +{ + if ( isValid() ) + osl_closeFile(m_file); +} + +sal_Bool FileStream::isValid() +{ + if ( m_file ) + return sal_True; + + return sal_False; +} + +void FileStream::createTempFile(const OString& sPath) +{ + OString sTmp("."); + OUString sTmpPath; + OUString sTmpName; + + if (sPath.getLength() > 0) + sTmp = sPath; + + sTmpPath = convertToFileUrl(sTmp); + + if (osl_createTempFile(sTmpPath.pData, &m_file, &sTmpName.pData) == osl_File_E_None) { +#ifdef SAL_UNX + sal_uInt64 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 = NULL; + return; + } +#endif + OUString sSysTmpName; + FileBase::getSystemPathFromFileURL(sTmpName, sSysTmpName); + m_name = OUStringToOString(sSysTmpName, osl_getThreadTextEncoding()); + } else + m_file = NULL; +} + +void FileStream::open(const OString& name, FileAccessMode mode) +{ + if ( name.getLength() > 0 ) + { + oslFileError ret = osl_File_E_None; + if ((ret = osl_openFile(convertToFileUrl(name).pData, &m_file, checkAccessMode(mode))) == osl_File_E_None) + m_name = name; + else + m_file = NULL; + } +} + +void FileStream::close() +{ + if ( isValid() ) + { + osl_closeFile(m_file); + m_file = NULL; + m_name = OString(); + } +} + +sal_uInt32 FileStream::checkAccessMode(FileAccessMode mode) +{ + switch( mode ) + { + case FAM_READ: + return osl_File_OpenFlag_Read; + case FAM_WRITE: + return osl_File_OpenFlag_Write; + case FAM_READWRITE_EXIST: + return osl_File_OpenFlag_Read | osl_File_OpenFlag_Write; + case FAM_READWRITE: + return osl_File_OpenFlag_Read | osl_File_OpenFlag_Write | osl_File_OpenFlag_Create; + } + return osl_File_OpenFlag_Read | osl_File_OpenFlag_Write | osl_File_OpenFlag_Create; +} + +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::valueOf((sal_Int32)i); + osl_writeFile(o.m_file, s.getStr(), s.getLength() * sizeof(sal_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, ::rtl::OString* s) { + sal_uInt64 writtenBytes; + osl_writeFile(o.m_file, s->getStr(), s->getLength() * sizeof(sal_Char), &writtenBytes); + return o; +} +FileStream &operator<<(FileStream& o, const ::rtl::OString& s) { + sal_uInt64 writtenBytes; + osl_writeFile(o.m_file, s.getStr(), s.getLength() * sizeof(sal_Char), &writtenBytes); + return o; + +} +FileStream &operator<<(FileStream& o, ::rtl::OStringBuffer* s) { + sal_uInt64 writtenBytes; + osl_writeFile(o.m_file, s->getStr(), s->getLength() * sizeof(sal_Char), &writtenBytes); + return o; +} +FileStream &operator<<(FileStream& o, const ::rtl::OStringBuffer& s) { + sal_uInt64 writtenBytes; + osl_writeFile( + o.m_file, s.getStr(), s.getLength() * sizeof(sal_Char), &writtenBytes); + return o; +} diff --git a/codemaker/source/codemaker/makefile.mk b/codemaker/source/codemaker/makefile.mk new file mode 100644 index 000000000000..515d3657969e --- /dev/null +++ b/codemaker/source/codemaker/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ := ..$/.. +PRJNAME := codemaker +TARGET := codemaker + +ENABLE_EXCEPTIONS := TRUE + +.INCLUDE: settings.mk + +SLOFILES = \ + $(SLO)$/dependencies.obj \ + $(SLO)$/exceptiontree.obj \ + $(SLO)$/global.obj \ + $(SLO)$/options.obj \ + $(SLO)$/typemanager.obj \ + $(SLO)$/unotype.obj \ + $(SLO)$/codemaker.obj + +LIB1TARGET=$(LB)$/$(TARGET).lib +.IF "$(GUI)" != "OS2" +LIB1ARCHIV=$(LB)$/lib$(TARGET).a +.ENDIF +LIB1OBJFILES=$(SLOFILES) + +.INCLUDE: target.mk diff --git a/codemaker/source/codemaker/options.cxx b/codemaker/source/codemaker/options.cxx new file mode 100644 index 000000000000..7bbc67056e75 --- /dev/null +++ b/codemaker/source/codemaker/options.cxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_codemaker.hxx" + +#include "codemaker/options.hxx" + +using namespace rtl; + +Options::Options() +{ +} + +Options::~Options() +{ + +} + +const OString& Options::getProgramName() const +{ + return m_program; +} + +sal_Bool Options::isValid(const OString& option) +{ + return (m_options.count(option) > 0); +} + +const OString Options::getOption(const OString& option) + throw( IllegalArgument ) +{ + if (m_options.count(option) > 0) + { + return m_options[option]; + } else + { + throw IllegalArgument("Option is not valid or currently not set."); + } +} + +const OptionMap& Options::getOptions() +{ + return m_options; +} + +const OString Options::getInputFile(sal_uInt16 index) + throw( IllegalArgument ) +{ + if (index < m_inputFiles.size()) + { + return m_inputFiles[index]; + } else + { + throw IllegalArgument("index is out of bound."); + } +} + +const StringVector& Options::getInputFiles() +{ + return m_inputFiles; +} + +OString Options::getExtraInputFile(sal_uInt16 index) const + throw( IllegalArgument ) +{ + if (index < m_extra_input_files.size()) + { + return m_extra_input_files[index]; + } else + { + throw IllegalArgument("index is out of bound."); + } +} + diff --git a/codemaker/source/codemaker/typemanager.cxx b/codemaker/source/codemaker/typemanager.cxx new file mode 100644 index 000000000000..b1edde7f26c4 --- /dev/null +++ b/codemaker/source/codemaker/typemanager.cxx @@ -0,0 +1,403 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_codemaker.hxx" + +#include "rtl/alloc.h" +#include "codemaker/typemanager.hxx" +#include "registry/reader.hxx" +#include "registry/version.h" + +using namespace rtl; + +TypeManager::TypeManager() +{ + m_pImpl = new TypeManagerImpl(); + acquire(); +} + +TypeManager::~TypeManager() +{ + release(); +} + +sal_Int32 TypeManager::acquire() +{ + return osl_incrementInterlockedCount(&m_pImpl->m_refCount); +} + +sal_Int32 TypeManager::release() +{ + sal_Int32 refCount = 0; + if (0 == (refCount = osl_decrementInterlockedCount(&m_pImpl->m_refCount)) ) + { + delete m_pImpl; + } + return refCount;; +} + +sal_Bool TypeManager::isBaseType(const ::rtl::OString& name) +{ + if ( name.equals(OString("short")) ) + return sal_True; + if ( name.equals(OString("unsigned short")) ) + return sal_True; + if ( name.equals(OString("long")) ) + return sal_True; + if ( name.equals(OString("unsigned long")) ) + return sal_True; + if ( name.equals(OString("hyper")) ) + return sal_True; + if ( name.equals(OString("unsigned hyper")) ) + return sal_True; + if ( name.equals(OString("string")) ) + return sal_True; + if ( name.equals(OString("boolean")) ) + return sal_True; + if ( name.equals(OString("char")) ) + return sal_True; + if ( name.equals(OString("byte")) ) + return sal_True; + if ( name.equals(OString("any")) ) + return sal_True; + if ( name.equals(OString("type")) ) + return sal_True; + if ( name.equals(OString("float")) ) + return sal_True; + if ( name.equals(OString("double")) ) + return sal_True; + if ( name.equals(OString("void")) ) + return sal_True; + + return sal_False; +} + +RegistryTypeManager::RegistryTypeManager() +{ + m_pImpl = new RegistryTypeManagerImpl(); + acquire(); +} + +RegistryTypeManager::~RegistryTypeManager() +{ + release(); +} + +void RegistryTypeManager::acquire() +{ + TypeManager::acquire(); +} + +void RegistryTypeManager::release() +{ + if (0 == TypeManager::release()) + { + freeRegistries(); + + delete m_pImpl; + } +} + +sal_Bool RegistryTypeManager::init( + const StringVector& regFiles, + StringVector const & extraFiles ) +{ + if (regFiles.empty()) + return sal_False; + + StringVector::const_iterator iter = regFiles.begin(); + + Registry tmpReg; + while (iter != regFiles.end()) + { + if (!tmpReg.open( convertToFileUrl(*iter), REG_READONLY)) + m_pImpl->m_registries.push_back(new Registry(tmpReg)); + else + { + freeRegistries(); + return sal_False; + } + ++iter; + } + iter = extraFiles.begin(); + while (iter != extraFiles.end()) + { + if (!tmpReg.open( convertToFileUrl(*iter), REG_READONLY)) + m_pImpl->m_extra_registries.push_back(new Registry(tmpReg)); + else + { + freeRegistries(); + return sal_False; + } + ++iter; + } + + return sal_True; +} + +::rtl::OString RegistryTypeManager::getTypeName(RegistryKey& rTypeKey) const +{ + OString typeName = OUStringToOString(rTypeKey.getName(), RTL_TEXTENCODING_UTF8); + + if (m_pImpl->m_base.getLength() > 1) + typeName = typeName.copy(typeName.indexOf('/', 1) + 1); + else + typeName = typeName.copy(1); + + return typeName; +} + +typereg::Reader RegistryTypeManager::getTypeReader( + const OString& name, sal_Bool * pIsExtraType ) const +{ + typereg::Reader reader; + RegistryKey key(searchTypeKey(name, pIsExtraType)); + + if (key.isValid()) + { + RegValueType valueType; + sal_uInt32 valueSize; + + if (!key.getValueInfo(OUString(), &valueType, &valueSize)) + { + sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + if (!key.getValue(OUString(), pBuffer)) + { + reader = typereg::Reader( + pBuffer, valueSize, true, TYPEREG_VERSION_1); + } + rtl_freeMemory(pBuffer); + } + } + return reader; +} + +typereg::Reader RegistryTypeManager::getTypeReader(RegistryKey& rTypeKey) const +{ + typereg::Reader reader; + + if (rTypeKey.isValid()) + { + RegValueType valueType; + sal_uInt32 valueSize; + + if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize)) + { + sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + if (!rTypeKey.getValue(OUString(), pBuffer)) + { + reader = typereg::Reader( + pBuffer, valueSize, true, TYPEREG_VERSION_1); + } + rtl_freeMemory(pBuffer); + } + } + return reader; +} + + +RTTypeClass RegistryTypeManager::getTypeClass(const OString& name) const +{ + if (m_pImpl->m_t2TypeClass.count(name) > 0) + { + return m_pImpl->m_t2TypeClass[name]; + } else + { + RegistryKey key(searchTypeKey(name)); + + if (key.isValid()) + { + RegValueType valueType; + sal_uInt32 valueSize; + + if (!key.getValueInfo(OUString(), &valueType, &valueSize)) + { + sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + if (!key.getValue(OUString(), pBuffer)) + { + typereg::Reader reader( + pBuffer, valueSize, false, TYPEREG_VERSION_1); + + RTTypeClass ret = reader.getTypeClass(); + + rtl_freeMemory(pBuffer); + + m_pImpl->m_t2TypeClass[name] = ret; + return ret; + } + rtl_freeMemory(pBuffer); + } + } + } + + return RT_TYPE_INVALID; +} + +RTTypeClass RegistryTypeManager::getTypeClass(RegistryKey& rTypeKey) const +{ + OString name = getTypeName(rTypeKey); + + if (m_pImpl->m_t2TypeClass.count(name) > 0) + { + return m_pImpl->m_t2TypeClass[name]; + } else + { + if (rTypeKey.isValid()) + { + RegValueType valueType; + sal_uInt32 valueSize; + + if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize)) + { + sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + if (!rTypeKey.getValue(OUString(), pBuffer)) + { + typereg::Reader reader( + pBuffer, valueSize, false, TYPEREG_VERSION_1); + + RTTypeClass ret = reader.getTypeClass(); + + rtl_freeMemory(pBuffer); + + m_pImpl->m_t2TypeClass[name] = ret; + return ret; + } + rtl_freeMemory(pBuffer); + } + } + } + + return RT_TYPE_INVALID; +} + +void RegistryTypeManager::setBase(const OString& base) +{ + + if (base.lastIndexOf('/') == (base.getLength() - 1)) + m_pImpl->m_base += base.copy(0, base.lastIndexOf('/') - 1); + else + m_pImpl->m_base += base; +} + +void RegistryTypeManager::freeRegistries() +{ + RegistryList::const_iterator iter = m_pImpl->m_registries.begin(); + while (iter != m_pImpl->m_registries.end()) + { + delete *iter; + ++iter; + } + iter = m_pImpl->m_extra_registries.begin(); + while (iter != m_pImpl->m_extra_registries.end()) + { + delete *iter; + ++iter; + } +} + +RegistryKey RegistryTypeManager::searchTypeKey(const OString& name_, sal_Bool * pIsExtraType ) + const +{ + OUString name( OStringToOUString(m_pImpl->m_base + "/" + name_, RTL_TEXTENCODING_UTF8) ); + RegistryKey key, rootKey; + + RegistryList::const_iterator iter = m_pImpl->m_registries.begin(); + while (iter != m_pImpl->m_registries.end()) + { + if (!(*iter)->openRootKey(rootKey)) + { + if (!rootKey.openKey(name, key)) + { + if (pIsExtraType) + *pIsExtraType = sal_False; + return key; + } + } + ++iter; + } + iter = m_pImpl->m_extra_registries.begin(); + while (iter != m_pImpl->m_extra_registries.end()) + { + if (!(*iter)->openRootKey(rootKey)) + { + if (!rootKey.openKey(name, key)) + { + if (pIsExtraType) + *pIsExtraType = sal_True; + break; + } + } + ++iter; + } + + return key; +} + +RegistryKeyList RegistryTypeManager::getTypeKeys(const ::rtl::OString& name_) const +{ + RegistryKeyList keyList= RegistryKeyList(); + OString tmpName; + if ( name_.equals("/") || name_.equals(m_pImpl->m_base) ) { + tmpName = m_pImpl->m_base; + } else { + if ( m_pImpl->m_base.equals("/") ) + tmpName = name_; + else + tmpName = m_pImpl->m_base + "/" + name_; + } + + OUString name( OStringToOUString(tmpName, RTL_TEXTENCODING_UTF8) ); + RegistryKey key, rootKey; + + RegistryList::const_iterator iter = m_pImpl->m_registries.begin(); + while (iter != m_pImpl->m_registries.end()) + { + if (!(*iter)->openRootKey(rootKey)) + { + if (!rootKey.openKey(name, key)) + { + keyList.push_back(KeyPair(key, sal_False)); + } + } + ++iter; + } + iter = m_pImpl->m_extra_registries.begin(); + while (iter != m_pImpl->m_extra_registries.end()) + { + if (!(*iter)->openRootKey(rootKey)) + { + if (!rootKey.openKey(name, key)) + { + keyList.push_back(KeyPair(key, sal_True)); + } + } + ++iter; + } + + return keyList; +} diff --git a/codemaker/source/codemaker/unotype.cxx b/codemaker/source/codemaker/unotype.cxx new file mode 100644 index 000000000000..c1b00dcb9b3d --- /dev/null +++ b/codemaker/source/codemaker/unotype.cxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_codemaker.hxx" + +#include "codemaker/unotype.hxx" + +#include "osl/diagnose.h" +#include "rtl/string.hxx" +#include "sal/types.h" + +#include <vector> + +codemaker::UnoType::Sort codemaker::UnoType::getSort(rtl::OString const & type) +{ + return type == "void" ? SORT_VOID + : type == "boolean" ? SORT_BOOLEAN + : type == "byte" ? SORT_BYTE + : type == "short" ? SORT_SHORT + : type == "unsigned short" ? SORT_UNSIGNED_SHORT + : type == "long" ? SORT_LONG + : type == "unsigned long" ? SORT_UNSIGNED_LONG + : type == "hyper" ? SORT_HYPER + : type == "unsigned hyper" ? SORT_UNSIGNED_HYPER + : type == "float" ? SORT_FLOAT + : type == "double" ? SORT_DOUBLE + : type == "char" ? SORT_CHAR + : type == "string" ? SORT_STRING + : type == "type" ? SORT_TYPE + : type == "any" ? SORT_ANY + : SORT_COMPLEX; +} + +bool codemaker::UnoType::isSequenceType(rtl::OString const & type) { + return type.getLength() > 0 && type[0] == '['; +} + +rtl::OString codemaker::UnoType::decompose( + rtl::OString const & type, sal_Int32 * rank, + std::vector< rtl::OString > * arguments) +{ + sal_Int32 len = type.getLength(); + sal_Int32 i = 0; + while (len - i > 1 && type[i + 1] == ']') { + i += 2; + } + if (rank != 0) { + *rank = i / 2; + } + sal_Int32 j = arguments == 0 ? -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); +} |