diff options
Diffstat (limited to 'codemaker')
74 files changed, 28272 insertions, 0 deletions
diff --git a/codemaker/codemaker.pmk b/codemaker/codemaker.pmk new file mode 100755 index 000000000000..976c162e71b3 --- /dev/null +++ b/codemaker/codemaker.pmk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +.IF "$(GUI)" == "OS2" +STL_OS2_BUILDING=1 +.ENDIF + +.IF "$(GUI)"=="WNT" || "$(GUI)"=="OS2" +CODEMAKERLIBDEPN=codemaker.lib +COMMONCPPLIBDEPN=commoncpp.lib +COMMONJAVALIBDEPN=commonjava.lib +.IF "$(COM)"=="GCC" && "$(GUI)"=="WNT" +CODEMAKERLIBST=-lcodemaker +COMMONCPPLIBST=-lcommoncpp +COMMONJAVALIBST=-lcommonjava +.ELSE +CODEMAKERLIBST=codemaker.lib +COMMONCPPLIBST=commoncpp.lib +COMMONJAVALIBST=commonjava.lib +.ENDIF +.ELSE +CODEMAKERLIBDEPN=libcodemaker.a +COMMONCPPLIBDEPN=libcommoncpp.a +COMMONJAVALIBDEPN=libcommonjava.a +CODEMAKERLIBST=-lcodemaker +COMMONCPPLIBST=-lcommoncpp +COMMONJAVALIBST=-lcommonjava +.ENDIF + diff --git a/codemaker/inc/codemaker/codemaker.hxx b/codemaker/inc/codemaker/codemaker.hxx new file mode 100644 index 000000000000..fee56c307b11 --- /dev/null +++ b/codemaker/inc/codemaker/codemaker.hxx @@ -0,0 +1,56 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_CODEMAKER_HXX +#define INCLUDED_CODEMAKER_CODEMAKER_HXX + +#include "sal/config.h" +#include "codemaker/unotype.hxx" +#include "registry/types.h" +#include "sal/types.h" + +#include <vector> + +namespace rtl { + class OString; + class OUString; +} +class TypeManager; + +namespace codemaker { + +rtl::OString convertString(rtl::OUString const & string); + +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); + +} + +#endif // INCLUDED_CODEMAKER_CODEMAKER_HXX diff --git a/codemaker/inc/codemaker/commoncpp.hxx b/codemaker/inc/codemaker/commoncpp.hxx new file mode 100644 index 000000000000..241336775d2b --- /dev/null +++ b/codemaker/inc/codemaker/commoncpp.hxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_COMMONCPP_HXX +#define INCLUDED_CODEMAKER_COMMONCPP_HXX + +#include "codemaker/codemaker.hxx" + +namespace codemaker { namespace cpp { + +rtl::OString typeToPrefix(TypeManager const & manager, rtl::OString const & type); + +rtl::OString scopedCppName(rtl::OString const & type, bool bNoNameSpace=false, + bool shortname=false); + +rtl::OString translateUnoToCppType( + codemaker::UnoType::Sort sort, RTTypeClass typeClass, + rtl::OString const & nucleus, bool shortname); + +enum IdentifierTranslationMode { + ITM_GLOBAL, + ITM_NONGLOBAL, + ITM_KEYWORDSONLY +}; + +rtl::OString translateUnoToCppIdentifier( + rtl::OString const & identifier, rtl::OString const & prefix, + IdentifierTranslationMode transmode = ITM_GLOBAL, + rtl::OString const * forbidden = 0); + +} } + +#endif // INCLUDED_CODEMAKER_COMMONCPP_HXX diff --git a/codemaker/inc/codemaker/commonjava.hxx b/codemaker/inc/codemaker/commonjava.hxx new file mode 100644 index 000000000000..ae5c8b18fc3b --- /dev/null +++ b/codemaker/inc/codemaker/commonjava.hxx @@ -0,0 +1,44 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_COMMONJAVA_HXX +#define INCLUDED_CODEMAKER_COMMONJAVA_HXX + +#include "codemaker/codemaker.hxx" + +namespace codemaker { namespace java { + +rtl::OString translateUnoToJavaType( + codemaker::UnoType::Sort sort, RTTypeClass typeClass, + rtl::OString const & nucleus, bool referenceType); + +rtl::OString translateUnoToJavaIdentifier( + rtl::OString const & identifier, rtl::OString const & prefix); + +} } + +#endif // INCLUDED_CODEMAKER_COMMONJAVA_HXX diff --git a/codemaker/inc/codemaker/dependencies.hxx b/codemaker/inc/codemaker/dependencies.hxx new file mode 100644 index 000000000000..66aad808a130 --- /dev/null +++ b/codemaker/inc/codemaker/dependencies.hxx @@ -0,0 +1,149 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_DEPENDENCIES_HXX +#define INCLUDED_CODEMAKER_DEPENDENCIES_HXX + +#include "rtl/string.hxx" + +#include <hash_map> + +namespace rtl { class OUString; } +class TypeManager; + +/// @HTML + +namespace codemaker { + +/** + A simple class to track which other types a given type depends on. + + <p>This class is not multi-thread–safe.</p> + */ +class Dependencies { +public: + /** + Flags to distinguish whether or not one type depends on another type + because the second is a direct base of the first. + */ + enum Kind { KIND_NO_BASE, KIND_BASE }; + + typedef std::hash_map< rtl::OString, Kind, rtl::OStringHash > Map; + + /** + Constructs the dependencies for a given type. + + <p>If the given type is not successfully available at the given type + manager, <code>isValid()</code> will return <code>false</code>.</p> + + @param manager a type manager, to obtain information about the given type + + @param type the UNO type registry name of an enum type, plain struct + type, polymorphic struct type template, exception type, interface type, + typedef, module, constant group, service, or singleton + */ + Dependencies(TypeManager const & manager, rtl::OString const & type); + + ~Dependencies(); + + /** + Add a special dependency (which is not obvious from the type's data + available at the type manager). + + @param type a UNO type registry name + */ + void add(rtl::OString const & type) { insert(type, false); } + + bool isValid() const { return m_valid; } + + Map const & getMap() const { return m_map; } + + bool hasVoidDependency() const { return m_voidDependency; } + + bool hasBooleanDependency() const { return m_booleanDependency; } + + bool hasByteDependency() const { return m_byteDependency; } + + bool hasShortDependency() const { return m_shortDependency; } + + bool hasUnsignedShortDependency() const + { return m_unsignedShortDependency; } + + bool hasLongDependency() const { return m_longDependency; } + + bool hasUnsignedLongDependency() const { return m_unsignedLongDependency; } + + bool hasHyperDependency() const { return m_hyperDependency; } + + bool hasUnsignedHyperDependency() const + { return m_unsignedHyperDependency; } + + bool hasFloatDependency() const { return m_floatDependency; } + + bool hasDoubleDependency() const { return m_doubleDependency; } + + bool hasCharDependency() const { return m_charDependency; } + + bool hasStringDependency() const { return m_stringDependency; } + + bool hasTypeDependency() const { return m_typeDependency; } + + bool hasAnyDependency() const { return m_anyDependency; } + + bool hasSequenceDependency() const { return m_sequenceDependency; } + +private: + Dependencies(Dependencies &); // not implemented + void operator =(Dependencies); // not implemented + + void insert(rtl::OUString const & type, bool base); + + void insert(rtl::OString const & type, bool base); + + Map m_map; + bool m_valid; + bool m_voidDependency; + bool m_booleanDependency; + bool m_byteDependency; + bool m_shortDependency; + bool m_unsignedShortDependency; + bool m_longDependency; + bool m_unsignedLongDependency; + bool m_hyperDependency; + bool m_unsignedHyperDependency; + bool m_floatDependency; + bool m_doubleDependency; + bool m_charDependency; + bool m_stringDependency; + bool m_typeDependency; + bool m_anyDependency; + bool m_sequenceDependency; +}; + +} + +#endif // INCLUDED_CODEMAKER_DEPENDENCIES_HXX diff --git a/codemaker/inc/codemaker/exceptiontree.hxx b/codemaker/inc/codemaker/exceptiontree.hxx new file mode 100644 index 000000000000..7a8e1bb837c2 --- /dev/null +++ b/codemaker/inc/codemaker/exceptiontree.hxx @@ -0,0 +1,124 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_EXCEPTIONTREE_HXX +#define INCLUDED_CODEMAKER_EXCEPTIONTREE_HXX + +#include "codemaker/global.hxx" +#include "rtl/string.hxx" + +#include <vector> + +class TypeManager; + +namespace codemaker { + +/** + Represents a node of the hierarchy from the ExceptionTree class. + */ +struct ExceptionTreeNode { + typedef std::vector< ExceptionTreeNode * > Children; + + // Internally used by ExceptionTree: + ExceptionTreeNode(rtl::OString const & theName): + name(theName), present(false) {} + + // Internally used by ExceptionTree: + ~ExceptionTreeNode() { clearChildren(); } + + // Internally used by ExceptionTree: + void setPresent() { present = true; clearChildren(); } + + // Internally used by ExceptionTree: + ExceptionTreeNode * add(rtl::OString const & theName); + + rtl::OString name; + bool present; + Children children; + +private: + ExceptionTreeNode(ExceptionTreeNode &); // not implemented + void operator =(ExceptionTreeNode); // not implemented + + void clearChildren(); +}; + +/** + Represents the hierarchy formed by a set of UNO exception types. + + The hierarchy is rooted at com.sun.star.uno.Exception. For each exception E + from the given set S, the hierarchy from com.sun.star.uno.Exception to the + first supertype E' of E which is itself a member of S is represented (i.e., + subtypes that are hidden by supertypes are pruned from the hierarchy). The + exception com.sun.star.uno.RuntimeException and its subtypes are pruned + completely from the hierarchy. Each node of the hierarchy is represented by + an instance of ExceptionTreeNode, where name gives the slashified name of + the UNO exception type, present is true iff the given exception type is a + member of the set S, and children contains all the relevant direct subtypes + of the given exception type, in no particular order (for nodes other than the + root node it holds that children is non-empty iff present is false). + */ +class ExceptionTree { +public: + ExceptionTree(): m_root("com/sun/star/uno/Exception") {} + + ~ExceptionTree() {} + + /** + Builds the exception hierarchy, by adding one exception type at a time. + + This function can be called more than once for the same exception name. + + @param name the name of a UNO exception type, in slashified form; it is + an error if the given name does not represent a UNO exception type + + @param manager a type manager, used to resolve type names; it is an error + if different calls to this member function use different, incompatible + type managers + */ + void add(rtl::OString const & name, TypeManager const & manager) + throw( CannotDumpException ); + + /** + Gives access to the resultant exception hierarchy. + + @return a non-null pointer to the root of the exception hierarchy, as + formed by all previous calls to add; it is an error if any calls to add + follow the first call to getRoot + */ + ExceptionTreeNode const * getRoot() const { return &m_root; } + +private: + ExceptionTree(ExceptionTree &); // not implemented + void operator =(ExceptionTree); // not implemented + + ExceptionTreeNode m_root; +}; + +} + +#endif diff --git a/codemaker/inc/codemaker/generatedtypeset.hxx b/codemaker/inc/codemaker/generatedtypeset.hxx new file mode 100644 index 000000000000..c5a481893b14 --- /dev/null +++ b/codemaker/inc/codemaker/generatedtypeset.hxx @@ -0,0 +1,79 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_GENERATEDTYPESET_HXX +#define INCLUDED_CODEMAKER_GENERATEDTYPESET_HXX + +#include "rtl/string.hxx" + +#include <hash_set> + +/// @HTML + +namespace codemaker { + +/** + A simple class to track which types have already been processed by a code + maker. + + <p>This class is not multi-thread–safe.</p> + */ +class GeneratedTypeSet { +public: + GeneratedTypeSet() {} + + ~GeneratedTypeSet() {} + + /** + Add a type to the set of generated types. + + <p>If the type was already present, nothing happens.</p> + + @param type a UNO type registry name + */ + void add(rtl::OString const & type) { m_set.insert(type); } + + /** + Checks whether a given type has already been generated. + + @param type a UNO type registry name + + @return true iff the given type has already been generated + */ + bool contains(rtl::OString const & type) const + { return m_set.find(type) != m_set.end(); } + +private: + GeneratedTypeSet(GeneratedTypeSet &); // not implemented + void operator =(GeneratedTypeSet); // not implemented + + std::hash_set< rtl::OString, rtl::OStringHash > m_set; +}; + +} + +#endif // INCLUDED_CODEMAKER_GENERATEDTYPESET_HXX diff --git a/codemaker/inc/codemaker/global.hxx b/codemaker/inc/codemaker/global.hxx new file mode 100644 index 000000000000..b1919d041daf --- /dev/null +++ b/codemaker/inc/codemaker/global.hxx @@ -0,0 +1,151 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_GLOBAL_HXX +#define INCLUDED_CODEMAKER_GLOBAL_HXX + +#include <list> +#include <vector> +#include <set> + +#include <stdio.h> + +#include "osl/file.hxx" +#include "rtl/ustring.hxx" +#include "rtl/strbuf.hxx" + +struct EqualString +{ + sal_Bool operator()(const ::rtl::OString& str1, const ::rtl::OString& str2) const + { + return (str1 == str2); + } +}; + +struct HashString +{ + size_t operator()(const ::rtl::OString& str) const + { + return str.hashCode(); + } +}; + +struct LessString +{ + sal_Bool operator()(const ::rtl::OString& str1, const ::rtl::OString& str2) const + { + return (str1 < str2); + } +}; + +#if defined(_MSC_VER) && _MSC_VER < 1200 +typedef ::std::new_alloc NewAlloc; +#endif + + +typedef ::std::list< ::rtl::OString > StringList; +typedef ::std::vector< ::rtl::OString > StringVector; +typedef ::std::set< ::rtl::OString, LessString > StringSet; + +//************************************************************************* +// FileStream +//************************************************************************* +enum FileAccessMode +{ + FAM_READ, // "r" + FAM_WRITE, // "w" + FAM_READWRITE_EXIST, // "r+" + FAM_READWRITE // "w+" +}; + +class FileStream +{ +public: + FileStream(); + FileStream(const ::rtl::OString& name, FileAccessMode nMode = FAM_READWRITE); + virtual ~FileStream(); + + sal_Bool isValid(); + + void open(const ::rtl::OString& name, FileAccessMode nMode = FAM_READWRITE); + void createTempFile(const ::rtl::OString& sPath); + void close(); + + ::rtl::OString getName() { return m_name; } + + bool write(void const * buffer, sal_uInt64 size); + + // friend functions + friend FileStream &operator<<(FileStream& o, sal_uInt32 i); + friend FileStream &operator<<(FileStream& o, char const * s); + friend FileStream &operator<<(FileStream& o, ::rtl::OString* s); + friend FileStream &operator<<(FileStream& o, const ::rtl::OString& s); + friend FileStream &operator<<(FileStream& o, ::rtl::OStringBuffer* s); + friend FileStream &operator<<(FileStream& o, const ::rtl::OStringBuffer& s); + +private: + sal_uInt32 checkAccessMode(FileAccessMode mode); + + oslFileHandle m_file; + ::rtl::OString m_name; +}; + + +//************************************************************************* +// Helper functions +//************************************************************************* +::rtl::OString getTempDir(const ::rtl::OString& sFileName); + +::rtl::OString createFileNameFromType(const ::rtl::OString& destination, + const ::rtl::OString type, + const ::rtl::OString postfix, + sal_Bool bLowerCase=sal_False, + const ::rtl::OString prefix=""); + +sal_Bool fileExists(const ::rtl::OString& fileName); +sal_Bool makeValidTypeFile(const ::rtl::OString& targetFileName, + const ::rtl::OString& tmpFileName, + sal_Bool bFileCheck); +sal_Bool removeTypeFile(const ::rtl::OString& fileName); + +::rtl::OUString convertToFileUrl(const ::rtl::OString& fileName); + +//************************************************************************* +// Global exception to signal problems when a type cannot be dumped +//************************************************************************* +class CannotDumpException +{ +public: + CannotDumpException(const ::rtl::OString& msg) + : m_message(msg) {} + + ::rtl::OString m_message; +}; + + +#endif // INCLUDED_CODEMAKER_GLOBAL_HXX + diff --git a/codemaker/inc/codemaker/options.hxx b/codemaker/inc/codemaker/options.hxx new file mode 100644 index 000000000000..5f440744cc2a --- /dev/null +++ b/codemaker/inc/codemaker/options.hxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_OPTIONS_HXX +#define INCLUDED_CODEMAKER_OPTIONS_HXX + +#include <hash_map> + +#include <codemaker/global.hxx> + +#if defined( _MSC_VER ) && ( _MSC_VER < 1200 ) +typedef ::std::__hash_map__ +< + ::rtl::OString, + ::rtl::OString, + HashString, + EqualString, + NewAlloc +> OptionMap; +#else +typedef ::std::hash_map +< + ::rtl::OString, + ::rtl::OString, + HashString, + EqualString +> OptionMap; +#endif + +class IllegalArgument +{ +public: + IllegalArgument(const ::rtl::OString& msg) + : m_message(msg) {} + + ::rtl::OString m_message; +}; + +class Options +{ +public: + Options(); + virtual ~Options(); + + virtual sal_Bool initOptions(int ac, char* av[], sal_Bool bCmdFile=sal_False) + throw( IllegalArgument ) = 0; + + virtual ::rtl::OString prepareHelp() = 0; + + const ::rtl::OString& getProgramName() const; + sal_Bool isValid(const ::rtl::OString& option); + const ::rtl::OString getOption(const ::rtl::OString& option) + throw( IllegalArgument ); + const OptionMap& getOptions(); + + const ::rtl::OString getInputFile(sal_uInt16 index) + throw( IllegalArgument ); + + const StringVector& getInputFiles(); + + ::rtl::OString getExtraInputFile(sal_uInt16 index) const throw( IllegalArgument ); + inline sal_uInt16 getNumberOfExtraInputFiles() const + { return (sal_uInt16)m_extra_input_files.size(); } + inline const StringVector& getExtraInputFiles() const + { return m_extra_input_files; } +protected: + ::rtl::OString m_program; + StringVector m_inputFiles; + StringVector m_extra_input_files; + OptionMap m_options; +}; + +#endif // INCLUDED_CODEMAKER_OPTIONS_HXX + diff --git a/codemaker/inc/codemaker/typemanager.hxx b/codemaker/inc/codemaker/typemanager.hxx new file mode 100644 index 000000000000..dacb97b1214b --- /dev/null +++ b/codemaker/inc/codemaker/typemanager.hxx @@ -0,0 +1,182 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_TYPEMANAGER_HXX +#define INCLUDED_CODEMAKER_TYPEMANAGER_HXX + +#include "codemaker/global.hxx" +#include "registry/registry.hxx" +#include "registry/types.h" + +#include <hash_map> +#include <list> + +namespace typereg { class Reader; } + +//typedef ::std::list< Registry* > RegistryList; +typedef ::std::vector< Registry* > RegistryList; +typedef ::std::pair< RegistryKey, sal_Bool > KeyPair; +typedef ::std::vector< KeyPair > RegistryKeyList; + +#if defined( _MSC_VER ) && ( _MSC_VER < 1200 ) +typedef ::std::__hash_map__ +< + ::rtl::OString, // Typename + RTTypeClass, // TypeClass + HashString, + EqualString, + NewAlloc +> T2TypeClassMap; +#else +typedef ::std::hash_map +< + ::rtl::OString, // Typename + RTTypeClass, // TypeClass + HashString, + EqualString +> T2TypeClassMap; +#endif + +struct TypeManagerImpl +{ + TypeManagerImpl() + : m_refCount(0) + {} + + sal_Int32 m_refCount; +}; + +class TypeManager +{ +public: + TypeManager(); + virtual ~TypeManager(); + + TypeManager( const TypeManager& value ) + : m_pImpl( value.m_pImpl ) + { + acquire(); + } + + TypeManager& operator = ( const TypeManager& value ) + { + release(); + m_pImpl = value.m_pImpl; + acquire(); + return *this; + } + + virtual sal_Bool isValidType(const ::rtl::OString&) const + { return sal_False; } + + virtual ::rtl::OString getTypeName(RegistryKey&) const + { return ::rtl::OString(); } + + virtual RegistryKey getTypeKey(const ::rtl::OString&, sal_Bool * = 0 ) const + { return RegistryKey(); } + virtual RegistryKeyList getTypeKeys(const ::rtl::OString&) const + { return RegistryKeyList(); } + virtual typereg::Reader getTypeReader( + const ::rtl::OString& name, sal_Bool * pIsExtraType = 0 ) const = 0; + virtual typereg::Reader getTypeReader(RegistryKey& rTypeKey) const = 0; + virtual RTTypeClass getTypeClass(const ::rtl::OString&) const + { return RT_TYPE_INVALID; } + virtual RTTypeClass getTypeClass(RegistryKey&) const + { return RT_TYPE_INVALID; } + + virtual void setBase(const ::rtl::OString&) {} + virtual ::rtl::OString getBase() const { return ::rtl::OString(); } + + virtual sal_Int32 getSize() const { return 0; } + + static sal_Bool isBaseType(const ::rtl::OString& name); +protected: + sal_Int32 acquire(); + sal_Int32 release(); + +protected: + TypeManagerImpl* m_pImpl; +}; + +struct RegistryTypeManagerImpl +{ + RegistryTypeManagerImpl() + : m_base("/") + {} + + T2TypeClassMap m_t2TypeClass; + RegistryList m_registries; + RegistryList m_extra_registries; + ::rtl::OString m_base; +}; + +class RegistryTypeManager : public TypeManager +{ +public: + RegistryTypeManager(); + virtual ~RegistryTypeManager(); + + RegistryTypeManager( const RegistryTypeManager& value ) + : TypeManager(value) + , m_pImpl( value.m_pImpl ) + { + acquire(); + } + + sal_Bool init(const StringVector& regFiles, const StringVector& extraFiles = StringVector() ); + + ::rtl::OString getTypeName(RegistryKey& rTypeKey) const; + + sal_Bool isValidType(const ::rtl::OString& name) const + { return searchTypeKey(name, 0).isValid(); } + RegistryKey getTypeKey( + const ::rtl::OString& name, sal_Bool * pIsExtraType = 0 ) const + { return searchTypeKey(name, pIsExtraType); } + RegistryKeyList getTypeKeys(const ::rtl::OString& name) const; + typereg::Reader getTypeReader( + const ::rtl::OString& name, sal_Bool * pIsExtraType = 0 ) const; + typereg::Reader getTypeReader(RegistryKey& rTypeKey) const; + RTTypeClass getTypeClass(const ::rtl::OString& name) const; + RTTypeClass getTypeClass(RegistryKey& rTypeKey) const; + + void setBase(const ::rtl::OString& base); + ::rtl::OString getBase() const { return m_pImpl->m_base; } + + sal_Int32 getSize() const { return m_pImpl->m_t2TypeClass.size(); } +protected: + RegistryKey searchTypeKey( + const ::rtl::OString& name, sal_Bool * pIsExtraType = 0 ) const; + void freeRegistries(); + + void acquire(); + void release(); + +protected: + RegistryTypeManagerImpl* m_pImpl; +}; + +#endif // INCLUDED_CODEMAKER_TYPEMANAGER_HXX diff --git a/codemaker/inc/codemaker/unotype.hxx b/codemaker/inc/codemaker/unotype.hxx new file mode 100644 index 000000000000..24a3d7adcba1 --- /dev/null +++ b/codemaker/inc/codemaker/unotype.hxx @@ -0,0 +1,110 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_UNOTYPE_HXX +#define INCLUDED_CODEMAKER_UNOTYPE_HXX + +#include "sal/types.h" + +#include <vector> + +namespace rtl { class OString; } + +namespace codemaker { + +namespace UnoType { + /** + An enumeration of all the sorts of UNO types. + + All complex UNO types are subsumed under SORT_COMPLEX. + */ + enum Sort { + SORT_VOID, + SORT_BOOLEAN, + SORT_BYTE, + SORT_SHORT, + SORT_UNSIGNED_SHORT, + SORT_LONG, + SORT_UNSIGNED_LONG, + SORT_HYPER, + SORT_UNSIGNED_HYPER, + SORT_FLOAT, + SORT_DOUBLE, + SORT_CHAR, + SORT_STRING, + SORT_TYPE, + SORT_ANY, + SORT_COMPLEX + }; + + /** + Maps from a binary UNO type name or UNO type registry name to its type + sort. + + @param type a binary UNO type name or UNO type registry name + + @return the sort of the UNO type denoted by the given type; the detection + of the correct sort is purely syntactical (especially, if the given input + is a UNO type registry name that denotes something other than a UNO type, + SORT_COMPLEX is returned) + */ + Sort getSort(rtl::OString const & type); + + /** + Determines whether a UNO type name or UNO type registry name denotes a + UNO sequence type. + + @param type a binary UNO type name or UNO type registry name + + @return true iff the given type denotes a UNO sequence type; the + detection is purely syntactical + */ + bool isSequenceType(rtl::OString const & type); + + /** + Decomposes a UNO type name or UNO type registry name. + + @param type a binary UNO type name or UNO type registry name + + @param rank if non-null, returns the rank of the denoted UNO type (which + is zero for any given type that does not denote a UNO sequence type) + + @param arguments if non-null, the type arguments are stripped from an + instantiated polymorphic struct type and returned via this parameter (in + the correct order); if null, type arguments are not stripped from + instantiated polymorphic struct types + + @return the base part of the given type + */ + rtl::OString decompose( + rtl::OString const & type, sal_Int32 * rank = 0, + std::vector< rtl::OString > * arguments = 0); +} + +} + +#endif diff --git a/codemaker/inc/makefile.mk b/codemaker/inc/makefile.mk new file mode 100644 index 000000000000..99789bfe38da --- /dev/null +++ b/codemaker/inc/makefile.mk @@ -0,0 +1,47 @@ +#************************************************************************* +# +# 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=inc + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + +.IF "$(ENABLE_PCH)"!="" +ALLTAR : \ + $(SLO)$/precompiled.pch \ + $(SLO)$/precompiled_ex.pch + +.ENDIF # "$(ENABLE_PCH)"!="" + diff --git a/codemaker/inc/pch/precompiled_codemaker.cxx b/codemaker/inc/pch/precompiled_codemaker.cxx new file mode 100644 index 000000000000..50632d92b15c --- /dev/null +++ b/codemaker/inc/pch/precompiled_codemaker.cxx @@ -0,0 +1,29 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_codemaker.hxx" + diff --git a/codemaker/inc/pch/precompiled_codemaker.hxx b/codemaker/inc/pch/precompiled_codemaker.hxx new file mode 100644 index 000000000000..5d7cafb7573a --- /dev/null +++ b/codemaker/inc/pch/precompiled_codemaker.hxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * 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): Generated on 2006-09-01 17:49:33.874150 + +#ifdef PRECOMPILED_HEADERS +#endif + diff --git a/codemaker/prj/build.lst b/codemaker/prj/build.lst new file mode 100644 index 000000000000..e0520d5cc71f --- /dev/null +++ b/codemaker/prj/build.lst @@ -0,0 +1,11 @@ +cm codemaker : udkapi NULL +cm codemaker usr1 - all cm_mkout NULL +cm codemaker\inc nmake - all cm_inc NULL +cm codemaker\prj get - all cm_prj NULL +cm codemaker\source\codemaker nmake - all cm_codemaker cm_inc NULL +cm codemaker\source\commoncpp nmake - all cm_cpp cm_inc NULL +cm codemaker\source\cppumaker nmake - all cm_cppumaker cm_codemaker cm_cpp cm_inc NULL +cm codemaker\source\commonjava nmake - all cm_java cm_inc NULL +cm codemaker\source\javamaker nmake - all cm_javamaker cm_codemaker cm_java cm_inc NULL + + diff --git a/codemaker/prj/d.lst b/codemaker/prj/d.lst new file mode 100644 index 000000000000..62b56b948e5c --- /dev/null +++ b/codemaker/prj/d.lst @@ -0,0 +1,14 @@ +..\%__SRC%\bin\cppumaker.exe %_DEST%\bin%_EXT%\cppumaker.exe +..\%__SRC%\bin\cppumaker.pdb %_DEST%\bin%_EXT%\cppumaker.pdb +..\%__SRC%\bin\javamaker.exe %_DEST%\bin%_EXT%\javamaker.exe +..\%__SRC%\bin\javamaker.pdb %_DEST%\bin%_EXT%\javamaker.pdb + +..\inc\codemaker\*.h %_DEST%\inc%_EXT%\codemaker\*.h +..\inc\codemaker\*.hxx %_DEST%\inc%_EXT%\codemaker\*.hxx + +..\%__SRC%\bin\cppumaker %_DEST%\bin%_EXT%\cppumaker +..\%__SRC%\bin\javamaker %_DEST%\bin%_EXT%\javamaker + +..\%__SRC%\lib\*.lib %_DEST%\lib%_EXT%\*.lib +..\%__SRC%\lib\i*.lib %_DEST%\lib%_EXT%\i*.lib +..\%__SRC%\lib\*.a %_DEST%\lib%_EXT%\*.a diff --git a/codemaker/source/bonobowrappermaker/corbamaker.cxx b/codemaker/source/bonobowrappermaker/corbamaker.cxx new file mode 100644 index 000000000000..85221b53f9ec --- /dev/null +++ b/codemaker/source/bonobowrappermaker/corbamaker.cxx @@ -0,0 +1,239 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 <stdio.h> + +#include "sal/main.h" + +#include <codemaker/typemanager.hxx> +#include <codemaker/dependency.hxx> + +#include "corbaoptions.hxx" +#include "corbatype.hxx" + +using namespace rtl; + +sal_Bool produceAllTypes(const OString& typeName, + TypeManager& typeMgr, + TypeDependency& typeDependencies, + CorbaOptions* pOptions, + sal_Bool bFullScope, + FileStream& o, + TypeSet* pAllreadyDumped, + TypeSet* generatedConversion) + + throw( CannotDumpException ) +{ + if (!produceType(typeName, typeMgr, typeDependencies, pOptions, o, pAllreadyDumped, generatedConversion)) + { + fprintf(stderr, "%s ERROR: %s\n", + pOptions->getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + + RegistryKey typeKey = typeMgr.getTypeKey(typeName); + RegistryKeyNames subKeys; + + if (typeKey.getKeyNames(OUString(), subKeys)) + return sal_False; + + OString tmpName; + for (sal_uInt32 i=0; i < subKeys.getLength(); i++) + { + tmpName = OUStringToOString(subKeys.getElement(i), RTL_TEXTENCODING_UTF8); + + if (pOptions->isValid("-B")) + tmpName = tmpName.copy(tmpName.indexOf('/', 1) + 1); + else + tmpName = tmpName.copy(1); + + if (bFullScope) + { + if (!produceAllTypes(tmpName, typeMgr, typeDependencies, pOptions, sal_True, o, pAllreadyDumped, generatedConversion)) + return sal_False; + } else + { + if (!produceType(tmpName, typeMgr, typeDependencies, pOptions, o, pAllreadyDumped, generatedConversion)) + return sal_False; + } + } + + return sal_True; +} + +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) +{ + CorbaOptions options; + + try + { + if (!options.initOptions(argc, argv)) + { + exit(1); + } + } + catch( IllegalArgument& e) + { + fprintf(stderr, "Illegal option: %s\n", e.m_message.getStr()); + exit(99); + } + + RegistryTypeManager typeMgr; + TypeDependency typeDependencies; + + if (!typeMgr.init(!options.isValid("-T"), options.getInputFiles())) + { + fprintf(stderr, "%s : init registries failed, check your registry files.\n", options.getProgramName().getStr()); + exit(99); + } + + if (options.isValid("-B")) + { + typeMgr.setBase(options.getOption("-B")); + } + + try + { + TypeSet generatedConversion; + FileStream cppFile; + OString outPath; + if (options.isValid("-O")) + outPath = options.getOption("-O"); + + cppFile.open(outPath); + + if(!cppFile.isValid()) + { + OString message("cannot open "); + message += outPath + " for writing"; + throw CannotDumpException(message); + } + + if (options.isValid("-H")) + { + OString corbaHeader = options.getOption("-H"); + + cppFile << "#include <" + << corbaHeader + << ">\n\n"; + + CorbaType::dumpDefaultHxxIncludes(cppFile); + cppFile << "\n"; + } + + if (options.isValid("-T")) + { + OString tOption(options.getOption("-T")); + + OString typeName, tmpName; + sal_Bool ret = sal_False; + sal_Int32 nIndex = 0; + do + { + typeName = tOption.getToken(0, ';', nIndex); + + sal_Int32 nPos = typeName.lastIndexOf( '.' ); + tmpName = typeName.copy( nPos != -1 ? nPos+1 : 0 ); + if (tmpName == "*") + { + // produce this type and his scope, but the scope is not recursively generated. + if (typeName.equals("*")) + { + tmpName = "/"; + } else + { + tmpName = typeName.copy(0, typeName.lastIndexOf('.')).replace('.', '/'); + if (tmpName.getLength() == 0) + tmpName = "/"; + else + tmpName.replace('.', '/'); + } + ret = produceAllTypes(tmpName, typeMgr, typeDependencies, &options, sal_False, cppFile, NULL, &generatedConversion); + } else + { + // produce only this type + ret = produceType(typeName.replace('.', '/'), typeMgr, typeDependencies, &options, cppFile, NULL, &generatedConversion); + } + + if (!ret) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + } while( nIndex != -1 ); + } else + { + // produce all types + if (!produceAllTypes("/", typeMgr, typeDependencies, &options, sal_True, cppFile, NULL, &generatedConversion)) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + "an error occurs while dumping all types."); + exit(99); + } + } + + cppFile << "namespace bonobobridge {\n" + << "const ConversionInfo* get_conversion_functions() {\n" + << " static ConversionInfo allFunctions[" << generatedConversion.size()+1<< "] = {\n"; + + for (TypeSet::iterator iter = generatedConversion.begin(); iter != generatedConversion.end(); iter++) + { + cppFile << " {\"" << (*iter).getStr() << "\"" + << ", &TC_" << (*iter).replace('/','_').getStr() << "_struct" + << ", sizeof(" << (*iter).replace('/','_').getStr() << ")" + << ", convert_b2u_" << (*iter).replace('/','_').getStr() + << ", convert_u2b_" << (*iter).replace('/','_').getStr() + << " },\n"; + } + + cppFile << " {NULL, NULL, 0 , NULL, NULL} };\n" + << " return allFunctions;\n" + << "}\n" + << "}; // namespace bonobobridge\n"; + + cppFile.close(); + } + catch( CannotDumpException& e) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + e.m_message.getStr()); + exit(99); + } + + return 0; +} + + diff --git a/codemaker/source/bonobowrappermaker/corbaoptions.cxx b/codemaker/source/bonobowrappermaker/corbaoptions.cxx new file mode 100644 index 000000000000..3c644b6ff4dd --- /dev/null +++ b/codemaker/source/bonobowrappermaker/corbaoptions.cxx @@ -0,0 +1,256 @@ +/************************************************************************* + * + * 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 <stdio.h> + +#include "corbaoptions.hxx" + +using namespace rtl; + +sal_Bool CorbaOptions::initOptions(int ac, char* av[], sal_Bool bCmdFile) + throw( IllegalArgument ) +{ + sal_Bool ret = sal_True; + sal_uInt16 i=0; + + if (!bCmdFile) + { + bCmdFile = sal_True; + + m_program = av[0]; + + if (ac < 2) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } + + i = 1; + } else + { + i = 0; + } + + char *s=NULL; + for (i; i < ac; i++) + { + if (av[i][0] == '-') + { + switch (av[i][1]) + { + case 'O': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-O', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_options["-O"] = OString(s); + break; + case 'H': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-H', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_options["-H"] = OString(s); + break; + case 'B': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-B', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_options["-B"] = OString(s); + break; + case 'T': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-T', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + if (m_options.count("-T") > 0) + { + OString tmp(m_options["-T"]); + tmp = tmp + ";" + s; + m_options["-T"] = tmp; + } else + { + m_options["-T"] = OString(s); + } + break; + case 'G': + if (av[i][2] != '\0') + { + OString tmp("'-G', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + m_options["-G"] = OString(""); + break; + default: + throw IllegalArgument("the option is unknown" + OString(av[i])); + break; + } + } else + { + if (av[i][0] == '@') + { + FILE* cmdFile = fopen(av[i]+1, "r"); + if( cmdFile == NULL ) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } else + { + int rargc=0; + char* rargv[512]; + char buffer[512]; + + while ( fscanf(cmdFile, "%s", buffer) != EOF ) + { + rargv[rargc]= strdup(buffer); + rargc++; + } + fclose(cmdFile); + + ret = initOptions(rargc, rargv, bCmdFile); + + for (long i=0; i < rargc; i++) + { + free(rargv[i]); + } + } + } else + { + m_inputFiles.push_back(av[i]); + } + } + } + printf("-T: %s\n", m_options["-T"].getStr()); + + return ret; +} + +OString CorbaOptions::prepareHelp() +{ + OString help("\nusing: "); + help += m_program + " [-options] file_1 ... file_n\nOptions:\n"; + help += " -O<file> = file name for the generated output.\n"; + help += " The output directory tree is generated under this directory.\n"; + help += " -T<name> = name specifies a type or a list of types. The output for this\n"; + help += " [t1;...] type is generated. If no '-T' option is specified,\n"; + help += " then output for all types is generated.\n"; + help += " Example: 'com.sun.star.uno.XInterface' is a valid type.\n"; + help += " -B<name> = name specifies the base node. All types are searched under this\n"; + help += " node. Default is the root '/' of the registry files.\n"; + help += " -G = generate only target files which does not exists.\n"; + help += " -H<header> = include CORBA generated <header>.\n"; + help += prepareVersion(); + + return help; +} + +OString CorbaOptions::prepareVersion() +{ + OString version("\nSun Microsystems (R) "); + version += m_program + " Version 2.0\n\n"; + + return version; +} + + diff --git a/codemaker/source/bonobowrappermaker/corbaoptions.hxx b/codemaker/source/bonobowrappermaker/corbaoptions.hxx new file mode 100644 index 000000000000..aa08016f5ee7 --- /dev/null +++ b/codemaker/source/bonobowrappermaker/corbaoptions.hxx @@ -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. + * + ************************************************************************/ + +#ifndef _CORBAMAKER_CPPUOPTIONS_HXX_ +#define _CORBAMAKER_CPPUOPTIONS_HXX_ + +#include <codemaker/options.hxx> + +class CorbaOptions : public Options +{ +public: + CorbaOptions() + : Options() {} + + ~CorbaOptions() {} + + sal_Bool initOptions(int ac, char* av[], sal_Bool bCmdFile=sal_False) + throw( IllegalArgument ); + + ::rtl::OString prepareHelp(); + + ::rtl::OString prepareVersion(); + +protected: +}; + +#endif // _CORBAMAKER_CPPUOPTIONS_HXX_ diff --git a/codemaker/source/bonobowrappermaker/corbatype.cxx b/codemaker/source/bonobowrappermaker/corbatype.cxx new file mode 100644 index 000000000000..417af55b326e --- /dev/null +++ b/codemaker/source/bonobowrappermaker/corbatype.cxx @@ -0,0 +1,2782 @@ +/************************************************************************* + * + * 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 <stdio.h> +#include <rtl/alloc.h> +#include <rtl/ustring.hxx> +#include <rtl/strbuf.hxx> + +#include "corbatype.hxx" +#include "corbaoptions.hxx" + +#include <hash_set> +#include <list> + +using namespace rtl; + + +//************************************************************************* +// CorbaType +//************************************************************************* +CorbaType::CorbaType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversions) + : m_inheritedMemberCount(0) + , m_indentLength(0) + , m_typeName(typeName) + , m_reader(typeReader) + , m_typeMgr((TypeManager&)typeMgr) + , m_dependencies(typeDependencies) + , m_generatedConversions(generatedConversions) +{ + sal_Int32 i = typeName.lastIndexOf('/'); + m_name = typeName.copy( i != -1 ? i+1 : 0 ); +} + +CorbaType::~CorbaType() +{ + +} + +sal_Bool CorbaType::isNestedTypeByName(const ::rtl::OString& type) +{ + sal_Bool ret = sal_False; + + sal_Int32 i = type.lastIndexOf('/'); + + if (i >= 0) + { + OString outerTypeName(type.copy(0, i)); + ret = (m_typeMgr.getTypeClass(outerTypeName) == RT_TYPE_INTERFACE); + } + + return ret; +} + +sal_Bool CorbaType::dump(CorbaOptions* pOptions, FileStream& o, TypeSet* allreadyDumped) + throw( CannotDumpException ) +{ + sal_Bool ret = sal_False; + + ret = dumpConversionFunctions(o, allreadyDumped); + + return ret; +} + +sal_Bool CorbaType::dumpDependedTypes(CorbaOptions* pOptions, FileStream& o, TypeSet* allreadyDumped) + throw( CannotDumpException ) +{ + sal_Bool ret = sal_True; + + TypeUsingSet usingSet(m_dependencies.getDependencies(m_typeName)); + + TypeUsingSet::const_iterator iter = usingSet.begin(); + OString typeName; + sal_uInt32 index = 0; + while (iter != usingSet.end()) + { + typeName = (*iter).m_type; + if ((index = typeName.lastIndexOf(']')) > 0) + typeName = typeName.copy(index + 1); + + if (getUnoBaseType(typeName).getLength() == 0) + { + if (!produceType(typeName, + m_typeMgr, + m_dependencies, + pOptions, + o, allreadyDumped, m_generatedConversions)) + { + fprintf(stderr, "%s ERROR: %s\n", + pOptions->getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + } + ++iter; + } + + return ret; +} + +sal_Bool CorbaType::dumpConversionFunctions(FileStream& o, TypeSet* allreadyDumped) + throw( CannotDumpException ) +{ + if (m_typeName.lastIndexOf(']') < 0) + { + dumpInclude(o, allreadyDumped, m_typeName, "hpp", sal_False); + dumpDepIncludes(o, allreadyDumped, m_typeName, "hpp"); + + dumpFunctions(o); + } + + return sal_True; +} + + +void CorbaType::dumpDefaultHxxIncludes(FileStream& o) +{ + o << "#ifndef _OSL_MUTEX_HXX_\n" + << "#include <osl/mutex.hxx>\n" + << "#endif\n\n"; + + o << "#ifndef _RTL_USTRING_HXX_\n" + << "#include <rtl/ustring.hxx>\n" + << "#endif\n\n"; + + o << "#ifndef _COM_SUN_STAR_UNO_TYPE_HXX_\n" + << "#include <com/sun/star/uno/Type.hxx>\n" + << "#endif\n"; + + o << "#ifndef _COM_SUN_STAR_UNO_ANY_HXX_\n" + << "#include <com/sun/star/uno/Any.hxx>\n" + << "#endif\n"; + + o << "#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_\n" + << "#include <com/sun/star/uno/Reference.hxx>\n" + << "#endif\n"; + + o << "#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HPP_\n" + << "#include <com/sun/star/uno/XInterface.hpp>\n" + << "#endif\n"; + + o << "#ifndef _BONOBO_NULLINTERFACE_HPP_\n" + << "#include <Bonobo/NullInterface.hpp>\n" + << "#endif\n"; + + o << "#ifndef _COM_SUN_STAR_UNO_EXCEPTION_HPP_\n" + << "#include <com/sun/star/uno/Exception.hpp>\n" + << "#endif\n"; + + o << "#ifndef _COM_SUN_STAR_UNO_RUNTIMEEXCEPTION_HPP_\n" + << "#include <com/sun/star/uno/RuntimeException.hpp>\n" + << "#endif\n"; + + o << "#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_\n" + << "#include <com/sun/star/uno/Sequence.hxx>\n" + << "#endif\n"; +} + + +void CorbaType::dumpInclude(FileStream& o, TypeSet* allreadyDumped, const OString& typeName, sal_Char* prefix, sal_Bool bExtended, sal_Bool bCaseSensitive) +{ + OString realTypeName = checkRealBaseType( typeName ); + + if (!isNestedTypeByName(typeName) && + (BT_INVALID == isBaseType(realTypeName)) && + !realTypeName.equals("Bonobo/NullInterface") && + !realTypeName.equals("com/sun/star/uno/XInterface") && + !realTypeName.equals("com/sun/star/uno/TypeClass") && + !realTypeName.equals("com/sun/star/uno/Type") && + !realTypeName.equals("com/sun/star/uno/Exception") && + !realTypeName.equals("com/sun/star/uno/RuntimeException")) + { + TypeSet::const_iterator iter = allreadyDumped->find(realTypeName); + + if (iter == allreadyDumped->end()) + { + allreadyDumped->insert(realTypeName); + + sal_uInt32 length = 3+ m_typeName.getLength() + strlen(prefix); + + if (bExtended) + length += m_name.getLength() + 1; + + OStringBuffer tmpBuf(length); + + tmpBuf.append('_'); + tmpBuf.append(typeName); + tmpBuf.append('_'); + if (bExtended) + { + tmpBuf.append(m_name); + tmpBuf.append('_'); + } + tmpBuf.append(prefix); + tmpBuf.append('_'); + + OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase()); + + length = 1 + typeName.getLength() + strlen(prefix); + if (bExtended) + length += m_name.getLength() + 1; + + tmpBuf.ensureCapacity(length); + tmpBuf.append(typeName); + if (bExtended) + { + tmpBuf.append('/'); + tmpBuf.append(m_name); + } + tmpBuf.append('.'); + tmpBuf.append(prefix); + + o << "#ifndef " << tmp << "\n#include <"; + if (bCaseSensitive) + { + o << tmpBuf.makeStringAndClear(); + } else + { + o << tmpBuf.makeStringAndClear(); + } + + o << ">\n"; + o << "#endif\n"; + + o << "namespace bonobobridge {\n\n"; + + std::list<OString> nestedTypes; + + do + { + if ((realTypeName.lastIndexOf(']') < 0) && + (BT_INVALID == isBaseType(realTypeName)) && + !realTypeName.equals("Bonobo/NullInterface") && + !realTypeName.equals("com/sun/star/uno/XInterface") && + !realTypeName.equals("com/sun/star/uno/TypeClass") && + !realTypeName.equals("com/sun/star/uno/Type") && + !realTypeName.equals("com/sun/star/uno/Exception") && + !realTypeName.equals("com/sun/star/uno/RuntimeException") && + !realTypeName.equals("com/sun/star/uno/TypeClass")) + { + o << "inline sal_Bool cpp_convert_b2u("; + dumpUnoType(o, realTypeName, sal_False, sal_True); + o << " u, "; + dumpCorbaType(o, realTypeName, sal_True, sal_True); + o << " b, const ::vos::ORef< ::bonobobridge::Bridge >& bridge);\n"; + o << "inline sal_Bool cpp_convert_u2b("; + dumpCorbaType(o, realTypeName, sal_False, sal_True); + o << " b, "; + dumpUnoType(o, realTypeName, sal_True, sal_True); + o << " u, const ::vos::ORef< ::bonobobridge::Bridge >& bridge);\n"; + } + + RegistryKey key = m_typeMgr.getTypeKey(realTypeName); + RegistryKeyNames nestedTypeNames; + key.getKeyNames(OUString(), nestedTypeNames); + for (sal_uInt32 i = 0; i < nestedTypeNames.getLength(); i++) + { + OString nTypeName(OUStringToOString(nestedTypeNames.getElement(i), RTL_TEXTENCODING_UTF8)); + + nTypeName = checkRealBaseType(nTypeName.copy(5)); + + if (BT_INVALID == isBaseType(nTypeName)) + { + allreadyDumped->insert(nTypeName); + nestedTypes.push_back(nTypeName); + } + } + + if (nestedTypes.size() > 0) + { + realTypeName = nestedTypes.front(); + nestedTypes.pop_front(); + } + else + { + realTypeName = ""; + } + } + while (realTypeName.getLength() > 0); + + o << "}; // namespace bonobobridge\n"; + } + } +} + +void CorbaType::dumpDepIncludes(FileStream& o, TypeSet* allreadyDumped, const OString& typeName, sal_Char* prefix) +{ + TypeUsingSet usingSet(m_dependencies.getDependencies(typeName)); + + TypeUsingSet::const_iterator iter = usingSet.begin(); + + OString sPrefix(OString(prefix).toAsciiUpperCase()); + sal_Bool bSequenceDumped = sal_False; + sal_Bool bInterfaceDumped = sal_False; + sal_uInt32 index = 0; + sal_uInt32 seqNum = 0; + OString relType; + while (iter != usingSet.end()) + { + index = (*iter).m_type.lastIndexOf(']'); + seqNum = (index > 0 ? ((index+1) / 2) : 0); + + relType = (*iter).m_type; + if (index > 0) + relType = relType.copy(index+1); + + if (!isNestedTypeByName(relType)) + { + OString defPrefix("HXX"); + if (sPrefix.equals("HDL")) + defPrefix = "H"; + + if (seqNum > 0 && !bSequenceDumped) + { + bSequenceDumped = sal_True; + } + + if (getUnoBaseType(relType).getLength() == 0 && + m_typeName != relType) + { + if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE + && sPrefix.equals("HDL")) + { + if (!bInterfaceDumped) + { + bInterfaceDumped = sal_True; + } + + if (!((*iter).m_use & TYPEUSE_SUPER)) + { + o << "\n"; + dumpNameSpace(o, sal_True, sal_False, relType); + o << "\nclass " << scopedName(m_typeName, relType, sal_True) << ";\n"; + dumpNameSpace(o, sal_False, sal_False, relType); + o << "\n\n"; + } else + { + dumpInclude(o, allreadyDumped, relType, prefix); + } + } else + { + dumpInclude(o, allreadyDumped, relType, prefix); + } + } + } + ++iter; + } +} + +void CorbaType::dumpNameSpace(FileStream& o, sal_Bool bOpen, sal_Bool bFull, const OString& type) +{ + OString typeName(type); + sal_Bool bOneLine = sal_True; + if (typeName.getLength() == 0) + { + typeName = m_typeName; + bOneLine = sal_False; + } + + if (typeName == "/") + return; + + if (typeName.indexOf( '/' ) == -1 && !bFull) + return; + + if (!bFull) + typeName = typeName.copy( 0, typeName.lastIndexOf( '/' ) ); + + if (bOpen) + { + sal_Int32 nIndex = 0; + do + { + o << "namespace " << typeName.getToken(0, '/', nIndex); + if (bOneLine) + o << " { "; + else + o << "\n{\n"; + } while( nIndex != -1 ); + } else + { + sal_Int32 nPos = 0; + do + { + nPos = typeName.lastIndexOf( '/' ); + o << "}"; + if( bOneLine ) + o << " "; + else + o << " // " << typeName.copy( nPos+1 ) << "\n"; + if( nPos != -1 ) + typeName = typeName.copy( 0, nPos ); + } while( nPos != -1 ); + } +} + + +sal_uInt32 CorbaType::getMemberCount() +{ + sal_uInt32 count = m_reader.getMethodCount(); + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + count++; + } + return count; +} + +sal_uInt32 CorbaType::checkInheritedMemberCount(const TypeReader* pReader) +{ + sal_Bool bSelfCheck = sal_True; + if (!pReader) + { + bSelfCheck = sal_False; + pReader = &m_reader; + } + + sal_uInt32 count = 0; + OString superType(pReader->getSuperTypeName()); + if (superType.getLength() > 0) + { + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + if ( aSuperReader.isValid() ) + { + count = checkInheritedMemberCount(&aSuperReader); + } + } + + if (bSelfCheck) + { + count += pReader->getMethodCount(); + sal_uInt32 fieldCount = pReader->getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = pReader->getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + count++; + } + } + + return count; +} + +sal_uInt32 CorbaType::getInheritedMemberCount() +{ + if (m_inheritedMemberCount == 0) + { + m_inheritedMemberCount = checkInheritedMemberCount(0); + } + + return m_inheritedMemberCount; +} + +OString CorbaType::getTypeClass(const OString& type, sal_Bool bCStyle) +{ + OString typeName = (type.getLength() > 0 ? type : m_typeName); + RTTypeClass rtTypeClass = RT_TYPE_INVALID; + + if (type.getLength() > 0) + { + typeName = type; + rtTypeClass = m_typeMgr.getTypeClass(typeName); + } else + { + typeName = m_typeName; + rtTypeClass = m_reader.getTypeClass(); + } + + if (typeName.lastIndexOf(']') > 0) + return bCStyle ? "typelib_TypeClass_SEQUENCE" : "::com::sun::star::uno::TypeClass_SEQUENCE"; + + switch (rtTypeClass) + { + case RT_TYPE_INTERFACE: + return bCStyle ? "typelib_TypeClass_INTERFACE" : "::com::sun::star::uno::TypeClass_INTERFACE"; + break; + case RT_TYPE_MODULE: + return bCStyle ? "typelib_TypeClass_MODULE" : "::com::sun::star::uno::TypeClass_MODULE"; + break; + case RT_TYPE_STRUCT: + return bCStyle ? "typelib_TypeClass_STRUCT" : "::com::sun::star::uno::TypeClass_STRUCT"; + break; + case RT_TYPE_ENUM: + return bCStyle ? "typelib_TypeClass_ENUM" : "::com::sun::star::uno::TypeClass_ENUM"; + break; + case RT_TYPE_EXCEPTION: + return bCStyle ? "typelib_TypeClass_EXCEPTION" : "::com::sun::star::uno::TypeClass_EXCEPTION"; + break; + case RT_TYPE_TYPEDEF: + { + OString realType = checkRealBaseType( typeName ); + return getTypeClass( realType, bCStyle ); + } +// return bCStyle ? "typelib_TypeClass_TYPEDEF" : "::com::sun::star::uno::TypeClass_TYPEDEF"; + break; + case RT_TYPE_SERVICE: + return bCStyle ? "typelib_TypeClass_SERVICE" : "::com::sun::star::uno::TypeClass_SERVICE"; + break; + case RT_TYPE_INVALID: + { + if (type.equals("long")) + return bCStyle ? "typelib_TypeClass_LONG" : "::com::sun::star::uno::TypeClass_LONG"; + if (type.equals("short")) + return bCStyle ? "typelib_TypeClass_SHORT" : "::com::sun::star::uno::TypeClass_SHORT"; + if (type.equals("hyper")) + return bCStyle ? "typelib_TypeClass_HYPER" : "::com::sun::star::uno::TypeClass_HYPER"; + if (type.equals("string")) + return bCStyle ? "typelib_TypeClass_STRING" : "::com::sun::star::uno::TypeClass_STRING"; + if (type.equals("boolean")) + return bCStyle ? "typelib_TypeClass_BOOLEAN" : "::com::sun::star::uno::TypeClass_BOOLEAN"; + if (type.equals("char")) + return bCStyle ? "typelib_TypeClass_CHAR" : "::com::sun::star::uno::TypeClass_CHAR"; + if (type.equals("byte")) + return bCStyle ? "typelib_TypeClass_BYTE" : "::com::sun::star::uno::TypeClass_BYTE"; + if (type.equals("any")) + return bCStyle ? "typelib_TypeClass_ANY" : "::com::sun::star::uno::TypeClass_ANY"; + if (type.equals("type")) + return bCStyle ? "typelib_TypeClass_TYPE" : "::com::sun::star::uno::TypeClass_TYPE"; + if (type.equals("float")) + return bCStyle ? "typelib_TypeClass_FLOAT" : "::com::sun::star::uno::TypeClass_FLOAT"; + if (type.equals("double")) + return bCStyle ? "typelib_TypeClass_DOUBLE" : "::com::sun::star::uno::TypeClass_DOUBLE"; + if (type.equals("void")) + return bCStyle ? "typelib_TypeClass_VOID" : "::com::sun::star::uno::TypeClass_VOID"; + if (type.equals("unsigned long")) + return bCStyle ? "typelib_TypeClass_UNSIGNED_LONG" : "::com::sun::star::uno::TypeClass_UNSIGNED_LONG"; + if (type.equals("unsigned short")) + return bCStyle ? "typelib_TypeClass_UNSIGNED_SHORT" : "::com::sun::star::uno::TypeClass_UNSIGNED_SHORT"; + if (type.equals("unsigned hyper")) + return bCStyle ? "typelib_TypeClass_UNSIGNED_HYPER" : "::com::sun::star::uno::TypeClass_UNSIGNED_HYPER"; + } + break; + } + + return bCStyle ? "typelib_TypeClass_UNKNOWN" : "::com::sun::star::uno::TypeClass_UNKNOWN"; +} + +OString CorbaType::printUnoType(const OString& type, sal_Bool bConst, sal_Bool bRef, sal_Bool bNative) + throw( CannotDumpException ) +{ + OStringBuffer ret(1024); + OString sType(checkRealBaseType(type, sal_True)); + sal_uInt32 index = sType.lastIndexOf(']'); + sal_uInt32 seqNum = (index > 0 ? ((index+1) / 2) : 0); + + OString relType = (index > 0 ? (sType).copy(index+1) : type); + + RTTypeClass typeClass = m_typeMgr.getTypeClass(relType); + + if (bConst) ret.append("const "); + + sal_uInt32 i; + for (i=0; i < seqNum; i++) + { + ret.append("::com::sun::star::uno::Sequence< "); + } + + switch (typeClass) + { + case RT_TYPE_INTERFACE: + if (bNative) + ret.append(scopedName(m_typeName, relType)); + else + ret.append("::com::sun::star::uno::Reference< ").append(scopedName(m_typeName, relType)).append(" >"); + break; + case RT_TYPE_INVALID: + { + OString tmp(getUnoBaseType(relType)); + if (tmp.getLength() > 0) + { + ret.append(getUnoBaseType(relType)); + } else + throw CannotDumpException("Unknown type '" + relType + "', incomplete type library. ("+type+")"); + } + break; + case RT_TYPE_STRUCT: + case RT_TYPE_ENUM: + case RT_TYPE_TYPEDEF: + case RT_TYPE_EXCEPTION: + ret.append(scopedName(m_typeName, relType)); + break; + } + + for (i=0; i < seqNum; i++) + { + ret.append(" >"); + } + + if (bRef) ret.append("&"); + return ret.makeStringAndClear(); +} + +void CorbaType::dumpUnoType(FileStream& o, const OString& type, + sal_Bool bConst, sal_Bool bRef, sal_Bool bNative) + throw( CannotDumpException ) +{ + OString ret = printUnoType(type, bConst, bRef, bNative); + o << ret; +} + +OString CorbaType::printCorbaType(const OString& type, sal_Bool bConst, sal_Bool bRef) + throw( CannotDumpException ) +{ + OStringBuffer ret(1024); + + OString sType(type); + + sal_uInt32 index = sType.lastIndexOf(']'); + sal_uInt32 seqNum = (index > 0 ? ((index+1) / 2) : 0); + + OString relType = (index > 0 ? (sType).copy(index+1) : type); + + RTTypeClass typeClass = m_typeMgr.getTypeClass(relType); + + if (relType.equals("com/sun/star/uno/XInterface")) + relType = "Bonobo/Unknown"; + + if (relType.equals("com/sun/star/uno/TypeClass")) + relType = "CORBA_TypeCode"; + + if (relType.equals("com/sun/star/uno/RuntimeException")) + relType = "CORBA_SystemException"; + + if (relType.equals("com/sun/star/uno/Exception")) + relType = "CORBA_any"; + + if (bConst) ret.append("const "); + + + sal_uInt32 i; + for (i=0; i < seqNum; i++) + { + ret.append("CORBA_sequence_"); + } + + switch (typeClass) + { + case RT_TYPE_INTERFACE: + ret.append(relType.replace('/', '_')); + break; + case RT_TYPE_INVALID: + { + OString tmp(getUnoBaseType(relType)); + if (tmp.getLength() > 0) + ret.append(getCorbaBaseType(relType)); + else + throw CannotDumpException("Unknown type '" + relType + "', incomplete type library. ("+type+")"); + } + break; + case RT_TYPE_STRUCT: + case RT_TYPE_ENUM: + case RT_TYPE_TYPEDEF: + case RT_TYPE_EXCEPTION: + ret.append(relType.replace('/', '_')); + break; + } + + if (bRef) ret.append("&"); + + return ret.makeStringAndClear(); +} + +sal_Bool CorbaType::isPassedAsPointer(const OString& type) +{ + sal_Bool ret = sal_False; + + OString sType(checkSpecialCorbaType(type)); + + sal_Int32 index = sType.lastIndexOf(']'); + sal_Int32 seqNum = (index > 0 ? ((index+1) / 2) : 0); + + OString relType = (index > 0 ? (sType).copy(index+1) : type); + + if (index > 0) + { + OString fakeTest; + + sal_Int32 j = type.lastIndexOf('/'); + if (j >= 0) + fakeTest = type.copy(0, j+1)+"_faked_array_"+type.copy(j+1); + else + fakeTest = "_faked_array_"+sType; + + TypeReader fakeTestReader = m_typeMgr.getTypeReader(fakeTest); + + if (fakeTestReader.isValid()) + ret = sal_False; + else + ret = sal_True; + } + else + { + RTTypeClass typeClass = m_typeMgr.getTypeClass(sType); + + switch (typeClass) + { + case RT_TYPE_STRUCT: + case RT_TYPE_EXCEPTION: + ret = sal_True; + break; + + case RT_TYPE_INTERFACE: + case RT_TYPE_ENUM: + case RT_TYPE_INVALID: + if (sType.equals("any")) + ret = sal_True; + else + ret = sal_False; + break; + } + } + + return ret; +} + +sal_Bool CorbaType::isDerivedFromUnknown(const ::rtl::OString& typeName) +{ + sal_Bool ret = sal_True; + if (typeName.getLength() == 0) + ret = sal_False; + else if (typeName.equals("Bonobo/NullInterface")) + ret = sal_False; + else if (typeName.equals("com/sun/star/uno/XInterface")) + ret = sal_True; + else + { + TypeReader reader(m_typeMgr.getTypeReader(typeName)); + if (reader.isValid()) + ret = isDerivedFromUnknown(reader.getSuperTypeName()); + else + ret = sal_False; + } + return ret; +} + + +sal_Bool CorbaType::isArray(const OString& type) +{ + sal_Bool ret = sal_False; + + OString sType(checkSpecialCorbaType(type)); + + sal_Int32 index = sType.lastIndexOf(']'); + sal_Int32 seqNum = (index > 0 ? ((index+1) / 2) : 0); + + OString relType = (index > 0 ? (sType).copy(index+1) : type); + + if (index > 0) + { + OString fakeTest; + + sal_Int32 j = type.lastIndexOf('/'); + if (j >= 0) + fakeTest = type.copy(0, j+1)+"_faked_array_"+type.copy(j+1); + else + fakeTest = "_faked_array_"+sType; + + TypeReader fakeTestReader = m_typeMgr.getTypeReader(fakeTest); + + if (fakeTestReader.isValid()) + ret = sal_True; + } + + return ret; +} + +OString CorbaType::printCorbaParameter(const OString& type, sal_Bool bOut) + throw( CannotDumpException ) +{ + OStringBuffer ret(1024); + + OString sType(type); + sal_Int32 index = sType.lastIndexOf(']'); + sal_Int32 seqNum = (index > 0 ? ((index+1) / 2) : 0); + + OString relType = (index > 0 ? (sType).copy(index+1) : type); + + RTTypeClass typeClass = m_typeMgr.getTypeClass(relType); + + if (relType.equals("Bonobo/NullInterface")) + relType = "CORBA_Object"; + + if (relType.equals("com/sun/star/uno/XInterface")) + relType = "Bonobo/Unknown"; + + if (relType.equals("com/sun/star/uno/TypeClass")) + relType = "CORBA_TypeCode"; + + if (relType.equals("com/sun/star/uno/RuntimeException")) + relType = "CORBA_SystemException"; + + if (relType.equals("com/sun/star/uno/Exception")) + relType = "CORBA_any"; + + int i; + for (i=0; i < seqNum; i++) + { + ret.append("CORBA_sequence_"); + } + + switch (typeClass) + { + case RT_TYPE_INTERFACE: + ret.append(relType.replace('/', '_')); + break; + case RT_TYPE_INVALID: + { + OString tmp(getUnoBaseType(relType)); + if (tmp.getLength() > 0) + { + ret.append(getCorbaBaseType(relType)); + } else + throw CannotDumpException("Unknown type '" + relType + "', incomplete type library. ("+type+")"); + } + break; + case RT_TYPE_STRUCT: + case RT_TYPE_EXCEPTION: + case RT_TYPE_ENUM: + case RT_TYPE_TYPEDEF: + ret.append(relType.replace('/', '_')); + break; + } + + return ret.makeStringAndClear(); +} + +void CorbaType::dumpCorbaType(FileStream& o, const OString& type, + sal_Bool bConst, sal_Bool bRef) + throw( CannotDumpException ) +{ + OString ret = printCorbaType(type, bConst, bRef); + o << ret; +} + +OString CorbaType::getUnoBaseType(const OString& type) +{ + if (type.equals("long")) + return "sal_Int32"; + if (type.equals("short")) + return "sal_Int16"; + if (type.equals("hyper")) + return "sal_Int64"; + if (type.equals("string")) + return "::rtl::OUString"; + if (type.equals("boolean")) + return "sal_Bool"; + if (type.equals("char")) + return "sal_Unicode"; + if (type.equals("byte")) + return "sal_Int8"; + if (type.equals("any")) + return "::com::sun::star::uno::Any"; + if (type.equals("type")) + return "::com::sun::star::uno::Type"; + if (type.equals("float")) + return "float"; + if (type.equals("double")) + return "double"; + if (type.equals("octet")) + return "sal_Int8"; + if (type.equals("void")) + return type; + if (type.equals("unsigned long")) + return "sal_uInt32"; + if (type.equals("unsigned short")) + return "sal_uInt16"; + if (type.equals("unsigned hyper")) + return "sal_uInt64"; + + return OString(); +} + +OString CorbaType::getCorbaBaseType(const OString& type) +{ + if (type.equals("long")) + return "CORBA_long"; + if (type.equals("short")) + return "CORBA_short"; + if (type.equals("hyper")) + return "CORBA_long_long"; + if (type.equals("string")) + return "CORBA_char*"; + if (type.equals("boolean")) + return "CORBA_boolean"; + if (type.equals("char")) + return "CORBA_char"; + if (type.equals("byte")) + return "CORBA_octet"; + if (type.equals("any")) + return "CORBA_any"; + if (type.equals("type")) + return "CORBA_TypeCode"; + if (type.equals("float")) + return "CORBA_float"; + if (type.equals("double")) + return "CORBA_double"; + if (type.equals("octet")) + return "CORBA_octet"; + if (type.equals("void")) + return type; + if (type.equals("unsigned long")) + return "CORBA_unsigned_long"; + if (type.equals("unsigned short")) + return "CORBA_unsigned_short"; + if (type.equals("unsigned hyper")) + return "CORBA_unsigned_long_long"; + + return OString(); +} + + +void CorbaType::dumpTypeInit(FileStream& o, const OString& typeName) +{ + OString type(checkSpecialCorbaType(typeName)); + + BASETYPE baseType = isBaseType(type); + + switch (baseType) + { + case BT_BOOLEAN: + o << "(sal_False)"; + return; + break; + case BT_ANY: + case BT_STRING: + o << "()"; + return; + break; + case BT_INVALID: + break; + default: + o << "(("; + dumpUnoType(o, type); + o << ")" << "0)"; + return; + } + + RTTypeClass typeClass = m_typeMgr.getTypeClass(type); + + if (typeClass == RT_TYPE_ENUM) + { + RegistryTypeReaderLoader aReaderLoader; + + if (aReaderLoader.isLoaded()) + { + TypeReader reader(m_typeMgr.getTypeReader(type)); + + if ( reader.isValid() ) + { + sal_Int32 nPos = type.lastIndexOf( '/' ); + o << "(" << shortScopedName("", type, sal_False) + << "::" << type.copy( nPos != -1 ? nPos+1 : 0 ) + << "_" << reader.getFieldName(0) << ")"; + return; + } + } + } + + o << "()"; +} + +BASETYPE CorbaType::isBaseType(const OString& type) +{ + if (type.equals("long")) + return BT_LONG; + if (type.equals("short")) + return BT_SHORT; + if (type.equals("hyper")) + return BT_HYPER; + if (type.equals("string")) + return BT_STRING; + if (type.equals("boolean")) + return BT_BOOLEAN; + if (type.equals("char")) + return BT_CHAR; + if (type.equals("byte")) + return BT_BYTE; + if (type.equals("any")) + return BT_ANY; + if (type.equals("float")) + return BT_FLOAT; + if (type.equals("double")) + return BT_DOUBLE; + if (type.equals("void")) + return BT_VOID; + if (type.equals("unsigned long")) + return BT_UNSIGNED_LONG; + if (type.equals("unsigned short")) + return BT_UNSIGNED_SHORT; + if (type.equals("unsigned hyper")) + return BT_UNSIGNED_HYPER; + + return BT_INVALID; +} + +OString CorbaType::typeToIdentifier(const OString& type) +{ + sal_uInt32 index = type.lastIndexOf(']'); + sal_uInt32 seqNum = (index > 0 ? ((index+1) / 2) : 0); + + OString relType = (index > 0 ? ((OString)type).copy(index+1) : type); + OString sIdentifier; + + while( seqNum > 0 ) + { + sIdentifier += OString("seq"); + + if ( --seqNum == 0 ) + { + sIdentifier += OString("_"); + } + } + + if ( isBaseType(relType) ) + { + sIdentifier += relType.replace(' ', '_'); + } else + { + sIdentifier += relType.replace('/', '_'); + } + + + return sIdentifier; +} + +OString CorbaType::checkSpecialCorbaType(const OString& type) +{ + OString baseType(type); + + RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader(); + + RegistryKey key; + sal_uInt8* pBuffer=NULL; + RTTypeClass typeClass; + sal_Bool isTypeDef = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); + TypeReader reader; + + while (isTypeDef) + { + reader = m_typeMgr.getTypeReader(baseType); + + if (reader.isValid()) + { + typeClass = reader.getTypeClass(); + + if (typeClass == RT_TYPE_TYPEDEF) + baseType = reader.getSuperTypeName(); + else + isTypeDef = sal_False; + } else + break; + } + + return baseType; +} + +OString CorbaType::checkRealBaseType(const OString& type, sal_Bool bResolveTypeOnly) +{ + sal_uInt32 index = type.lastIndexOf(']'); + OString baseType = (index > 0 ? ((OString)type).copy(index+1) : type); + OString seqPrefix = (index > 0 ? ((OString)type).copy(0, index+1) : OString()); + + RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader(); + + RegistryKey key; + sal_uInt8* pBuffer=NULL; + RTTypeClass typeClass; + sal_Bool mustBeChecked = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); + TypeReader reader; + + while (mustBeChecked) + { + reader = m_typeMgr.getTypeReader(baseType); + + if (reader.isValid()) + { + typeClass = reader.getTypeClass(); + + if (typeClass == RT_TYPE_TYPEDEF) + { + baseType = reader.getSuperTypeName(); + index = baseType.lastIndexOf(']'); + if (index > 0) + { + seqPrefix += baseType.copy(0, index+1); + baseType = baseType.copy(index+1); + } + } else + mustBeChecked = sal_False; + } else + break; + } + + if ( bResolveTypeOnly ) + baseType = seqPrefix + baseType; + + return baseType; +} + + +void CorbaType::inc(sal_uInt32 num) +{ + m_indentLength += num; +} + +void CorbaType::dec(sal_uInt32 num) +{ + if (m_indentLength - num < 0) + m_indentLength = 0; + else + m_indentLength -= num; +} + +OString CorbaType::indent() +{ + OStringBuffer tmp(m_indentLength); + + for (sal_uInt32 i=0; i < m_indentLength; i++) + { + tmp.append(' '); + } + return tmp.makeStringAndClear(); +} + +OString CorbaType::indent(sal_uInt32 num) +{ + OStringBuffer tmp(m_indentLength + num); + + for (sal_uInt32 i=0; i < m_indentLength + num; i++) + { + tmp.append(' '); + } + return tmp.makeStringAndClear(); +} + +//************************************************************************* +// InterfaceType +//************************************************************************* +InterfaceType::InterfaceType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversions) + : CorbaType(typeReader, typeName, typeMgr, typeDependencies, generatedConversions) +{ + m_inheritedMemberCount = 0; + m_hasAttributes = sal_False; + m_hasMethods = sal_False; +} + +InterfaceType::~InterfaceType() +{ + +} + + +void InterfaceType::dumpUnoMethods(FileStream& o, sal_Bool bDeclOnly, sal_Bool bDelegateToSuper) +{ + OString superName(m_reader.getSuperTypeName()); + if (bDeclOnly && + !superName.equals("Bonobo/NullInterface") && + !superName.equals("com/sun/star/uno/XInterface")) + { + TypeReader reader(m_typeMgr.getTypeReader(superName)); + InterfaceType iType(reader, superName, m_typeMgr, TypeDependency(), m_generatedConversions); + iType.inc(); + iType.dumpUnoMethods(o, bDeclOnly, sal_True); + } + + sal_uInt32 methodCount = m_reader.getMethodCount(); + sal_Bool first=sal_True; + + OString methodName, returnType, paramType, paramName; + sal_uInt32 paramCount = 0; + sal_uInt32 excCount = 0; + RTMethodMode methodMode = RT_MODE_INVALID; + RTParamMode paramMode = RT_PARAM_INVALID; + + sal_Bool bRef = sal_False; + sal_Bool bConst = sal_False; + sal_Bool bWithRunTimeExcp = sal_True; + + for (sal_uInt16 i=0; i < methodCount; i++) + { + methodName = m_reader.getMethodName(i); + returnType = m_reader.getMethodReturnType(i); + paramCount = m_reader.getMethodParamCount(i); + excCount = m_reader.getMethodExcCount(i); + methodMode = m_reader.getMethodMode(i); + + if ( methodName.equals("acquire") || methodName.equals("release") ) + bWithRunTimeExcp = sal_False; + + if (first) + { + first = sal_False; + o << "\n" << indent() << "// Methods\n"; + } + + o << indent(); + if (bDeclOnly) + o << "virtual "; + dumpUnoType(o, returnType); + o << " SAL_CALL "; + if (!bDeclOnly) + { + o << "bonobobridge::BonoboWrapper_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "::"; + } + + o << methodName << "( "; + + sal_uInt16 j; + for (j=0; j < paramCount; j++) + { + paramName = m_reader.getMethodParamName(i, j); + paramType = m_reader.getMethodParamType(i, j); + paramMode = m_reader.getMethodParamMode(i, j); + + switch (paramMode) + { + case RT_PARAM_IN: + { + OString relType = checkSpecialCorbaType(paramType); + if (m_typeMgr.getTypeClass(relType) == RT_TYPE_ENUM || + (isBaseType(relType) && !relType.equals("string") && !relType.equals("any"))) + { + bConst = sal_False; + bRef = sal_False; + } else + { + bConst = sal_True; + bRef = sal_True; + } + break; + } + case RT_PARAM_OUT: + case RT_PARAM_INOUT: + bConst = sal_False; + bRef = sal_True; + break; + } + + dumpUnoType(o, paramType, bConst, bRef); + o << " " << paramName; + + if (j+1 < paramCount) o << ", "; + } + o << " )"; + + o << " throw("; + OString excpName; + for (j=0; j < excCount; j++) + { + excpName = m_reader.getMethodExcType(i, j); + if (excpName != "com/sun/star/uno/RuntimeException") + o << scopedName(m_typeName, excpName); + if (bWithRunTimeExcp) + o << ", "; + } + + if ( bWithRunTimeExcp ) + { + o << " ::com::sun::star::uno::RuntimeException"; + } + + if (bDeclOnly && bDelegateToSuper) + { + o << " ) {\n"; + if (returnType.equals("void")) + o << indent() << " "; + else + o << indent() << " return "; + o << "BonoboWrapper_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "::" << methodName << "( "; + for (j = 0; j < paramCount; j++) + { + paramName = m_reader.getMethodParamName(i, j); + o << paramName; + if (j < (paramCount-1)) + o << ", "; + } + o << " );\n" + << indent() << "}\n"; + } + else if (!bDeclOnly) + { + o << " ) {\n"; + + OStringBuffer preBuffer(1024); + OStringBuffer callBuffer(1024); + OStringBuffer postBuffer(1024); + + callBuffer.append(" "); + + if (!returnType.equals("void")) + { + preBuffer.append(" "); + preBuffer.append(printCorbaParameter(returnType)); + if (isPassedAsPointer(returnType)) + preBuffer.append("*"); + preBuffer.append(" _b_ret;\n"); + preBuffer.append(" "); + preBuffer.append(printUnoType(returnType, sal_False, sal_False)); + preBuffer.append(" _u_ret;\n"); + + callBuffer.append("_b_ret = "); + } + + callBuffer.append(printCorbaType(m_typeName, sal_False, sal_False)); + callBuffer.append("_"); + if (methodName.indexOf("_reserved_identifier_") == 0) + callBuffer.append(methodName.copy(OString("_reserved_identifier_").getLength())); + else + callBuffer.append(methodName); + + callBuffer.append("( m_corbaObject"); + + for (j=0; j < paramCount; j++) + { + paramName = m_reader.getMethodParamName(i, j); + paramType = m_reader.getMethodParamType(i, j); + paramMode = m_reader.getMethodParamMode(i, j); + + preBuffer.append(" "); + preBuffer.append(printCorbaParameter(paramType)); + if (isPassedAsPointer(paramType) && (paramMode == RT_PARAM_OUT)) + { + preBuffer.append("* _b_"); + preBuffer.append(paramName); + preBuffer.append(";\n"); + } + else + { + preBuffer.append(" _b_"); + preBuffer.append(paramName); + preBuffer.append(";\n"); + } + + switch (paramMode) { + case RT_PARAM_IN: + + if (isArray(paramType)) + preBuffer.append(" // fix me: conversion of array types!\n"); + else + { + preBuffer.append(" cpp_convert_u2b("); + preBuffer.append("_b_"); + preBuffer.append(paramName); + preBuffer.append(", "); + preBuffer.append(paramName); + preBuffer.append(", m_bridge);\n"); + } + + if (isPassedAsPointer(paramType)) + callBuffer.append(", &_b_"); + else + callBuffer.append(", _b_"); + break; + case RT_PARAM_INOUT: + + if (isArray(paramType)) + preBuffer.append(" // fix me: conversion of array types!\n"); + else + { + preBuffer.append(" cpp_convert_u2b("); + if (isPassedAsPointer(paramType)) + preBuffer.append("_b_"); + else + preBuffer.append("_b_"); + preBuffer.append(paramName); + preBuffer.append(", "); + preBuffer.append(paramName); + preBuffer.append(", m_bridge);\n"); + } + + callBuffer.append(", &_b_"); + + if (isArray(paramType)) + postBuffer.append(" // fix me: conversion of array types!\n"); + else + { + postBuffer.append(" cpp_convert_b2u("); + postBuffer.append(paramName); + postBuffer.append(", _b_"); + postBuffer.append(paramName); + postBuffer.append(", m_bridge);\n"); + } + + break; + case RT_PARAM_OUT: + + callBuffer.append(", &_b_"); + + if (isArray(paramType)) + postBuffer.append(" // fix me: conversion of array types!\n"); + else + { + postBuffer.append(" cpp_convert_b2u("); + postBuffer.append(paramName); + if (isPassedAsPointer(paramType)) + postBuffer.append(", *_b_"); + else + postBuffer.append(", _b_"); + postBuffer.append(paramName); + postBuffer.append(", m_bridge);\n"); + } + + break; + } + + + callBuffer.append(paramName); + } + + callBuffer.append(", &_ev );\n"); + + if (!returnType.equals("void")) + { + if (isArray(returnType)) + { + postBuffer.append(" // fix me: conversion of array types!\n"); + } + else + { + if (isPassedAsPointer(returnType)) + postBuffer.append(" cpp_convert_b2u(_u_ret, *_b_ret, m_bridge);\n"); + else + postBuffer.append(" cpp_convert_b2u(_u_ret, _b_ret, m_bridge);\n"); + } + postBuffer.append(" return _u_ret;\n"); + } + + o << " ::osl::MutexGuard guard(m_bridge->getORBLock());\n" + << " CORBA_Environment _ev;\n" + << " CORBA_exception_init (&_ev);\n"; + + o << preBuffer; + o << callBuffer; + + o << " if (_ev._major != CORBA_NO_EXCEPTION) {\n" + << " ::com::sun::star::uno::RuntimeException _ex(::rtl::OUString::createFromAscii(\"exception raised in bonobobridge\"), NULL);\n" + << " CORBA_exception_free (&_ev);\n" + << " throw _ex;\n" + << " }\n" + << " CORBA_exception_free (&_ev);\n"; + + o << postBuffer; + + o << indent() << "}\n"; + } + else + o << " );\n"; + } +} + +void InterfaceType::dumpCorbaMethods(FileStream& o, sal_Bool bDeclOnly) +{ + OString superName(m_reader.getSuperTypeName()); + + sal_uInt32 methodCount = m_reader.getMethodCount(); + + OString methodName, returnType, paramType, paramName; + sal_uInt32 paramCount = 0; + sal_uInt32 excCount = 0; + RTMethodMode methodMode = RT_MODE_INVALID; + RTParamMode paramMode = RT_PARAM_INVALID; + + sal_Bool bRef = sal_False; + sal_Bool bConst = sal_False; + sal_Bool bWithRunTimeExcp = sal_True; + + for (sal_uInt16 i=0; i < methodCount; i++) + { + methodName = m_reader.getMethodName(i); + returnType = m_reader.getMethodReturnType(i); + paramCount = m_reader.getMethodParamCount(i); + excCount = m_reader.getMethodExcCount(i); + methodMode = m_reader.getMethodMode(i); + + o << indent() + << "extern \"C\" " + << printCorbaParameter(returnType); + + if (isPassedAsPointer(returnType)) + o << "*"; + + o << " bonobobridge_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "_" << methodName << "( PortableServer_Servant _servant, "; + + sal_uInt16 j; + for (j=0; j < paramCount; j++) + { + paramName = m_reader.getMethodParamName(i, j); + paramType = m_reader.getMethodParamType(i, j); + paramMode = m_reader.getMethodParamMode(i, j); + + if ((isPassedAsPointer(paramType) || paramType.equals("string") || isArray(paramType)) && + (paramMode == RT_PARAM_IN)) + o << "const "; + + o << printCorbaParameter(paramType); + + if (isPassedAsPointer(paramType)) + { + if (paramMode == RT_PARAM_OUT) + o << "**"; + else + o << "*"; + } + else + { + if (paramMode != RT_PARAM_IN) + o << "*"; + } + + + o << " " << paramName << ", "; + } + + o << "CORBA_Environment * _ev)"; + + if (bDeclOnly) + o << ";\n"; + else + { + o << " {\n"; + OStringBuffer preBuffer(1024); + OStringBuffer callBuffer(1024); + OStringBuffer postBuffer(1024); + + callBuffer.append(" "); + + preBuffer.append(" "); + preBuffer.append(printUnoType(m_typeName, sal_False, sal_False)); + preBuffer.append(" rThis(("); + preBuffer.append(printUnoType(m_typeName, sal_False, sal_False, sal_True)); + preBuffer.append(" *)((bonobobridge::UNO_POA_com_sun_star_uno_XInterface*)_servant)->pThis->getUnoObject());\n"); + + if (!returnType.equals("void")) + { + preBuffer.append(" "); + preBuffer.append(printCorbaParameter(returnType)); + if (isPassedAsPointer(returnType)) + { + preBuffer.append("* _b_ret = "); + preBuffer.append(printCorbaType(returnType, sal_False, sal_False)); + preBuffer.append("__alloc();\n"); + + } + else + { + preBuffer.append(" _b_ret;\n"); + } + preBuffer.append(" "); + preBuffer.append(printUnoType(returnType, sal_False, sal_False)); + preBuffer.append(" _u_ret;\n"); + + callBuffer.append("_u_ret = "); + } + + callBuffer.append("rThis->"); + callBuffer.append(methodName); + callBuffer.append("( "); + + for (j=0; j < paramCount; j++) + { + paramName = m_reader.getMethodParamName(i, j); + paramType = m_reader.getMethodParamType(i, j); + paramMode = m_reader.getMethodParamMode(i, j); + + preBuffer.append(" "); + preBuffer.append(printUnoType(paramType, sal_False, sal_False)); + preBuffer.append(" _u_"); + preBuffer.append(paramName); + preBuffer.append(";\n"); + + callBuffer.append("_u_"); + callBuffer.append(paramName); + + if (j < (paramCount-1)) + callBuffer.append(", "); + + switch (paramMode) { + case RT_PARAM_IN: + + if (isArray(paramType)) + preBuffer.append(" // fix me: conversion of array types!\n"); + else + { + preBuffer.append(" cpp_convert_b2u("); + preBuffer.append("_u_"); + preBuffer.append(paramName); + preBuffer.append(", "); + if (isPassedAsPointer(paramType)) + preBuffer.append("*"); + preBuffer.append(paramName); + preBuffer.append(", ((bonobobridge::UNO_POA_com_sun_star_uno_XInterface*)_servant)->pThis->getBridge());\n"); + } + break; + case RT_PARAM_INOUT: + + if (isArray(paramType)) + { + preBuffer.append(" // fix me: conversion of array types!\n"); + postBuffer.append(" // fix me: conversion of array types!\n"); + } + else + { + preBuffer.append(" cpp_convert_b2u("); + preBuffer.append("_u_"); + preBuffer.append(paramName); + preBuffer.append(", "); + if (isPassedAsPointer(paramType)) + preBuffer.append("*"); + preBuffer.append(paramName); + preBuffer.append(", ((bonobobridge::UNO_POA_com_sun_star_uno_XInterface*)_servant)->pThis->getBridge());\n"); + + postBuffer.append(" cpp_convert_u2b("); + if (isPassedAsPointer(paramType)) + postBuffer.append("*"); + postBuffer.append(paramName); + postBuffer.append(", _u_"); + postBuffer.append(paramName); + postBuffer.append(", ((bonobobridge::UNO_POA_com_sun_star_uno_XInterface*)_servant)->pThis->getBridge());\n"); + } + break; + case RT_PARAM_OUT: + + if (isArray(paramType)) + preBuffer.append(" // fix me: conversion of array types!\n"); + else + { + postBuffer.append(" cpp_convert_u2b("); + if (isPassedAsPointer(paramType)) + postBuffer.append("**"); + else + postBuffer.append("*"); + postBuffer.append(paramName); + postBuffer.append(", _u_"); + postBuffer.append(paramName); + postBuffer.append(", ((bonobobridge::UNO_POA_com_sun_star_uno_XInterface*)_servant)->pThis->getBridge());\n"); + } + break; + } + } + + callBuffer.append(" );\n"); + + if (!returnType.equals("void")) + { + if (isArray(returnType)) + postBuffer.append(" // fix me: conversion of array types!\n"); + else + { + if (isPassedAsPointer(returnType)) + postBuffer.append(" cpp_convert_u2b(*_b_ret, _u_ret, ((bonobobridge::UNO_POA_com_sun_star_uno_XInterface*)_servant)->pThis->getBridge());\n"); + else + postBuffer.append(" cpp_convert_u2b(_b_ret, _u_ret, ((bonobobridge::UNO_POA_com_sun_star_uno_XInterface*)_servant)->pThis->getBridge());\n"); + } + + postBuffer.append(" return _b_ret;\n"); + } + + o << preBuffer; + o << callBuffer; + o << postBuffer; + + o << "}\n"; + } + } +} + +void InterfaceType::dumpFunctions(FileStream& o) +{ + if (m_typeName.equals("com/sun/star/uno/XInterface") || + m_typeName.equals("Bonobo/NullInterface")) + return; + + m_generatedConversions->insert(m_typeName); + + o << "namespace bonobobridge {\n\n"; + + /* bonobo implementation class */ + o << "class BonoboWrapper_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + + OString superName(m_reader.getSuperTypeName()); + o << " : public BonoboWrapper< BonoboWrapper_"; + dumpCorbaType(o, superName, sal_False, sal_False); + o << ", "; + dumpUnoType(o, m_typeName, sal_False, sal_False, sal_True); + o << " > {\n"; + + o << "public: \n" + << " BonoboWrapper_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "("; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << " corbaObject," + << "const vos::ORef<bonobobridge::Bridge>& bridge)\n"; + + o << " : BonoboWrapper< " + << "BonoboWrapper_"; + dumpCorbaType(o, superName, sal_False, sal_False); + o << ", "; + dumpUnoType(o, m_typeName, sal_False, sal_False, sal_True); + o << " >(corbaObject, bridge) {\n"; + + if (isDerivedFromUnknown(m_typeName)) + { + o << " m_bridge->registerObjectWrapper(::getCppuType(("; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "*)NULL), m_corbaObject, ("; + dumpUnoType(o, m_typeName, sal_False, sal_False, sal_True); + o << "*)this);\n"; + } + + o << " }\n"; + + o << " virtual ~BonoboWrapper_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "() {\n"; + if (isDerivedFromUnknown(m_typeName)) + { + o << " m_bridge->unregisterObjectWrapper(::getCppuType(("; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "*)NULL), m_corbaObject, ("; + dumpUnoType(o, m_typeName, sal_False, sal_False, sal_True); + o << "*)this);\n"; + } + o << " }\n"; + inc(); + dumpUnoMethods(o, sal_True, sal_False); + dec(); + + o << "};\n\n"; + + o << "}; // namespace bonobobridge\n"; + + dumpUnoMethods(o, sal_False, sal_False); + + /* convert function bonobo to uno */ + o << "static sal_Bool convert_b2u_" << m_typeName.replace('/', '_') + << "(void* pOut, const void* pIn, const ::com::sun::star::uno::Type& type, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " sal_Bool ret = sal_True;\n "; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "& _u = *("; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "*) pOut;\n const "; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "& _b = *(const "; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "*) pIn;\n\n" + << " _u = new bonobobridge::BonoboWrapper_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "(_b, bridge);\n" + << " return ret;\n"; + + o << "}\n\n"; + + /* POA implementation class */ + dumpCorbaMethods(o, sal_True); + o << "static POA_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "__epv bonobobridge_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "_epv = {\n"; + sal_uInt32 methodCount = m_reader.getMethodCount(); + OString methodName; + + o << " NULL,\n"; + + for (sal_uInt16 i=0; i < methodCount; i++) + { + methodName = m_reader.getMethodName(i); + o << " bonobobridge_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "_" << methodName; + + if (i < (methodCount-1)) + o << ",\n"; + else + o << "\n};\n"; + } + + OStringBuffer initBuffer(1024); + + initBuffer.insert(0, OString("&bonobobridge_") + printCorbaType(m_typeName, sal_False, sal_False) + OString("_epv")); + + while(superName.getLength() != 0) + { + if (superName.equals("Bonobo/NullInterface")) + { + superName = ""; + } + else + { + if (superName.equals("com/sun/star/uno/XInterface")) + { + initBuffer.insert(0, OString("&bonobobridge_com_sun_star_uno_XInterface_epv, ")); + } + else + { + initBuffer.insert(0, OString("&bonobobridge_") + printCorbaType(superName, sal_False, sal_False) + OString("_epv, ")); + } + TypeReader reader(m_typeMgr.getTypeReader(superName)); + superName = reader.getSuperTypeName(); + } + } + + initBuffer.insert(0, OString("NULL, ")); + + o << "static POA_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "__vepv bonobobridge_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "__vepv = {"; + o << initBuffer.makeStringAndClear(); + o << " };\n"; + + superName = m_reader.getSuperTypeName(); + + o << "namespace bonobobridge {\n\n"; + + o << "class UnoServant_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << " : public UnoServant_com_sun_star_uno_XInterface {\n"; + + o << "public:\n" + << " UnoServant_"; + + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "("; + dumpUnoType(o, m_typeName, sal_False, sal_False, sal_True); + o << "* unoObject," + << " const ::vos::ORef<bonobobridge::Bridge>& bridge," + << " CORBA_Environment *ev," + << " sal_Bool bInitPoa)\n" + << " : UnoServant_com_sun_star_uno_XInterface(unoObject, bridge, ev, sal_False) {\n" + << " if (bInitPoa) {\n" + << " memset(&m_POAUnknown, 0, sizeof(m_POAUnknown));\n" + << " POA_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "__init((PortableServer_Servant) &(m_POAUnknown.poa), ev);\n" + << " m_POAUnknown.pThis = (UnoServant_com_sun_star_uno_XInterface*)this;\n" + << " m_POAUnknown.poa.vepv = (POA_Bonobo_Unknown__vepv*)&bonobobridge_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "__vepv;\n" + << " }\n" + << " }\n" + << "};\n" + << "}; // namespace bonobobridge\n"; + + dumpCorbaMethods(o, sal_False); + + /* convert function uno to bonobo */ + o << "static sal_Bool convert_u2b_" << m_typeName.replace('/', '_') + << "(void* pOut, const void* pIn, const ::com::sun::star::uno::Type& type, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n"; + o << " sal_Bool ret = sal_True;\n const "; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "& _u = *(const "; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "*) pIn;\n "; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "& _b = *("; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "*) pOut;\n\n" + << " if (_u.is()) {\n" + << " bonobobridge::UnoServant_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << " *uno_servant;\n" + << " POA_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << " *poa;\n" + << " CORBA_Environment ev;\n" + << " CORBA_exception_init (&ev);\n" + << " uno_servant = new bonobobridge::UnoServant_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "(_u.get(), bridge, &ev, sal_True);\n" + << " poa = (POA_"; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "*)uno_servant->getPOA();\n" + << " if (ev._major != CORBA_NO_EXCEPTION) {\n" + << " delete uno_servant;\n" + << " CORBA_exception_free (&ev);\n" + << " _b = CORBA_OBJECT_NIL;\n" + << " ret = sal_False;\n" + << " }\n" + << " else {\n" + << " CORBA_free(PortableServer_POA_activate_object(bridge->getPOA(), poa, &ev));\n" + << " _b = PortableServer_POA_servant_to_reference (bridge->getPOA(), poa, &ev);\n" + << " uno_servant->corbaObjectRegistered(_b, getCppuType(("; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "*)NULL)"; + + if (!isDerivedFromUnknown(m_typeName)) + o << ", sal_False"; + + o << ");\n" + << " }\n" + << " CORBA_exception_free (&ev);\n" + << " }\n" + << " return ret;\n" + << "}\n\n"; + + o << "inline sal_Bool bonobobridge::cpp_convert_b2u("; + dumpUnoType(o, m_typeName, sal_False, sal_True); + o << " u, "; + dumpCorbaType(o, m_typeName, sal_True, sal_True); + o << " b, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " return bridge->convertB2U(&u, &b, ::getCppuType(&u));\n" + << "};\n\n"; + + o << "inline sal_Bool bonobobridge::cpp_convert_u2b("; + dumpCorbaType(o, m_typeName, sal_False, sal_True); + o << " b, "; + dumpUnoType(o, m_typeName, sal_True, sal_True); + o << " u, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " return bridge->convertU2B(&b, &u, ::getCppuType(&u));\n" + << "};\n\n"; + + return; +} + + + + +sal_uInt32 InterfaceType::getMemberCount() +{ + sal_uInt32 count = m_reader.getMethodCount(); + + if (count) + m_hasMethods = sal_True; + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + { + m_hasAttributes = sal_True; + count++; + } + } + return count; +} + +sal_uInt32 InterfaceType::checkInheritedMemberCount(const TypeReader* pReader) +{ + sal_uInt32 cout = 0; + sal_Bool bSelfCheck = sal_True; + if (!pReader) + { + bSelfCheck = sal_False; + pReader = &m_reader; + } + + sal_uInt32 count = 0; + OString superType(pReader->getSuperTypeName()); + if (superType.getLength() > 0) + { + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + if (aSuperReader.isValid()) + { + count = checkInheritedMemberCount(&aSuperReader); + } + } + + if (bSelfCheck) + { + count += pReader->getMethodCount(); + sal_uInt32 fieldCount = pReader->getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = pReader->getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + count++; + } + } + + return count; +} + +sal_uInt32 InterfaceType::getInheritedMemberCount() +{ + if (m_inheritedMemberCount == 0) + { + m_inheritedMemberCount = checkInheritedMemberCount(0); + } + + return m_inheritedMemberCount; +} + + + + +//************************************************************************* +// ModuleType +//************************************************************************* +ModuleType::ModuleType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversions) + : CorbaType(typeReader, typeName, typeMgr, typeDependencies, generatedConversions) +{ +} + +ModuleType::~ModuleType() +{ + +} + + +sal_Bool ModuleType::hasConstants() +{ + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST) + return sal_True; + } + + return sal_False; +} + +void ModuleType::dumpFunctions(FileStream& o) +{ +}; + +sal_Bool ModuleType::dumpConversionFunctions(FileStream& o, TypeSet* allreadyDumped) + throw( CannotDumpException ) +{ + sal_Bool bSpecialDefine = sal_True; + + if (m_reader.getTypeClass() == RT_TYPE_CONSTANTS) + { + bSpecialDefine = sal_False; + } + + dumpInclude(o, allreadyDumped, m_typeName, "hpp", bSpecialDefine); + + return sal_True; +} + +//************************************************************************* +// ConstantsType +//************************************************************************* +ConstantsType::ConstantsType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversions) + : ModuleType(typeReader, typeName, typeMgr, typeDependencies, generatedConversions) +{ +} + +ConstantsType::~ConstantsType() +{ + +} + +void ConstantsType::dumpFunctions(FileStream& o) +{ +}; + +//************************************************************************* +// StructureType +//************************************************************************* +StructureType::StructureType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversions) + : CorbaType(typeReader, typeName, typeMgr, typeDependencies, generatedConversions) +{ +} + +StructureType::~StructureType() +{ + +} + +void StructureType::dumpFunctions(FileStream& o) +{ + m_generatedConversions->insert(m_typeName); + + OString superType(m_reader.getSuperTypeName()); + + o << "static sal_Bool convert_b2u_" << m_typeName.replace('/', '_') + << "(void* pOut, const void* pIn, const ::com::sun::star::uno::Type& type, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " sal_Bool ret = sal_True;\n "; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "& _u = *("; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "*) pOut;\n const "; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "& _b = *(const "; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "*) pIn;\n\n"; + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + OString fieldName; + OString fieldType; + sal_uInt16 i=0; + sal_Int32 cIndex; + OString corbaFieldName; + + sal_Bool bIsUnion = sal_False; + + for (i=0; !bIsUnion && (i < fieldCount); i++) + bIsUnion = OString("_union_fake_tag").equals(m_reader.getFieldName(i)); + + if (bIsUnion) + { + o << " // fix me: union !!!!\n ret = sal_False;\n"; + } + else + { + if (superType.getLength() > 0) + { + o << " ret = bonobobridge::cpp_convert_b2u(("; + dumpUnoType(o, superType, sal_False, sal_False); + o << "&) _u, (const "; + dumpCorbaType(o, superType, sal_False, sal_False); + o << "&) _b, bridge);\n"; + } + + for (i=0; i < fieldCount; i++) + { + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + cIndex = fieldName.indexOf("_reserved_identifier_"); + + if (cIndex == 0) + corbaFieldName = fieldName.copy(OString("_reserved_identifier_").getLength()); + else + corbaFieldName = fieldName; + + if (isArray(fieldType)) + o << " // fix me: no conversion of array types!\n"; + else + o << " if (ret)\n" + << " ret = bonobobridge::cpp_convert_b2u(" + << "_u." << fieldName.getStr() + << " , _b." << corbaFieldName.getStr() + << ", bridge);\n"; + } + } + o << " return ret;\n" + << "}\n\n" + << "static sal_Bool convert_u2b_" << m_typeName.replace('/', '_') + << "(void* pOut, const void* pIn, const ::com::sun::star::uno::Type& type, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " sal_Bool ret = sal_True;\n const "; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "& _u = *(const "; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "*) pIn;\n "; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "& _b = *("; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "*) pOut;\n\n"; + + if (bIsUnion) + o << " // fix me: union !!!!\n ret = sal_False;\n"; + else + { + if (superType.getLength() > 0) + { + o << " ret = bonobobridge::cpp_convert_u2b(("; + dumpCorbaType(o, superType, sal_False, sal_False); + o << "&) _u, (const "; + dumpUnoType(o, superType, sal_False, sal_False); + o << "&) _b, bridge);\n"; + } + + for (i=0; i < fieldCount; i++) + { + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + + cIndex = fieldName.indexOf("_reserved_identifier_"); + + if (cIndex == 0) + corbaFieldName = fieldName.copy(OString("_reserved_identifier_").getLength()); + else + corbaFieldName = fieldName; + + if (isArray(fieldType)) + o << " // fix me: no conversion of array types!\n"; + else + o << " if (ret)\n" + << " ret = bonobobridge::cpp_convert_u2b(" + << "_b." << corbaFieldName.getStr() + << ", _u." << fieldName.getStr() + << ", bridge);\n"; + } + } + + o << " return ret;\n" + << "}\n\n"; + + o << "inline sal_Bool bonobobridge::cpp_convert_b2u("; + dumpUnoType(o, m_typeName, sal_False, sal_True); + o << " u , "; + dumpCorbaType(o, m_typeName, sal_True, sal_True); + o << " b, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " return convert_b2u_" << m_typeName.replace('/', '_') + << "(&u, &b, ::getCppuType(&u), bridge);\n" + << "};\n\n"; + + o << "inline sal_Bool bonobobridge::cpp_convert_u2b("; + dumpCorbaType(o, m_typeName, sal_False, sal_True); + o << " b, "; + dumpUnoType(o, m_typeName, sal_True, sal_True); + o << " u, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " return convert_u2b_" << m_typeName.replace('/', '_') + << "(&b, &u, ::getCppuType(&u), bridge);\n" + << "};\n\n"; +} + +sal_Bool StructureType::dumpSuperMember(FileStream& o, const OString& superType, sal_Bool bWithType) +{ + sal_Bool hasMember = sal_False; + + if (superType.getLength() > 0) + { + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + + if (aSuperReader.isValid()) + { + hasMember = dumpSuperMember(o, aSuperReader.getSuperTypeName(), bWithType); + + sal_uInt32 fieldCount = aSuperReader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = aSuperReader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = aSuperReader.getFieldName(i); + fieldType = aSuperReader.getFieldType(i); + + if (hasMember) + { + o << ", "; + } else + { + hasMember = (fieldCount > 0); + } + + if (bWithType) + { + dumpUnoType(o, fieldType, sal_True, sal_True); + o << " "; + } + o << "__" << fieldName; + } + } + } + + return hasMember; +} + +//************************************************************************* +// ExceptionType +//************************************************************************* +ExceptionType::ExceptionType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversions) + : CorbaType(typeReader, typeName, typeMgr, typeDependencies, generatedConversions) +{ +} + +ExceptionType::~ExceptionType() +{ + +} + +void ExceptionType::dumpFunctions(FileStream& o) +{ + if (m_typeName.equals("com/sun/star/uno/Exception")) + return; + + if (m_typeName.equals("com/sun/star/uno/RuntimeException")) + return; + + m_generatedConversions->insert(m_typeName); + + OString superType(m_reader.getSuperTypeName()); + + o << "static sal_Bool convert_b2u_" << m_typeName.replace('/', '_') + << "(void* pOut, const void* pIn, const ::com::sun::star::uno::Type& type, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " sal_Bool ret = sal_True;\n"; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "& _u = *("; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "*) pOut;\n const "; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "& _b = *(const "; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "*) pIn;\n\n"; + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + OString fieldName; + OString fieldType; + sal_uInt16 i=0; + sal_Int32 cIndex; + OString corbaFieldName; + + if (superType.getLength() > 0) + { + o << " ret = bonobobridge::cpp_convert_b2u(("; + dumpUnoType(o, superType, sal_False, sal_False); + o << "&) _u, (const "; + dumpCorbaType(o, superType, sal_False, sal_False); + o << "&) _b, bridge);\n"; + } + + for (i=0; i < fieldCount; i++) + { + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + cIndex = fieldName.indexOf("_reserved_identifier_"); + + if (cIndex == 0) + corbaFieldName = fieldName.copy(OString("_reserved_identifier_").getLength()); + else + corbaFieldName = fieldName; + + if (isArray(fieldType)) + o << " // fix me: no conversion of array types!\n"; + else + o << " if (ret)\n" + << " ret = bonobobridge::cpp_convert_b2u(" + << "_u." << fieldName.getStr() + << ", _b." << corbaFieldName.getStr() + << ", bridge);\n"; + } + o << " return ret;\n" + << "}\n\n"; + + + o << "static sal_Bool convert_u2b_" << m_typeName.replace('/', '_') + << "(void* pOut, const void* pIn, const ::com::sun::star::uno::Type& type, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " sal_Bool ret = sal_True;\n const "; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "& _u = *(const "; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "*) pIn;\n "; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "& _b = *("; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "*) pOut;\n\n"; + + if (superType.getLength() > 0) + { + o << " ret = bonobobridge::cpp_convert_u2b(("; + dumpCorbaType(o, superType, sal_False, sal_False); + o << "&) _u, (const "; + dumpUnoType(o, superType, sal_False, sal_False); + o << "&) _b, bridge);\n"; + } + + for (i=0; i < fieldCount; i++) + { + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + + cIndex = fieldName.indexOf("_reserved_identifier_"); + + if (cIndex == 0) + corbaFieldName = fieldName.copy(OString("_reserved_identifier_").getLength()); + else + corbaFieldName = fieldName; + + if (isArray(fieldType)) + o << " // fix me: no conversion of array types!\n"; + else + o << " if (ret)\n" + << " ret = bonobobridge::cpp_convert_u2b(" + << "_b." << corbaFieldName.getStr() + << ", _u." << fieldName.getStr() + << ", bridge);\n"; + } + + o << " return ret;\n" + << "}\n\n"; + + o << "inline sal_Bool bonobobridge::cpp_convert_b2u("; + dumpUnoType(o, m_typeName, sal_False, sal_True); + o << " u , "; + dumpCorbaType(o, m_typeName, sal_True, sal_True); + o << " b, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " return convert_b2u_" << m_typeName.replace('/', '_') + << "(&u, &b, ::getCppuType(&u), bridge);\n" + << "};\n\n"; + + o << "inline sal_Bool bonobobridge::cpp_convert_u2b("; + dumpCorbaType(o, m_typeName, sal_False, sal_True); + o << " b, "; + dumpUnoType(o, m_typeName, sal_True, sal_True); + o << " u, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " return convert_u2b_" << m_typeName.replace('/', '_') + << "(&b, &u, ::getCppuType(&u), bridge);\n" + << "};\n\n"; +} + + + +sal_Bool ExceptionType::dumpSuperMember(FileStream& o, const OString& superType, sal_Bool bWithType) +{ + sal_Bool hasMember = sal_False; + + if (superType.getLength() > 0) + { + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + + if (aSuperReader.isValid()) + { + hasMember = dumpSuperMember(o, aSuperReader.getSuperTypeName(), bWithType); + + sal_uInt32 fieldCount = aSuperReader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = aSuperReader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = aSuperReader.getFieldName(i); + fieldType = aSuperReader.getFieldType(i); + + if (hasMember) + { + o << ", "; + } else + { + hasMember = (fieldCount > 0); + } + + if (bWithType) + { + dumpUnoType(o, fieldType, sal_True, sal_True); + o << " "; + } + o << "__" << fieldName; + } + } + } + + return hasMember; +} + +//************************************************************************* +// EnumType +//************************************************************************* +EnumType::EnumType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversions) + : CorbaType(typeReader, typeName, typeMgr, typeDependencies, generatedConversions) +{ +} + +EnumType::~EnumType() +{ + +} + +void EnumType::dumpFunctions(FileStream& o) +{ + if (m_typeName.equals("com/sun/star/uno/TypeClass")) + return; + + m_generatedConversions->insert(m_typeName); + + o << "static sal_Bool convert_b2u_" << m_typeName.replace('/', '_') + << "(void* pOut, const void* pIn, const ::com::sun::star::uno::Type& type, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " *("; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "*) pOut = ("; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << ") *(const "; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "*) pIn;\n\n" + << " return sal_True;\n" + << "}\n\n"; + + o << "static sal_Bool convert_u2b_" << m_typeName.replace('/', '_') + << "(void* pOut, const void* pIn, const ::com::sun::star::uno::Type& type, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " *("; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << "*) pOut = ("; + dumpCorbaType(o, m_typeName, sal_False, sal_False); + o << ") *(const "; + dumpUnoType(o, m_typeName, sal_False, sal_False); + o << "*) pIn;\n\n" + << " return sal_True;\n" + << "}\n\n"; + + o << "inline sal_Bool bonobobridge::cpp_convert_b2u("; + dumpUnoType(o, m_typeName, sal_False, sal_True); + o << " u , "; + dumpCorbaType(o, m_typeName, sal_True, sal_True); + o << " b, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " return convert_b2u_" << m_typeName.replace('/', '_') + << "(&u, &b, ::getCppuType(&u), bridge);\n" + << "};\n\n"; + + o << "inline sal_Bool bonobobridge::cpp_convert_u2b("; + dumpCorbaType(o, m_typeName, sal_False, sal_True); + o << " b, "; + dumpUnoType(o, m_typeName, sal_True, sal_True); + o << " u, const ::vos::ORef< ::bonobobridge::Bridge >& bridge) {\n" + << " return convert_u2b_" << m_typeName.replace('/', '_') + << "(&b, &u, ::getCppuType(&u), bridge);\n" + << "};\n\n"; + + return; +} + + +//************************************************************************* +// TypeDefType +//************************************************************************* +TypeDefType::TypeDefType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversions) + : CorbaType(typeReader, typeName, typeMgr, typeDependencies, generatedConversions) +{ +} + +TypeDefType::~TypeDefType() +{ + +} + +void TypeDefType::dumpFunctions(FileStream& o) +{ +} + + + +//************************************************************************* +// produceType +//************************************************************************* +sal_Bool produceType(const OString& typeName, + TypeManager& typeMgr, + TypeDependency& typeDependencies, + CorbaOptions* pOptions, + FileStream& o, TypeSet* allreadyDumped, + TypeSet* generatedConversions) + throw( CannotDumpException ) +{ + sal_Bool bNewTypeSet = (allreadyDumped == NULL); + sal_Bool ret = sal_True; + + if (bNewTypeSet) + allreadyDumped = new TypeSet(); + + + if (!typeDependencies.isGenerated(typeName)) + { + TypeReader reader(typeMgr.getTypeReader(typeName)); + + if (!reader.isValid() && !typeName.equals("/")) + ret = sal_False; + + if( ret && !checkTypeDependencies(typeMgr, typeDependencies, typeName)) + ret = sal_False; + + if (ret) + { + RTTypeClass typeClass = reader.getTypeClass(); + + switch (typeClass) + { + case RT_TYPE_INTERFACE: + { + InterfaceType iType(reader, typeName, typeMgr, typeDependencies, generatedConversions); + ret = iType.dump(pOptions, o, allreadyDumped); + if (ret) typeDependencies.setGenerated(typeName); + ret = iType.dumpDependedTypes(pOptions, o, allreadyDumped); + } + break; + case RT_TYPE_MODULE: + { + ModuleType mType(reader, typeName, typeMgr, typeDependencies, generatedConversions); + if (mType.hasConstants()) + { + ret = mType.dump(pOptions, o, allreadyDumped); + if (ret) typeDependencies.setGenerated(typeName); + } else + { + typeDependencies.setGenerated(typeName); + ret = sal_True; + } + } + break; + case RT_TYPE_STRUCT: + { + StructureType sType(reader, typeName, typeMgr, typeDependencies, generatedConversions); + ret = sType.dump(pOptions, o, allreadyDumped); + if (ret) typeDependencies.setGenerated(typeName); + ret = sType.dumpDependedTypes(pOptions, o, allreadyDumped); + } + break; + case RT_TYPE_ENUM: + { + EnumType enType(reader, typeName, typeMgr, typeDependencies, generatedConversions); + ret = enType.dump(pOptions, o, allreadyDumped); + if (ret) typeDependencies.setGenerated(typeName); + ret = enType.dumpDependedTypes(pOptions, o, allreadyDumped); + } + break; + case RT_TYPE_EXCEPTION: + { + ExceptionType eType(reader, typeName, typeMgr, typeDependencies, generatedConversions); + ret = eType.dump(pOptions, o, allreadyDumped); + if (ret) typeDependencies.setGenerated(typeName); + ret = eType.dumpDependedTypes(pOptions, o, allreadyDumped); + } + break; + case RT_TYPE_TYPEDEF: + { + TypeDefType tdType(reader, typeName, typeMgr, typeDependencies, generatedConversions); + ret = tdType.dump(pOptions, o, allreadyDumped); + if (ret) typeDependencies.setGenerated(typeName); + ret = tdType.dumpDependedTypes(pOptions, o, allreadyDumped); + } + break; + case RT_TYPE_CONSTANTS: + { + ConstantsType cType(reader, typeName, typeMgr, typeDependencies, generatedConversions); + if (cType.hasConstants()) + { + ret = cType.dump(pOptions, o, allreadyDumped); + if (ret) typeDependencies.setGenerated(typeName); + } else + { + typeDependencies.setGenerated(typeName); + ret = sal_True; + } + } + break; + case RT_TYPE_SERVICE: + case RT_TYPE_OBJECT: + ret = sal_True; + break; + } + } + } + + if (bNewTypeSet) + delete allreadyDumped; + + return ret; +} + +//************************************************************************* +// scopedName +//************************************************************************* +OString scopedName(const OString& scope, const OString& type, + sal_Bool bNoNameSpace) +{ + sal_Int32 nPos = type.lastIndexOf( '/' ); + if (nPos == -1) + return type; + + if (bNoNameSpace) + return type.copy(nPos+1); + + OStringBuffer tmpBuf(type.getLength()*2); + nPos = 0; + do + { + tmpBuf.append("::"); + tmpBuf.append(type.getToken(0, '/', nPos)); + } while( nPos != -1 ); + + return tmpBuf.makeStringAndClear(); +} + +//************************************************************************* +// shortScopedName +//************************************************************************* +OString shortScopedName(const OString& scope, const OString& type, + sal_Bool bNoNameSpace) +{ + sal_Int32 nPos = type.lastIndexOf( '/' ); + if( nPos == -1 ) + return OString(); + + if (bNoNameSpace) + return OString(); + + // scoped name only if the namespace is not equal + if (scope.lastIndexOf('/') > 0) + { + OString tmpScp(scope.copy(0, scope.lastIndexOf('/'))); + OString tmpScp2(type.copy(0, nPos)); + + if (tmpScp == tmpScp2) + return OString(); + } + + OString aScope( type.copy( 0, nPos ) ); + OStringBuffer tmpBuf(aScope.getLength()*2); + + nPos = 0; + do + { + tmpBuf.append("::"); + tmpBuf.append(aScope.getToken(0, '/', nPos)); + } while( nPos != -1 ); + + return tmpBuf.makeStringAndClear(); +} + + diff --git a/codemaker/source/bonobowrappermaker/corbatype.hxx b/codemaker/source/bonobowrappermaker/corbatype.hxx new file mode 100644 index 000000000000..439aba86e68e --- /dev/null +++ b/codemaker/source/bonobowrappermaker/corbatype.hxx @@ -0,0 +1,310 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _CORBAMAKER_CPPUTYPE_HXX_ +#define _CORBAMAKER_CPPUTYPE_HXX_ + +#include <codemaker/typemanager.hxx> +#include <codemaker/dependency.hxx> + +#include <hash_set> + +enum BASETYPE +{ + BT_INVALID, + BT_VOID, + BT_ANY, + BT_TYPE, + BT_BOOLEAN, + BT_CHAR, + BT_STRING, + BT_FLOAT, + BT_DOUBLE, + BT_OCTET, + BT_BYTE, + BT_SHORT, + BT_LONG, + BT_HYPER, + BT_UNSIGNED_SHORT, + BT_UNSIGNED_LONG, + BT_UNSIGNED_HYPER +}; + + +class CorbaOptions; +class FileStream; + +struct OStringEqual +{ + sal_Bool operator() (const ::rtl::OString& lhs, const ::rtl::OString& rhs) const + { return lhs.equals( rhs );} +}; + +struct OStringHash : public std::unary_function< const ::rtl::OString &, size_t > +{ + size_t operator()( const ::rtl::OString & rStr ) const + { return rStr.hashCode(); } +}; + +typedef std::hash_set< ::rtl::OString, OStringHash, OStringEqual > TypeSet; + +class CorbaType +{ +public: + CorbaType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversion); + + virtual ~CorbaType(); + + virtual sal_Bool dump(CorbaOptions* pOptions, FileStream& o, TypeSet* allreadyDumped) throw( CannotDumpException ); + virtual sal_Bool dumpDependedTypes(CorbaOptions* pOptions, FileStream& o, TypeSet* allreadyDumped) throw( CannotDumpException ); + virtual sal_Bool dumpConversionFunctions(FileStream& o, TypeSet* allreadyDumped) throw( CannotDumpException ); + + static void dumpDefaultHxxIncludes(FileStream& o); + + virtual void dumpInclude(FileStream& o, TypeSet* allreadyDumped, const ::rtl::OString& typeName, sal_Char* prefix, sal_Bool bExtended=sal_False, sal_Bool bCaseSensitive=sal_False); + virtual void dumpDepIncludes(FileStream& o, TypeSet* allreadyDumped, const ::rtl::OString& typeName, sal_Char* prefix); + + virtual void dumpNameSpace(FileStream& o, sal_Bool bOpen = sal_True, sal_Bool bFull = sal_False, const ::rtl::OString& type=""); + virtual void dumpFunctions(FileStream& o) = 0; + + virtual ::rtl::OString printUnoType( const ::rtl::OString& type, + sal_Bool bConst=sal_False, + sal_Bool bRef=sal_False, + sal_Bool bNative=sal_False) + throw( CannotDumpException ); + + virtual void dumpUnoType(FileStream& o, + const ::rtl::OString& type, + sal_Bool bConst=sal_False, + sal_Bool bRef=sal_False, + sal_Bool bNative=sal_False) + throw( CannotDumpException ); + + virtual ::rtl::OString printCorbaType(const ::rtl::OString& type, + sal_Bool bConst, + sal_Bool bRef) + throw( CannotDumpException ); + + virtual void dumpCorbaType(FileStream& o, + const ::rtl::OString& type, + sal_Bool bConst=sal_False, + sal_Bool bRef=sal_False) + throw( CannotDumpException ); + + sal_Bool isPassedAsPointer(const ::rtl::OString& type); + sal_Bool isArray(const ::rtl::OString& type); + + sal_Bool isDerivedFromUnknown(const ::rtl::OString& typeName); + + + ::rtl::OString printCorbaParameter(const ::rtl::OString& type, + sal_Bool bOut = sal_False) + throw( CannotDumpException ); + + ::rtl::OString getTypeClass(const ::rtl::OString& type="", + sal_Bool bCStyle=sal_False); + ::rtl::OString getUnoBaseType(const ::rtl::OString& type); + ::rtl::OString getCorbaBaseType(const ::rtl::OString& type); + + void dumpTypeInit(FileStream& o, const ::rtl::OString& type); + BASETYPE isBaseType(const ::rtl::OString& type); + + ::rtl::OString typeToIdentifier(const ::rtl::OString& type); + + virtual sal_uInt32 getMemberCount(); + virtual sal_uInt32 getInheritedMemberCount(); + + sal_Bool isNestedTypeByName(const ::rtl::OString& type); + + void inc(sal_uInt32 num=4); + void dec(sal_uInt32 num=4); + ::rtl::OString indent(); + ::rtl::OString indent(sal_uInt32 num); +protected: + virtual sal_uInt32 checkInheritedMemberCount(const TypeReader* pReader); + + ::rtl::OString checkSpecialCorbaType(const ::rtl::OString& type); + ::rtl::OString checkRealBaseType(const ::rtl::OString& type, sal_Bool bResolveTypeOnly = sal_False); + +protected: + sal_uInt32 m_inheritedMemberCount; + sal_uInt32 m_indentLength; + ::rtl::OString m_typeName; + ::rtl::OString m_name; + TypeReader m_reader; + TypeManager& m_typeMgr; + TypeDependency m_dependencies; + TypeSet* m_generatedConversions; +}; + +class InterfaceType : public CorbaType +{ +public: + InterfaceType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversion); + + virtual ~InterfaceType(); + + void dumpFunctions(FileStream& o); + + void dumpUnoMethods(FileStream& o, sal_Bool bDeclOnly, sal_Bool bDelegateToSuper); + void dumpCorbaMethods(FileStream& o, sal_Bool bDeclOnly); + + sal_uInt32 getMemberCount(); + sal_uInt32 getInheritedMemberCount(); + +protected: + sal_uInt32 checkInheritedMemberCount(const TypeReader* pReader); + +protected: + sal_uInt32 m_inheritedMemberCount; + sal_Bool m_hasAttributes; + sal_Bool m_hasMethods; +}; + +class ModuleType : public CorbaType +{ +public: + ModuleType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversion); + + virtual ~ModuleType(); + + sal_Bool dumpConversionFunctions(FileStream& o, TypeSet* allreadyDumped) throw( CannotDumpException ); + void dumpFunctions(FileStream& o); + sal_Bool hasConstants(); +}; + +class ConstantsType : public ModuleType +{ +public: + ConstantsType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversion); + + virtual ~ConstantsType(); + + void dumpFunctions(FileStream& o); +}; + +class StructureType : public CorbaType +{ +public: + StructureType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversion); + + virtual ~StructureType(); + + void dumpFunctions(FileStream& o); + + sal_Bool dumpSuperMember(FileStream& o, const ::rtl::OString& super, sal_Bool bWithType); +}; + +class ExceptionType : public CorbaType +{ +public: + ExceptionType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversions); + + virtual ~ExceptionType(); + + void dumpFunctions(FileStream& o); + + sal_Bool dumpSuperMember(FileStream& o, const ::rtl::OString& super, sal_Bool bWithType); +}; + +class EnumType : public CorbaType +{ +public: + EnumType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversion); + + virtual ~EnumType(); + + void dumpFunctions(FileStream& o); +}; + +class TypeDefType : public CorbaType +{ +public: + TypeDefType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies, + TypeSet* generatedConversion); + + virtual ~TypeDefType(); + + void dumpFunctions(FileStream& o); +}; + + +sal_Bool produceType(const ::rtl::OString& typeName, + TypeManager& typeMgr, + TypeDependency& typeDependencies, + CorbaOptions* pOptions, + FileStream& o, TypeSet* allreadyDumped, + TypeSet* generatedConversions) + throw( CannotDumpException ); + +/** + * This function returns a C++ scoped name, represents the namespace + * scoping of this type, e.g. com:.sun::star::uno::XInterface. If the scope of + * the type is equal scope, the relativ name will be used. + */ +::rtl::OString scopedName(const ::rtl::OString& scope, + const ::rtl::OString& type, + sal_Bool bNoNameSpace=sal_False); + +::rtl::OString shortScopedName(const ::rtl::OString& scope, + const ::rtl::OString& type, + sal_Bool bNoNameSpace=sal_False); + + +#endif // _CORBAMAKER_CPPUTYPE_HXX_ + diff --git a/codemaker/source/bonobowrappermaker/makefile.mk b/codemaker/source/bonobowrappermaker/makefile.mk new file mode 100644 index 000000000000..36889e96400f --- /dev/null +++ b/codemaker/source/bonobowrappermaker/makefile.mk @@ -0,0 +1,62 @@ +#************************************************************************* +# +# 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=bonobowrappermaker +TARGETTYPE=CUI +LIBTARGET=NO + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + + +CXXFILES= corbamaker.cxx \ + corbaoptions.cxx \ + corbatype.cxx + + +APP1TARGET= $(TARGET) + +APP1OBJS= $(OBJ)$/corbamaker.obj \ + $(OBJ)$/corbaoptions.obj \ + $(OBJ)$/corbatype.obj + +APP1STDLIBS= \ + $(SALLIB) \ + $(SALHELPERLIB) \ + $(REGLIB) + +APP1LIBS= \ + $(LB)$/codemaker.lib + +.INCLUDE : target.mk 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); +} diff --git a/codemaker/source/commoncpp/commoncpp.cxx b/codemaker/source/commoncpp/commoncpp.cxx new file mode 100644 index 000000000000..4744af6df023 --- /dev/null +++ b/codemaker/source/commoncpp/commoncpp.cxx @@ -0,0 +1,355 @@ +/************************************************************************* + * + * 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/commoncpp.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.hxx" +#include "rtl/string.hxx" +#include "rtl/ustring.hxx" +#include "sal/types.h" + +#include <vector> + +namespace codemaker { namespace cpp { + +rtl::OString typeToPrefix(TypeManager const & manager, rtl::OString const & type) +{ + RTTypeClass typeclass = manager.getTypeClass(type); + if (typeclass == RT_TYPE_INVALID || + typeclass == RT_TYPE_PUBLISHED) + return rtl::OString("_"); + + static char const * const typeclassPrefix[RT_TYPE_UNION + 1] = { + "invalid", /* RT_TYPE_INVALID, is here only as placeholder */ + "interface", /* RT_TYPE_INTERFACE */ + "module", /* RT_TYPE_MODULE */ + "struct", /* RT_TYPE_STRUCT */ + "enum", /* RT_TYPE_ENUM */ + "exception", /* RT_TYPE_EXCEPTION */ + "typedef", /* RT_TYPE_TYPEDEF */ + "service", /* RT_TYPE_SERVICE */ + "singleton", /* RT_TYPE_SINGLETON */ + "object", /* RT_TYPE_OBJECT */ + "constants", /* RT_TYPE_CONSTANTS */ + "union" /* RT_TYPE_UNION */ + }; + + return rtl::OString(typeclassPrefix[typeclass]); +} + +rtl::OString scopedCppName(rtl::OString const & type, bool bNoNameSpace, + bool shortname) +{ + char c('/'); + sal_Int32 nPos = type.lastIndexOf( c ); + if (nPos == -1) { + nPos = type.lastIndexOf( '.' ); + if (nPos == -1) + return type; + + c = '.'; + } + if (bNoNameSpace) + return type.copy(nPos+1); + + rtl::OStringBuffer tmpBuf(type.getLength()*2); + nPos = 0; + do + { + tmpBuf.append("::"); + tmpBuf.append(type.getToken(0, c, nPos)); + } while( nPos != -1 ); + + if (shortname) { + rtl::OString s(tmpBuf.makeStringAndClear()); + if (s.indexOf("::com::sun::star") == 0) + return s.replaceAt(0, 16, "css"); + else + return s; + } + + return tmpBuf.makeStringAndClear(); +} + + +rtl::OString translateUnoToCppType( + codemaker::UnoType::Sort sort, RTTypeClass typeClass, + rtl::OString const & nucleus, bool shortname) +{ + rtl::OStringBuffer buf; + if (sort == codemaker::UnoType::SORT_COMPLEX) { + if (typeClass == RT_TYPE_INTERFACE + && nucleus == rtl::OString("com/sun/star/uno/XInterface")) + { + buf.append(RTL_CONSTASCII_STRINGPARAM("::com::sun::star::uno::XInterface")); + } else { + //TODO: check that nucleus is a valid (UTF-8) identifier + buf.append(nucleus); + } + } else { + static char const * const cppTypes[codemaker::UnoType::SORT_ANY + 1] = { + "void", "::sal_Bool", "::sal_Int8", "::sal_Int16", "::sal_uInt16", + "::sal_Int32", "::sal_uInt32", "::sal_Int64", "::sal_uInt64", + "float", "double", "::sal_Unicode", "::rtl::OUString", + "::com::sun::star::uno::Type", "::com::sun::star::uno::Any" }; + buf.append(cppTypes[sort]); + } + + if (shortname) { + rtl::OString s(buf.makeStringAndClear()); + if (s.indexOf("::com::sun::star") == 0) + return s.replaceAt(0, 16, "css"); + else + return s; + } + + return buf.makeStringAndClear(); +} + +rtl::OString translateUnoToCppIdentifier( + rtl::OString const & unoIdentifier, rtl::OString const & prefix, + IdentifierTranslationMode transmode, rtl::OString const * forbidden) +{ + if (// Keywords: + unoIdentifier == "asm" + || unoIdentifier == "auto" + || unoIdentifier == "bool" + || unoIdentifier == "break" + || unoIdentifier == "case" + || unoIdentifier == "catch" + || unoIdentifier == "char" + || unoIdentifier == "class" + || unoIdentifier == "const" + /* unoIdentifier == "const_cast" */ + || unoIdentifier == "continue" + || unoIdentifier == "default" + || unoIdentifier == "delete" + || unoIdentifier == "do" + || unoIdentifier == "double" + /* unoIdentifier == "dynamic_cast" */ + || unoIdentifier == "else" + || unoIdentifier == "enum" + || unoIdentifier == "explicit" + || unoIdentifier == "export" + || unoIdentifier == "extern" + || unoIdentifier == "false" + || unoIdentifier == "float" + || unoIdentifier == "for" + || unoIdentifier == "friend" + || unoIdentifier == "goto" + || unoIdentifier == "if" + || unoIdentifier == "inline" + || unoIdentifier == "int" + || unoIdentifier == "long" + || unoIdentifier == "mutable" + || unoIdentifier == "namespace" + || unoIdentifier == "new" + || unoIdentifier == "operator" + || unoIdentifier == "private" + || unoIdentifier == "protected" + || unoIdentifier == "public" + || unoIdentifier == "register" + /* unoIdentifier == "reinterpret_cast" */ + || unoIdentifier == "return" + || unoIdentifier == "short" + || unoIdentifier == "signed" + || unoIdentifier == "sizeof" + || unoIdentifier == "static" + /* unoIdentifier == "static_cast" */ + || unoIdentifier == "struct" + || unoIdentifier == "switch" + || unoIdentifier == "template" + || unoIdentifier == "this" + || unoIdentifier == "throw" + || unoIdentifier == "true" + || unoIdentifier == "try" + || unoIdentifier == "typedef" + || unoIdentifier == "typeid" + || unoIdentifier == "typename" + || unoIdentifier == "union" + || unoIdentifier == "unsigned" + || unoIdentifier == "using" + || unoIdentifier == "virtual" + || unoIdentifier == "void" + || unoIdentifier == "volatile" + /* unoIdentifier == "wchar_t" */ + || unoIdentifier == "while" + // Alternative representations: + || unoIdentifier == "and" + /* unoIdentifier == "and_eq" */ + || unoIdentifier == "bitand" + || unoIdentifier == "bitor" + || unoIdentifier == "compl" + || unoIdentifier == "not" + /* unoIdentifier == "not_eq" */ + || unoIdentifier == "or" + /* unoIdentifier == "or_eq" */ + || unoIdentifier == "xor" + /* unoIdentifier == "xor_eq" */ + // Standard macros: + || (transmode != ITM_KEYWORDSONLY + && (unoIdentifier == "BUFSIZ" + || unoIdentifier == "CLOCKS_PER_SEC" + || unoIdentifier == "EDOM" + || unoIdentifier == "EOF" + || unoIdentifier == "ERANGE" + || unoIdentifier == "EXIT_FAILURE" + || unoIdentifier == "EXIT_SUCCESS" + || unoIdentifier == "FILENAME_MAX" + || unoIdentifier == "FOPEN_MAX" + || unoIdentifier == "HUGE_VAL" + || unoIdentifier == "LC_ALL" + || unoIdentifier == "LC_COLLATE" + || unoIdentifier == "LC_CTYPE" + || unoIdentifier == "LC_MONETARY" + || unoIdentifier == "LC_NUMERIC" + || unoIdentifier == "LC_TIME" + || unoIdentifier == "L_tmpnam" + || unoIdentifier == "MB_CUR_MAX" + || unoIdentifier == "NULL" + || unoIdentifier == "RAND_MAX" + || unoIdentifier == "SEEK_CUR" + || unoIdentifier == "SEEK_END" + || unoIdentifier == "SEEK_SET" + || unoIdentifier == "SIGABRT" + || unoIdentifier == "SIGFPE" + || unoIdentifier == "SIGILL" + || unoIdentifier == "SIGINT" + || unoIdentifier == "SIGSEGV" + || unoIdentifier == "SIGTERM" + || unoIdentifier == "SIG_DFL" + || unoIdentifier == "SIG_ERR" + || unoIdentifier == "SIG_IGN" + || unoIdentifier == "TMP_MAX" + || unoIdentifier == "WCHAR_MAX" + || unoIdentifier == "WCHAR_MIN" + || unoIdentifier == "WEOF" + /* unoIdentifier == "_IOFBF" */ + /* unoIdentifier == "_IOLBF" */ + /* unoIdentifier == "_IONBF" */ + || unoIdentifier == "assert" + || unoIdentifier == "errno" + || unoIdentifier == "offsetof" + || unoIdentifier == "setjmp" + || unoIdentifier == "stderr" + || unoIdentifier == "stdin" + || unoIdentifier == "stdout" + /* unoIdentifier == "va_arg" */ + /* unoIdentifier == "va_end" */ + /* unoIdentifier == "va_start" */ + // Standard values: + || unoIdentifier == "CHAR_BIT" + || unoIdentifier == "CHAR_MAX" + || unoIdentifier == "CHAR_MIN" + || unoIdentifier == "DBL_DIG" + || unoIdentifier == "DBL_EPSILON" + || unoIdentifier == "DBL_MANT_DIG" + || unoIdentifier == "DBL_MAX" + || unoIdentifier == "DBL_MAX_10_EXP" + || unoIdentifier == "DBL_MAX_EXP" + || unoIdentifier == "DBL_MIN" + || unoIdentifier == "DBL_MIN_10_EXP" + || unoIdentifier == "DBL_MIN_EXP" + || unoIdentifier == "FLT_DIG" + || unoIdentifier == "FLT_EPSILON" + || unoIdentifier == "FLT_MANT_DIG" + || unoIdentifier == "FLT_MAX" + || unoIdentifier == "FLT_MAX_10_EXP" + || unoIdentifier == "FLT_MAX_EXP" + || unoIdentifier == "FLT_MIN" + || unoIdentifier == "FLT_MIN_10_EXP" + || unoIdentifier == "FLT_MIN_EXP" + || unoIdentifier == "FLT_RADIX" + || unoIdentifier == "FLT_ROUNDS" + || unoIdentifier == "INT_MAX" + || unoIdentifier == "INT_MIN" + || unoIdentifier == "LDBL_DIG" + || unoIdentifier == "LDBL_EPSILON" + || unoIdentifier == "LDBL_MANT_DIG" + || unoIdentifier == "LDBL_MAX" + || unoIdentifier == "LDBL_MAX_10_EXP" + || unoIdentifier == "LDBL_MAX_EXP" + || unoIdentifier == "LDBL_MIN" + || unoIdentifier == "LDBL_MIN_10_EXP" + || unoIdentifier == "LDBL_MIN_EXP" + || unoIdentifier == "LONG_MAX" + || unoIdentifier == "LONG_MIN" + || unoIdentifier == "MB_LEN_MAX" + || unoIdentifier == "SCHAR_MAX" + || unoIdentifier == "SCHAR_MIN" + || unoIdentifier == "SHRT_MAX" + || unoIdentifier == "SHRT_MIN" + || unoIdentifier == "UCHAR_MAX" + || unoIdentifier == "UINT_MAX" + || unoIdentifier == "ULONG_MAX" + || unoIdentifier == "USHRT_MAX")) + || (transmode == ITM_GLOBAL + && (// Standard types: + /* unoIdentifier == "clock_t" */ + /* unoIdentifier == "div_t" */ + unoIdentifier == "FILE" + /* unoIdentifier == "fpos_t" */ + /* unoIdentifier == "jmp_buf" */ + || unoIdentifier == "lconv" + /* unoIdentifier == "ldiv_t" */ + /* unoIdentifier == "mbstate_t" */ + /* unoIdentifier == "ptrdiff_t" */ + /* unoIdentifier == "sig_atomic_t" */ + /* unoIdentifier == "size_t" */ + /* unoIdentifier == "time_t" */ + || unoIdentifier == "tm" + /* unoIdentifier == "va_list" */ + /* unoIdentifier == "wctrans_t" */ + /* unoIdentifier == "wctype_t" */ + /* unoIdentifier == "wint_t" */ + // Standard namespaces: + || unoIdentifier == "std")) + // Others: + || unoIdentifier == "NDEBUG" + || (forbidden != 0 && unoIdentifier == *forbidden) ) + { + rtl::OStringBuffer buf(prefix); + buf.append('_'); + buf.append(unoIdentifier); + return buf.makeStringAndClear(); + } else { + return unoIdentifier; + } +} + +} } diff --git a/codemaker/source/commoncpp/makefile.mk b/codemaker/source/commoncpp/makefile.mk new file mode 100644 index 000000000000..c6799c55a01d --- /dev/null +++ b/codemaker/source/commoncpp/makefile.mk @@ -0,0 +1,42 @@ +#************************************************************************* +# +# 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 := commoncpp + +ENABLE_EXCEPTIONS := TRUE + +.INCLUDE: settings.mk + +SLOFILES = $(SLO)$/commoncpp.obj + +LIB1TARGET=$(LB)$/$(TARGET).lib +LIB1ARCHIV=$(LB)$/lib$(TARGET).a +LIB1OBJFILES=$(SLOFILES) + +.INCLUDE: target.mk diff --git a/codemaker/source/commonjava/commonjava.cxx b/codemaker/source/commonjava/commonjava.cxx new file mode 100644 index 000000000000..8ae254cbde84 --- /dev/null +++ b/codemaker/source/commonjava/commonjava.cxx @@ -0,0 +1,167 @@ +/************************************************************************* + * + * 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/commonjava.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 codemaker { namespace java { + +rtl::OString translateUnoToJavaType( + codemaker::UnoType::Sort sort, RTTypeClass typeClass, + rtl::OString const & nucleus, bool referenceType) +{ + rtl::OStringBuffer buf; + if (sort == codemaker::UnoType::SORT_COMPLEX) { + if (typeClass == RT_TYPE_INTERFACE + && nucleus == rtl::OString("com/sun/star/uno/XInterface")) + { + buf.append(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")); + } else { + //TODO: check that nucleus is a valid (Java-modified UTF-8) + // identifier + buf.append(nucleus); + } + } else { + rtl::OString const javaTypes[codemaker::UnoType::SORT_ANY + 1][2] = { + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("void")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Void")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("boolean")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Boolean")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("byte")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Byte")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("short")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Short")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("short")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Short")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("int")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Integer")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("int")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Integer")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("long")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Long")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("long")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Long")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("float")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Float")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("double")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Double")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("char")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Character")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/String")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/String")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")) }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")) } }; + buf.append(javaTypes[sort][referenceType]); + } + return buf.makeStringAndClear(); +} + +rtl::OString translateUnoToJavaIdentifier( + rtl::OString const & identifier, rtl::OString const & prefix) +{ + if (identifier == "abstract" + || identifier == "assert" // since Java 1.4 + || identifier == "boolean" + || identifier == "break" + || identifier == "byte" + || identifier == "case" + || identifier == "catch" + || identifier == "char" + || identifier == "class" + || identifier == "const" + || identifier == "continue" + || identifier == "default" + || identifier == "do" + || identifier == "double" + || identifier == "else" + || identifier == "enum" // probable addition in Java 1.5 + || identifier == "extends" + || identifier == "final" + || identifier == "finally" + || identifier == "float" + || identifier == "for" + || identifier == "goto" + || identifier == "if" + || identifier == "implements" + || identifier == "import" + || identifier == "instanceof" + || identifier == "int" + || identifier == "interface" + || identifier == "long" + || identifier == "native" + || identifier == "new" + || identifier == "package" + || identifier == "private" + || identifier == "protected" + || identifier == "public" + || identifier == "return" + || identifier == "short" + || identifier == "static" + || identifier == "strictfp" + || identifier == "super" + || identifier == "switch" + || identifier == "synchronized" + || identifier == "this" + || identifier == "throw" + || identifier == "throws" + || identifier == "transient" + || identifier == "try" + || identifier == "void" + || identifier == "volatile" + || identifier == "while") + { + rtl::OStringBuffer buf(prefix); + buf.append('_'); + buf.append(identifier); + return buf.makeStringAndClear(); + } else { + return identifier; + } +} + +} } diff --git a/codemaker/source/commonjava/makefile.mk b/codemaker/source/commonjava/makefile.mk new file mode 100644 index 000000000000..6d108c68cf86 --- /dev/null +++ b/codemaker/source/commonjava/makefile.mk @@ -0,0 +1,42 @@ +#************************************************************************* +# +# 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 := commonjava + +ENABLE_EXCEPTIONS := TRUE + +.INCLUDE: settings.mk + +SLOFILES = $(SLO)$/commonjava.obj + +LIB1TARGET=$(LB)$/$(TARGET).lib +LIB1ARCHIV=$(LB)$/lib$(TARGET).a +LIB1OBJFILES=$(SLOFILES) + +.INCLUDE: target.mk diff --git a/codemaker/source/cppumaker/cppumaker.cxx b/codemaker/source/cppumaker/cppumaker.cxx new file mode 100644 index 000000000000..e6d5679409e8 --- /dev/null +++ b/codemaker/source/cppumaker/cppumaker.cxx @@ -0,0 +1,244 @@ +/************************************************************************* + * + * 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 <stdio.h> + +#include "sal/main.h" + +#include "codemaker/typemanager.hxx" +#include "codemaker/generatedtypeset.hxx" + +#include "cppuoptions.hxx" +#include "cpputype.hxx" + +using namespace rtl; + +namespace { + +void failed(rtl::OString const & typeName, CppuOptions * options) { + fprintf(stderr, "%s ERROR: %s\n", options->getProgramName().getStr(), + rtl::OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); +} + +void produce( + RegistryKey& rTypeKey, bool bIsExtraType, TypeManager const & typeMgr, + codemaker::GeneratedTypeSet & generated, CppuOptions * options) +{ + if (!produceType(rTypeKey, bIsExtraType, typeMgr, generated, options)) { + OString typeName = typeMgr.getTypeName(rTypeKey); + failed(typeName, options); + } +} + +void produce( + rtl::OString const & typeName, TypeManager const & typeMgr, + codemaker::GeneratedTypeSet & generated, CppuOptions * options) +{ + if (!produceType(typeName, typeMgr, generated, options)) { + failed(typeName, options); + } +} + +void produceAllTypes(RegistryKey& rTypeKey, bool bIsExtraType, + TypeManager const & typeMgr, + codemaker::GeneratedTypeSet & generated, + CppuOptions* pOptions, + sal_Bool bFullScope) + throw( CannotDumpException ) +{ + OString typeName = typeMgr.getTypeName(rTypeKey); + + produce(rTypeKey, bIsExtraType, typeMgr, generated, pOptions); + + RegistryKeyList typeKeys = typeMgr.getTypeKeys(typeName); + RegistryKeyList::const_iterator iter = typeKeys.begin(); + RegistryKey key, subKey; + RegistryKeyArray subKeys; + + while (iter != typeKeys.end()) + { + key = (*iter).first; + + if (!(*iter).second && !key.openSubKeys(OUString(), subKeys)) + { + for (sal_uInt32 i = 0; i < subKeys.getLength(); i++) + { + subKey = subKeys.getElement(i); + if (bFullScope) + { + produceAllTypes(subKey, (*iter).second, typeMgr, + generated, pOptions, true); + } else + { + produce(subKey, (*iter).second, + typeMgr, generated, pOptions); + } + } + } + + ++iter; + } +} + +void produceAllTypes(const OString& typeName, + TypeManager const & typeMgr, + codemaker::GeneratedTypeSet & generated, + CppuOptions* pOptions, + sal_Bool bFullScope) + throw( CannotDumpException ) +{ + produce(typeName, typeMgr, generated, pOptions); + + RegistryKeyList typeKeys = typeMgr.getTypeKeys(typeName); + RegistryKeyList::const_iterator iter = typeKeys.begin(); + RegistryKey key, subKey; + RegistryKeyArray subKeys; + + while (iter != typeKeys.end()) + { + key = (*iter).first; + if (!(*iter).second && !key.openSubKeys(OUString(), subKeys)) + { + for (sal_uInt32 i = 0; i < subKeys.getLength(); i++) + { + subKey = subKeys.getElement(i); + if (bFullScope) + { + produceAllTypes(subKey, (*iter).second, typeMgr, + generated, pOptions, true); + } else + { + produce(subKey, (*iter).second, + typeMgr, generated, pOptions); + } + } + } + + ++iter; + } +} + +} + +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) +{ + CppuOptions options; + + try + { + if (!options.initOptions(argc, argv)) + { + exit(1); + } + } + catch( IllegalArgument& e) + { + fprintf(stderr, "Illegal option: %s\n", e.m_message.getStr()); + exit(99); + } + + RegistryTypeManager typeMgr; + + if (!typeMgr.init(options.getInputFiles(), options.getExtraInputFiles())) + { + fprintf(stderr, "%s : init registries failed, check your registry files.\n", options.getProgramName().getStr()); + exit(99); + } + + if (options.isValid("-B")) + { + typeMgr.setBase(options.getOption("-B")); + } + + codemaker::GeneratedTypeSet generated; + try + { + if (options.isValid("-T")) + { + OString tOption(options.getOption("-T")); + + OString typeName, tmpName; + sal_Int32 nIndex = 0; + do + { + typeName = tOption.getToken(0, ';', nIndex); + + sal_Int32 nPos = typeName.lastIndexOf( '.' ); + tmpName = typeName.copy( nPos != -1 ? nPos+1 : 0 ); + if (tmpName == "*") + { + // produce this type and his scope + if (typeName.equals("*")) + { + tmpName = "/"; + } else + { + tmpName = typeName.copy(0, typeName.lastIndexOf('.')).replace('.', '/'); + if (tmpName.getLength() == 0) + tmpName = "/"; + else + tmpName.replace('.', '/'); + } + // related to task #116780# the scope is recursively + // generated. bFullScope = true + produceAllTypes( + tmpName, typeMgr, generated, &options, true); + } else + { + // produce only this type + produce( + typeName.replace('.', '/'), typeMgr, generated, &options); + } + } while( nIndex != -1 ); + } else + { + // produce all types + produceAllTypes("/", typeMgr, generated, &options, true); + } + // C++ header files generated for the following UNO types are included + // in header files in cppu/inc/com/sun/star/uno (Any.hxx, Reference.hxx, + // Type.h), so it seems best to always generate those C++ header files: + produce("com/sun/star/uno/RuntimeException", typeMgr, generated, &options); + produce("com/sun/star/uno/TypeClass", typeMgr, generated, &options); + produce("com/sun/star/uno/XInterface", typeMgr, generated, &options); + } + catch( CannotDumpException& e) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + e.m_message.getStr()); + exit(99); + } + + return 0; +} + + diff --git a/codemaker/source/cppumaker/cppuoptions.cxx b/codemaker/source/cppumaker/cppuoptions.cxx new file mode 100644 index 000000000000..1bc398391c9d --- /dev/null +++ b/codemaker/source/cppumaker/cppuoptions.cxx @@ -0,0 +1,355 @@ +/************************************************************************* + * + * 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 <stdio.h> +#include <string.h> + +#include "cppuoptions.hxx" +#include "osl/thread.h" +#include "osl/process.h" + +using namespace rtl; + +sal_Bool CppuOptions::initOptions(int ac, char* av[], sal_Bool bCmdFile) + throw( IllegalArgument ) +{ + sal_Bool ret = sal_True; + sal_uInt16 i=0; + + if (!bCmdFile) + { + bCmdFile = sal_True; + + m_program = av[0]; + + if (ac < 2) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } + + i = 1; + } else + { + i = 0; + } + + char *s=NULL; + for( ; i < ac; i++) + { + if (av[i][0] == '-') + { + switch (av[i][1]) + { + case 'O': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-O', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_options["-O"] = OString(s); + break; + case 'B': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-B', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_options["-B"] = OString(s); + break; + case 'T': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-T', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + if (m_options.count("-T") > 0) + { + OString tmp(m_options["-T"]); + tmp = tmp + ";" + s; + m_options["-T"] = tmp; + } else + { + m_options["-T"] = OString(s); + } + break; + case 'L': + if (av[i][2] != '\0') + { + OString tmp("'-L', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + if (isValid("-C") || isValid("-CS")) + { + OString tmp("'-L' could not be combined with '-C' or '-CS' option"); + throw IllegalArgument(tmp); + } + m_options["-L"] = OString(""); + break; + case 'C': + if (av[i][2] == 'S') + { + if (av[i][3] != '\0') + { + OString tmp("'-CS', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + if (isValid("-L") || isValid("-C")) + { + OString tmp("'-CS' could not be combined with '-L' or '-C' option"); + throw IllegalArgument(tmp); + } + m_options["-CS"] = OString(""); + break; + } else + if (av[i][2] != '\0') + { + OString tmp("'-C', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + if (isValid("-L") || isValid("-CS")) + { + OString tmp("'-C' could not be combined with '-L' or '-CS' option"); + throw IllegalArgument(tmp); + } + m_options["-C"] = OString(""); + break; + case 'G': + if (av[i][2] == 'c') + { + if (av[i][3] != '\0') + { + OString tmp("'-Gc', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + m_options["-Gc"] = OString(""); + break; + } else + if (av[i][2] != '\0') + { + OString tmp("'-G', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + m_options["-G"] = OString(""); + break; + case 'X': // support for eXtra type rdbs + { + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-X', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_extra_input_files.push_back( s ); + break; + } + + default: + throw IllegalArgument("the option is unknown" + OString(av[i])); + } + } else + { + if (av[i][0] == '@') + { + FILE* cmdFile = fopen(av[i]+1, "r"); + if( cmdFile == NULL ) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } else + { + int rargc=0; + char* rargv[512]; + char buffer[512]; + + while ( fscanf(cmdFile, "%s", buffer) != EOF ) + { + rargv[rargc]= strdup(buffer); + rargc++; + } + fclose(cmdFile); + + ret = initOptions(rargc, rargv, bCmdFile); + + for (long j=0; j < rargc; j++) + { + free(rargv[j]); + } + } + } else + { + if (bCmdFile) + { + m_inputFiles.push_back(av[i]); + } else + { + OUString system_filepath; + if (osl_getCommandArg( i-1, &system_filepath.pData ) + != osl_Process_E_None) + { + OSL_ASSERT(false); + } + m_inputFiles.push_back(OUStringToOString(system_filepath, osl_getThreadTextEncoding())); + } + } + } + } + + return ret; +} + +OString CppuOptions::prepareHelp() +{ + OString help("\nusing: "); + help += m_program + " [-options] file_1 ... file_n\nOptions:\n"; + help += " -O<path> = path describes the root directory for the generated output.\n"; + help += " The output directory tree is generated under this directory.\n"; + help += " -T<name> = name specifies a type or a list of types. The output for this\n"; + help += " [t1;...] type is generated. If no '-T' option is specified,\n"; + help += " then output for all types is generated.\n"; + help += " Example: 'com.sun.star.uno.XInterface' is a valid type.\n"; + help += " -B<name> = name specifies the base node. All types are searched under this\n"; + help += " node. Default is the root '/' of the registry files.\n"; + help += " -L = UNO type functions are generated lightweight, that means only\n"; + help += " the name and typeclass are given and everything else is retrieved\n"; + help += " from the type library dynamically. The default is that UNO type\n"; + help += " functions provides enough type information for boostrapping C++.\n"; + help += " '-L' should be the default for external components.\n"; + help += " -C = UNO type functions are generated comprehensive that means all\n"; + help += " necessary information is available for bridging the type in UNO.\n"; + help += " -G = generate only target files which does not exists.\n"; + help += " -Gc = generate only target files which content will be changed.\n"; + help += " -X<file> = extra types which will not be taken into account for generation.\n"; + help += prepareVersion(); + + return help; +} + +OString CppuOptions::prepareVersion() +{ + OString version("\nSun Microsystems (R) "); + version += m_program + " Version 2.0\n\n"; + + return version; +} + + diff --git a/codemaker/source/cppumaker/cppuoptions.hxx b/codemaker/source/cppumaker/cppuoptions.hxx new file mode 100644 index 000000000000..b291eb548e73 --- /dev/null +++ b/codemaker/source/cppumaker/cppuoptions.hxx @@ -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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_CPPUOPTIONS_HXX +#define INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_CPPUOPTIONS_HXX + +#include "codemaker/options.hxx" + +class CppuOptions : public Options +{ +public: + CppuOptions() + : Options() {} + + ~CppuOptions() {} + + sal_Bool initOptions(int ac, char* av[], sal_Bool bCmdFile=sal_False) + throw( IllegalArgument ); + + ::rtl::OString prepareHelp(); + + ::rtl::OString prepareVersion(); + +protected: +}; + +#endif // INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_CPPUOPTIONS_HXX diff --git a/codemaker/source/cppumaker/cpputype.cxx b/codemaker/source/cppumaker/cpputype.cxx new file mode 100644 index 000000000000..a08e0be518be --- /dev/null +++ b/codemaker/source/cppumaker/cpputype.cxx @@ -0,0 +1,4504 @@ +/************************************************************************* + * + * 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 <algorithm> +#include <map> +#include <set> +#include <stdio.h> +#include <string.h> +#include <vector> + +#include "registry/reader.hxx" +#include "rtl/alloc.h" +#include "rtl/ustring.hxx" +#include "rtl/strbuf.hxx" + +#include "codemaker/dependencies.hxx" +#include "codemaker/exceptiontree.hxx" +#include "codemaker/generatedtypeset.hxx" +#include "codemaker/unotype.hxx" + +#include "cpputype.hxx" +#include "cppuoptions.hxx" +#include "dumputils.hxx" +#include "includes.hxx" + +using namespace rtl; +using namespace codemaker::cpp; + +namespace { + +rtl::OString translateSimpleUnoType(rtl::OString const & unoType, bool cppuUnoType=false) { + static rtl::OString const trans[codemaker::UnoType::SORT_COMPLEX + 1] = { + "void", "::sal_Bool", "::sal_Int8", "::sal_Int16", "::sal_uInt16", + "::sal_Int32", "::sal_uInt32", "::sal_Int64", "::sal_uInt64", "float", + "double", "::sal_Unicode", "::rtl::OUString", + "::com::sun::star::uno::Type", "::com::sun::star::uno::Any", + rtl::OString() }; + + const codemaker::UnoType::Sort sort = codemaker::UnoType::getSort(unoType); + if (cppuUnoType && + (sort == codemaker::UnoType::SORT_UNSIGNED_SHORT || + sort == codemaker::UnoType::SORT_CHAR) ) + { + if (sort == codemaker::UnoType::SORT_CHAR) + return "::cppu::UnoCharType"; + else + return "::cppu::UnoUnsignedShortType"; + } + + return trans[sort]; +} + +} + +//************************************************************************* +// CppuType +//************************************************************************* +CppuType::CppuType(typereg::Reader& typeReader, + const OString& typeName, + const TypeManager& typeMgr) + : m_inheritedMemberCount(0) + , m_cppuTypeLeak(sal_False) + , m_cppuTypeDynamic(sal_True) + , m_indentLength(0) + , m_typeName(typeName) + , m_name(typeName.copy(typeName.lastIndexOf('/') + 1)) + , m_reader(typeReader) + , m_typeMgr(typeMgr) + , m_dependencies(typeMgr, typeName) +{} + +CppuType::~CppuType() +{ + +} + +void CppuType::addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes) + const +{ + if (m_typeName.equals("com/sun/star/uno/XInterface") + || m_typeName.equals("com/sun/star/uno/Exception")) + { + includes.addType(); + includes.addCppuUnotypeHxx(); + includes.addSalTypesH(); + includes.addTypelibTypeclassH(); + includes.addTypelibTypedescriptionH(); + } else if (m_cppuTypeLeak) { + addLightGetCppuTypeIncludes(includes); + } else if (m_cppuTypeDynamic) { + addNormalGetCppuTypeIncludes(includes); + } else { + addComprehensiveGetCppuTypeIncludes(includes); + } +} + +bool CppuType::dumpFiles(CppuOptions * options, rtl::OString const & outPath) { + return dumpFile(options, ".hdl", m_typeName, outPath) + && dumpFile(options, ".hpp", m_typeName, outPath); +} + +void CppuType::addLightGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const +{ + //TODO: Determine what is really needed, instead of relying on + // addDefaultHxxIncludes + includes.addCppuUnotypeHxx(); +} + +void CppuType::addNormalGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const +{ + //TODO: Determine what is really needed, instead of relying on + // addDefaultHxxIncludes + includes.addCppuUnotypeHxx(); +} + +void CppuType::addComprehensiveGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const +{ + //TODO: Determine what is really needed, instead of relying on + // addDefaultHxxIncludes + includes.addCppuUnotypeHxx(); +} + +bool CppuType::isPolymorphic() const { return false; } + +void CppuType::dumpTemplateHead(FileStream &) const {} + +void CppuType::dumpTemplateParameters(FileStream &) const {} + +void CppuType::dumpGetCppuTypePreamble(FileStream & out) { + if (isPolymorphic()) { + out << "namespace cppu {\n\n"; + dumpTemplateHead(out); + out << "class UnoType< "; + dumpType(out, m_typeName); + dumpTemplateParameters(out); + out << " > {\npublic:\n"; + inc(); + out << indent() + << "static inline ::com::sun::star::uno::Type const & get() {\n"; + } else { + if (codemaker::cppumaker::dumpNamespaceOpen(out, m_typeName, false)) { + out << "\n\n"; + } + out << ("inline ::com::sun::star::uno::Type const &" + " cppu_detail_getUnoType("); + dumpType(out, m_typeName, false, false, true); + out << " const *) {\n"; + } + inc(); +} + +void CppuType::dumpGetCppuTypePostamble(FileStream & out) { + dec(); + if (isPolymorphic()) { + out << indent() << "}\n\nprivate:\n" + << indent() << "UnoType(UnoType &); // not defined\n" + << indent() << "~UnoType(); // not defined\n" + << indent() + << "void operator =(UnoType); // not defined\n};\n\n}\n\n"; + } else { + out << "}\n\n"; + if (codemaker::cppumaker::dumpNamespaceClose(out, m_typeName, false)) { + out << "\n\n"; + } + } + dumpTemplateHead(out); + out << "inline ::com::sun::star::uno::Type const & SAL_CALL getCppuType("; + dumpType(out, m_typeName); + dumpTemplateParameters(out); + out << " const *) SAL_THROW(()) {\n"; + inc(); + out << indent() << "return ::cppu::UnoType< "; + dumpType(out, m_typeName); + dumpTemplateParameters(out); + out << " >::get();\n"; + dec(); + out << indent() << "}\n"; +} + +sal_Bool CppuType::dump(CppuOptions* pOptions) + throw( CannotDumpException ) +{ + if (!m_dependencies.isValid()) { + return false; + } + addSpecialDependencies(); + + // -CS was used as an undocumented option to generate static getCppuType + // functions; since the introduction of cppu::UnoType this no longer is + // meaningful (getCppuType is just a forward to cppu::UnoType::get now), and + // -CS is handled the same way as -C now: + if (pOptions->isValid("-L")) + m_cppuTypeLeak = sal_True; + if (pOptions->isValid("-C") || pOptions->isValid("-CS")) + m_cppuTypeDynamic = sal_False; + + OString outPath; + if (pOptions->isValid("-O")) + outPath = pOptions->getOption("-O"); + + return dumpFiles(pOptions, outPath); +} + +sal_Bool CppuType::dumpFile(CppuOptions* pOptions, + const OString& sExtension, + const OString& sName, + const OString& sOutPath ) + throw( CannotDumpException ) +{ + sal_Bool ret = sal_False; + + OString sTmpExt(".tml"); + sal_Bool bHdl = sal_True; ; + if (sExtension.equals(".hpp")) { + sTmpExt = ".tmp"; + bHdl = sal_False; + } + + OString sFileName = createFileNameFromType(sOutPath, sName, sExtension); + if (sFileName.getLength() == 0) + return sal_False; + + sal_Bool bFileExists = fileExists( sFileName ); + sal_Bool bFileCheck = sal_False; + + if ( bFileExists && pOptions->isValid("-G") ) + return sal_True; + + if ( bFileExists && pOptions->isValid("-Gc") ) + bFileCheck = sal_True; + + OString sTmpDir = getTempDir(sFileName); + FileStream oFile; + oFile.createTempFile(sTmpDir); + OString sTmpFileName; + + if(!oFile.isValid()) + { + OString message("cannot open "); + message += sFileName + " for writing"; + throw CannotDumpException(message); + } else + sTmpFileName = oFile.getName(); + + codemaker::cppumaker::Includes includes(m_typeMgr, m_dependencies, !bHdl); + if (bHdl) + ret = dumpHFile(oFile, includes); + else { + addGetCppuTypeIncludes(includes); + ret = dumpHxxFile(oFile, includes); + } + + oFile.close(); + + if (ret) { + ret = makeValidTypeFile(sFileName, sTmpFileName, bFileCheck); + } else { + // remove existing type file if something goes wrong to ensure consistency + if (fileExists(sFileName)) + removeTypeFile(sFileName); + + // remove tmp file if something goes wrong + removeTypeFile(sTmpFileName); + } + + return ret; +} + +void CppuType::dumpDependedTypes( + codemaker::GeneratedTypeSet & generated, CppuOptions * options) +{ + codemaker::Dependencies::Map const & map(m_dependencies.getMap()); + for (codemaker::Dependencies::Map::const_iterator i(map.begin()); + i != map.end(); ++i) + { + if (!produceType(i->first, m_typeMgr, generated, options)) { + fprintf( + stderr, "%s ERROR: cannot dump Type '%s'\n", + options->getProgramName().getStr(), i->first.getStr()); + exit(99); + } + } +} + +OString CppuType::dumpHeaderDefine( + FileStream& o, char const * prefix, sal_Bool bExtended) +{ + if (m_typeName.equals("/")) + { + bExtended = sal_False; + m_typeName = "global"; + } + + sal_uInt32 length = 3 + m_typeName.getLength() + strlen(prefix); + + if (bExtended) + length += m_name.getLength() + 1; + + OStringBuffer tmpBuf(length); + + tmpBuf.append("INCLUDED_"); + tmpBuf.append(m_typeName); + tmpBuf.append('_'); + if (bExtended) + { + tmpBuf.append(m_name); + tmpBuf.append('_'); + } + tmpBuf.append(prefix); + + OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase()); + + o << "#ifndef " << tmp << "\n#define " << tmp << "\n"; + + return tmp; +} + +void CppuType::addDefaultHIncludes(codemaker::cppumaker::Includes & includes) + const +{ + //TODO: Only include what is really needed + includes.addCppuMacrosHxx(); + if (m_typeMgr.getTypeClass(m_typeName) == RT_TYPE_INTERFACE) { + includes.addReference(); + } +} + +void CppuType::addDefaultHxxIncludes(codemaker::cppumaker::Includes & includes) + const +{ + //TODO: Only include what is really needed + includes.addOslMutexHxx(); + includes.addType(); + if (m_typeMgr.getTypeClass(m_typeName) == RT_TYPE_INTERFACE) { + includes.addReference(); + } +} + +void CppuType::dumpInitializer( + FileStream & out, bool parameterized, rtl::OUString const & type) const +{ + out << "("; + if (!parameterized) { + for (rtl::OString t( + rtl::OUStringToOString(type, RTL_TEXTENCODING_UTF8));;) + { + sal_Int32 rank; + std::vector< rtl::OString > args; + t = codemaker::UnoType::decompose(t, &rank, &args); + if (rank == 0) { + switch (codemaker::UnoType::getSort(t)) { + case codemaker::UnoType::SORT_BOOLEAN: + out << "false"; + break; + + case codemaker::UnoType::SORT_BYTE: + case codemaker::UnoType::SORT_SHORT: + case codemaker::UnoType::SORT_UNSIGNED_SHORT: + case codemaker::UnoType::SORT_LONG: + case codemaker::UnoType::SORT_UNSIGNED_LONG: + case codemaker::UnoType::SORT_HYPER: + case codemaker::UnoType::SORT_UNSIGNED_HYPER: + case codemaker::UnoType::SORT_FLOAT: + case codemaker::UnoType::SORT_DOUBLE: + case codemaker::UnoType::SORT_CHAR: + out << "0"; + break; + + case codemaker::UnoType::SORT_COMPLEX: + switch (m_typeMgr.getTypeClass(t)) { + case RT_TYPE_ENUM: + { + typereg::Reader reader(m_typeMgr.getTypeReader(t)); + OSL_ASSERT(reader.isValid()); + out << scopedCppName(t) << "_" + << rtl::OUStringToOString( + reader.getFieldName(0), + RTL_TEXTENCODING_UTF8); + break; + } + + case RT_TYPE_TYPEDEF: + t = resolveTypedefs(t); + continue; + + default: + break; + } + break; + + default: + break; + } + } + break; + } + } + out << ")"; +} + +void CppuType::dumpGetCppuType(FileStream & out) { + if (m_typeName.equals("com/sun/star/uno/XInterface")) { + out << indent() + << ("inline ::com::sun::star::uno::Type const & SAL_CALL" + " getCppuType("); + dumpType(out, m_typeName, true, false); + out << " *) SAL_THROW(()) {\n"; + inc(); + out << indent() + << ("return ::cppu::UnoType< ::com::sun::star::uno::XInterface" + " >::get();\n"); + dec(); + out << indent() << "}\n"; + } else if (m_typeName.equals("com/sun/star/uno/Exception")) { + out << indent() + << ("inline ::com::sun::star::uno::Type const & SAL_CALL" + " getCppuType("); + dumpType(out, m_typeName, true, false); + out << " *) SAL_THROW(()) {\n"; + inc(); + out << indent() + << ("return ::cppu::UnoType< ::com::sun::star::uno::Exception" + " >::get();\n"); + dec(); + out << indent() << "}\n"; + } else if (m_cppuTypeLeak) { + dumpLightGetCppuType(out); + } else if (m_cppuTypeDynamic) { + dumpNormalGetCppuType(out); + } else { + dumpComprehensiveGetCppuType(out); + } +} + +void CppuType::dumpLightGetCppuType(FileStream& o) +{ + dumpGetCppuTypePreamble(o); + o << indent() + << "static typelib_TypeDescriptionReference * the_type = 0;\n"; + + o << indent() << "if ( !the_type )\n" << indent() << "{\n"; + inc(); + o << indent() << "typelib_static_type_init( &the_type, " + << getTypeClass(m_typeName, sal_True) << ", \"" << m_typeName.replace('/', '.') << "\" );\n"; + dec(); + o << indent() << "}\n"; + o << indent() + << ("return * reinterpret_cast< ::com::sun::star::uno::Type * >(" + " &the_type );\n"); + dumpGetCppuTypePostamble(o); +} + +void CppuType::dumpNormalGetCppuType(FileStream& o) +{ + dumpGetCppuTypePreamble(o); + + o << indent() + << "static typelib_TypeDescriptionReference * the_type = 0;\n"; + + o << indent() << "if ( !the_type )\n" << indent() << "{\n"; + inc(); + + OString superType; + if (m_reader.getSuperTypeCount() >= 1) { + superType = rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); + } + sal_Bool bIsBaseException = sal_False; + if (superType.getLength() > 0) + { + if ( superType.equals("com/sun/star/uno/Exception") ) + { + bIsBaseException = sal_True; + } else + { + o << indent() << "const ::com::sun::star::uno::Type& rBaseType = ::cppu::UnoType< "; + dumpType(o, superType, true, false, false, true); + o << " >::get();\n\n"; + } + } + + sal_uInt32 count = getMemberCount(); + if (count) + { + o << indent() << "typelib_TypeDescriptionReference * aMemberRefs[" << count << "];\n"; + + sal_uInt16 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldType, fieldName; + OString scope = m_typeName.replace('/', '.'); + OString modFieldType; + StringSet generatedTypeSet; + StringSet::iterator findIter; + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + fieldType = checkRealBaseType( + rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8), + sal_True); + + modFieldType = typeToIdentifier(fieldType); + + findIter = generatedTypeSet.find(fieldType); + if ( findIter == generatedTypeSet.end() ) + { + generatedTypeSet.insert(fieldType); + o << indent() << "const ::com::sun::star::uno::Type& rMemberType_" + << modFieldType/*i*/ << " = ::cppu::UnoType< "; + dumpType(o, fieldType, false, false, false, true); + o << " >::get();\n"; + } + + o << indent() << "aMemberRefs[" << i << "] = rMemberType_" + << modFieldType/*i*/ << ".getTypeLibType();\n"; + } + o << "\n"; + } + + o << indent() << "typelib_static_compound_type_init( &the_type, " + << getTypeClass(m_typeName, sal_True) << ", \"" << m_typeName.replace('/', '.') << "\", "; + if ( superType.getLength() > 0 || bIsBaseException ) + { + if ( bIsBaseException ) + { + o << "* ::typelib_static_type_getByTypeClass( typelib_TypeClass_EXCEPTION ), " + << count << ", "; + } else + { + o << "rBaseType.getTypeLibType(), " << count << ", "; + } + } else + { + o << "0, " << count << ", "; + } + + if (count) + { + o << " aMemberRefs );\n"; + } else + { + o << " 0 );\n"; + } + dec(); + o << indent() << "}\n"; + o << indent() + << ("return * reinterpret_cast< const ::com::sun::star::uno::Type * >(" + " &the_type );\n"); + + dumpGetCppuTypePostamble(o); +} + +void CppuType::dumpComprehensiveGetCppuType(FileStream& o) +{ + dumpGetCppuTypePreamble(o); + + o << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n"; + + o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; + inc(); + o << indent() << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n"; + + o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; + inc(); + o << indent() << "::rtl::OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM(\"" + << m_typeName.replace('/', '.') << "\") );\n\n"; + + o << indent() << "// Start inline typedescription generation\n" + << indent() << "typelib_TypeDescription * pTD = 0;\n"; + + OString superType; + if (m_reader.getSuperTypeCount() >= 1) { + superType = rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); + } + if (superType.getLength() > 0) { + o << indent() + << "const ::com::sun::star::uno::Type& rSuperType = ::cppu::UnoType< "; + dumpType(o, superType, false, false, false, true); + o << " >::get();\n"; + } + + dumpCppuGetTypeMemberDecl(o, CPPUTYPEDECL_ALLTYPES); + + sal_uInt32 count = getMemberCount(); + if (count) + { + o << "\n" << indent() << "typelib_CompoundMember_Init aMembers[" + << count << "];\n"; + + sal_uInt16 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldType, fieldName; + OString scope = m_typeName.replace('/', '.'); + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) { + continue; + } + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + fieldType = checkRealBaseType( + rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8), + sal_True); + + o << indent() << "::rtl::OUString sMemberType" << i + << "( RTL_CONSTASCII_USTRINGPARAM(\"" + << fieldType.replace('/', '.') << "\") );\n"; + o << indent() << "::rtl::OUString sMemberName" << i + << "( RTL_CONSTASCII_USTRINGPARAM(\""; + o << fieldName << "\") );\n"; + o << indent() << "aMembers[" << i << "].eTypeClass = " + << "(typelib_TypeClass)" << getTypeClass(fieldType) << ";\n" + << indent() << "aMembers[" << i << "].pTypeName = sMemberType" + << i << ".pData;\n" + << indent() << "aMembers[" << i << "].pMemberName = sMemberName" + << i << ".pData;\n"; + } + } + + o << "\n" << indent() << "typelib_typedescription_new(\n"; + inc(); + o << indent() << "&pTD,\n" << indent() << "(typelib_TypeClass)" + << getTypeClass() << ", sTypeName.pData,\n"; + + if (superType.getLength() > 0) { + o << indent() << "rSuperType.getTypeLibType(),\n"; + } else { + o << indent() << "0,\n"; + } + + if ( count ) { + o << indent() << count << ",\n" << indent() << "aMembers );\n\n"; + } else { + o << indent() << count << ",\n" << indent() << "0 );\n\n"; + } + + dec(); + o << indent() + << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD" + " );\n\n"); + + o << indent() << "typelib_typedescription_release( pTD );\n" + << indent() << "// End inline typedescription generation\n\n"; + + o << indent() << "static ::com::sun::star::uno::Type the_staticType( " + << getTypeClass(m_typeName) << ", sTypeName );\n"; + o << indent() << "the_pType = &the_staticType;\n"; + + dec(); + o << indent() << "}\n"; + dec(); + o << indent() << "}\n\n"; + o << indent() << "return *the_pType;\n"; + dumpGetCppuTypePostamble(o); +} + +void CppuType::dumpCppuGetTypeMemberDecl(FileStream& o, CppuTypeDecl eDeclFlag) +{ + sal_uInt16 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + + StringSet aFinishedTypes; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID + || (access & RT_ACCESS_PARAMETERIZED_TYPE) != 0) + continue; + + rtl::OString typeName( + rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); + if (aFinishedTypes.count(typeName) == 0) + { + aFinishedTypes.insert(typeName); + dumpCppuGetType(o, typeName, sal_True, eDeclFlag); + } + } +} + +IdentifierTranslationMode CppuType::isGlobal() const { + if ( m_typeName.indexOf('/') < 0 ) + return ITM_GLOBAL; + else + return ITM_NONGLOBAL; +} + +sal_uInt32 CppuType::getMemberCount() +{ + sal_uInt16 count = m_reader.getMethodCount(); + + sal_uInt16 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + count++; + } + return count; +} + +sal_uInt32 CppuType::checkInheritedMemberCount(const typereg::Reader* pReader) +{ + sal_Bool bSelfCheck = sal_True; + if (!pReader) + { + bSelfCheck = sal_False; + pReader = &m_reader; + } + + sal_uInt32 count = 0; + OString superType; + if (pReader->getSuperTypeCount() >= 1) { + superType = rtl::OUStringToOString( + pReader->getSuperTypeName(0), RTL_TEXTENCODING_UTF8); + } + if (superType.getLength() > 0) + { + typereg::Reader aSuperReader(m_typeMgr.getTypeReader(superType)); + if ( aSuperReader.isValid() ) + { + count = checkInheritedMemberCount(&aSuperReader); + } + } + + if (bSelfCheck) + { + count += pReader->getMethodCount(); + sal_uInt16 fieldCount = pReader->getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = pReader->getFieldFlags(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + { + count++; + } + } + } + + return count; +} + +sal_uInt32 CppuType::getInheritedMemberCount() +{ + if (m_inheritedMemberCount == 0) + { + m_inheritedMemberCount = checkInheritedMemberCount(0); + } + + return m_inheritedMemberCount; +} + +OString CppuType::getTypeClass(const OString& type, sal_Bool bCStyle) +{ + OString typeName = (type.getLength() > 0 ? type : m_typeName); + RTTypeClass rtTypeClass = RT_TYPE_INVALID; + + if (type.getLength() > 0) + { + typeName = type; + rtTypeClass = m_typeMgr.getTypeClass(typeName); + } else + { + typeName = m_typeName; + rtTypeClass = m_reader.getTypeClass(); + } + + if (codemaker::UnoType::isSequenceType(typeName)) + return bCStyle ? "typelib_TypeClass_SEQUENCE" : "::com::sun::star::uno::TypeClass_SEQUENCE"; + + switch (rtTypeClass) + { + case RT_TYPE_INTERFACE: + return bCStyle ? "typelib_TypeClass_INTERFACE" : "::com::sun::star::uno::TypeClass_INTERFACE"; + case RT_TYPE_MODULE: + return bCStyle ? "typelib_TypeClass_MODULE" : "::com::sun::star::uno::TypeClass_MODULE"; + case RT_TYPE_STRUCT: + return bCStyle ? "typelib_TypeClass_STRUCT" : "::com::sun::star::uno::TypeClass_STRUCT"; + case RT_TYPE_ENUM: + return bCStyle ? "typelib_TypeClass_ENUM" : "::com::sun::star::uno::TypeClass_ENUM"; + case RT_TYPE_EXCEPTION: + return bCStyle ? "typelib_TypeClass_EXCEPTION" : "::com::sun::star::uno::TypeClass_EXCEPTION"; + case RT_TYPE_TYPEDEF: + { + OString realType = checkRealBaseType( typeName ); + return getTypeClass( realType, bCStyle ); + } + case RT_TYPE_SERVICE: + return bCStyle ? "typelib_TypeClass_SERVICE" : "::com::sun::star::uno::TypeClass_SERVICE"; + case RT_TYPE_INVALID: + { + if (type.equals("long")) + return bCStyle ? "typelib_TypeClass_LONG" : "::com::sun::star::uno::TypeClass_LONG"; + if (type.equals("short")) + return bCStyle ? "typelib_TypeClass_SHORT" : "::com::sun::star::uno::TypeClass_SHORT"; + if (type.equals("hyper")) + return bCStyle ? "typelib_TypeClass_HYPER" : "::com::sun::star::uno::TypeClass_HYPER"; + if (type.equals("string")) + return bCStyle ? "typelib_TypeClass_STRING" : "::com::sun::star::uno::TypeClass_STRING"; + if (type.equals("boolean")) + return bCStyle ? "typelib_TypeClass_BOOLEAN" : "::com::sun::star::uno::TypeClass_BOOLEAN"; + if (type.equals("char")) + return bCStyle ? "typelib_TypeClass_CHAR" : "::com::sun::star::uno::TypeClass_CHAR"; + if (type.equals("byte")) + return bCStyle ? "typelib_TypeClass_BYTE" : "::com::sun::star::uno::TypeClass_BYTE"; + if (type.equals("any")) + return bCStyle ? "typelib_TypeClass_ANY" : "::com::sun::star::uno::TypeClass_ANY"; + if (type.equals("type")) + return bCStyle ? "typelib_TypeClass_TYPE" : "::com::sun::star::uno::TypeClass_TYPE"; + if (type.equals("float")) + return bCStyle ? "typelib_TypeClass_FLOAT" : "::com::sun::star::uno::TypeClass_FLOAT"; + if (type.equals("double")) + return bCStyle ? "typelib_TypeClass_DOUBLE" : "::com::sun::star::uno::TypeClass_DOUBLE"; + if (type.equals("void")) + return bCStyle ? "typelib_TypeClass_VOID" : "::com::sun::star::uno::TypeClass_VOID"; + if (type.equals("unsigned long")) + return bCStyle ? "typelib_TypeClass_UNSIGNED_LONG" : "::com::sun::star::uno::TypeClass_UNSIGNED_LONG"; + if (type.equals("unsigned short")) + return bCStyle ? "typelib_TypeClass_UNSIGNED_SHORT" : "::com::sun::star::uno::TypeClass_UNSIGNED_SHORT"; + if (type.equals("unsigned hyper")) + return bCStyle ? "typelib_TypeClass_UNSIGNED_HYPER" : "::com::sun::star::uno::TypeClass_UNSIGNED_HYPER"; + } + break; + default: + OSL_ASSERT(false); + break; + } + + return bCStyle ? "typelib_TypeClass_UNKNOWN" : "::com::sun::star::uno::TypeClass_UNKNOWN"; +} + +void CppuType::dumpType(FileStream& o, const OString& type, + bool bConst, bool bRef, bool bNative, bool cppuUnoType) + const throw( CannotDumpException ) +{ + sal_Int32 seqNum; + std::vector< rtl::OString > args; + rtl::OString relType( + codemaker::UnoType::decompose( + checkRealBaseType(type, true), &seqNum, &args)); + + RTTypeClass typeClass = m_typeMgr.getTypeClass(relType); + + if (bConst) o << "const "; + + {for (sal_Int32 i = 0; i < seqNum; ++i) { + if (cppuUnoType) + o << "::cppu::UnoSequenceType< "; + else + o << "::com::sun::star::uno::Sequence< "; + }} + + switch (typeClass) + { + case RT_TYPE_INTERFACE: + if (bNative) + o << scopedCppName(relType); + else + o << "::com::sun::star::uno::Reference< " + << scopedCppName(relType) << " >"; + break; + case RT_TYPE_INVALID: + { + OString tmp(translateSimpleUnoType(relType, cppuUnoType)); + if (tmp.getLength() > 0) + { + o << tmp; + } else + throw CannotDumpException("Unknown type '" + relType + + "', incomplete type library."); + } + break; + case RT_TYPE_STRUCT: + case RT_TYPE_ENUM: + case RT_TYPE_TYPEDEF: + case RT_TYPE_EXCEPTION: + { + o << scopedCppName(relType); + if (!args.empty()) { + o << "< "; + for (std::vector< rtl::OString >::iterator i(args.begin()); + i != args.end(); ++i) + { + if (i != args.begin()) { + o << ", "; + } + dumpType(o, *i); + } + o << " >"; + } + break; + } + default: + OSL_ASSERT(false); + break; + } + + {for (sal_Int32 i = 0; i < seqNum; ++i) { + o << " >"; + }} + + if (bRef) o << "&"; +} + +void CppuType::dumpCppuGetType(FileStream& o, const OString& type, sal_Bool bDecl, CppuTypeDecl eDeclFlag) +{ + rtl::OString relType( + codemaker::UnoType::decompose(checkRealBaseType(type, true))); + + if (eDeclFlag == CPPUTYPEDECL_ONLYINTERFACES) + { + if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) + { + o << indent() << "::cppu::UnoType< "; + dumpType(o, type, false, false, false, true); + o << " >::get()"; + + if (bDecl) + o << ";\n"; + } + } else + { + if (codemaker::UnoType::getSort(type) + != codemaker::UnoType::SORT_COMPLEX) + { + return; + } else + { + if (eDeclFlag == CPPUTYPEDECL_NOINTERFACES && + m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) + return; + +// if (m_typeMgr.getTypeClass(type) == RT_TYPE_TYPEDEF) +// { +// o << indent() << "get_" << type.replace('/', '_') << "_Type()"; +// } else +// { + o << indent() << "::cppu::UnoType< "; + dumpType(o, type, false, false, false, true); + o << " >::get()"; +// } + } + if (bDecl) + o << ";\n"; + } +} + +OString CppuType::typeToIdentifier(const OString& type) +{ + sal_Int32 seqNum; + rtl::OString relType(codemaker::UnoType::decompose(type, &seqNum)); + OString sIdentifier; + + while( seqNum > 0 ) + { + sIdentifier += OString("seq"); + + if ( --seqNum == 0 ) + { + sIdentifier += OString("_"); + } + } + + sIdentifier += relType.replace( + ((codemaker::UnoType::getSort(relType) + == codemaker::UnoType::SORT_COMPLEX) + ? '/' : ' '), + '_'); + + // TODO: find better solution to create an identifier + sIdentifier = sIdentifier.replace('<', '_'); + sIdentifier = sIdentifier.replace('>', '_'); + sIdentifier = sIdentifier.replace(',', '_'); + + return sIdentifier; +} + +bool CppuType::passByReference(rtl::OString const & unoType) { + rtl::OString type(resolveTypedefs(unoType)); + switch (codemaker::UnoType::getSort(type)) { + default: + return false; + + case codemaker::UnoType::SORT_STRING: + case codemaker::UnoType::SORT_TYPE: + case codemaker::UnoType::SORT_ANY: + return true; + + case codemaker::UnoType::SORT_COMPLEX: + return m_typeMgr.getTypeClass(type) != RT_TYPE_ENUM; + } +} + +OString CppuType::resolveTypedefs(const OString& type) const +{ + OString baseType(type); + + RegistryKey key; + RTTypeClass typeClass; + sal_Bool isTypeDef = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); + typereg::Reader reader; + + while (isTypeDef) + { + reader = m_typeMgr.getTypeReader(baseType); + + if (reader.isValid()) + { + typeClass = reader.getTypeClass(); + + if (typeClass == RT_TYPE_TYPEDEF) + baseType = rtl::OUStringToOString( + reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); + else + isTypeDef = sal_False; + } else + { + break; + } + } + + return baseType; +} + +OString CppuType::checkRealBaseType(const OString& type, sal_Bool bResolveTypeOnly) const +{ + sal_Int32 rank; + rtl::OString baseType(codemaker::UnoType::decompose(type, &rank)); + + RegistryKey key; + RTTypeClass typeClass; + sal_Bool mustBeChecked = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); + typereg::Reader reader; + + while (mustBeChecked) + { + reader = m_typeMgr.getTypeReader(baseType); + + if (reader.isValid()) + { + typeClass = reader.getTypeClass(); + + if (typeClass == RT_TYPE_TYPEDEF) + { + sal_Int32 n; + baseType = codemaker::UnoType::decompose( + rtl::OUStringToOString( + reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8), + &n); + OSL_ASSERT(n <= SAL_MAX_INT32 - rank); //TODO + rank += n; + } else + mustBeChecked = sal_False; + } else + { + break; + } + } + + if (bResolveTypeOnly) { + rtl::OStringBuffer buf; + for (sal_Int32 i = 0; i < rank; ++i) { + buf.append(RTL_CONSTASCII_STRINGPARAM("[]")); + } + baseType = buf.makeStringAndClear() + baseType; + } + + return baseType; +} + +void CppuType::dumpConstantValue(FileStream& o, sal_uInt16 index) +{ + RTConstValue constValue = m_reader.getFieldValue(index); + + switch (constValue.m_type) + { + case RT_TYPE_NONE: + break; + case RT_TYPE_BOOL: + if (constValue.m_value.aBool) + o << "sal_True"; + else + o << "sal_False"; + break; + case RT_TYPE_BYTE: + o << "(sal_Int8)" + << sal::static_int_cast< sal_Int8 >(constValue.m_value.aByte); + break; + case RT_TYPE_INT16: + o << "(sal_Int16)" << constValue.m_value.aShort; + break; + case RT_TYPE_UINT16: + o << "(sal_uInt16)" << constValue.m_value.aUShort; + break; + case RT_TYPE_INT32: + // Avoid C++ compiler warnings about (un)signedness of literal + // -2^31: + if (constValue.m_value.aLong == SAL_MIN_INT32) { + o << "SAL_MIN_INT32"; + } else { + o << "(sal_Int32)" << constValue.m_value.aLong; + } + break; + case RT_TYPE_UINT32: + o << "(sal_uInt32)" + << OString::valueOf( + static_cast< sal_Int64 >(constValue.m_value.aULong)).getStr() + << "U"; + break; + case RT_TYPE_INT64: + // Avoid C++ compiler warnings about (un)signedness of literal + // -2^63: + if (constValue.m_value.aHyper == SAL_MIN_INT64) { + o << "SAL_MIN_INT64"; + } else { + ::rtl::OString tmp(OString::valueOf(constValue.m_value.aHyper)); + o << "(sal_Int64) SAL_CONST_INT64(" << tmp.getStr() << ")"; + } + break; + case RT_TYPE_UINT64: + { + o << "SAL_CONST_UINT64("; + sal_uInt64 n = constValue.m_value.aUHyper; + if (n == 0) { + o << "0"; + } else { + std::vector< char > buf; + for (; n != 0; n /= 10) { + buf.push_back('0' + static_cast< char >(n % 10)); + } + for (std::vector< char >::reverse_iterator i(buf.rbegin()); + i != buf.rend(); ++i) + { + o << rtl::OString::valueOf(*i).getStr(); + } + } + o << ")"; + } + break; + case RT_TYPE_FLOAT: + { + ::rtl::OString tmp( OString::valueOf(constValue.m_value.aFloat) ); + o << "(float)" << tmp.getStr(); + } + break; + case RT_TYPE_DOUBLE: + { + ::rtl::OString tmp( OString::valueOf(constValue.m_value.aDouble) ); + o << "(double)" << tmp.getStr(); + } + break; + case RT_TYPE_STRING: + { + ::rtl::OUString aUStr(constValue.m_value.aString); + ::rtl::OString aStr = ::rtl::OUStringToOString(aUStr, RTL_TEXTENCODING_ASCII_US); + o << "::rtl::OUString::createFromAscii(\"" << aStr.getStr() << "\")"; + } + break; + } +} + +void CppuType::inc(sal_Int32 num) +{ + m_indentLength += num; +} + +void CppuType::dec(sal_Int32 num) +{ + m_indentLength = std::max< sal_Int32 >(m_indentLength - num, 0); +} + +OString CppuType::indent() const +{ + OStringBuffer tmp(m_indentLength); + + for (sal_Int32 i=0; i < m_indentLength; i++) + { + tmp.append(' '); + } + return tmp.makeStringAndClear(); +} + +//************************************************************************* +// InterfaceType +//************************************************************************* +InterfaceType::InterfaceType(typereg::Reader& typeReader, + const OString& typeName, + const TypeManager& typeMgr) + : CppuType(typeReader, typeName, typeMgr) +{ + m_inheritedMemberCount = 0; + m_hasAttributes = sal_False; + m_hasMethods = sal_False; +} + +InterfaceType::~InterfaceType() +{ + +} + +sal_Bool InterfaceType::dumpHFile( + FileStream& o, codemaker::cppumaker::Includes & includes) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "HDL")); + o << "\n"; + + addDefaultHIncludes(includes); + if (m_reader.getMethodCount() != 0) { + includes.add("com/sun/star/uno/RuntimeException"); + } + includes.dump(o, 0); + o << ("\nnamespace com { namespace sun { namespace star { namespace uno {\n" + "class Type;\n} } } }\n\n"); + + if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { + o << "\n"; + } + dumpDeclaration(o); + if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { + o << "\n"; + } + + o << "\ninline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( "; + dumpType(o, m_typeName, sal_True, sal_False); + o << "* ) SAL_THROW( () );\n\n"; + + o << "#endif // "<< headerDefine << "\n"; + return sal_True; +} + +sal_Bool InterfaceType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ +// rtl::OString cppName(translateUnoToCppIdentifier( +// m_name, "interface", ITM_KEYWORDSONLY, &m_name)); + +// o << "\nclass SAL_NO_VTABLE " << cppName; + o << "\nclass SAL_NO_VTABLE " << m_name; + + for (sal_Int16 i = 0; i < m_reader.getSuperTypeCount(); ++i) { + o << (i == 0 ? " :" : ",") << " public " + << scopedCppName(rtl::OUStringToOString( + m_reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8)); + } + + o << "\n{\npublic:\n"; + + inc(); + + dumpAttributes(o); + dumpMethods(o); + + o << "\n" << indent() + << ("static inline ::com::sun::star::uno::Type const & SAL_CALL" + " static_type(void * = 0);\n"); + + dec(); + o << "};\n\n"; + + return sal_True; +} + +sal_Bool InterfaceType::dumpHxxFile( + FileStream& o, codemaker::cppumaker::Includes & includes) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "HPP")); + o << "\n"; + + addDefaultHxxIncludes(includes); + includes.dump(o, &m_typeName); + o << "\n"; + + dumpGetCppuType(o); + +// rtl::OString cppName(translateUnoToCppIdentifier( +// m_name, "interface", ITM_KEYWORDSONLY, &m_name)); + + o << "\n::com::sun::star::uno::Type const & " + << scopedCppName(m_typeName) + << "::static_type(void *) {\n"; + inc(); + o << indent() << "return ::getCppuType(static_cast< "; + dumpType(o, m_typeName); + o << " * >(0));\n"; + dec(); + o << "}\n"; + + o << "\n#endif // "<< headerDefine << "\n"; + return sal_True; +} + +void InterfaceType::dumpAttributes(FileStream& o) +{ + sal_uInt16 fieldCount = m_reader.getFieldCount(); + sal_Bool first=sal_True; + + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + rtl::OUString name(m_reader.getFieldName(i)); + fieldName = rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8); + fieldType = rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); + + if (first) + { + first = sal_False; + o << "\n" << indent() << "// Attributes\n"; + } + + o << indent() << "virtual "; + dumpType(o, fieldType); + o << " SAL_CALL get" << fieldName << "()"; + dumpAttributeExceptionSpecification(o, name, RT_MODE_ATTRIBUTE_GET); + o << " = 0;\n"; + + if ((access & RT_ACCESS_READONLY) == 0) + { + bool byRef = passByReference(fieldType); + o << indent() << "virtual void SAL_CALL set" << fieldName << "( "; + dumpType(o, fieldType, byRef, byRef); + o << " _" << fieldName.toAsciiLowerCase() << " )"; + dumpAttributeExceptionSpecification(o, name, RT_MODE_ATTRIBUTE_SET); + o << " = 0;\n"; + } + } +} + +void InterfaceType::dumpMethods(FileStream& o) +{ + sal_uInt16 methodCount = m_reader.getMethodCount(); + sal_Bool first=sal_True; + + OString methodName, returnType, paramType, paramName; + sal_uInt16 paramCount = 0; + RTMethodMode methodMode = RT_MODE_INVALID; + RTParamMode paramMode = RT_PARAM_INVALID; + + sal_Bool bRef = sal_False; + sal_Bool bConst = sal_False; + sal_Bool bWithRunTimeExcp = sal_True; + + for (sal_uInt16 i=0; i < methodCount; i++) + { + methodMode = m_reader.getMethodFlags(i); + if (methodMode == RT_MODE_ATTRIBUTE_GET + || methodMode == RT_MODE_ATTRIBUTE_SET) + { + continue; + } + + methodName = rtl::OUStringToOString( + m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8); + returnType = rtl::OUStringToOString( + m_reader.getMethodReturnTypeName(i), RTL_TEXTENCODING_UTF8); + paramCount = m_reader.getMethodParameterCount(i); + + if ( methodName.equals("acquire") || methodName.equals("release") ) + { + bWithRunTimeExcp = sal_False; + } + + if (first) + { + first = sal_False; + o << "\n" << indent() << "// Methods\n"; + } + + o << indent() << "virtual "; + dumpType(o, returnType); + o << " SAL_CALL " << methodName << "( "; + for (sal_uInt16 j=0; j < paramCount; j++) + { + paramName = rtl::OUStringToOString( + m_reader.getMethodParameterName(i, j), RTL_TEXTENCODING_UTF8); + paramType = rtl::OUStringToOString( + m_reader.getMethodParameterTypeName(i, j), + RTL_TEXTENCODING_UTF8); + paramMode = m_reader.getMethodParameterFlags(i, j); + + switch (paramMode) + { + case RT_PARAM_IN: + bConst = passByReference(paramType); + bRef = bConst; + break; + case RT_PARAM_OUT: + case RT_PARAM_INOUT: + bConst = sal_False; + bRef = sal_True; + break; + default: + break; + } + + dumpType(o, paramType, bConst, bRef); +// o << " " << translateUnoToCppIdentifier( +// paramName, "param", ITM_KEYWORDSONLY, NULL); + o << " " << paramName; + + if (j+1 < (sal_uInt16)paramCount) o << ", "; + } + o << " )"; + dumpExceptionSpecification(o, i, bWithRunTimeExcp); + o << " = 0;\n"; + } +} + +void InterfaceType::dumpNormalGetCppuType(FileStream& o) +{ + dumpGetCppuTypePreamble(o); + + o << indent() + << "static typelib_TypeDescriptionReference * the_type = 0;\n"; + + o << indent() << "if ( !the_type )\n" << indent() << "{\n"; + inc(); + sal_Int16 nBases = m_reader.getSuperTypeCount(); + OSL_ASSERT(nBases > 0); + if (nBases == 1 + && m_reader.getSuperTypeName(0).equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XInterface"))) + { + nBases = 0; + } + if (nBases > 0) { + o << indent() << "typelib_TypeDescriptionReference * aSuperTypes[" + << nBases << "];\n"; + for (sal_Int16 i = 0; i < nBases; ++i) { + o << indent() << "aSuperTypes[" << i << "] = ::cppu::UnoType< "; + dumpType( + o, + rtl::OUStringToOString( + m_reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8), + true, false, false, true); + o << " >::get().getTypeLibType();\n"; + } + } + + o << indent() << "typelib_static_mi_interface_type_init( &the_type, \"" + << m_typeName.replace('/', '.') << "\", " << nBases << ", "; + + if ( nBases > 0 ) + { + o << "aSuperTypes );\n"; + } else + { + o << "0 );\n"; + } + + dec(); + o << indent() << "}\n"; + o << indent() + << ("return * reinterpret_cast< ::com::sun::star::uno::Type * >(" + " &the_type );\n"); + + dumpGetCppuTypePostamble(o); +} + +void InterfaceType::dumpComprehensiveGetCppuType(FileStream& o) +{ + dumpGetCppuTypePreamble(o); + + o << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n"; + + o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; + inc(); + o << indent() << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n"; + + o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; + inc(); + o << indent() << "::rtl::OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM(\"" + << m_typeName.replace('/', '.') << "\") );\n\n"; + + o << indent() << "// Start inline typedescription generation\n" + << indent() << "typelib_InterfaceTypeDescription * pTD = 0;\n\n"; + + OSL_ASSERT(m_reader.getSuperTypeCount() > 0); + o << indent() << "typelib_TypeDescriptionReference * aSuperTypes[" + << m_reader.getSuperTypeCount() << "];\n"; + for (sal_Int16 i = 0; i < m_reader.getSuperTypeCount(); ++i) { + o << indent() << "aSuperTypes[" << i << "] = ::cppu::UnoType< "; + dumpType( + o, + rtl::OUStringToOString( + m_reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8), + false, false, false, true); + o << " >::get().getTypeLibType();\n"; + } + + sal_uInt32 count = getMemberCount(); + if (count) + { + o << indent() << "typelib_TypeDescriptionReference * pMembers[" << count + << "] = { "; + for (sal_uInt32 i = 0; i < count; i++) + { + o << "0"; + if (i+1 < count) { + o << ","; + } else { + o << " };\n"; + } + } + + sal_uInt32 index = 0; + dumpCppuAttributeRefs(o, index); + dumpCppuMethodRefs(o, index); + } + + o << "\n" << indent() << "typelib_typedescription_newMIInterface(\n"; + inc(); + o << indent() << "&pTD,\n" << indent() << "sTypeName.pData, "; + + o << "0x00000000, 0x0000, 0x0000, 0x00000000, 0x00000000,\n"; // UIK + + o << indent() << m_reader.getSuperTypeCount() << ", aSuperTypes,\n"; + + if ( count ) { + o << indent() << count << ",\n" << indent() << "pMembers );\n\n"; + } else { + o << indent() << count << ",\n" << indent() << "0 );\n\n"; + } + dec(); + + o << indent() + << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD" + " );\n"); + if ( count ) + { + for (sal_uInt16 i=0; i < count; i++) + { + o << indent() + << "typelib_typedescriptionreference_release( pMembers[" << i + << "] );\n"; + } + } + o << indent() + << ("typelib_typedescription_release( (typelib_TypeDescription*)pTD" + " );\n\n"); + + o << indent() << "static ::com::sun::star::uno::Type the_staticType( " + << getTypeClass(m_typeName) << ", sTypeName );\n"; + o << indent() << "the_pType = &the_staticType;\n"; + + StringSet aTypes; + // type for RuntimeException is always needed + OString sRunTimeExceptionType("com/sun/star/uno/RuntimeException"); + aTypes.insert(sRunTimeExceptionType); + dumpCppuGetType(o, sRunTimeExceptionType, sal_True, CPPUTYPEDECL_ALLTYPES); + + dumpAttributesCppuDecl(o, &aTypes, CPPUTYPEDECL_ALLTYPES); + dumpMethodsCppuDecl(o, &aTypes, CPPUTYPEDECL_ALLTYPES); + + if (count) + { + sal_uInt32 index = getInheritedMemberCount(); + dumpCppuAttributes(o, index); + dumpCppuMethods(o, index); + } + + o << indent() << "// End inline typedescription generation\n"; + + dec(); + o << indent() << "}\n"; + dec(); + o << indent() << "}\n\n" + << indent() << "return *the_pType;\n"; + + dumpGetCppuTypePostamble(o); +} + +void InterfaceType::dumpCppuAttributeRefs(FileStream& o, sal_uInt32& index) +{ + sal_uInt16 fieldCount = m_reader.getFieldCount(); + + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString scope = m_typeName.replace('/', '.'); + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + + o << indent() << "::rtl::OUString sAttributeName" << i << "( RTL_CONSTASCII_USTRINGPARAM(\"" + << scope.replace('/', '.') << "::" << fieldName << "\") );\n"; + o << indent() << "typelib_typedescriptionreference_new( &pMembers[" + << index << "],\n"; + inc(38); + o << indent() << "(typelib_TypeClass)::com::sun::star::uno::TypeClass_INTERFACE_ATTRIBUTE,\n" + << indent() << "sAttributeName" << i << ".pData );\n"; + dec(38); + index++; + } +} + +void InterfaceType::dumpCppuMethodRefs(FileStream& o, sal_uInt32& index) +{ + sal_uInt16 methodCount = m_reader.getMethodCount(); + OString methodName; + OString scope = m_typeName.replace('/', '.'); + + for (sal_uInt16 i = 0; i < methodCount; i++) + { + RTMethodMode flags = m_reader.getMethodFlags(i); + if (flags == RT_MODE_ATTRIBUTE_GET || flags == RT_MODE_ATTRIBUTE_SET) { + continue; + } + + methodName = rtl::OUStringToOString( + m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8); + + o << indent() << "::rtl::OUString sMethodName" << i << "( RTL_CONSTASCII_USTRINGPARAM(\"" + << scope.replace('/', '.') << "::" << methodName << "\") );\n"; + o << indent() << "typelib_typedescriptionreference_new( &pMembers[" + << index << "],\n"; + inc(38); + o << indent() << "(typelib_TypeClass)::com::sun::star::uno::TypeClass_INTERFACE_METHOD,\n" + << indent() << "sMethodName" << i << ".pData );\n"; + dec(38); + index++; + } +} + +sal_uInt32 InterfaceType::getMemberCount() { + sal_uInt16 count = 0; + sal_uInt16 methodCount = m_reader.getMethodCount(); + {for (sal_uInt16 i = 0; i < methodCount; ++i) { + RTMethodMode flags = m_reader.getMethodFlags(i); + if (flags != RT_MODE_ATTRIBUTE_GET && flags != RT_MODE_ATTRIBUTE_SET) { + m_hasMethods = true; + ++count; + } + }} + sal_uInt16 fieldCount = m_reader.getFieldCount(); + {for (sal_uInt16 i = 0; i < fieldCount; ++i) { + RTFieldAccess flags = m_reader.getFieldFlags(i); + if (flags != RT_ACCESS_CONST && flags != RT_ACCESS_INVALID) { + m_hasAttributes = true; + ++count; + } + }} + return count; +} + +namespace { + +class BaseOffset { +public: + BaseOffset(TypeManager const & theManager, typereg::Reader const & reader); + + sal_Int32 get() const { return offset; } + +private: + void calculateBases(typereg::Reader const & reader); + + void calculate(typereg::Reader const & reader); + + TypeManager const & manager; + std::set< rtl::OString > set; + sal_Int32 offset; +}; + +BaseOffset::BaseOffset( + TypeManager const & theManager, typereg::Reader const & reader): + manager(theManager) +{ + offset = 0; + calculateBases(reader); +} + +void BaseOffset::calculateBases(typereg::Reader const & reader) { + for (sal_Int16 i = 0; i < reader.getSuperTypeCount(); ++i) { + typereg::Reader super( + manager.getTypeReader( + rtl::OUStringToOString( + reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8))); + if (super.isValid()) { + calculate(super); + } + } +} + +void BaseOffset::calculate(typereg::Reader const & reader) { + if (set.insert( + rtl::OUStringToOString(reader.getTypeName(), RTL_TEXTENCODING_UTF8)) + .second) + { + calculateBases(reader); + {for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) { + RTMethodMode flags = reader.getMethodFlags(i); + if (flags != RT_MODE_ATTRIBUTE_GET + && flags != RT_MODE_ATTRIBUTE_SET) + { + ++offset; + } + }} + {for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) { + RTFieldAccess flags = reader.getFieldFlags(i); + if (flags != RT_ACCESS_CONST && flags != RT_ACCESS_INVALID) { + ++offset; + } + }} + } +} + +} + +void InterfaceType::addSpecialDependencies() { + if (m_reader.getMethodCount() > 0 || m_reader.getFieldCount() > 0) { + m_dependencies.add("com/sun/star/uno/RuntimeException"); + } +} + +void InterfaceType::addComprehensiveGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const +{ + // The comprehensive getCppuType method always includes a line + // "getCppuType( (const ::com::sun::star::uno::RuntimeException*)0 );": + includes.addCppuUnotypeHxx(); + includes.add("com/sun/star/uno/RuntimeException"); +} + +sal_uInt32 InterfaceType::checkInheritedMemberCount(const typereg::Reader*) +{ + return BaseOffset(m_typeMgr, m_reader).get(); +} + +sal_uInt32 InterfaceType::getInheritedMemberCount() +{ + if (m_inheritedMemberCount == 0) + { + m_inheritedMemberCount = checkInheritedMemberCount(0); + } + + return m_inheritedMemberCount; +} + +void InterfaceType::dumpCppuAttributes(FileStream& o, sal_uInt32& index) +{ + sal_uInt16 fieldCount = m_reader.getFieldCount(); + + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + OString scope = m_typeName.replace('/', '.'); + + sal_uInt32 absoluteIndex = index; + + if (m_hasAttributes) + { + o << "\n" << indent() << "typelib_InterfaceAttributeTypeDescription * pAttribute = 0;\n"; + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + rtl::OUString name(m_reader.getFieldName(i)); + fieldName = rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8); + fieldType = checkRealBaseType( + rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8), + sal_True); + + o << indent() << "{\n"; + inc(); + o << indent() << "::rtl::OUString sAttributeType" << i << "( RTL_CONSTASCII_USTRINGPARAM(\"" + << fieldType.replace('/', '.') << "\") );\n"; + sal_Int32 getExceptions = dumpAttributeExceptionTypeNames( + o, "get", name, RT_MODE_ATTRIBUTE_GET); + sal_Int32 setExceptions = dumpAttributeExceptionTypeNames( + o, "set", name, RT_MODE_ATTRIBUTE_SET); + o << indent() + << ("typelib_typedescription_newExtendedInterfaceAttribute(" + " &pAttribute,\n"); + inc(); + o << indent() << absoluteIndex++ << ", sAttributeName" << i << ".pData,\n"; + o << indent() << "(typelib_TypeClass)" << getTypeClass(fieldType) + << ", sAttributeType" << i << ".pData,\n"; + o << indent() << "sal_" + << ((access & RT_ACCESS_READONLY) == 0 ? "False" : "True") << ", " + << getExceptions << ", " + << (getExceptions == 0 ? "0" : "the_getExceptions") << ", " + << setExceptions << ", " + << (setExceptions == 0 ? "0" : "the_setExceptions") << " );\n"; + dec(); + o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pAttribute );\n"; + dec(); + o << indent() << "}\n"; + } + o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pAttribute );\n"; + + index = absoluteIndex; + } +} + +void InterfaceType::dumpCppuMethods(FileStream& o, sal_uInt32& index) +{ + sal_uInt16 methodCount = m_reader.getMethodCount(); + OString methodName, returnType, paramType, paramName; + sal_uInt16 paramCount = 0; + RTMethodMode methodMode = RT_MODE_INVALID; + RTParamMode paramMode = RT_PARAM_INVALID; + sal_Bool bWithRuntimeException = sal_True; + + sal_uInt32 absoluteIndex = index; + + if (m_hasMethods) + { + o << "\n" << indent() << "typelib_InterfaceMethodTypeDescription * pMethod = 0;\n"; + + for (sal_uInt16 i=0; i < methodCount; i++) + { + methodMode = m_reader.getMethodFlags(i); + if (methodMode == RT_MODE_ATTRIBUTE_GET + || methodMode == RT_MODE_ATTRIBUTE_SET) + { + continue; + } + + methodName = rtl::OUStringToOString( + m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8); + returnType = checkRealBaseType( + rtl::OUStringToOString( + m_reader.getMethodReturnTypeName(i), RTL_TEXTENCODING_UTF8), + sal_True); + paramCount = m_reader.getMethodParameterCount(i); + + if ( methodName.equals("acquire") || methodName.equals("release") ) + { + bWithRuntimeException = sal_False; + } + + o << indent() << "{\n"; + inc(); + + if (paramCount) + { + o << indent() << "typelib_Parameter_Init aParameters[" << paramCount << "];\n"; + } + + sal_uInt16 j; + for (j=0; j < paramCount; j++) + { + paramName = rtl::OUStringToOString( + m_reader.getMethodParameterName(i, j), + RTL_TEXTENCODING_UTF8); + paramType = checkRealBaseType( + rtl::OUStringToOString( + m_reader.getMethodParameterTypeName(i, j), + RTL_TEXTENCODING_UTF8), + sal_True); + paramMode = m_reader.getMethodParameterFlags(i, j); + + o << indent() << "::rtl::OUString sParamName" << j << "( RTL_CONSTASCII_USTRINGPARAM(\"" + << paramName << "\") );\n"; + o << indent() << "::rtl::OUString sParamType" << j << "( RTL_CONSTASCII_USTRINGPARAM(\"" + << paramType.replace('/', '.') << "\") );\n"; + o << indent() << "aParameters[" << j << "].pParamName = sParamName" << j << ".pData;\n"; + o << indent() << "aParameters[" << j << "].eTypeClass = (typelib_TypeClass)" + << getTypeClass(paramType) << ";\n"; + o << indent() << "aParameters[" << j << "].pTypeName = sParamType" << j << ".pData;\n"; + + if (paramMode == RT_PARAM_IN || paramMode == RT_PARAM_INOUT) + o << indent() << "aParameters[" << j << "].bIn = sal_True;\n"; + else + o << indent() << "aParameters[" << j << "].bIn = sal_False;\n"; + + if (paramMode == RT_PARAM_OUT || paramMode == RT_PARAM_INOUT) + o << indent() << "aParameters[" << j << "].bOut = sal_True;\n"; + else + o << indent() << "aParameters[" << j << "].bOut = sal_False;\n"; + } + + sal_Int32 excCount = dumpExceptionTypeNames( + o, "", i, bWithRuntimeException); + + o << indent() << "::rtl::OUString sReturnType" << i << "( RTL_CONSTASCII_USTRINGPARAM(\"" + << returnType.replace('/', '.') << "\") );\n"; + o << indent() << "typelib_typedescription_newInterfaceMethod( &pMethod,\n"; + inc(); + o << indent() << absoluteIndex++ << ", "; + if (methodMode == RT_MODE_ONEWAY || methodMode == RT_MODE_ONEWAY_CONST) + o << "sal_True,\n"; + else + o << "sal_False,\n"; + o << indent() << "sMethodName" << i << ".pData,\n"; + o << indent() << "(typelib_TypeClass)" << getTypeClass(returnType) + << ", sReturnType" << i << ".pData,\n"; + if (paramCount) + o << indent() << paramCount << ", aParameters,\n"; + else + o << indent() << "0, 0,\n"; + o << indent() << excCount << ", " + << (excCount == 0 ? "0" : "the_Exceptions") << " );\n"; + + dec(); + o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );\n"; + + dec(); + o << indent() << "}\n"; + } + o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pMethod );\n"; + + index = absoluteIndex; + } +} + +void InterfaceType::dumpAttributesCppuDecl(FileStream& o, StringSet* pFinishedTypes, CppuTypeDecl eDeclFlag) +{ + sal_uInt16 fieldCount = m_reader.getFieldCount(); + + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + fieldType = rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); + + if (pFinishedTypes->count(fieldType) == 0) + { + pFinishedTypes->insert(fieldType); + dumpCppuGetType(o, fieldType, sal_True, eDeclFlag); + } + } +} + +void InterfaceType::dumpMethodsCppuDecl(FileStream& o, StringSet* pFinishedTypes, CppuTypeDecl eDeclFlag) +{ + sal_uInt16 methodCount = m_reader.getMethodCount(); + OString returnType, paramType, excType; + sal_uInt16 paramCount = 0; + sal_uInt16 excCount = 0; + + for (sal_uInt16 i=0; i < methodCount; i++) + { + returnType = rtl::OUStringToOString( + m_reader.getMethodReturnTypeName(i), RTL_TEXTENCODING_UTF8); + paramCount = m_reader.getMethodParameterCount(i); + excCount = m_reader.getMethodExceptionCount(i); + + if (pFinishedTypes->count(returnType) == 0) + { + pFinishedTypes->insert(returnType); + dumpCppuGetType(o, returnType, sal_True, eDeclFlag); + } + sal_uInt16 j; + for (j=0; j < paramCount; j++) + { + paramType = rtl::OUStringToOString( + m_reader.getMethodParameterTypeName(i, j), + RTL_TEXTENCODING_UTF8); + + if (pFinishedTypes->count(paramType) == 0) + { + pFinishedTypes->insert(paramType); + dumpCppuGetType(o, paramType, sal_True, eDeclFlag); + } + } + + for (j=0; j < excCount; j++) + { + excType = rtl::OUStringToOString( + m_reader.getMethodExceptionTypeName(i, j), + RTL_TEXTENCODING_UTF8); + if (pFinishedTypes->count(excType) == 0) + { + pFinishedTypes->insert(excType); + dumpCppuGetType(o, excType, sal_True, eDeclFlag); + } + } + } +} + +void InterfaceType::dumpExceptionSpecification( + FileStream & out, sal_uInt32 methodIndex, bool runtimeException) +{ + out << " throw ("; + bool first = true; + if (methodIndex <= SAL_MAX_UINT16) { + sal_uInt16 count = m_reader.getMethodExceptionCount( + static_cast< sal_uInt16 >(methodIndex)); + for (sal_uInt16 i = 0; i < count; ++i) { + rtl::OUString name( + m_reader.getMethodExceptionTypeName( + static_cast< sal_uInt16 >(methodIndex), i)); + if (!name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/RuntimeException"))) + { + if (!first) { + out << ", "; + } + first = false; + out << scopedCppName( + rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8)); + } + } + } + if (runtimeException) { + if (!first) { + out << ", "; + } + out << "::com::sun::star::uno::RuntimeException"; + } + out << ")"; +} + +void InterfaceType::dumpAttributeExceptionSpecification( + FileStream & out, rtl::OUString const & name, RTMethodMode sort) +{ + sal_uInt16 methodCount = m_reader.getMethodCount(); + for (sal_uInt16 i = 0; i < methodCount; ++i) { + if (m_reader.getMethodFlags(i) == sort + && m_reader.getMethodName(i) == name) + { + dumpExceptionSpecification(out, i, true); + return; + } + } + dumpExceptionSpecification(out, 0xFFFFFFFF, true); +} + +void InterfaceType::dumpExceptionTypeName( + FileStream & out, char const * prefix, sal_uInt32 index, rtl::OUString name) +{ + out << indent() << "::rtl::OUString the_" << prefix << "ExceptionName" + << index << "(RTL_CONSTASCII_USTRINGPARAM(\"" + << rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).replace('/', '.') + << "\"));\n"; +} + +sal_Int32 InterfaceType::dumpExceptionTypeNames( + FileStream & out, char const * prefix, sal_uInt16 methodIndex, + bool runtimeException) +{ + sal_Int32 count = 0; + sal_uInt16 n = m_reader.getMethodExceptionCount(methodIndex); + for (sal_uInt16 i = 0; i < n; ++i) { + rtl::OUString name(m_reader.getMethodExceptionTypeName(methodIndex, i)); + if (!name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/RuntimeException"))) + { + dumpExceptionTypeName(out, prefix, count++, name); + } + } + if (runtimeException) { + dumpExceptionTypeName( + out, prefix, count++, + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com/sun/star/uno/RuntimeException"))); + } + if (count > 0) { + out << indent() << "rtl_uString * the_" << prefix << "Exceptions[] = {"; + for (sal_Int32 i = 0; i < count; ++i) { + out << (i == 0 ? " " : ", ") << "the_" << prefix << "ExceptionName" + << i << ".pData"; + } + out << " };\n"; + } + return count; +} + +sal_Int32 InterfaceType::dumpAttributeExceptionTypeNames( + FileStream & out, char const * prefix, rtl::OUString const & name, + RTMethodMode sort) +{ + sal_uInt16 methodCount = m_reader.getMethodCount(); + for (sal_uInt16 i = 0; i < methodCount; ++i) { + if (m_reader.getMethodFlags(i) == sort + && m_reader.getMethodName(i) == name) + { + return dumpExceptionTypeNames(out, prefix, i, false); + } + } + return 0; +} + +//************************************************************************* +// ConstantsType +//************************************************************************* +ConstantsType::ConstantsType(typereg::Reader& typeReader, + const OString& typeName, + const TypeManager& typeMgr) + : CppuType(typeReader, typeName, typeMgr) +{ +} + +ConstantsType::~ConstantsType() +{ + +} + +sal_Bool ConstantsType::dump(CppuOptions* pOptions) + throw( CannotDumpException ) +{ + if (!m_dependencies.isValid()) { + return false; + } + addSpecialDependencies(); + + if (pOptions->isValid("-U")) + m_cppuTypeDynamic = sal_True; + + OString outPath; + if (pOptions->isValid("-O")) + outPath = pOptions->getOption("-O"); + + return dumpFiles(pOptions, outPath); +} + +sal_Bool ConstantsType::dumpHFile( + FileStream& o, codemaker::cppumaker::Includes & includes) + throw( CannotDumpException ) +{ + sal_Bool bSpecialDefine = sal_True; + + if (m_reader.getTypeClass() == RT_TYPE_CONSTANTS) + { + bSpecialDefine = sal_False; + } + + OString headerDefine(dumpHeaderDefine(o, "HDL", bSpecialDefine)); + o << "\n"; + + addDefaultHIncludes(includes); + includes.dump(o, 0); + o << "\n"; + + if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, true)) { + o << "\n"; + } + o << "\n"; + + dumpDeclaration(o); + o << "\n"; + + if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, true)) { + o << "\n"; + } + o << "\n#endif // "<< headerDefine << "\n"; + + return sal_True; +} + +sal_Bool ConstantsType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ + sal_uInt16 fieldCount = m_reader.getFieldCount(); + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + fieldType = rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); + + o << "static const "; + dumpType(o, fieldType); + o << " " << fieldName << " = "; + dumpConstantValue(o, i); + o << ";\n"; + } + + return sal_True; +} + +sal_Bool ConstantsType::hasConstants() +{ + return m_reader.getFieldCount() > 0; +} + +sal_Bool ConstantsType::dumpHxxFile( + FileStream& o, codemaker::cppumaker::Includes &) + throw( CannotDumpException ) +{ + sal_Bool bSpecialDefine = sal_True; + + if (m_reader.getTypeClass() == RT_TYPE_CONSTANTS) + { + bSpecialDefine = sal_False; + } + + OString headerDefine(dumpHeaderDefine(o, "HPP", bSpecialDefine)); + o << "\n"; + + rtl::OString suffix; + if (bSpecialDefine) { + suffix = m_name; + } + codemaker::cppumaker::Includes::dumpInclude(o, m_typeName, false, suffix); + + o << "\n#endif // "<< headerDefine << "\n"; + + return sal_True; +} + +//************************************************************************* +// ModuleType +//************************************************************************* +ModuleType::ModuleType(typereg::Reader& typeReader, + const OString& typeName, + const TypeManager& typeMgr) + : ConstantsType(typeReader, typeName, typeMgr) +{ +} + +ModuleType::~ModuleType() +{ + +} + +bool ModuleType::dumpFiles( + CppuOptions * options, rtl::OString const & outPath) +{ + rtl::OString tmpName(m_typeName); + if (tmpName.equals("/")) { + tmpName = "global"; + } else { + tmpName += "/" + m_typeName.copy(m_typeName.lastIndexOf('/') + 1); + } + return dumpFile(options, ".hdl", tmpName, outPath) + && dumpFile(options, ".hpp", tmpName, outPath); +} + +//************************************************************************* +// StructureType +//************************************************************************* + +namespace { + +void dumpTypeParameterName(FileStream & out, rtl::OString const & name) { + // Prefix all type parameters with "typeparam_" to avoid problems when a + // struct member has the same name as a type parameter, as in + // struct<T> { T T; }; + out << "typeparam_" << name; +} + +} + +StructureType::StructureType(typereg::Reader& typeReader, + const OString& typeName, + const TypeManager& typeMgr) + : CppuType(typeReader, typeName, typeMgr) +{ +} + +StructureType::~StructureType() +{ + +} + +sal_Bool StructureType::dumpHFile( + FileStream& o, codemaker::cppumaker::Includes & includes) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "HDL")); + o << "\n"; + + addDefaultHIncludes(includes); + includes.dump(o, 0); + o << "\n"; + + if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { + o << "\n"; + } + + dumpDeclaration(o); + + if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { + o << "\n"; + } + + o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n" + << "class Type;\n} } } }\n\n"; + + dumpTemplateHead(o); + o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( "; + dumpType(o, m_typeName, sal_True, sal_False); + dumpTemplateParameters(o); + o << "* );\n\n"; + + o << "#endif // "<< headerDefine << "\n"; + + return sal_True; +} + +sal_Bool StructureType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ + o << "\n#ifdef SAL_W32\n" + << "# pragma pack(push, 8)\n" + << "#elif defined(SAL_OS2)\n" + << "# pragma pack(8)\n" + << "#endif\n\n"; + + OSL_ASSERT(!isPolymorphic() || m_reader.getSuperTypeCount() == 0); //TODO + o << indent(); + dumpTemplateHead(o); + o << "struct " << m_name; + rtl::OString base; + if (m_reader.getSuperTypeCount() != 0) { + base = rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); + OSL_ASSERT(base.getLength() > 0); //TODO + } + if (base.getLength() > 0) { + o << ": public " << scopedCppName(base); + } + o << " {\n"; + inc(); + o << indent() << "inline " << m_name << "() SAL_THROW(());\n"; + sal_uInt16 members = m_reader.getFieldCount(); + if (members > 0 || getInheritedMemberCount() > 0) { + o << "\n" << indent() << "inline " << m_name << "("; + bool prev = dumpSuperMember(o, base, true); + for (sal_uInt16 i = 0; i < members; ++i) { + if (prev) { + o << ", "; + } + prev = true; + rtl::OString type( + rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); + if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) + { + dumpTypeParameterName(o, type); + o << " const &"; + } else { + dumpType(o, type, true, true); + } + o << " " + << rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8) + << "_"; + } + o << ") SAL_THROW(());\n"; + } + if (members > 0) { + o << "\n"; + for (sal_uInt16 i = 0; i < members; ++i) { + o << indent(); + bool parameterized + = ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) + != 0); + rtl::OString type( + rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); + if (parameterized) { + dumpTypeParameterName(o, type); + } else { + dumpType(o, type); + } + o << " " + << rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + if (i == 0 && base.getLength() > 0 && type != "double" + && type != "hyper" && type != "unsigned hyper") + { + OSL_ASSERT(!parameterized); + o << " CPPU_GCC3_ALIGN(" << scopedCppName(base) << ")"; + } + o << ";\n"; + } + } + dec(); + o << "};\n\n"; + + o << "#ifdef SAL_W32\n" + << "# pragma pack(pop)\n" + << "#elif defined(SAL_OS2)\n" + << "# pragma pack()\n" + << "#endif\n\n"; + + return sal_True; +} + +sal_Bool StructureType::dumpHxxFile( + FileStream& o, codemaker::cppumaker::Includes & includes) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "HPP")); + o << "\n"; + + includes.dump(o, &m_typeName); + o << "\n"; + + if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { + o << "\n"; + } + o << "\n"; + + dumpTemplateHead(o); + o << "inline " << m_name; + dumpTemplateParameters(o); + o << "::" << m_name << "() SAL_THROW( () )\n"; + inc(); + OString superType; + if (m_reader.getSuperTypeCount() >= 1) { + superType = rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); + } + sal_Bool first = sal_True; + if (superType.getLength() > 0) + { + o << indent() << ": " << scopedCppName(superType) << "()\n"; + first = sal_False; + } + + sal_uInt16 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + + if (first) + { + first = sal_False; + o << indent() << ": "; + } else + o << indent() << ", "; + + o << fieldName; + dumpInitializer( + o, (access & RT_ACCESS_PARAMETERIZED_TYPE) != 0, + m_reader.getFieldTypeName(i)); + o << "\n"; + } + dec(); + o << "{\n}\n\n"; + + if (fieldCount > 0 || getInheritedMemberCount() > 0) + { + dumpTemplateHead(o); + o << "inline " << m_name; + dumpTemplateParameters(o); + o << "::" << m_name << "("; + + sal_Bool superHasMember = dumpSuperMember(o, superType, sal_True); + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + fieldType = rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); + + if (superHasMember) + o << ", "; + else + superHasMember = sal_True; + + if ((access & RT_ACCESS_PARAMETERIZED_TYPE) != 0) { + dumpTypeParameterName(o, fieldType); + o << " const &"; + } else { + dumpType(o, fieldType, sal_True, sal_True); + } +// o << " __" << fieldName; + o << " " << fieldName << "_"; + } + o << ") SAL_THROW( () )\n"; + + inc(); + first = sal_True; + if (superType.getLength() > 0) + { + o << indent() << ": " << scopedCppName(superType) << "("; + dumpSuperMember(o, superType, sal_False); + o << ")\n"; + first = sal_False; + } + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + + if (first) + { + first = sal_False; + o << indent() << ": "; + } else + o << indent() << ", "; + +// o << fieldName << "(__" << fieldName << ")\n"; + o << fieldName << "(" << fieldName << "_)\n"; + } + + dec(); + o << "{\n}\n\n"; + } + + if (isPolymorphic() && fieldCount > 0) { + o << indent(); + dumpTemplateHead(o); + o << "\n"; + o << indent(); + o << "inline " << m_name; + dumpTemplateParameters(o); + o << "\n"; + o << indent(); + o << "make_" << m_name << "("; + for (sal_uInt16 i = 0; i < fieldCount; ++i) { + if (i > 0) { + o << ", "; + } + rtl::OString type( + rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); + if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) + { + dumpTypeParameterName(o, type); + o << " const &"; + } else { + dumpType(o, type, true, true); + } + o << " " + << rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8) + << "_"; + } + o << ") SAL_THROW(())\n"; + o << indent() << "{\n"; + inc(); + o << indent() << "return " << m_name; + dumpTemplateParameters(o); + o << "("; + for (sal_uInt16 i = 0; i < fieldCount; ++i) { + if (i > 0) { + o << ", "; + } + o << rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8) + << "_"; + } + o << ");\n"; + dec(); + o << indent() << "}\n\n"; + } + + if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { + o << "\n"; + } + + o << "\n"; + dumpGetCppuType(o); + + o << "\n#endif // "<< headerDefine << "\n"; + + return sal_True; +} + +void StructureType::dumpLightGetCppuType(FileStream & out) { + dumpGetCppuTypePreamble(out); + out << indent() + << ("//TODO: On certain platforms with weak memory models, the" + " following code can result in some threads observing that the_type" + " points to garbage\n") + << indent() + << "static ::typelib_TypeDescriptionReference * the_type = 0;\n" + << indent() << "if (the_type == 0) {\n"; + inc(); + if (isPolymorphic()) { + out << indent() << "::rtl::OStringBuffer the_buffer(\"" + << m_typeName.replace('/', '.') << "<\");\n"; + sal_uInt16 n = m_reader.getReferenceCount(); + for (sal_uInt16 i = 0; i < n; ++i) { + out << indent() + << ("the_buffer.append(::rtl::OUStringToOString(" + "::cppu::getTypeFavourChar(static_cast< "); + dumpTypeParameterName( + out, + rtl::OUStringToOString( + m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8)); + out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n"; + if (i != n - 1) { + out << indent() << "the_buffer.append(',');\n"; + } + } + out << indent() << "the_buffer.append('>');\n"; + } + out << indent() << "::typelib_static_type_init(&the_type, " + << getTypeClass(m_typeName, true) << ", "; + if (isPolymorphic()) { + out << "the_buffer.getStr()"; + } else { + out << "\"" << m_typeName.replace('/', '.') << "\""; + } + out << ");\n"; + dec(); + out << indent() << "}\n" << indent() + << ("return *reinterpret_cast< ::com::sun::star::uno::Type * >(" + "&the_type);\n"); + dumpGetCppuTypePostamble(out); +} + +void StructureType::dumpNormalGetCppuType(FileStream & out) { + dumpGetCppuTypePreamble(out); + out << indent() + << ("//TODO: On certain platforms with weak memory models, the" + " following code can result in some threads observing that the_type" + " points to garbage\n") + << indent() + << "static ::typelib_TypeDescriptionReference * the_type = 0;\n" + << indent() << "if (the_type == 0) {\n"; + inc(); + if (isPolymorphic()) { + out << indent() << "::rtl::OStringBuffer the_buffer(\"" + << m_typeName.replace('/', '.') << "<\");\n"; + sal_uInt16 n = m_reader.getReferenceCount(); + for (sal_uInt16 i = 0; i < n; ++i) { + out << indent() + << ("the_buffer.append(::rtl::OUStringToOString(" + "::cppu::getTypeFavourChar(static_cast< "); + dumpTypeParameterName( + out, + rtl::OUStringToOString( + m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8)); + out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n"; + if (i != n - 1) { + out << indent() << "the_buffer.append(',');\n"; + } + } + out << indent() << "the_buffer.append('>');\n"; + } + out << indent() + << "::typelib_TypeDescriptionReference * the_members[] = {\n"; + inc(); + sal_uInt16 fields = m_reader.getFieldCount(); + for (sal_uInt16 i = 0; i < fields; ++i) { + out << indent(); + rtl::OString type( + rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); + if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) { + out << "::cppu::getTypeFavourChar(static_cast< "; + dumpTypeParameterName(out, type); + out << " * >(0))"; + } else { + out << "::cppu::UnoType< "; + dumpType(out, type, false, false, false, true); + out << " >::get()"; + } + out << ".getTypeLibType()" << (i == fields - 1 ? " };" : ",") + << "\n"; + } + dec(); + if (isPolymorphic()) { + out << indent() + << "static ::sal_Bool const the_parameterizedTypes[] = { "; + for (sal_uInt16 i = 0; i < fields; ++i) { + if (i != 0) { + out << ", "; + } + out << (((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) + == 0) + ? "false" : "true"); + } + out << " };\n"; + } + out << indent() << "::typelib_static_struct_type_init(&the_type, "; + if (isPolymorphic()) { + out << "the_buffer.getStr()"; + } else { + out << "\"" << m_typeName.replace('/', '.') << "\""; + } + out << ", "; + if (m_reader.getSuperTypeCount() == 0) { + out << "0"; + } else { + out << "::cppu::UnoType< "; + dumpType( + out, + rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8), + false, false, false, true); + out << " >::get().getTypeLibType()"; + } + out << ", " << fields << ", the_members, " + << (isPolymorphic() ? "the_parameterizedTypes" : "0") << ");\n"; + dec(); + out << indent() << "}\n" << indent() + << ("return *reinterpret_cast< ::com::sun::star::uno::Type * >(" + "&the_type);\n"); + dumpGetCppuTypePostamble(out); +} + +void StructureType::dumpComprehensiveGetCppuType(FileStream & out) { + dumpGetCppuTypePreamble(out); + out << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n" + << indent() << "if (the_pType == 0) {\n"; + inc(); + out << indent() + << "::osl::MutexGuard the_guard(::osl::Mutex::getGlobalMutex());\n" + << indent() << "if (the_pType == 0) {\n"; + inc(); + if (isPolymorphic()) { + out << indent() << "::rtl::OUStringBuffer the_buffer;\n" << indent() + << "the_buffer.appendAscii(RTL_CONSTASCII_STRINGPARAM(\"" + << m_typeName.replace('/', '.') << "<\"));\n"; + sal_uInt16 n = m_reader.getReferenceCount(); + for (sal_uInt16 i = 0; i < n; ++i) { + out << indent() + << "the_buffer.append(::cppu::getTypeFavourChar(static_cast< "; + dumpTypeParameterName( + out, + rtl::OUStringToOString( + m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8)); + out << " * >(0)).getTypeName());\n"; + if (i != n - 1) { + out << indent() + << ("the_buffer.append(" + "static_cast< ::sal_Unicode >(','));\n"); + } + } + out << indent() + << "the_buffer.append(static_cast< ::sal_Unicode >('>'));\n" + << indent() + << "::rtl::OUString the_name(the_buffer.makeStringAndClear());\n"; + } else { + out << indent() + << "::rtl::OUString the_name(RTL_CONSTASCII_USTRINGPARAM(\"" + << m_typeName.replace('/', '.') << "\"));\n"; + } + sal_uInt16 fields = m_reader.getFieldCount(); + typedef std::map< rtl::OString, sal_uInt32 > Map; + Map parameters; + Map types; + {for (sal_uInt16 i = 0; i < fields; ++i) { + rtl::OString type( + rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); + if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) { + if (parameters.insert( + Map::value_type( + type, static_cast< sal_uInt32 >(parameters.size()))). + second) + { + sal_uInt32 n = static_cast< sal_uInt32 >(parameters.size() - 1); + out << indent() + << "::com::sun::star::uno::Type const & the_ptype" << n + << " = ::cppu::getTypeFavourChar(static_cast< "; + dumpTypeParameterName(out, type); + out << " * >(0));\n" << indent() + << "::typelib_TypeClass the_pclass" << n + << " = (::typelib_TypeClass) the_ptype" << n + << ".getTypeClass();\n" << indent() + << "::rtl::OUString the_pname" << n << "(the_ptype" << n + << ".getTypeName());\n"; + } + } else if (types.insert( + Map::value_type( + type, static_cast< sal_uInt32 >(types.size()))). + second) + { + if ((codemaker::UnoType::getSort(type) == + codemaker::UnoType::SORT_COMPLEX) && + codemaker::UnoType::decompose(type) != m_typeName) + // take care of recursion like struct S { sequence<S> x; }; + { + out << indent() << "::cppu::UnoType< "; + dumpType(out, type, false, false, false, true); + out << " >::get();\n"; + } + // For typedefs, use the resolved type name, as there will be no + // information available about the typedef itself at runtime (the + // above getCppuType call will make available information about the + // resolved type); no extra #include for the resolved type is + // needed, as the header for the typedef includes it already: + out << indent() << "::rtl::OUString the_tname" + << static_cast< sal_uInt32 >(types.size() - 1) + << "(RTL_CONSTASCII_USTRINGPARAM(\"" + << checkRealBaseType(type, true).replace('/', '.') << "\"));\n"; + } + out << indent() << "::rtl::OUString the_name" << i + << "(RTL_CONSTASCII_USTRINGPARAM(\"" + << rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8).replace( + '/', '.') + << "\"));\n"; + }} + out << indent() << "::typelib_StructMember_Init the_members[] = {\n"; + inc(); + {for (sal_uInt16 i = 0; i < fields; ++i) { + out << indent() << "{ { "; + rtl::OString type( + rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); + if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) { + sal_uInt32 n = parameters.find(type)->second; + out << "the_pclass" << n << ", the_pname" << n << ".pData"; + } else { + out << getTypeClass(type, true) << ", the_tname" + << types.find(type)->second << ".pData"; + } + out << ", the_name" << i << ".pData }, " + << ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) == 0 + ? "false" : "true") + << " }" << (i == fields - 1 ? " };" : ",") << "\n"; + }} + dec(); + out << indent() << "::typelib_TypeDescription * the_newType = 0;\n"; + out << indent() + << "::typelib_typedescription_newStruct(&the_newType, the_name.pData, "; + if (m_reader.getSuperTypeCount() == 0) { + out << "0"; + } else { + out << "::cppu::UnoType< "; + dumpType( + out, + rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8), + false, false, false, true); + out << " >::get().getTypeLibType()"; + } + out << ", " << fields << ", the_members);\n"; + out << indent() << "::typelib_typedescription_register(&the_newType);\n"; + out << indent() << "::typelib_typedescription_release(the_newType);\n"; + out << indent() << "static ::com::sun::star::uno::Type the_staticType(" + << getTypeClass(m_typeName) << ", the_name);\n"; + out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n"; + out << indent() << "the_pType = &the_staticType;\n"; + dec(); + out << indent() << "}\n"; + dec(); + out << indent() << "} else {\n"; + inc(); + out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n"; + dec(); + out << indent() << "}\n" << indent() << "return *the_pType;\n"; + dumpGetCppuTypePostamble(out); +} + +sal_Bool StructureType::dumpSuperMember(FileStream& o, const OString& superType, sal_Bool bWithType) +{ + sal_Bool hasMember = sal_False; + + if (superType.getLength() > 0) + { + typereg::Reader aSuperReader(m_typeMgr.getTypeReader(superType)); + + if (aSuperReader.isValid()) + { + rtl::OString superSuper; + if (aSuperReader.getSuperTypeCount() >= 1) { + superSuper = rtl::OUStringToOString( + aSuperReader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); + } + hasMember = dumpSuperMember(o, superSuper, bWithType); + + sal_uInt16 fieldCount = aSuperReader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = aSuperReader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + aSuperReader.getFieldName(i), RTL_TEXTENCODING_UTF8); + fieldType = rtl::OUStringToOString( + aSuperReader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); + + if (hasMember) + { + o << ", "; + } else + { + hasMember = (fieldCount > 0); + } + + if (bWithType) + { + dumpType(o, fieldType, sal_True, sal_True); + o << " "; + } +// o << "__" << fieldName; + o << fieldName << "_"; + } + } + } + + return hasMember; +} + +void StructureType::addLightGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const +{ + includes.addType(); + includes.addCppuUnotypeHxx(); + includes.addSalTypesH(); + includes.addTypelibTypeclassH(); + includes.addTypelibTypedescriptionH(); + if (isPolymorphic()) { + includes.addRtlStrbufHxx(); + includes.addRtlTextencH(); + includes.addRtlUstringHxx(); + } +} + +void StructureType::addNormalGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const +{ + includes.addType(); + includes.addCppuUnotypeHxx(); + includes.addSalTypesH(); + includes.addTypelibTypeclassH(); + includes.addTypelibTypedescriptionH(); + if (isPolymorphic()) { + includes.addRtlStrbufHxx(); + includes.addRtlTextencH(); + includes.addRtlUstringHxx(); + } +} + +void StructureType::addComprehensiveGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const +{ + includes.addType(); + includes.addCppuUnotypeHxx(); + includes.addOslDoublecheckedlockingH(); + includes.addOslMutexHxx(); + includes.addRtlUstringH(); + includes.addRtlUstringHxx(); + includes.addSalTypesH(); + includes.addTypelibTypeclassH(); + includes.addTypelibTypedescriptionH(); + if (isPolymorphic()) { + includes.addRtlStringH(); + includes.addRtlUstrbufHxx(); + } +} + +bool StructureType::isPolymorphic() const { + return m_reader.getReferenceCount() > 0; +} + +void StructureType::dumpTemplateHead(FileStream & out) const { + if (isPolymorphic()) { + out << "template< "; + for (sal_uInt16 i = 0; i < m_reader.getReferenceCount(); ++i) { + if (i != 0) { + out << ", "; + } + OSL_ASSERT( + m_reader.getReferenceFlags(i) == RT_ACCESS_INVALID + && m_reader.getReferenceSort(i) == RT_REF_TYPE_PARAMETER); + out << "typename "; + dumpTypeParameterName( + out, + rtl::OUStringToOString( + m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8)); + } + out << " > "; + } +} + +void StructureType::dumpTemplateParameters(FileStream & out) const { + if (isPolymorphic()) { + out << "< "; + for (sal_uInt16 i = 0; i < m_reader.getReferenceCount(); ++i) { + if (i != 0) { + out << ", "; + } + OSL_ASSERT( + m_reader.getReferenceFlags(i) == RT_ACCESS_INVALID + && m_reader.getReferenceSort(i) == RT_REF_TYPE_PARAMETER); + dumpTypeParameterName( + out, + rtl::OUStringToOString( + m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8)); + } + out << " >"; + } +} + +//************************************************************************* +// ExceptionType +//************************************************************************* +ExceptionType::ExceptionType(typereg::Reader& typeReader, + const OString& typeName, + const TypeManager& typeMgr) + : CppuType(typeReader, typeName, typeMgr) +{ +} + +ExceptionType::~ExceptionType() +{ + +} + +sal_Bool ExceptionType::dumpHFile( + FileStream& o, codemaker::cppumaker::Includes & includes) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "HDL")); + o << "\n"; + + addDefaultHIncludes(includes); + includes.dump(o, 0); + o << "\n"; + + if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { + o << "\n"; + } + + dumpDeclaration(o); + + if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { + o << "\n"; + } + + o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n" + << "class Type;\n} } } }\n\n"; + + o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( "; + dumpType(o, m_typeName, sal_True, sal_False); + o << "* ) SAL_THROW( () );\n\n"; + + o << "#endif // "<< headerDefine << "\n"; + + return sal_True; +} + +sal_Bool ExceptionType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ + o << "\nclass CPPU_GCC_DLLPUBLIC_EXPORT " << m_name; + + OString superType; + if (m_reader.getSuperTypeCount() >= 1) { + superType = rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); + } + if (superType.getLength() > 0) + o << " : public " << scopedCppName(superType); + + o << "\n{\npublic:\n"; + inc(); + o << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name + << "() SAL_THROW( () );\n\n"; + + sal_uInt16 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + sal_uInt16 i = 0; + + if (fieldCount > 0 || getInheritedMemberCount() > 0) + { + o << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name << "("; + + sal_Bool superHasMember = dumpSuperMember(o, superType, sal_True); + + for (i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + fieldType = rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); + + if (superHasMember) + o << ", "; + else + superHasMember = sal_True; + + dumpType(o, fieldType, sal_True, sal_True); +// o << " __" << fieldName; + o << " " << fieldName << "_"; + } + o << ") SAL_THROW( () );\n\n"; + } + o << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name << "(" << m_name + << " const &);\n\n" + << indent() << "inline CPPU_GCC_DLLPRIVATE ~" << m_name << "();\n\n" + << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name << " & operator =(" + << m_name << " const &);\n\n"; + + for (i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + fieldType = rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); + + o << indent(); + dumpType(o, fieldType); + o << " " << fieldName; + if (i == 0 && superType.getLength() && + !fieldType.equals("double") && !fieldType.equals("hyper") && !fieldType.equals("unsigned hyper")) + { + o << " CPPU_GCC3_ALIGN( " << scopedCppName(superType) << " )"; + } + o << ";\n"; + } + + + dec(); + o << "};\n\n"; + + return sal_True; +} + +sal_Bool ExceptionType::dumpHxxFile( + FileStream& o, codemaker::cppumaker::Includes & includes) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "HPP")); + o << "\n"; + + addDefaultHxxIncludes(includes); + includes.dump(o, &m_typeName); + o << "\n"; + + if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { + o << "\n"; + } + o << "\n"; + + o << "inline " << m_name << "::" << m_name << "() SAL_THROW( () )\n"; + inc(); + OString superType; + if (m_reader.getSuperTypeCount() >= 1) { + superType = rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); + } + sal_Bool first = sal_True; + if (superType.getLength() > 0) + { + o << indent() << ": " << scopedCppName(superType) << "()\n"; + first = sal_False; + } + + sal_uInt16 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + + if (first) + { + first = sal_False; + o << indent() << ": "; + } else + o << indent() << ", "; + + o << fieldName; + dumpInitializer(o, false, m_reader.getFieldTypeName(i)); + o << "\n"; + } + dec(); + if ( !m_cppuTypeDynamic ) + { + o << "{\n"; + inc(); + dumpCppuGetType(o, m_typeName, sal_True); + dec(); + o << "}\n\n"; + } else + { + o << "{ }\n\n"; + } + + if (fieldCount > 0 || getInheritedMemberCount() > 0) + { + o << indent() << "inline " << m_name << "::" << m_name << "("; + + sal_Bool superHasMember = dumpSuperMember(o, superType, sal_True); + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + fieldType = rtl::OUStringToOString( + m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); + + if (superHasMember) + o << ", "; + else + superHasMember = sal_True; + + dumpType(o, fieldType, sal_True, sal_True); +// o << " __" << fieldName; + o << " " << fieldName << "_"; + } + o << ") SAL_THROW( () )\n"; + + inc(); + first = sal_True; + if (superType.getLength() > 0) + { + o << indent() << ": " << scopedCppName(superType) << "("; + dumpSuperMember(o, superType, sal_False); + o << ")\n"; + first = sal_False; + } + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + + if (first) + { + first = sal_False; + o << indent() << ": "; + } else + o << indent() << ", "; + +// o << fieldName << "(__" << fieldName << ")\n"; + o << fieldName << "(" << fieldName << "_)\n"; + } + + dec(); + if ( !m_cppuTypeDynamic ) + { + o << "{\n"; + inc(); + dumpCppuGetType(o, m_typeName, sal_True); + dec(); + o << "}\n\n"; + } else + { + o << "{ }\n\n"; + } + } + o << indent() << m_name << "::" << m_name << "(" << m_name + << " const & the_other)"; + first = true; + if (superType.getLength() > 0) { + o << ": " << scopedCppName(superType) << "(the_other)"; + first = false; + } + for (sal_uInt16 i = 0; i < fieldCount; ++i) { + rtl::OString name( + rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8)); + o << (first ? ": " : ", ") << name << "(the_other." << name << ")"; + first = false; + } + o << indent() << " {}\n\n" + << indent() << m_name << "::~" << m_name << "() {}\n\n" + << indent() << m_name << " & " << m_name << "::operator =(" << m_name + << " const & the_other) {\n"; + inc(); + o << indent() + << ("//TODO: Just like its implicitly-defined counterpart, this function" + " definition is not exception-safe\n"); + if (superType.getLength() > 0) { + o << indent() << scopedCppName(superType) + << "::operator =(the_other);\n"; + } + for (sal_uInt16 i = 0; i < fieldCount; ++i) { + rtl::OString name( + rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8)); + o << indent() << name << " = the_other." << name << ";\n"; + } + o << indent() << "return *this;\n"; + dec(); + o << indent() << "}\n\n"; + + if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { + o << "\n"; + } + + o << "\n"; + dumpGetCppuType(o); + + o << "\n#endif // "<< headerDefine << "\n"; + return sal_True; +} + +sal_Bool ExceptionType::dumpSuperMember(FileStream& o, const OString& superType, sal_Bool bWithType) +{ + sal_Bool hasMember = sal_False; + + if (superType.getLength() > 0) + { + typereg::Reader aSuperReader(m_typeMgr.getTypeReader(superType)); + + if (aSuperReader.isValid()) + { + rtl::OString superSuper; + if (aSuperReader.getSuperTypeCount() >= 1) { + superSuper = rtl::OUStringToOString( + aSuperReader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); + } + hasMember = dumpSuperMember(o, superSuper, bWithType); + + sal_uInt16 fieldCount = aSuperReader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = aSuperReader.getFieldFlags(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = rtl::OUStringToOString( + aSuperReader.getFieldName(i), RTL_TEXTENCODING_UTF8); + fieldType = rtl::OUStringToOString( + aSuperReader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); + + if (hasMember) + { + o << ", "; + } else + { + hasMember = (fieldCount > 0); + } + + if (bWithType) + { + dumpType(o, fieldType, sal_True, sal_True); + o << " "; + } +// o << "__" << fieldName; + o << fieldName << "_"; + } + } + } + + return hasMember; +} + +//************************************************************************* +// EnumType +//************************************************************************* +EnumType::EnumType(typereg::Reader& typeReader, + const OString& typeName, + const TypeManager& typeMgr) + : CppuType(typeReader, typeName, typeMgr) +{ +} + +EnumType::~EnumType() +{ + +} + +sal_Bool EnumType::dumpHFile( + FileStream& o, codemaker::cppumaker::Includes & includes) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "HDL")); + o << "\n"; + + addDefaultHIncludes(includes); + includes.dump(o, 0); + o << "\n"; + + if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { + o << "\n"; + } + + dumpDeclaration(o); + + if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { + o << "\n"; + } + + o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n" + << "class Type;\n} } } }\n\n"; + + o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( "; + dumpType(o, m_typeName, sal_True, sal_False); + o << "* ) SAL_THROW( () );\n\n"; + + o << "#endif // "<< headerDefine << "\n"; + + return sal_True; +} + +sal_Bool EnumType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ + o << "\nenum " << m_name << "\n{\n"; + inc(); + + sal_uInt16 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + RTConstValue constValue; + OString fieldName; + sal_Int32 value=0; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldFlags(i); + + if (access != RT_ACCESS_CONST) + continue; + + fieldName = rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); + constValue = m_reader.getFieldValue(i); + + if (constValue.m_type == RT_TYPE_INT32) + value = constValue.m_value.aLong; + else + value++; + + o << indent() << m_name << "_" << fieldName << " = " << value << ",\n"; + } + + o << indent() << m_name << "_MAKE_FIXED_SIZE = SAL_MAX_ENUM\n"; + + dec(); + o << "};\n\n"; + + return sal_True; +} + +sal_Bool EnumType::dumpHxxFile( + FileStream& o, codemaker::cppumaker::Includes & includes) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "HPP")); + o << "\n"; + + addDefaultHxxIncludes(includes); + includes.dump(o, &m_typeName); + o << "\n"; + + dumpGetCppuType(o); + + o << "\n#endif // "<< headerDefine << "\n"; + return sal_True; +} + +void EnumType::dumpNormalGetCppuType(FileStream& o) +{ + dumpGetCppuTypePreamble(o); + + o << indent() + << "static typelib_TypeDescriptionReference * the_type = 0;\n"; + + o << indent() << "if ( !the_type )\n" << indent() << "{\n"; + inc(); + + o << indent() << "typelib_static_enum_type_init( &the_type,\n"; + inc(31); + o << indent() << "\"" << m_typeName.replace('/', '.') << "\",\n" + << indent() << scopedCppName(m_typeName) << "_" + << rtl::OUStringToOString(m_reader.getFieldName(0), RTL_TEXTENCODING_UTF8) + << " );\n"; + dec(31); + dec(); + o << indent() << "}\n"; + o << indent() + << ("return * reinterpret_cast< ::com::sun::star::uno::Type * >(" + " &the_type );\n"); + dumpGetCppuTypePostamble(o); +} + +void EnumType::dumpComprehensiveGetCppuType(FileStream& o) +{ + dumpGetCppuTypePreamble(o); + + o << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n"; + + o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; + inc(); + o << indent() << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n"; + + o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; + inc(); + o << indent() << "::rtl::OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM(\"" + << m_typeName.replace('/', '.') << "\") );\n\n"; + + o << indent() << "// Start inline typedescription generation\n" + << indent() << "typelib_TypeDescription * pTD = 0;\n\n"; + + sal_uInt16 count = m_reader.getFieldCount(); + o << indent() << "rtl_uString* enumValueNames[" << count << "];\n"; + sal_uInt16 i; + for (i = 0; i < count; i++) + { + o << indent() << "::rtl::OUString sEnumValue" << i + << "( RTL_CONSTASCII_USTRINGPARAM(\"" + << rtl::OUStringToOString( + m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8) + << "\") );\n"; + o << indent() << "enumValueNames[" << i << "] = sEnumValue" << i + << ".pData;\n"; + } + + o << "\n" << indent() << "sal_Int32 enumValues[" << count << "];\n"; + RTConstValue constValue; + sal_Int32 value=0; + for (i = 0; i < count; i++) + { + o << indent() << "enumValues[" << i << "] = "; + constValue = m_reader.getFieldValue(i); + if (constValue.m_type == RT_TYPE_INT32) + value = constValue.m_value.aLong; + else + value++; + o << value << ";\n"; + } + + o << "\n" << indent() << "typelib_typedescription_newEnum( &pTD,\n"; + inc(); + o << indent() << "sTypeName.pData,\n" + << indent() << "(sal_Int32)" << scopedCppName(m_typeName, sal_False) + << "_" + << rtl::OUStringToOString(m_reader.getFieldName(0), RTL_TEXTENCODING_UTF8) + << ",\n" + << indent() << count << ", enumValueNames, enumValues );\n\n"; + dec(); + + o << indent() + << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD" + " );\n"); + o << indent() << "typelib_typedescription_release( pTD );\n" + << indent() << "// End inline typedescription generation\n\n"; + + o << indent() << "static ::com::sun::star::uno::Type the_staticType( " + << getTypeClass(m_typeName) << ", sTypeName );\n"; + o << indent() << "the_pType = &the_staticType;\n"; + + dec(); + o << indent() << "}\n"; + dec(); + o << indent() << "}\n\n" + << indent() << "return *the_pType;\n"; + + dumpGetCppuTypePostamble(o); +} + +//************************************************************************* +// TypeDefType +//************************************************************************* +TypeDefType::TypeDefType(typereg::Reader& typeReader, + const OString& typeName, + const TypeManager& typeMgr) + : CppuType(typeReader, typeName, typeMgr) +{ +} + +TypeDefType::~TypeDefType() +{ + +} + +sal_Bool TypeDefType::dumpHFile( + FileStream& o, codemaker::cppumaker::Includes & includes) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "HDL")); + o << "\n"; + + addDefaultHIncludes(includes); + includes.dump(o, 0); + o << "\n"; + + if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { + o << "\n"; + } + + dumpDeclaration(o); + + if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { + o << "\n"; + } + +// o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n" +// << "class Type;\n} } } }\n\n"; +// o << "inline const ::com::sun::star::uno::Type& SAL_CALL get_" << m_typeName.replace('/', '_') +// << "_Type( ) SAL_THROW( () );\n\n"; + + o << "#endif // "<< headerDefine << "\n"; + + return sal_True; +} + +sal_Bool TypeDefType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ + o << "\ntypedef "; + dumpType( + o, + rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8)); + o << " " << m_name << ";\n\n"; + + return sal_True; +} + +sal_Bool TypeDefType::dumpHxxFile( + FileStream& o, codemaker::cppumaker::Includes & includes) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "HPP")); + o << "\n"; + + addDefaultHxxIncludes(includes); + includes.dump(o, &m_typeName); + o << "\n"; + + o << "\n#endif // "<< headerDefine << "\n"; + return sal_True; +} + +//************************************************************************* +// ConstructiveType +//************************************************************************* + +sal_Bool ConstructiveType::dumpHFile( + FileStream &, codemaker::cppumaker::Includes &) throw (CannotDumpException) +{ + OSL_ASSERT(false); + return false; +} + +bool ConstructiveType::dumpFiles( + CppuOptions * options, rtl::OString const & outPath) +{ + return dumpFile(options, ".hpp", m_typeName, outPath); +} + +//************************************************************************* +// ServiceType +//************************************************************************* + +namespace { + +void includeExceptions( + codemaker::cppumaker::Includes & includes, + codemaker::ExceptionTreeNode const * node) +{ + if (node->present) { + includes.add(node->name); + } else { + for (codemaker::ExceptionTreeNode::Children::const_iterator i( + node->children.begin()); + i != node->children.end(); ++i) + { + includeExceptions(includes, *i); + } + } +} + +} + +bool ServiceType::isSingleInterfaceBased() { + return m_reader.getSuperTypeCount() == 1; +} + +sal_Bool ServiceType::dumpHxxFile( + FileStream & o, codemaker::cppumaker::Includes & includes) + throw (CannotDumpException) +{ + sal_uInt16 ctors = m_reader.getMethodCount(); + if (ctors > 0) { + //TODO: Decide whether the types added to includes should rather be + // added to m_dependencies (and thus be generated during + // dumpDependedTypes): + includes.addReference(); + includes.addRtlUstringH(); + includes.addRtlUstringHxx(); + includes.add("com/sun/star/lang/XMultiComponentFactory"); + includes.add("com/sun/star/uno/DeploymentException"); + includes.add("com/sun/star/uno/XComponentContext"); + for (sal_uInt16 i = 0; i < ctors; ++i) { + if (isDefaultConstructor(i)) { + includes.add("com/sun/star/uno/Exception"); + includes.add("com/sun/star/uno/RuntimeException"); + } else { + if (!hasRestParameter(i)) { + includes.addAny(); + includes.addSequence(); + sal_uInt16 params = m_reader.getMethodParameterCount(i); + for (sal_uInt16 j = 0; j < params; ++j) { + if (codemaker::UnoType::getSort( + codemaker::UnoType::decompose( + rtl::OUStringToOString( + m_reader.getMethodParameterTypeName( + i, j), + RTL_TEXTENCODING_UTF8), + 0, 0)) + == codemaker::UnoType::SORT_CHAR) + { + includes.addCppuUnotypeHxx(); + break; + } + } + } + codemaker::ExceptionTree tree; + for (sal_uInt16 j = 0; j < m_reader.getMethodExceptionCount(i); + ++j) + { + tree.add( + rtl::OUStringToOString( + m_reader.getMethodExceptionTypeName(i, j), + RTL_TEXTENCODING_UTF8), + m_typeMgr); + } + if (!tree.getRoot()->present) { + includes.add("com/sun/star/uno/Exception"); + includes.add("com/sun/star/uno/RuntimeException"); + includeExceptions(includes, tree.getRoot()); + } + } + } + } + rtl::OString cppName(translateUnoToCppIdentifier( + m_name, "service", isGlobal())); + rtl::OString headerDefine(dumpHeaderDefine(o, "HPP")); + o << "\n"; + includes.dump(o, 0); + o << "\n"; + if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { + o << "\n"; + } + o << "\nclass " << cppName << " {\n"; + inc(); + if (ctors > 0) { + rtl::OString fullName(m_typeName.replace('/', '.')); + rtl::OString baseName( + rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8)); + rtl::OString fullBaseName(baseName.replace('/', '.')); + rtl::OString scopedBaseName(scopedCppName(baseName)); + o << "public:\n"; + for (sal_uInt16 i = 0; i < ctors; ++i) { + if (isDefaultConstructor(i)) { + o << indent() << "static ::com::sun::star::uno::Reference< " + << scopedBaseName << " > " + << translateUnoToCppIdentifier( + "create", "method", ITM_NONGLOBAL, &cppName) + << ("(::com::sun::star::uno::Reference<" + " ::com::sun::star::uno::XComponentContext > const &" + " the_context) {\n"); + inc(); + o << indent() + << ("::com::sun::star::uno::Reference<" + " ::com::sun::star::lang::XMultiComponentFactory >" + " the_factory(the_context->getServiceManager());\n") + << indent() << "if (!the_factory.is()) {\n"; + inc(); + o << indent() + << ("throw ::com::sun::star::uno::DeploymentException(" + "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"component" + " context fails to supply service manager\"))," + " the_context);\n"); + dec(); + o << indent() << "}\n" << indent() + << "::com::sun::star::uno::Reference< " << scopedBaseName + << " > the_instance;\n" << indent() << "try {\n"; + inc(); + o << indent() + << "the_instance = ::com::sun::star::uno::Reference< " + << scopedBaseName + << (" >(the_factory->createInstanceWithContext(" + "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"") + << fullName + << "\")), the_context), ::com::sun::star::uno::UNO_QUERY);\n"; + dec(); + o << indent() + << "} catch (::com::sun::star::uno::RuntimeException &) {\n"; + inc(); + o << indent() << "throw;\n"; + dec(); + o << indent() + << ("} catch (::com::sun::star::uno::Exception &" + " the_exception) {\n"); + inc(); + o << indent() + << ("throw ::com::sun::star::uno::DeploymentException(" + "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" + "\"component context fails to supply service ") + << fullName << " of type " << fullBaseName + << ": \")) + the_exception.Message, the_context);\n"; + dec(); + o << indent() << "}\n" << indent() + << "if (!the_instance.is()) {\n"; + inc(); + o << indent() + << ("throw ::com::sun::star::uno::DeploymentException(" + "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" + "\"component context fails to supply service ") + << fullName << " of type " << fullBaseName + << "\")), the_context);\n"; + dec(); + o << indent() << "}\n" << indent() << "return the_instance;\n"; + dec(); + o << indent() << "}\n\n"; + } else { + o << indent() << "static ::com::sun::star::uno::Reference< " + << scopedBaseName << " > " + << translateUnoToCppIdentifier( + rtl::OUStringToOString( + m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8), + "method", ITM_NONGLOBAL, &cppName) + << ("(::com::sun::star::uno::Reference<" + " ::com::sun::star::uno::XComponentContext > const &" + " the_context"); + sal_uInt16 params = m_reader.getMethodParameterCount(i); + bool rest = hasRestParameter(i); + for (sal_uInt16 j = 0; j < params; ++j) { + o << ", "; + rtl::OStringBuffer buf; + if ((m_reader.getMethodParameterFlags(i, j) & RT_PARAM_REST) + != 0) + { + buf.append(RTL_CONSTASCII_STRINGPARAM("[]")); + } + buf.append( + rtl::OUStringToOString( + m_reader.getMethodParameterTypeName(i, j), + RTL_TEXTENCODING_UTF8)); + rtl::OString type(buf.makeStringAndClear()); + bool byRef = passByReference(type); + dumpType(o, type, byRef, byRef); + o << " " + << translateUnoToCppIdentifier( + rtl::OUStringToOString( + m_reader.getMethodParameterName(i, j), + RTL_TEXTENCODING_UTF8), + "param", ITM_NONGLOBAL); + } + o << ") {\n"; + inc(); + o << indent() + << ("::com::sun::star::uno::Reference<" + " ::com::sun::star::lang::XMultiComponentFactory >" + " the_factory(the_context->getServiceManager());\n") + << indent() << "if (!the_factory.is()) {\n"; + inc(); + o << indent() + << ("throw com::sun::star::uno::DeploymentException(" + "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" + "\"component context fails to supply service manager\"))," + " the_context);\n"); + dec(); + o << indent() << "}\n"; + if (!rest && params > 0) { + o << indent() + << ("::com::sun::star::uno::Sequence<" + " ::com::sun::star::uno::Any > the_arguments(") + << params << ");\n"; + for (sal_uInt16 j = 0; j < params; ++j) { + o << indent() << "the_arguments[" << j << "] "; + rtl::OString param( + translateUnoToCppIdentifier( + rtl::OUStringToOString( + m_reader.getMethodParameterName(i, j), + RTL_TEXTENCODING_UTF8), + "param", ITM_NONGLOBAL)); + sal_Int32 rank; + if (codemaker::UnoType::getSort( + codemaker::UnoType::decompose( + rtl::OUStringToOString( + m_reader.getMethodParameterTypeName( + i, j), + RTL_TEXTENCODING_UTF8), + &rank, 0)) + == codemaker::UnoType::SORT_CHAR) + { + o << "= ::com::sun::star::uno::Any(&" << param + << ", ::cppu::UnoType< "; + for (sal_Int32 k = 0; k < rank; ++k) { + o << "::cppu::UnoSequenceType< "; + } + o << "::cppu::UnoCharType"; + for (sal_Int32 k = 0; k < rank; ++k) { + o << " >"; + } + o << " >::get())"; + } else { + o << "<<= " << param; + } + o << ";\n"; + } + } + o << indent() << "::com::sun::star::uno::Reference< " + << scopedBaseName << " > the_instance;\n"; + codemaker::ExceptionTree tree; + sal_uInt16 exceptions = m_reader.getMethodExceptionCount(i); + for (sal_uInt16 j = 0; j < exceptions; ++j) { + tree.add( + rtl::OUStringToOString( + m_reader.getMethodExceptionTypeName(i, j), + RTL_TEXTENCODING_UTF8), + m_typeMgr); + } + if (!tree.getRoot()->present) { + o << indent() << "try {\n"; + inc(); + } + o << indent() + << "the_instance = ::com::sun::star::uno::Reference< " + << scopedBaseName + << (" >(the_factory->createInstanceWithArgumentsAndContext(" + "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"") + << fullName << "\")), "; + if (rest) { + o << translateUnoToCppIdentifier( + rtl::OUStringToOString( + m_reader.getMethodParameterName(i, 0), + RTL_TEXTENCODING_UTF8), + "param", ITM_NONGLOBAL); + } else if (params == 0) { + o << ("::com::sun::star::uno::Sequence<" + " ::com::sun::star::uno::Any >()"); + } else { + o << "the_arguments"; + } + o << ", the_context), ::com::sun::star::uno::UNO_QUERY);\n"; + if (!tree.getRoot()->present) { + dec(); + o << indent() + << ("} catch (::com::sun::star::uno::RuntimeException &)" + " {\n"); + inc(); + o << indent() << "throw;\n"; + dec(); + dumpCatchClauses(o, tree.getRoot()); + o << indent() + << ("} catch (::com::sun::star::uno::Exception &" + " the_exception) {\n"); + inc(); + o << indent() + << ("throw ::com::sun::star::uno::DeploymentException(" + "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" + "\"component context fails to supply service ") + << fullName << " of type " << fullBaseName + << ": \")) + the_exception.Message, the_context);\n"; + dec(); + o << indent() << "}\n"; + } + o << indent() << "if (!the_instance.is()) {\n"; + inc(); + o << indent() + << ("throw ::com::sun::star::uno::DeploymentException(" + "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" + "\"component context fails to supply service ") + << fullName << " of type " << fullBaseName + << "\")), the_context);\n"; + dec(); + o << indent() << "}\n" << indent() << "return the_instance;\n"; + dec(); + o << indent() << "}\n\n"; + } + } + } + o << "private:\n"; + o << indent() << cppName << "(); // not implemented\n" + << indent() << cppName << "(" << cppName << " &); // not implemented\n" + << indent() << "~" << cppName << "(); // not implemented\n" + << indent() << "void operator =(" << cppName << "); // not implemented\n"; + dec(); + o << "};\n\n"; + if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { + o << "\n"; + } + o << "\n#endif // "<< headerDefine << "\n"; + return true; +} + +void ServiceType::addSpecialDependencies() { + if (m_reader.getMethodCount() > 0) { + OSL_ASSERT(m_reader.getSuperTypeCount() == 1); + m_dependencies.add( + rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8)); + } +} + +bool ServiceType::isDefaultConstructor(sal_uInt16 ctorIndex) const { + return m_reader.getMethodName(ctorIndex).getLength() == 0; +} + +bool ServiceType::hasRestParameter(sal_uInt16 ctorIndex) const { + return m_reader.getMethodParameterCount(ctorIndex) == 1 + && ((m_reader.getMethodParameterFlags(ctorIndex, 0) & RT_PARAM_REST) + != 0); +} + +void ServiceType::dumpCatchClauses( + FileStream & out, codemaker::ExceptionTreeNode const * node) +{ + if (node->present) { + out << indent() << "} catch ("; + dumpType(out, node->name); + out << " &) {\n"; + inc(); + out << indent() << "throw;\n"; + dec(); + } else { + for (codemaker::ExceptionTreeNode::Children::const_iterator i( + node->children.begin()); + i != node->children.end(); ++i) + { + dumpCatchClauses(out, *i); + } + } +} + +//************************************************************************* +// SingletonType +//************************************************************************* + +bool SingletonType::isInterfaceBased() { + return (m_typeMgr.getTypeClass( + rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8))) + == RT_TYPE_INTERFACE; +} + +sal_Bool SingletonType::dumpHxxFile( + FileStream & o, codemaker::cppumaker::Includes & includes) + throw (CannotDumpException) +{ + rtl::OString cppName(translateUnoToCppIdentifier( + m_name, "singleton", isGlobal())); + rtl::OString fullName(m_typeName.replace('/', '.')); + rtl::OString baseName( + rtl::OUStringToOString( + m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8)); + rtl::OString fullBaseName(baseName.replace('/', '.')); + rtl::OString scopedBaseName(scopedCppName(baseName)); + rtl::OString headerDefine(dumpHeaderDefine(o, "HPP")); + o << "\n"; + //TODO: Decide whether the types added to includes should rather be added to + // m_dependencies (and thus be generated during dumpDependedTypes): + includes.add("com/sun/star/uno/DeploymentException"); + includes.add("com/sun/star/uno/XComponentContext"); + includes.addAny(); + includes.addReference(); + includes.addRtlUstringH(); + includes.addRtlUstringHxx(); + includes.dump(o, 0); + o << "\n"; + if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { + o << "\n"; + } + o << "\nclass " << cppName << " {\npublic:\n"; + inc(); + o << indent() << "static ::com::sun::star::uno::Reference< " + << scopedBaseName << " > " + << translateUnoToCppIdentifier("get", "method", ITM_NONGLOBAL, &cppName) + << ("(::com::sun::star::uno::Reference<" + " ::com::sun::star::uno::XComponentContext > const & context) {\n"); + inc(); + o << indent() << "::com::sun::star::uno::Reference< " << scopedBaseName + << " > instance;\n" << indent() + << ("if (!(context->getValueByName(" + "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"/singletons/") + << fullName << "\"))) >>= instance) || !instance.is()) {\n"; + inc(); + o << indent() + << ("throw ::com::sun::star::uno::DeploymentException(" + "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"component context" + " fails to supply singleton ") + << fullName << " of type " << fullBaseName << "\")), context);\n"; + dec(); + o << indent() << "}\n" << indent() << "return instance;\n"; + dec(); + o << indent() << "}\n\n"; + o << "private:\n"; + o << indent() << cppName << "(); // not implemented\n" + << indent() << cppName << "(" << cppName << " &); // not implemented\n" + << indent() << "~" << cppName << "(); // not implemented\n" + << indent() << "void operator =(" << cppName << "); // not implemented\n"; + dec(); + o << "};\n\n"; + if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { + o << "\n"; + } + o << "\n#endif // "<< headerDefine << "\n"; + return true; +} + +//************************************************************************* +// produceType +//************************************************************************* +bool produceType(const OString& typeName, + TypeManager const & typeMgr, + codemaker::GeneratedTypeSet & generated, + CppuOptions* pOptions) + throw( CannotDumpException ) +{ + if (typeName.equals("/") || typeName.equals(typeMgr.getBase()) || + TypeManager::isBaseType(typeName) || generated.contains(typeName)) + { + return true; + } + + sal_Bool bIsExtraType = sal_False; + typereg::Reader reader(typeMgr.getTypeReader(typeName, &bIsExtraType)); + if (bIsExtraType) { + generated.add(typeName); + return true; + } + + if (!reader.isValid()) { + return false; + } + + RTTypeClass typeClass = reader.getTypeClass(); + bool ret = false; + switch (typeClass) + { + case RT_TYPE_INTERFACE: + { + InterfaceType iType(reader, typeName, typeMgr); + ret = iType.dump(pOptions); + if (ret) generated.add(typeName); + iType.dumpDependedTypes(generated, pOptions); + } + break; + case RT_TYPE_MODULE: + { + ModuleType mType(reader, typeName, typeMgr); + if (mType.hasConstants()) + { + ret = mType.dump(pOptions); + if (ret) generated.add(typeName); + } else + { + generated.add(typeName); + ret = true; + } + } + break; + case RT_TYPE_STRUCT: + { + StructureType sType(reader, typeName, typeMgr); + ret = sType.dump(pOptions); + if (ret) generated.add(typeName); + sType.dumpDependedTypes(generated, pOptions); + } + break; + case RT_TYPE_ENUM: + { + EnumType enType(reader, typeName, typeMgr); + ret = enType.dump(pOptions); + if (ret) generated.add(typeName); + enType.dumpDependedTypes(generated, pOptions); + } + break; + case RT_TYPE_EXCEPTION: + { + ExceptionType eType(reader, typeName, typeMgr); + ret = eType.dump(pOptions); + if (ret) generated.add(typeName); + eType.dumpDependedTypes(generated, pOptions); + } + break; + case RT_TYPE_TYPEDEF: + { + TypeDefType tdType(reader, typeName, typeMgr); + ret = tdType.dump(pOptions); + if (ret) generated.add(typeName); + tdType.dumpDependedTypes(generated, pOptions); + } + break; + case RT_TYPE_CONSTANTS: + { + ConstantsType cType(reader, typeName, typeMgr); + if (cType.hasConstants()) + { + ret = cType.dump(pOptions); + if (ret) generated.add(typeName); + } else + { + generated.add(typeName); + ret = true; + } + } + break; + case RT_TYPE_SERVICE: + { + ServiceType t(reader, typeName, typeMgr); + if (t.isSingleInterfaceBased()) { + ret = t.dump(pOptions); + if (ret) { + generated.add(typeName); + t.dumpDependedTypes(generated, pOptions); + } + } else { + ret = true; + } + } + break; + case RT_TYPE_SINGLETON: + { + SingletonType t(reader, typeName, typeMgr); + if (t.isInterfaceBased()) { + ret = t.dump(pOptions); + if (ret) { + generated.add(typeName); + t.dumpDependedTypes(generated, pOptions); + } + } else { + ret = true; + } + } + break; + case RT_TYPE_OBJECT: + ret = true; + break; + default: + OSL_ASSERT(false); + break; + } + + return ret; +} + +bool produceType(RegistryKey& rTypeKey, bool bIsExtraType, + TypeManager const & typeMgr, + codemaker::GeneratedTypeSet & generated, + CppuOptions* pOptions) + throw( CannotDumpException ) +{ + OString typeName = typeMgr.getTypeName(rTypeKey); + + if (typeName.equals("/") ||typeName.equals(typeMgr.getBase()) || + TypeManager::isBaseType(typeName) || generated.contains(typeName)) + { + return true; + } + + if (bIsExtraType) { + generated.add(typeName); + return true; + } + + typereg::Reader reader(typeMgr.getTypeReader(rTypeKey)); + if (!reader.isValid()) { + return false; + } + + RTTypeClass typeClass = reader.getTypeClass(); + bool ret = false; + switch (typeClass) + { + case RT_TYPE_INTERFACE: + { + InterfaceType iType(reader, typeName, typeMgr); + ret = iType.dump(pOptions); + if (ret) generated.add(typeName); + iType.dumpDependedTypes(generated, pOptions); + } + break; + case RT_TYPE_MODULE: + { + ModuleType mType(reader, typeName, typeMgr); + if (mType.hasConstants()) + { + ret = mType.dump(pOptions); + if (ret) generated.add(typeName); + } else + { + generated.add(typeName); + ret = true; + } + } + break; + case RT_TYPE_STRUCT: + { + StructureType sType(reader, typeName, typeMgr); + ret = sType.dump(pOptions); + if (ret) generated.add(typeName); + sType.dumpDependedTypes(generated, pOptions); + } + break; + case RT_TYPE_ENUM: + { + EnumType enType(reader, typeName, typeMgr); + ret = enType.dump(pOptions); + if (ret) generated.add(typeName); + enType.dumpDependedTypes(generated, pOptions); + } + break; + case RT_TYPE_EXCEPTION: + { + ExceptionType eType(reader, typeName, typeMgr); + ret = eType.dump(pOptions); + if (ret) generated.add(typeName); + eType.dumpDependedTypes(generated, pOptions); + } + break; + case RT_TYPE_TYPEDEF: + { + TypeDefType tdType(reader, typeName, typeMgr); + ret = tdType.dump(pOptions); + if (ret) generated.add(typeName); + tdType.dumpDependedTypes(generated, pOptions); + } + break; + case RT_TYPE_CONSTANTS: + { + ConstantsType cType(reader, typeName, typeMgr); + if (cType.hasConstants()) + { + ret = cType.dump(pOptions); + if (ret) generated.add(typeName); + } else + { + generated.add(typeName); + ret = true; + } + } + break; + case RT_TYPE_SERVICE: + { + ServiceType t(reader, typeName, typeMgr); + if (t.isSingleInterfaceBased()) { + ret = t.dump(pOptions); + if (ret) { + generated.add(typeName); + t.dumpDependedTypes(generated, pOptions); + } + } else { + ret = true; + } + } + break; + case RT_TYPE_SINGLETON: + { + SingletonType t(reader, typeName, typeMgr); + if (t.isInterfaceBased()) { + ret = t.dump(pOptions); + if (ret) { + generated.add(typeName); + t.dumpDependedTypes(generated, pOptions); + } + } else { + ret = true; + } + } + break; + case RT_TYPE_OBJECT: + ret = true; + break; + default: + OSL_ASSERT(false); + break; + } + + return ret; +} + +//************************************************************************* +// scopedName +//************************************************************************* +/* +OString scopedName(const OString& scope, const OString& type, + sal_Bool bNoNameSpace) +{ + sal_Int32 nPos = type.lastIndexOf( '/' ); + if (nPos == -1) + return type; + + OStringBuffer tmpBuf(type.getLength()*2); + nPos = 0; + do + { + tmpBuf.append("::"); + OString token(type.getToken(0, '/', nPos)); + if (nPos != -1) + tmpBuf.append(translateUnoToCppIndentifier( + token, "module", ITM_KEYWORDSONLY)); + else + tmpBuf.append(translateUnoToCppIndentifier( + token, "interface", ITM_KEYWORDSONLY)); + } while( nPos != -1 ); + + return tmpBuf.makeStringAndClear(); +} +*/ diff --git a/codemaker/source/cppumaker/cpputype.hxx b/codemaker/source/cppumaker/cpputype.hxx new file mode 100644 index 000000000000..55b74ff60f94 --- /dev/null +++ b/codemaker/source/cppumaker/cpputype.hxx @@ -0,0 +1,406 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_CPPUTYPE_HXX +#define INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_CPPUTYPE_HXX + +#include "codemaker/dependencies.hxx" +#include "codemaker/options.hxx" +#include "codemaker/typemanager.hxx" +#include "codemaker/commoncpp.hxx" +#include "registry/reader.hxx" +#include "registry/types.h" +#include "rtl/string.hxx" + +namespace rtl { class OUString; } +namespace codemaker { + namespace cppumaker { class Includes; } + struct ExceptionTreeNode; + class GeneratedTypeSet; +} + +enum CppuTypeDecl +{ + CPPUTYPEDECL_ALLTYPES, + CPPUTYPEDECL_NOINTERFACES, + CPPUTYPEDECL_ONLYINTERFACES +}; + +class CppuOptions; +class FileStream; + +class CppuType +{ +public: + CppuType(typereg::Reader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr); + + virtual ~CppuType(); + + virtual sal_Bool dump(CppuOptions* pOptions) throw( CannotDumpException ); + sal_Bool dumpFile(CppuOptions* pOptions, + const ::rtl::OString& sExtension, + const ::rtl::OString& sName, + const ::rtl::OString& sOutPath ) + throw( CannotDumpException ); + void dumpDependedTypes( + codemaker::GeneratedTypeSet & generated, CppuOptions * options); + virtual sal_Bool dumpHFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ) = 0; + virtual sal_Bool dumpHxxFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ) = 0; + + ::rtl::OString dumpHeaderDefine( + FileStream& o, char const * prefix, sal_Bool bExtended=sal_False); + + void dumpGetCppuType(FileStream & out); + virtual void dumpLightGetCppuType(FileStream& o); + virtual void dumpNormalGetCppuType(FileStream& o); + virtual void dumpComprehensiveGetCppuType(FileStream& o); + + virtual void dumpType(FileStream& o, const ::rtl::OString& type, bool bConst=false, + bool bRef=false, bool bNative=false, bool cppuUnoType=false) + const throw( CannotDumpException ); + ::rtl::OString getTypeClass(const ::rtl::OString& type="", sal_Bool bCStyle=sal_False); + void dumpCppuGetType(FileStream& o, const ::rtl::OString& type, sal_Bool bDecl=sal_False, CppuTypeDecl eDeclFlag=CPPUTYPEDECL_ALLTYPES); + + ::rtl::OString typeToIdentifier(const ::rtl::OString& type); + + void dumpConstantValue(FileStream& o, sal_uInt16 index); + + virtual sal_uInt32 getMemberCount(); + virtual sal_uInt32 getInheritedMemberCount(); + + void inc(sal_Int32 num=4); + void dec(sal_Int32 num=4); + ::rtl::OString indent() const; +protected: + virtual sal_uInt32 checkInheritedMemberCount( + const typereg::Reader* pReader); + + bool passByReference(rtl::OString const & unoType); + + ::rtl::OString resolveTypedefs(const ::rtl::OString& type) const; + ::rtl::OString checkRealBaseType(const ::rtl::OString& type, sal_Bool bResolveTypeOnly = sal_False) const; + void dumpCppuGetTypeMemberDecl(FileStream& o, CppuTypeDecl eDeclFlag); + + codemaker::cpp::IdentifierTranslationMode isGlobal() const; + + virtual void addSpecialDependencies() {} + + virtual bool dumpFiles(CppuOptions * options, rtl::OString const & outPath); + + virtual void addLightGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const; + + virtual void addNormalGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const; + + virtual void addComprehensiveGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const; + + virtual bool isPolymorphic() const; + + virtual void dumpTemplateHead(FileStream & out) const; + + virtual void dumpTemplateParameters(FileStream & out) const; + + void dumpGetCppuTypePreamble(FileStream & out); + + void dumpGetCppuTypePostamble(FileStream & out); + + void addDefaultHIncludes(codemaker::cppumaker::Includes & includes) const; + void addDefaultHxxIncludes(codemaker::cppumaker::Includes & includes) const; + + void dumpInitializer( + FileStream & out, bool parameterized, rtl::OUString const & type) const; + +protected: + sal_uInt32 m_inheritedMemberCount; + + sal_Bool m_cppuTypeLeak; + sal_Bool m_cppuTypeDynamic; + sal_Int32 m_indentLength; + ::rtl::OString m_typeName; + ::rtl::OString m_name; + typereg::Reader m_reader; + TypeManager const & m_typeMgr; + codemaker::Dependencies m_dependencies; + +private: + void addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes) + const; +}; + +class InterfaceType : public CppuType +{ +public: + InterfaceType(typereg::Reader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr); + + virtual ~InterfaceType(); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); + sal_Bool dumpHxxFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); + + void dumpAttributes(FileStream& o); + void dumpMethods(FileStream& o); + void dumpNormalGetCppuType(FileStream& o); + void dumpComprehensiveGetCppuType(FileStream& o); + void dumpCppuAttributeRefs(FileStream& o, sal_uInt32& index); + void dumpCppuMethodRefs(FileStream& o, sal_uInt32& index); + void dumpCppuAttributes(FileStream& o, sal_uInt32& index); + void dumpCppuMethods(FileStream& o, sal_uInt32& index); + void dumpAttributesCppuDecl(FileStream& o, StringSet* pFinishedTypes, CppuTypeDecl eDeclFlag); + void dumpMethodsCppuDecl(FileStream& o, StringSet* pFinishedTypes, CppuTypeDecl eDeclFlag ); + + sal_uInt32 getMemberCount(); + sal_uInt32 getInheritedMemberCount(); + +protected: + virtual void addSpecialDependencies(); + + virtual void addComprehensiveGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const; + + sal_uInt32 checkInheritedMemberCount(const typereg::Reader* pReader); + +protected: + sal_uInt32 m_inheritedMemberCount; + sal_Bool m_hasAttributes; + sal_Bool m_hasMethods; + +private: + void dumpExceptionSpecification( + FileStream & out, sal_uInt32 methodIndex, bool runtimeException); + + void dumpAttributeExceptionSpecification( + FileStream & out, rtl::OUString const & name, RTMethodMode sort); + + void dumpExceptionTypeName( + FileStream & out, char const * prefix, sal_uInt32 index, + rtl::OUString name); + + sal_Int32 dumpExceptionTypeNames( + FileStream & out, char const * prefix, sal_uInt16 methodIndex, + bool runtimeException); + + sal_Int32 dumpAttributeExceptionTypeNames( + FileStream & out, char const * prefix, rtl::OUString const & name, + RTMethodMode sort); +}; + +class ConstantsType : public CppuType +{ +public: + ConstantsType(typereg::Reader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr); + + virtual ~ConstantsType(); + + virtual sal_Bool dump(CppuOptions* pOptions) throw( CannotDumpException ); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); + sal_Bool dumpHxxFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); + sal_Bool hasConstants(); +}; + +class ModuleType : public ConstantsType +{ +public: + ModuleType(typereg::Reader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr); + + virtual ~ModuleType(); + +protected: + virtual bool dumpFiles(CppuOptions * options, rtl::OString const & outPath); +}; + +class StructureType : public CppuType +{ +public: + StructureType(typereg::Reader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr); + + virtual ~StructureType(); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); + sal_Bool dumpHxxFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); + + virtual void dumpLightGetCppuType(FileStream & out); + + virtual void dumpNormalGetCppuType(FileStream & out); + + virtual void dumpComprehensiveGetCppuType(FileStream & out); + + sal_Bool dumpSuperMember(FileStream& o, const ::rtl::OString& super, sal_Bool bWithType); + +protected: + virtual void addLightGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const; + + virtual void addNormalGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const; + + virtual void addComprehensiveGetCppuTypeIncludes( + codemaker::cppumaker::Includes & includes) const; + + virtual bool isPolymorphic() const; + + virtual void dumpTemplateHead(FileStream & out) const; + + virtual void dumpTemplateParameters(FileStream & out) const; +}; + +class ExceptionType : public CppuType +{ +public: + ExceptionType(typereg::Reader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr); + + virtual ~ExceptionType(); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); + sal_Bool dumpHxxFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); + + sal_Bool dumpSuperMember(FileStream& o, const ::rtl::OString& super, sal_Bool bWithType); +}; + +class EnumType : public CppuType +{ +public: + EnumType(typereg::Reader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr); + + virtual ~EnumType(); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); + sal_Bool dumpHxxFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); + + void dumpNormalGetCppuType(FileStream& o); + void dumpComprehensiveGetCppuType(FileStream& o); +}; + +class TypeDefType : public CppuType +{ +public: + TypeDefType(typereg::Reader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr); + + virtual ~TypeDefType(); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); + sal_Bool dumpHxxFile(FileStream& o, codemaker::cppumaker::Includes & includes) throw( CannotDumpException ); +}; + +class ConstructiveType: public CppuType { +public: + ConstructiveType( + typereg::Reader & reader, rtl::OString const & name, + TypeManager const & manager): + CppuType(reader, name, manager) {} + + virtual sal_Bool dumpHFile( + FileStream & o, codemaker::cppumaker::Includes & includes) + throw (CannotDumpException); + +protected: + virtual bool dumpFiles(CppuOptions * options, rtl::OString const & outPath); +}; + +class ServiceType: public ConstructiveType { +public: + ServiceType( + typereg::Reader & reader, rtl::OString const & name, + TypeManager const & manager): + ConstructiveType(reader, name, manager) {} + + bool isSingleInterfaceBased(); + + virtual sal_Bool dumpHxxFile( + FileStream & o, codemaker::cppumaker::Includes & includes) + throw (CannotDumpException); + +private: + virtual void addSpecialDependencies(); + + bool isDefaultConstructor(sal_uInt16 ctorIndex) const; + + bool hasRestParameter(sal_uInt16 ctorIndex) const; + + void dumpCatchClauses( + FileStream & out, codemaker::ExceptionTreeNode const * node); +}; + +class SingletonType: public ConstructiveType { +public: + SingletonType( + typereg::Reader & reader, rtl::OString const & name, + TypeManager const & manager): + ConstructiveType(reader, name, manager) {} + + bool isInterfaceBased(); + + virtual sal_Bool dumpHxxFile( + FileStream & o, codemaker::cppumaker::Includes & includes) + throw (CannotDumpException); +}; + +bool produceType(const ::rtl::OString& typeName, + TypeManager const & typeMgr, + codemaker::GeneratedTypeSet & generated, + CppuOptions* pOptions) + throw( CannotDumpException ); + +bool produceType(RegistryKey& typeName, bool bIsExtraType, + TypeManager const & typeMgr, + codemaker::GeneratedTypeSet & generated, + CppuOptions* pOptions) + throw( CannotDumpException ); + +/** + * This function returns a C++ scoped name, represents the namespace + * scoping of this type, e.g. com:.sun::star::uno::XInterface. + */ +// ::rtl::OString scopedName(const ::rtl::OString& scope, const ::rtl::OString& type, +// sal_Bool bNoNameSpace=sal_False); + +#endif // INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_CPPUTYPE_HXX + diff --git a/codemaker/source/cppumaker/dumputils.cxx b/codemaker/source/cppumaker/dumputils.cxx new file mode 100644 index 000000000000..b19a98af9f0f --- /dev/null +++ b/codemaker/source/cppumaker/dumputils.cxx @@ -0,0 +1,91 @@ +/************************************************************************* + * + * 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 "dumputils.hxx" + +#include "codemaker/global.hxx" +#include "codemaker/commoncpp.hxx" + +#include "rtl/ustring.hxx" +#include "sal/types.h" + + +namespace codemaker { namespace cppumaker { + +bool dumpNamespaceOpen( + FileStream & out, rtl::OString const & registryType, bool fullModuleType) +{ + bool output = false; + if (registryType != "/") { + bool first = true; + for (sal_Int32 i = 0; i >= 0;) { + rtl::OString id(registryType.getToken(0, '/', i)); + if (fullModuleType || i >= 0) { + if (!first) { + out << " "; + } + out << "namespace " << id << " {"; + first = false; + output = true; + } + } + } + return output; +} + +bool dumpNamespaceClose( + FileStream & out, rtl::OString const & registryType, bool fullModuleType) +{ + bool output = false; + if (registryType != "/") { + bool first = true; + for (sal_Int32 i = 0; i >= 0;) { + i = registryType.indexOf('/', i); + if (i >= 0) { + ++i; + } + if (fullModuleType || i >= 0) { + if (!first) { + out << " "; + } + out << "}"; + first = false; + output = true; + } + } + } + return output; +} + +void dumpTypeIdentifier(FileStream & out, rtl::OString const & registryType) { + out << registryType.copy(registryType.lastIndexOf('/') + 1); +} + +} } diff --git a/codemaker/source/cppumaker/dumputils.hxx b/codemaker/source/cppumaker/dumputils.hxx new file mode 100644 index 000000000000..1f8f1e831c12 --- /dev/null +++ b/codemaker/source/cppumaker/dumputils.hxx @@ -0,0 +1,46 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_DUMPUTILS_HXX +#define INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_DUMPUTILS_HXX + +namespace rtl { class OString; } +class FileStream; + +namespace codemaker { namespace cppumaker { + +bool dumpNamespaceOpen( + FileStream & out, rtl::OString const & registryType, bool fullModuleType); + +bool dumpNamespaceClose( + FileStream & out, rtl::OString const & registryType, bool fullModuleType); + +void dumpTypeIdentifier(FileStream & out, rtl::OString const & registryType); + +} } + +#endif // INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_DUMPUTILS_HXX diff --git a/codemaker/source/cppumaker/includes.cxx b/codemaker/source/cppumaker/includes.cxx new file mode 100644 index 000000000000..e1e3f43360fb --- /dev/null +++ b/codemaker/source/cppumaker/includes.cxx @@ -0,0 +1,280 @@ +/************************************************************************* + * + * 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 "includes.hxx" + +#include "dumputils.hxx" + +#include "codemaker/dependencies.hxx" +#include "codemaker/global.hxx" +#include "codemaker/typemanager.hxx" +#include "codemaker/unotype.hxx" + +#include "osl/diagnose.h" +#include "rtl/string.hxx" +#include "rtl/ustring.hxx" +#include "sal/types.h" + +#include <vector> + +using codemaker::cppumaker::Includes; + +Includes::Includes( + TypeManager const & manager, codemaker::Dependencies const & dependencies, + bool hpp): + m_manager(manager), m_map(dependencies.getMap()), m_hpp(hpp), + m_includeAny(dependencies.hasAnyDependency()), m_includeReference(false), + m_includeSequence(dependencies.hasSequenceDependency()), + m_includeType(dependencies.hasTypeDependency()), + m_includeCppuMacrosHxx(false), m_includeCppuUnotypeHxx(false), + m_includeOslDoublecheckedlockingH(false), m_includeOslMutexHxx(false), + m_includeRtlStrbufHxx(false), m_includeRtlStringH(false), + m_includeRtlTextencH(false), m_includeRtlUstrbufHxx(false), + m_includeRtlUstringH(false), + m_includeRtlUstringHxx(dependencies.hasStringDependency()), + m_includeSalTypesH( + dependencies.hasBooleanDependency() || dependencies.hasByteDependency() + || dependencies.hasShortDependency() + || dependencies.hasUnsignedShortDependency() + || dependencies.hasLongDependency() + || dependencies.hasUnsignedShortDependency() + || dependencies.hasHyperDependency() + || dependencies.hasUnsignedHyperDependency() + || dependencies.hasCharDependency()), + m_includeTypelibTypeclassH(false), + m_includeTypelibTypedescriptionH(false) +{} + +Includes::~Includes() +{} + +void Includes::add(rtl::OString const & registryType) { + sal_Int32 rank; + std::vector< rtl::OString > args; + rtl::OString type( + codemaker::UnoType::decompose(registryType, &rank, &args)); + if (rank > 0) { + m_includeSequence = true; + } + switch (codemaker::UnoType::getSort(type)) { + case codemaker::UnoType::SORT_VOID: + OSL_ASSERT(args.empty()); + OSL_ASSERT(false); + break; + + case codemaker::UnoType::SORT_BOOLEAN: + case codemaker::UnoType::SORT_BYTE: + case codemaker::UnoType::SORT_SHORT: + case codemaker::UnoType::SORT_UNSIGNED_SHORT: + case codemaker::UnoType::SORT_LONG: + case codemaker::UnoType::SORT_UNSIGNED_LONG: + case codemaker::UnoType::SORT_HYPER: + case codemaker::UnoType::SORT_UNSIGNED_HYPER: + case codemaker::UnoType::SORT_CHAR: + OSL_ASSERT(args.empty()); + m_includeSalTypesH = true; + break; + + case codemaker::UnoType::SORT_FLOAT: + case codemaker::UnoType::SORT_DOUBLE: + OSL_ASSERT(args.empty()); + break; + + case codemaker::UnoType::SORT_STRING: + OSL_ASSERT(args.empty()); + m_includeRtlUstringHxx = true; + break; + + case codemaker::UnoType::SORT_TYPE: + OSL_ASSERT(args.empty()); + m_includeType = true; + break; + + case codemaker::UnoType::SORT_ANY: + OSL_ASSERT(args.empty()); + m_includeAny = true; + break; + + case codemaker::UnoType::SORT_COMPLEX: + m_map.insert( + codemaker::Dependencies::Map::value_type( + type, codemaker::Dependencies::KIND_NO_BASE)); + {for (std::vector< rtl::OString >::iterator i(args.begin()); + i != args.end(); ++i) + { + add(*i); + }} + break; + + default: + OSL_ASSERT(false); + break; + } +} + +namespace { + +void dumpEmptyLineBeforeFirst(FileStream & out, bool * first) { + OSL_ASSERT(first != 0); + if (*first) { + out << "\n"; + *first = false; + } +} + +} + +void Includes::dump(FileStream & out, rtl::OString const * companionHdl) { + OSL_ASSERT(companionHdl == 0 || m_hpp); + if (!m_includeReference) { + for (codemaker::Dependencies::Map::iterator i(m_map.begin()); + i != m_map.end(); ++i) + { + if (isInterfaceType(i->first)) { + m_includeReference = true; + break; + } + } + } + out << "#include \"sal/config.h\"\n"; + if (companionHdl) { + out << "\n"; + dumpInclude(out, *companionHdl, false); + } + bool first = true; + for (codemaker::Dependencies::Map::iterator i(m_map.begin()); + i != m_map.end(); ++i) + { + dumpEmptyLineBeforeFirst(out, &first); + if (m_hpp || i->second == codemaker::Dependencies::KIND_BASE + || !isInterfaceType(i->first)) + { + dumpInclude(out, i->first, m_hpp); + } else { + bool ns = dumpNamespaceOpen(out, i->first, false); + if (ns) { + out << " "; + } + out << "class "; + dumpTypeIdentifier(out, i->first); + out << ";"; + if (ns) { + out << " "; + } + dumpNamespaceClose(out, i->first, false); + out << "\n"; + } + } + static char const * hxxExtension[2] = { "h", "hxx" }; + if (m_includeAny) { + dumpEmptyLineBeforeFirst(out, &first); + out << "#include \"com/sun/star/uno/Any." << hxxExtension[m_hpp] << "\"\n"; + } + if (m_includeReference) { + dumpEmptyLineBeforeFirst(out, &first); + out << "#include \"com/sun/star/uno/Reference." << hxxExtension[m_hpp] << "\"\n"; + } + if (m_includeSequence) { + dumpEmptyLineBeforeFirst(out, &first); + out << "#include \"com/sun/star/uno/Sequence." << hxxExtension[m_hpp] << "\"\n"; + } + if (m_includeType) { + dumpEmptyLineBeforeFirst(out, &first); + out << "#include \"com/sun/star/uno/Type." << hxxExtension[m_hpp] << "\"\n"; + } + if (m_includeCppuMacrosHxx) { + dumpEmptyLineBeforeFirst(out, &first); + out << ("#include \"cppu/macros.hxx\"\n"); + } + if (m_includeCppuUnotypeHxx) { + dumpEmptyLineBeforeFirst(out, &first); + out << ("#include \"cppu/unotype.hxx\"\n"); + } + if (m_includeOslDoublecheckedlockingH) { + dumpEmptyLineBeforeFirst(out, &first); + out << ("#include \"osl/doublecheckedlocking.h\"\n"); + } + if (m_includeOslMutexHxx) { + dumpEmptyLineBeforeFirst(out, &first); + out << "#include \"osl/mutex.hxx\"\n"; + } + if (m_includeRtlStrbufHxx) { + dumpEmptyLineBeforeFirst(out, &first); + out << ("#include \"rtl/strbuf.hxx\"\n"); + } + if (m_includeRtlStringH) { + dumpEmptyLineBeforeFirst(out, &first); + out << "#include \"rtl/string.h\"\n"; + } + if (m_includeRtlTextencH) { + dumpEmptyLineBeforeFirst(out, &first); + out << "#include \"rtl/textenc.h\"\n"; + } + if (m_includeRtlUstrbufHxx) { + dumpEmptyLineBeforeFirst(out, &first); + out << ("#include \"rtl/ustrbuf.hxx\"\n"); + } + if (m_includeRtlUstringH) { + dumpEmptyLineBeforeFirst(out, &first); + out << "#include \"rtl/ustring.h\"\n"; + } + if (m_includeRtlUstringHxx) { + dumpEmptyLineBeforeFirst(out, &first); + out << ("#include \"rtl/ustring.hxx\"\n"); + } + if (m_includeSalTypesH) { + dumpEmptyLineBeforeFirst(out, &first); + out << "#include \"sal/types.h\"\n"; + } + if (m_includeTypelibTypeclassH) { + dumpEmptyLineBeforeFirst(out, &first); + out << ("#include \"typelib/typeclass.h\"\n"); + } + if (m_includeTypelibTypedescriptionH) { + dumpEmptyLineBeforeFirst(out, &first); + out << ("#include \"typelib/typedescription.h\"\n"); + } +} + +void Includes::dumpInclude( + FileStream & out, rtl::OString const & registryType, bool hpp, + rtl::OString const & suffix) +{ + static char const * extension[2] = { "hdl", "hpp" }; + out << "#include \"" << registryType; + if (suffix.getLength() > 0) { + out << "/" << suffix; + } + out << "." << extension[hpp] << "\"\n"; +} + +bool Includes::isInterfaceType(rtl::OString const & registryType) const { + return m_manager.getTypeClass(registryType) == RT_TYPE_INTERFACE; +} diff --git a/codemaker/source/cppumaker/includes.hxx b/codemaker/source/cppumaker/includes.hxx new file mode 100644 index 000000000000..afa2b41f09f3 --- /dev/null +++ b/codemaker/source/cppumaker/includes.hxx @@ -0,0 +1,121 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_INCLUDES_HXX +#define INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_INCLUDES_HXX + +#include "codemaker/dependencies.hxx" +#include "rtl/ustring.hxx" + +class FileStream; +class TypeManager; + +namespace codemaker { namespace cppumaker { + +class Includes { +public: + Includes( + TypeManager const & manager, + codemaker::Dependencies const & dependencies, bool hpp); + + ~Includes(); + + void add(rtl::OString const & registryType); + + void addAny() { m_includeAny = true; } + + void addReference() { m_includeReference = true; } + + void addSequence() { m_includeSequence = true; } + + void addType() { m_includeType = true; } + + void addCppuMacrosHxx() { m_includeCppuMacrosHxx = true; } + + void addCppuUnotypeHxx() { m_includeCppuUnotypeHxx = true; } + + void addOslDoublecheckedlockingH() + { m_includeOslDoublecheckedlockingH = true; } + + void addOslMutexHxx() { m_includeOslMutexHxx = true; } + + void addRtlStrbufHxx() { m_includeRtlStrbufHxx = true; } + + void addRtlStringH() { m_includeRtlStringH = true; } + + void addRtlTextencH() { m_includeRtlTextencH = true; } + + void addRtlUstrbufHxx() { m_includeRtlUstrbufHxx = true; } + + void addRtlUstringH() { m_includeRtlUstringH = true; } + + void addRtlUstringHxx() { m_includeRtlUstringHxx = true; } + + void addSalTypesH() { m_includeSalTypesH = true; } + + void addTypelibTypeclassH() { m_includeTypelibTypeclassH = true; } + + void addTypelibTypedescriptionH() + { m_includeTypelibTypedescriptionH = true; } + + void dump(FileStream & out, rtl::OString const * companionHdl); + + static void dumpInclude( + FileStream & out, rtl::OString const & registryType, bool hpp, + rtl::OString const & suffix = rtl::OString()); + +private: + Includes(Includes &); // not implemented + void operator =(Includes); // not implemented; + + bool isInterfaceType(rtl::OString const & registryType) const; + + TypeManager const & m_manager; + codemaker::Dependencies::Map m_map; + bool m_hpp; + bool m_includeAny; + bool m_includeReference; + bool m_includeSequence; + bool m_includeType; + bool m_includeCppuMacrosHxx; + bool m_includeCppuUnotypeHxx; + bool m_includeOslDoublecheckedlockingH; + bool m_includeOslMutexHxx; + bool m_includeRtlStrbufHxx; + bool m_includeRtlStringH; + bool m_includeRtlTextencH; + bool m_includeRtlUstrbufHxx; + bool m_includeRtlUstringH; + bool m_includeRtlUstringHxx; + bool m_includeSalTypesH; + bool m_includeTypelibTypeclassH; + bool m_includeTypelibTypedescriptionH; +}; + +} } + +#endif // INCLUDED_CODEMAKER_SOURCE_CPPUMAKER_INCLUDES_HXX diff --git a/codemaker/source/cppumaker/makefile.mk b/codemaker/source/cppumaker/makefile.mk new file mode 100644 index 000000000000..a3ff38c4c07a --- /dev/null +++ b/codemaker/source/cppumaker/makefile.mk @@ -0,0 +1,65 @@ +#************************************************************************* +# +# 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=cppumaker +TARGETTYPE=CUI +LIBTARGET=NO + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/codemaker.pmk + +# --- Files -------------------------------------------------------- + +.IF "$(GUI)"=="WNT" +.IF "$(COM)"!="GCC" +CFLAGSNOOPT+=-Ob0 +.ENDIF +.ENDIF + +OBJFILES= $(OBJ)$/cppumaker.obj \ + $(OBJ)$/cppuoptions.obj \ + $(OBJ)$/cpputype.obj \ + $(OBJ)$/dumputils.obj \ + $(OBJ)$/includes.obj + +NOOPTFILES= \ + $(OBJ)$/cpputype.obj + +APP1TARGET= $(TARGET) +APP1RPATH=SDK +APP1OBJS= $(OBJFILES) + +APP1DEPN= $(OUT)$/lib$/$(CODEMAKERLIBDEPN) $(OUT)$/lib$/$(COMMONCPPLIBDEPN) +APP1STDLIBS= $(SALLIB) $(SALHELPERLIB) $(REGLIB) $(CODEMAKERLIBST) $(COMMONCPPLIBST) + +.INCLUDE : target.mk diff --git a/codemaker/source/cunomaker/cunomaker.cxx b/codemaker/source/cunomaker/cunomaker.cxx new file mode 100644 index 000000000000..56f20b0968c1 --- /dev/null +++ b/codemaker/source/cunomaker/cunomaker.cxx @@ -0,0 +1,186 @@ +/************************************************************************* + * + * 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 <stdio.h> + +#include "sal/main.h" + +#include <codemaker/typemanager.hxx> +#include <codemaker/dependency.hxx> + +#include "cunooptions.hxx" +#include "cunotype.hxx" + +using namespace rtl; + +sal_Bool produceAllTypes(const OString& typeName, + TypeManager& typeMgr, + TypeDependency& typeDependencies, + CunoOptions* pOptions, + sal_Bool bFullScope) + throw( CannotDumpException ) +{ + if (!produceType(typeName, typeMgr, typeDependencies, pOptions)) + { + fprintf(stderr, "%s ERROR: %s\n", + pOptions->getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + + RegistryKey typeKey = typeMgr.getTypeKey(typeName); + RegistryKeyNames subKeys; + + if (typeKey.getKeyNames(OUString(), subKeys)) + return sal_False; + + OString tmpName; + for (sal_uInt32 i=0; i < subKeys.getLength(); i++) + { + tmpName = OUStringToOString(subKeys.getElement(i), RTL_TEXTENCODING_UTF8); + + if (pOptions->isValid("-B")) + tmpName = tmpName.copy(tmpName.indexOf('/', 1) + 1); + else + tmpName = tmpName.copy(1); + + if (bFullScope) + { + if (!produceAllTypes(tmpName, typeMgr, typeDependencies, pOptions, sal_True)) + return sal_False; + } else + { + if (!produceType(tmpName, typeMgr, typeDependencies, pOptions)) + return sal_False; + } + } + + return sal_True; +} + +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) +{ + CunoOptions options; + + try + { + if (!options.initOptions(argc, argv)) + { + exit(1); + } + } + catch( IllegalArgument& e) + { + fprintf(stderr, "Illegal option: %s\n", e.m_message.getStr()); + exit(99); + } + + RegistryTypeManager typeMgr; + TypeDependency typeDependencies; + + if (!typeMgr.init(!options.isValid("-T"), options.getInputFiles())) + { + fprintf(stderr, "%s : init registries failed, check your registry files.\n", options.getProgramName().getStr()); + exit(99); + } + + if (options.isValid("-B")) + { + typeMgr.setBase(options.getOption("-B")); + } + + try + { + if (options.isValid("-T")) + { + OString tOption(options.getOption("-T")); + + OString typeName, tmpName; + sal_Bool ret = sal_False; + sal_Int32 nIndex = 0; + do + { + typeName = tOption.getToken(0, ';', nIndex); + + sal_Int32 nPos = typeName.lastIndexOf( '.' ); + tmpName = typeName.copy( nPos != -1 ? nPos+1 : 0 ); + if (tmpName == "*") + { + // produce this type and his scope, but the scope is not recursively generated. + if (typeName.equals("*")) + { + tmpName = "/"; + } else + { + tmpName = typeName.copy(0, typeName.lastIndexOf('.')).replace('.', '/'); + if (tmpName.getLength() == 0) + tmpName = "/"; + else + tmpName.replace('.', '/'); + } + ret = produceAllTypes(tmpName, typeMgr, typeDependencies, &options, sal_False); + } else + { + // produce only this type + ret = produceType(typeName.replace('.', '/'), typeMgr, typeDependencies, &options); + } + + if (!ret) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + } while( nIndex != -1 ); + } else + { + // produce all types + if (!produceAllTypes("/", typeMgr, typeDependencies, &options, sal_True)) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + "an error occurs while dumping all types."); + exit(99); + } + } + } + catch( CannotDumpException& e) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + e.m_message.getStr()); + exit(99); + } + + return 0; +} + + diff --git a/codemaker/source/cunomaker/cunooptions.cxx b/codemaker/source/cunomaker/cunooptions.cxx new file mode 100644 index 000000000000..50a1223d004f --- /dev/null +++ b/codemaker/source/cunomaker/cunooptions.cxx @@ -0,0 +1,330 @@ +/************************************************************************* + * + * 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 <stdio.h> + +#include "cunooptions.hxx" + +using namespace rtl; + +sal_Bool CunoOptions::initOptions(int ac, char* av[], sal_Bool bCmdFile) + throw( IllegalArgument ) +{ + sal_Bool ret = sal_True; + sal_uInt16 i=0; + + if (!bCmdFile) + { + bCmdFile = sal_True; + + m_program = av[0]; + + if (ac < 2) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } + + i = 1; + } else + { + i = 0; + } + + char *s=NULL; + for (i; i < ac; i++) + { + if (av[i][0] == '-') + { + switch (av[i][1]) + { + case 'O': + if (av[i][2] == 'C') + { + if (av[i][3] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-OC', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 3; + } + + m_options["-OC"] = OString(s); + break; + } else + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-O', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_options["-O"] = OString(s); + break; + case 'B': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-B', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_options["-B"] = OString(s); + break; + case 'T': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-T', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + if (m_options.count("-T") > 0) + { + OString tmp(m_options["-T"]); + tmp = tmp + ";" + s; + m_options["-T"] = tmp; + } else + { + m_options["-T"] = OString(s); + } + break; + case 'U': + if (av[i][2] != '\0') + { + OString tmp("'-U', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + m_options["-U"] = OString(""); + break; +/* + case 'L': + if (av[i][2] != '\0') + { + OString tmp("'-L', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + if (isValid("-C") || isValid("-CS")) + { + OString tmp("'-L' could not be combined with '-C' or '-CS' option"); + throw IllegalArgument(tmp); + } + m_options["-L"] = OString(""); + break; +*/ + case 'C': + if (av[i][2] != '\0') + { + OString tmp("'-C', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + if (isValid("-L") || isValid("-CS")) + { + OString tmp("'-C' could not be combined with '-L' or '-CS' option"); + throw IllegalArgument(tmp); + } + m_options["-C"] = OString(""); + break; + case 'G': + if (av[i][2] == 'c') + { + if (av[i][3] != '\0') + { + OString tmp("'-Gc', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + m_options["-Gc"] = OString(""); + break; + } else + if (av[i][2] != '\0') + { + OString tmp("'-G', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + m_options["-G"] = OString(""); + break; + default: + throw IllegalArgument("the option is unknown" + OString(av[i])); + break; + } + } else + { + if (av[i][0] == '@') + { + FILE* cmdFile = fopen(av[i]+1, "r"); + if( cmdFile == NULL ) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } else + { + int rargc=0; + char* rargv[512]; + char buffer[512]; + + while ( fscanf(cmdFile, "%s", buffer) != EOF ) + { + rargv[rargc]= strdup(buffer); + rargc++; + } + fclose(cmdFile); + + ret = initOptions(rargc, rargv, bCmdFile); + + for (long i=0; i < rargc; i++) + { + free(rargv[i]); + } + } + } else + { + m_inputFiles.push_back(av[i]); + } + } + } + + return ret; +} + +OString CunoOptions::prepareHelp() +{ + OString help("\nusing: "); + help += m_program + " [-options] file_1 ... file_n\nOptions:\n"; + help += " -O<path> = path describes the root directory for the generated output.\n"; + help += " The output directory tree is generated under this directory.\n"; + help += " -T<name> = name specifies a type or a list of types. The output for this\n"; + help += " [t1;...] type is generated. If no '-T' option is specified,\n"; + help += " then output for all types is generated.\n"; + help += " Example: 'com.sun.star.uno.XInterface' is a valid type.\n"; + help += " -B<name> = name specifies the base node. All types are searched under this\n"; + help += " node. Default is the root '/' of the registry files.\n"; + help += " -U = activate the generating of a getCppuType_<name> function.\n"; +// help += " -L = getCppuType function with a known leak.\n"; + help += " -C = getCppuType_<name> function keeps comprehensive type information.\n"; + help += " -G = generate only target files which does not exists.\n"; + help += " -Gc = generate only target files which content will be changed.\n"; + help += prepareVersion(); + + return help; +} + +OString CunoOptions::prepareVersion() +{ + OString version("\nSun Microsystems (R) "); + version += m_program + " Version 1.0\n\n"; + + return version; +} + + diff --git a/codemaker/source/cunomaker/cunooptions.hxx b/codemaker/source/cunomaker/cunooptions.hxx new file mode 100644 index 000000000000..ba47d6bcf1b9 --- /dev/null +++ b/codemaker/source/cunomaker/cunooptions.hxx @@ -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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_SOURCE_CUNOMAKER_CUNOOPTIONS_HXX +#define INCLUDED_CODEMAKER_SOURCE_CUNOMAKER_CUNOOPTIONS_HXX + +#include <codemaker/options.hxx> + +class CunoOptions : public Options +{ +public: + CunoOptions() + : Options() {} + + ~CunoOptions() {} + + sal_Bool initOptions(int ac, char* av[], sal_Bool bCmdFile=sal_False) + throw( IllegalArgument ); + + ::rtl::OString prepareHelp(); + + ::rtl::OString prepareVersion(); + +protected: +}; + +#endif // INCLUDED_CODEMAKER_SOURCE_CUNOMAKER_CUNOOPTIONS_HXX diff --git a/codemaker/source/cunomaker/cunotype.cxx b/codemaker/source/cunomaker/cunotype.cxx new file mode 100644 index 000000000000..56e87300eebe --- /dev/null +++ b/codemaker/source/cunomaker/cunotype.cxx @@ -0,0 +1,3533 @@ +/************************************************************************* + * + * 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 <stdio.h> +#include <rtl/alloc.h> +#include <rtl/ustring.hxx> +#include <rtl/strbuf.hxx> + +#include "cunotype.hxx" +#include "cunooptions.hxx" + +using namespace rtl; + +//************************************************************************* +// CunoType +//************************************************************************* +CunoType::CunoType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : m_inheritedMemberCount(0) + , m_cunoTypeLib(sal_False) + , m_cunoTypeLeak(sal_False) + , m_cunoTypeDynamic(sal_True) + , m_indentLength(0) + , m_typeName(typeName) +// , m_name(typeName.getToken(typeName.getTokenCount('/') - 1, '/')) + , m_name(typeName.replace('/', '_')) + , m_reader(typeReader) + , m_typeMgr((TypeManager&)typeMgr) + , m_dependencies(typeDependencies) + , m_bIsNestedType(sal_False) +{ + // check if this type is nested + sal_Int32 i = typeName.lastIndexOf('/'); + + if (i >= 0) + { + OString outerTypeName(typeName.copy(0, i)); + m_bIsNestedType = (m_typeMgr.getTypeClass(outerTypeName) == RT_TYPE_INTERFACE); + } + + // check if this type has nested types + RegistryKey key = m_typeMgr.getTypeKey(typeName); + + key.getKeyNames(OUString(), m_nestedTypeNames); +} + +CunoType::~CunoType() +{ + +} + +sal_Bool CunoType::isNestedTypeByName(const ::rtl::OString& type) +{ + sal_Bool ret = sal_False; + + sal_Int32 i = type.lastIndexOf('/'); + + if (i >= 0) + { + OString outerTypeName(type.copy(0, i)); + ret = (m_typeMgr.getTypeClass(outerTypeName) == RT_TYPE_INTERFACE); + } + + return ret; +} + +sal_Bool CunoType::hasNestedType(const ::rtl::OString& type) +{ + sal_Bool ret = sal_False; + + if (m_nestedTypeNames.getLength() > 0) + { + OUString typeName(OStringToOUString(type, RTL_TEXTENCODING_UTF8)); + + for (sal_uInt32 i = 0; !ret && (i < m_nestedTypeNames.getLength()); i++) + ret = typeName.equals(m_nestedTypeNames.getElement(i).copy(5)); + } + + return ret; +} + +sal_Bool CunoType::dump(CunoOptions* pOptions) + throw( CannotDumpException ) +{ + sal_Bool ret = sal_False; + + if (isNestedType()) + return sal_True; + + if (pOptions->isValid("-U")) + m_cunoTypeLib = sal_True; + if (pOptions->isValid("-L")) + m_cunoTypeLeak = sal_True; + if (pOptions->isValid("-C")) + m_cunoTypeDynamic = sal_False; + + OString outPath; + if (pOptions->isValid("-O")) + outPath = pOptions->getOption("-O"); + + OString tmpFileName; + OString hFileName = createFileNameFromType(outPath, m_typeName, ".h"); + + sal_Bool bFileExists = sal_False; + sal_Bool bFileCheck = sal_False; + + if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) + { + bFileExists = fileExists( hFileName ); + ret = sal_True; + } + + if ( bFileExists && pOptions->isValid("-Gc") ) + { + tmpFileName = createFileNameFromType(outPath, m_typeName, ".tmh"); + bFileCheck = sal_True; + } + + if ( !bFileExists || bFileCheck ) + { + FileStream hFile; + + if ( bFileCheck ) + hFile.open(tmpFileName); + else + hFile.open(hFileName); + + if(!hFile.isValid()) + { + OString message("cannot open "); + message += hFileName + " for writing"; + throw CannotDumpException(message); + } + + ret = dumpHFile(hFile); + + hFile.close(); + if (ret && bFileCheck) + { + ret = checkFileContent(hFileName, tmpFileName); + } + } + + if ( m_cunoTypeLib ) + { + bFileExists = sal_False; + bFileCheck = sal_False; + + if (pOptions->isValid("-OC")) + outPath = pOptions->getOption("-OC"); + else + outPath = OString(); + + OString cFileName = createFileNameFromType(outPath, m_typeName, ".c"); + + if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) + { + bFileExists = fileExists( cFileName ); + ret = sal_True; + } + + if ( bFileExists && pOptions->isValid("-Gc") ) + { + tmpFileName = createFileNameFromType(outPath, m_typeName, ".tmc"); + bFileCheck = sal_True; + } + + if ( !bFileExists || bFileCheck ) + { + FileStream cFile; + + if ( bFileCheck ) + cFile.open(tmpFileName); + else + cFile.open(cFileName); + + if(!cFile.isValid()) + { + OString message("cannot open "); + message += cFileName + " for writing"; + throw CannotDumpException(message); + } + + ret = dumpCFile(cFile); + + cFile.close(); + if (ret && bFileCheck) + { + ret = checkFileContent(cFileName, tmpFileName); + } + } + } + return ret; +} +sal_Bool CunoType::dumpDependedTypes(CunoOptions* pOptions) + throw( CannotDumpException ) +{ + sal_Bool ret = sal_True; + + TypeUsingSet usingSet(m_dependencies.getDependencies(m_typeName)); + + TypeUsingSet::const_iterator iter = usingSet.begin(); + OString typeName; + sal_uInt32 index = 0; + while (iter != usingSet.end()) + { + typeName = (*iter).m_type; + if ((index = typeName.lastIndexOf(']')) > 0) + typeName = typeName.copy(index + 1); + + if (getBaseType(typeName).getLength() == 0) + { + if (!produceType(typeName, + m_typeMgr, + m_dependencies, + pOptions)) + { + fprintf(stderr, "%s ERROR: %s\n", + pOptions->getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + } + ++iter; + } + + return ret; +} + +OString CunoType::dumpHeaderDefine(FileStream& o, sal_Char* prefix, sal_Bool bExtended) +{ + if (m_typeName.equals("/")) + { + bExtended = sal_False; + m_typeName = "global"; + } + + sal_uInt32 length = 3 + m_typeName.getLength() + strlen(prefix); + + if (bExtended) + length += m_name.getLength() + 1; + + OStringBuffer tmpBuf(length); + + tmpBuf.append('_'); + tmpBuf.append(m_typeName); + tmpBuf.append('_'); + if (bExtended) + { + tmpBuf.append(m_name); + tmpBuf.append('_'); + } + tmpBuf.append(prefix); + tmpBuf.append('_'); + + OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase()); + + o << "#ifndef " << tmp << "\n#define " << tmp << "\n"; + + return tmp; +} + +void CunoType::dumpDefaultHIncludes(FileStream& o) +{ + o << "#ifndef _UNO_CUNO_H_\n" + << "#include <uno/cuno.h>\n" + << "#endif\n"; +/* + if (m_typeMgr.getTypeClass(m_typeName) == RT_TYPE_INTERFACE && + !m_typeName.equals("com/sun/star/uno/XInterface") ) + { + o << "#ifndef _COM_SUN_STAR_UNO_XINTERFACE_H_\n" + << "#include <com/sun/star/uno/XInterface.h>\n" + << "#endif\n"; + } +*/ +} + +void CunoType::dumpDefaultCIncludes(FileStream& o) +{ + o << "#ifndef _OSL_MUTEX_H_\n" + << "#include <osl/mutex.h>\n" + << "#endif\n\n"; +} + +void CunoType::dumpInclude(FileStream& o, const OString& typeName, sal_Char* prefix, sal_Bool bExtended, sal_Bool bCaseSensitive) +{ + sal_uInt32 length = 3+ m_typeName.getLength() + strlen(prefix); + + if (bExtended) + length += m_name.getLength() + 1; + + OStringBuffer tmpBuf(length); + + tmpBuf.append('_'); + tmpBuf.append(typeName); + tmpBuf.append('_'); + if (bExtended) + { + tmpBuf.append(m_name); + tmpBuf.append('_'); + } + tmpBuf.append(prefix); + tmpBuf.append('_'); + + OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase()); + + length = 1 + typeName.getLength() + strlen(prefix); + if (bExtended) + length += m_name.getLength() + 1; + + tmpBuf.ensureCapacity(length); + tmpBuf.append(typeName); + if (bExtended) + { + tmpBuf.append('/'); + tmpBuf.append(m_name); + } + tmpBuf.append('.'); + tmpBuf.append(prefix); + + o << "#ifndef " << tmp << "\n#include <"; + if (bCaseSensitive) + { + o << tmpBuf.makeStringAndClear(); + } else + { + o << tmpBuf.makeStringAndClear(); + } + o << ">\n#endif\n"; +} + +void CunoType::dumpDepIncludes(FileStream& o, const OString& typeName, sal_Char* prefix) +{ + TypeUsingSet usingSet(m_dependencies.getDependencies(typeName)); + + TypeUsingSet::const_iterator iter = usingSet.begin(); + + OString sPrefix(OString(prefix).toAsciiUpperCase()); + sal_Bool bSequenceDumped = sal_False; + sal_uInt32 index = 0; + sal_uInt32 seqNum = 0; + OString relType; + while (iter != usingSet.end()) + { + sal_Bool bDumpThisType = sal_True; + index = (*iter).m_type.lastIndexOf(']'); + seqNum = (index > 0 ? ((index+1) / 2) : 0); + + relType = (*iter).m_type; + if (index > 0) + relType = relType.copy(index+1); + + if (isNestedTypeByName(relType) && hasNestedType(relType)) + bDumpThisType = sal_False; + + if (bDumpThisType) + { + OString defPrefix("H"); + if (sPrefix.equals("H")) + defPrefix = "H"; + + if (seqNum > 0 && !bSequenceDumped) + { + bSequenceDumped = sal_True; + o << "#ifndef _UNO_SEQUENCE2_" << defPrefix + << "_\n#include <uno/sequence2." << defPrefix.toAsciiLowerCase() + << ">\n#endif\n"; + } + + if (getBaseType(relType).getLength() == 0 && + m_typeName != relType) + { + if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE + && sPrefix.equals("H")) + { + if (!((*iter).m_use & TYPEUSE_SUPER)) + { + if (isNestedTypeByName(relType)) + { + sal_Int32 iLastS = relType.lastIndexOf('/'); + + OString outerNamespace(relType.copy(0,iLastS)); + OString innerClass(relType.copy(iLastS+1)); + + iLastS = outerNamespace.lastIndexOf('/'); + OString outerClass(outerNamespace.copy(iLastS+1)); + +// o << "\n"; +// dumpNameSpace(o, sal_True, sal_False, outerNamespace); +// o << "\nclass " << outerClass << "::" << innerClass << ";\n"; +// dumpNameSpace(o, sal_False, sal_False, outerNamespace); +// o << "\n\n"; + } + else + { +// dumpInclude(o, relType, prefix); + OString type(relType.replace('/', '_')); + o << "\n#ifndef " << type.toAsciiUpperCase() << "\n"; + o << "#define " << type.toAsciiUpperCase() << "\n"; + o << "struct _" << type << ";\n" + << "typedef struct _" << type << "_ftab * " << type << ";\n"; + o << "#endif\n\n"; + } + } else + { + if (isNestedTypeByName(relType)) + { + sal_Int32 iLastS = relType.lastIndexOf('/'); + + OString outerNamespace(relType.copy(0,iLastS)); + + dumpInclude(o, outerNamespace, prefix); + } + else + dumpInclude(o, relType, prefix); + } + } else + { + if (isNestedTypeByName(relType)) + { + sal_Int32 iLastS = relType.lastIndexOf('/'); + + OString outerNamespace(relType.copy(0,iLastS)); + + dumpInclude(o, outerNamespace, prefix); + } + else + dumpInclude(o, relType, prefix); + } + } else + if (relType == "any") + { + o << "#ifndef _UNO_ANY2_H_\n" + << "#include <uno/any2.h>\n" + << "#endif\n"; + } else + if (relType == "type") + { + o << "#ifndef _TYPELIB_TYPEDESCRIPTION_H_\n" + << "#include <typelib/typedescription.h>\n" + << "#endif\n"; + } else + if (relType == "string" && sPrefix.equals("H")) + { + o << "#ifndef _RTL_USTRING_H_\n" + << "#include <rtl/ustring.h>\n" + << "#endif\n"; + } + } + ++iter; + } + if (m_typeName.equals(typeName) && (getNestedTypeNames().getLength() > 0)) + { + o << "// includes for nested types\n\n"; + + for (sal_uInt32 i = 0; i < getNestedTypeNames().getLength(); i++) + { + OUString s(getNestedTypeNames().getElement(i)); + + OString nestedName(s.getStr(), s.getLength(), RTL_TEXTENCODING_UTF8); + + dumpDepIncludes(o, nestedName, prefix); + } + } +} + +void CunoType::dumpOpenExternC(FileStream& o) +{ + o << "#ifdef __cplusplus\n" + << "extern \"C\" {\n" + << "#endif\n\n"; +} + +void CunoType::dumpCloseExternC(FileStream& o) +{ + o << "#ifdef __cplusplus\n" + << "}\n" + << "#endif\n\n"; +} + +void CunoType::dumpLGetCunoType(FileStream& o) +{ + OString typeName(m_typeName.replace('/', '_')); + + o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << "#endif\n\n"; + + if (m_reader.getTypeClass() == RT_TYPE_TYPEDEF) + { + o << "inline const ::com::sun::star::uno::Type& SAL_CALL get_" << typeName << "_Type( ) SAL_THROW( () )\n{\n"; + } else + { + o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCunoType( "; + dumpType(o, m_typeName, sal_True, sal_False); + o << "* ) SAL_THROW( () )\n{\n"; + } + inc(); + + o << indent() << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << indent() << "#endif\n\n"; + + o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n"; + inc(); + o << indent() << "typelib_static_type_init( &s_pType_" << typeName << ", " + << getTypeClass(m_typeName, sal_True) << ", \"" << m_typeName.replace('/', '.') << "\" );\n"; + dec(); + o << indent() << "}\n"; + o << indent() << "return * reinterpret_cast< ::com::sun::star::uno::Type * >( &s_pType_" + << typeName <<" );\n"; + dec(); + o << indent() << "}\n"; + + return; +} + +void CunoType::dumpGetCunoType(FileStream& o) +{ + OString typeName(m_typeName.replace('/', '_')); + + if ( m_cunoTypeLeak ) + { + dumpLGetCunoType(o); + return; + } + if ( !m_cunoTypeDynamic ) + { + dumpCGetCunoType(o); + return; + } + + dumpOpenExternC(o); + + if ( !m_typeName.equals("com/sun/star/uno/Exception") ) + { + o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << "#endif\n\n"; + } + + o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n"; + inc(); + + if ( m_typeName.equals("com/sun/star/uno/Exception") ) + { + o << indent() << "return typelib_static_type_getByTypeClass( typelib_TypeClass_EXCEPTION );\n"; + } else + { + o << indent() << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << indent() << "#endif\n\n"; + + o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n"; + inc(); + + OString superType(m_reader.getSuperTypeName()); + sal_Bool bIsBaseException = sal_False; + if (superType.getLength() > 0) + { + if ( superType.equals("com/sun/star/uno/Exception") ) + { + bIsBaseException = sal_True; + } else + { + o << indent() << "typelib_TypeDescriptionReference * pBaseType = 0;\n"; + } + } + + sal_uInt32 count = getMemberCount(); + if (count) + { + o << indent() << "typelib_TypeDescriptionReference * aMemberRefs[" << count << "];\n"; + } + + if ( !bIsBaseException ) + { + o << indent() << "typelib_typedescriptionreference_newByAsciiName(&pBaseType, typelib_TypeClass_INTERFACE, \"" + << superType.replace('/', '.') << "\" );\n"; + } + + if (count) + { + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldType, fieldName; + OString scope = m_typeName.replace('/', '.'); + sal_Bool bWithScope = sal_True; + OString modFieldType; + StringSet generatedTypeSet; + StringSet::iterator findIter; + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = m_reader.getFieldName(i); + fieldType = checkRealBaseType(m_reader.getFieldType(i), sal_True); + +// modFieldType = typeToIdentifier(fieldType); + + findIter = generatedTypeSet.find(fieldType); + if ( findIter == generatedTypeSet.end() ) + { + generatedTypeSet.insert(fieldType); + o << indent() << "typelib_typedescriptionreference_newByAsciiName(&aMemberRefs[" + << i << "], " << getTypeClass(fieldType, sal_True); + o << " , \"" << fieldType.replace('/', '.') << "\" );\n"; + } + } + o << "\n"; + } + + o << indent() << "typelib_static_compound_type_init( &s_pType_" << typeName << ", " + << getTypeClass(m_typeName, sal_True) << ", \"" << m_typeName.replace('/', '.') << "\", "; + if ( superType.getLength() > 0 || bIsBaseException ) + { + if ( bIsBaseException ) + { + o << "* typelib_static_type_getByTypeClass( typelib_TypeClass_EXCEPTION ), " + << count << ", "; + } else + { + o << "pBaseType, " << count << ", "; + } + } else + { + o << "0, " << count << ", "; + } + + if (count) + { + o << " aMemberRefs );\n"; + } else + { + o << " 0 );\n"; + } + dec(); + o << indent() << "}\n" + << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName << " );\n" + << indent() << "return &_pType_" << typeName <<" );\n"; + } + dec(); + o << indent() << "}\n"; + + dumpCloseExternC(o); +} + +void CunoType::dumpCGetCunoType(FileStream& o) +{ + OString typeName(m_typeName.replace('/', '_')); + + dumpOpenExternC(o); + + o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << "#endif\n\n"; + + o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n"; + inc(); + + o << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << "#endif\n\n"; + + o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n"; + inc(); + o << indent() << "oslMutex * pMutex = osl_getGlobalMutex();\n" + << indent() << "osl_acquireMutex( pMutex );\n"; + + o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n"; + inc(); + o << indent() << "rtl_uString * pTypeName = 0;\n" + << indent() << "typelib_TypeDescription * pTD = 0;\n"; + + OString superType(m_reader.getSuperTypeName()); + if (superType.getLength() > 0) + o << indent() << "typelib_TypeDescriptionReference * pSuperType = 0;\n"; + + sal_uInt32 count = getMemberCount(); + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + if (count) + { + o << indent() << "typelib_CompoundMember_Init aMembers[" + << count << "];\n"; + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + o << indent() << "rtl_uString * pMemberName" << i << " = 0;\n" + << indent() << "rtl_uString * pMemberType" << i << " = 0;\n"; + } + } + + o << indent() << "rtl_uString_newFromAscii( &pTypeName, \"" << m_typeName.replace('/', '.') << "\" );\n"; + + if (superType.getLength() > 0) + { + o << indent() << "typelib_typedescriptionreference_newByAsciiName(&pSuperType, typelib_TypeClass_INTERFACE, \"" + << superType.replace('/', '.') << "\" );\n"; + } + + dumpCppuGetTypeMemberDecl(o, CUNOTYPEDECL_ALLTYPES); + + if (count) + { + OString fieldType, fieldName; + OString scope = m_typeName.replace('/', '.'); + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = m_reader.getFieldName(i); + fieldType = checkRealBaseType(m_reader.getFieldType(i), sal_True); + + o << indent() << "rtl_uString_newFromAscii( &pMemberType" << i << ", \"" + << fieldType.replace('/', '.') << "\") );\n"; + o << indent() << "rtl_uString_newFromAscii( &pMemberName" << i << ", \""; + o << fieldName << "\") );\n"; + o << indent() << "aMembers[" << i << "].eTypeClass = " + << getTypeClass(fieldType, sal_True) << ";\n" + << indent() << "aMembers[" << i << "].pTypeName = pMemberType" << i << ";\n" + << indent() << "aMembers[" << i << "].pMemberName = pMemberName" << i << ";\n"; + } + + o << "\n" << indent() << "typelib_typedescription_new(\n"; + inc(); + o << indent() << "&pTD,\n" << indent() + << getTypeClass(OString(), sal_True) << ", pTypeName,\n"; + + if (superType.getLength() > 0) + o << indent() << "pSuperType,\n"; + else + o << indent() << "0,\n"; + + if ( count ) + { + o << indent() << count << ",\n" << indent() << "aMembers );\n\n"; + } else + { + o << indent() << count << ",\n" << indent() << "0 );\n\n"; + } + + dec(); + o << indent() << "typelib_typedescription_register( &pTD );\n\n"; + + o << indent() << "typelib_typedescriptionreference_new( &s_pType_ " << typeName + << getTypeClass(OString(), sal_True) << ", pTD);\n\n"; + + o << indent() << "typelib_typedescription_release( pTD );\n" + << indent() << "typelib_typedescriptionreference_release( pSuperType );\n" + << indent() << "rtl_uString_release( pTypeName );\n"; + + for (i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + o << indent() << "rtl_uString_release( pMemberName" << i << " );\n" + << indent() << "rtl_uString_release( pMemberType" << i << " );\n"; + } + } + + dec(); + o << indent() << "}\n"; + o << indent() << "osl_releaseMutex( pMutex );\n"; + dec(); + o << indent() << "}\n" + << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName << " );\n" + << indent() << "return &s_pType_" << typeName <<" );\n"; + dec(); + o << "}\n"; + + dumpCloseExternC(o); +} + +void CunoType::dumpCppuGetTypeMemberDecl(FileStream& o, CunoTypeDecl eDeclFlag) +{ + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + + if ( fieldCount ) + { + o << indent() << "{\n" << indent() << "typelib_TypeDescriptionReference ** ppTypeRef = 0;\n"; + + StringSet aFinishedTypes; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + if (aFinishedTypes.count(m_reader.getFieldType(i)) == 0) + { + aFinishedTypes.insert(m_reader.getFieldType(i)); + dumpCppuGetType(o, m_reader.getFieldType(i), sal_True, eDeclFlag); + } + } + o << indent() << "}\n"; + } +} + +sal_uInt32 CunoType::getMemberCount() +{ + sal_uInt32 count = m_reader.getMethodCount(); + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + count++; + } + return count; +} + +sal_uInt32 CunoType::checkInheritedMemberCount(const TypeReader* pReader) +{ + sal_Bool bSelfCheck = sal_True; + if (!pReader) + { + bSelfCheck = sal_False; + pReader = &m_reader; + } + + sal_uInt32 count = 0; + OString superType(pReader->getSuperTypeName()); + if (superType.getLength() > 0) + { + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + if ( aSuperReader.isValid() ) + { + count = checkInheritedMemberCount(&aSuperReader); + } + } + + if (bSelfCheck) + { + count += pReader->getMethodCount(); + sal_uInt32 fieldCount = pReader->getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = pReader->getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + { + count++; + } + } + } + + return count; +} + +sal_uInt32 CunoType::getInheritedMemberCount() +{ + if (m_inheritedMemberCount == 0) + { + m_inheritedMemberCount = checkInheritedMemberCount(0); + } + + return m_inheritedMemberCount; +} + +void CunoType::dumpInheritedMembers(FileStream& o, rtl::OString& superType) +{ + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + + OString baseType(aSuperReader.getSuperTypeName()); + if (baseType.getLength() > 0) + { + dumpInheritedMembers(o, baseType); + } + + sal_uInt32 fieldCount = aSuperReader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = aSuperReader.getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + { + fieldName = aSuperReader.getFieldName(i); + fieldType = aSuperReader.getFieldType(i); + + o << indent(); + dumpType(o, fieldType); + o << " " << fieldName << ";\n"; + } + } +} + +OString CunoType::getTypeClass(const OString& type, sal_Bool bCStyle) +{ + OString typeName = (type.getLength() > 0 ? type : m_typeName); + RTTypeClass rtTypeClass = RT_TYPE_INVALID; + + if (type.getLength() > 0) + { + typeName = type; + rtTypeClass = m_typeMgr.getTypeClass(typeName); + } else + { + typeName = m_typeName; + rtTypeClass = m_reader.getTypeClass(); + } + + if (typeName.lastIndexOf(']') > 0) + return bCStyle ? "typelib_TypeClass_SEQUENCE" : "::com::sun::star::uno::TypeClass_SEQUENCE"; + + switch (rtTypeClass) + { + case RT_TYPE_INTERFACE: + return bCStyle ? "typelib_TypeClass_INTERFACE" : "::com::sun::star::uno::TypeClass_INTERFACE"; + break; + case RT_TYPE_MODULE: + return bCStyle ? "typelib_TypeClass_MODULE" : "::com::sun::star::uno::TypeClass_MODULE"; + break; + case RT_TYPE_STRUCT: + return bCStyle ? "typelib_TypeClass_STRUCT" : "::com::sun::star::uno::TypeClass_STRUCT"; + break; + case RT_TYPE_ENUM: + return bCStyle ? "typelib_TypeClass_ENUM" : "::com::sun::star::uno::TypeClass_ENUM"; + break; + case RT_TYPE_EXCEPTION: + return bCStyle ? "typelib_TypeClass_EXCEPTION" : "::com::sun::star::uno::TypeClass_EXCEPTION"; + break; + case RT_TYPE_TYPEDEF: + { + OString realType = checkRealBaseType( typeName ); + return getTypeClass( realType, bCStyle ); + } +// return bCStyle ? "typelib_TypeClass_TYPEDEF" : "::com::sun::star::uno::TypeClass_TYPEDEF"; + break; + case RT_TYPE_SERVICE: + return bCStyle ? "typelib_TypeClass_SERVICE" : "::com::sun::star::uno::TypeClass_SERVICE"; + break; + case RT_TYPE_INVALID: + { + if (type.equals("long")) + return bCStyle ? "typelib_TypeClass_LONG" : "::com::sun::star::uno::TypeClass_LONG"; + if (type.equals("short")) + return bCStyle ? "typelib_TypeClass_SHORT" : "::com::sun::star::uno::TypeClass_SHORT"; + if (type.equals("hyper")) + return bCStyle ? "typelib_TypeClass_HYPER" : "::com::sun::star::uno::TypeClass_HYPER"; + if (type.equals("string")) + return bCStyle ? "typelib_TypeClass_STRING" : "::com::sun::star::uno::TypeClass_STRING"; + if (type.equals("boolean")) + return bCStyle ? "typelib_TypeClass_BOOLEAN" : "::com::sun::star::uno::TypeClass_BOOLEAN"; + if (type.equals("char")) + return bCStyle ? "typelib_TypeClass_CHAR" : "::com::sun::star::uno::TypeClass_CHAR"; + if (type.equals("byte")) + return bCStyle ? "typelib_TypeClass_BYTE" : "::com::sun::star::uno::TypeClass_BYTE"; + if (type.equals("any")) + return bCStyle ? "typelib_TypeClass_ANY" : "::com::sun::star::uno::TypeClass_ANY"; + if (type.equals("type")) + return bCStyle ? "typelib_TypeClass_TYPE" : "::com::sun::star::uno::TypeClass_TYPE"; + if (type.equals("float")) + return bCStyle ? "typelib_TypeClass_FLOAT" : "::com::sun::star::uno::TypeClass_FLOAT"; + if (type.equals("double")) + return bCStyle ? "typelib_TypeClass_DOUBLE" : "::com::sun::star::uno::TypeClass_DOUBLE"; + if (type.equals("void")) + return bCStyle ? "typelib_TypeClass_VOID" : "::com::sun::star::uno::TypeClass_VOID"; + if (type.equals("unsigned long")) + return bCStyle ? "typelib_TypeClass_UNSIGNED_LONG" : "::com::sun::star::uno::TypeClass_UNSIGNED_LONG"; + if (type.equals("unsigned short")) + return bCStyle ? "typelib_TypeClass_UNSIGNED_SHORT" : "::com::sun::star::uno::TypeClass_UNSIGNED_SHORT"; + if (type.equals("unsigned hyper")) + return bCStyle ? "typelib_TypeClass_UNSIGNED_HYPER" : "::com::sun::star::uno::TypeClass_UNSIGNED_HYPER"; + } + break; + } + + return bCStyle ? "typelib_TypeClass_UNKNOWN" : "::com::sun::star::uno::TypeClass_UNKNOWN"; +} + +void CunoType::dumpType(FileStream& o, const OString& type, + sal_Bool bConst, sal_Bool bPointer, sal_Bool bParam) + throw( CannotDumpException ) +{ + OString sType(checkRealBaseType(type, sal_True)); + sal_uInt32 index = sType.lastIndexOf(']'); + sal_uInt32 seqNum = (index > 0 ? ((index+1) / 2) : 0); + + OString relType = (index > 0 ? (sType).copy(index+1) : type); + + RTTypeClass typeClass = m_typeMgr.getTypeClass(relType); + +// if (bConst) o << "const "; + + if ( seqNum ) + { + o << "/*"; + sal_uInt32 i; + for (i=0; i < seqNum; i++) + { + o << "sequence< "; + } + o << relType.replace( '/', '.'); + for (i=0; i < seqNum; i++) + { + o << " >"; + } + o << "*/ uno_Sequence *"; + if (bPointer) o << "*"; + return; + } + switch (typeClass) + { + case RT_TYPE_INTERFACE: + o << relType.replace('/', '_') << " *"; + break; + case RT_TYPE_INVALID: + { + OString tmp(getBaseType(relType)); + if (tmp.getLength() > 0) + { + o << tmp.getStr(); + if ( bParam && !bPointer && relType.equals("any") ) + o << " *"; + } else + throw CannotDumpException("Unknown type '" + relType + "', incomplete type library."); + } + break; + case RT_TYPE_STRUCT: + case RT_TYPE_EXCEPTION: + o << relType.replace('/', '_'); + if ( bParam && !bPointer ) o << " *"; + break; + case RT_TYPE_ENUM: + case RT_TYPE_TYPEDEF: + o << relType.replace('/', '_'); + break; + } + + if (bPointer) o << "*"; +} + +OString CunoType::getBaseType(const OString& type) +{ + if (type.equals("long")) + return "sal_Int32"; + if (type.equals("short")) + return "sal_Int16"; + if (type.equals("hyper")) + return "sal_Int64"; + if (type.equals("string")) + return "rtl_uString *"; + if (type.equals("boolean")) + return "sal_Bool"; + if (type.equals("char")) + return "sal_Unicode"; + if (type.equals("byte")) + return "sal_Int8"; + if (type.equals("any")) + return "uno_Any"; + if (type.equals("type")) + return "typelib_TypeDescriptionReference *"; + if (type.equals("float")) + return "float"; + if (type.equals("double")) + return "double"; + if (type.equals("octet")) + return "sal_Int8"; + if (type.equals("void")) + return type; + if (type.equals("unsigned long")) + return "sal_uInt32"; + if (type.equals("unsigned short")) + return "sal_uInt16"; + if (type.equals("unsigned hyper")) + return "sal_uInt64"; + + return OString(); +} + +void CunoType::dumpCppuGetType(FileStream& o, const OString& type, sal_Bool bDecl, CunoTypeDecl eDeclFlag) +{ + OString sType( checkRealBaseType(type, sal_True) ); + sal_uInt32 index = sType.lastIndexOf(']'); + OString relType = (index > 0 ? (sType).copy(index+1) : type); + + if (eDeclFlag == CUNOTYPEDECL_ONLYINTERFACES) + { + if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) + { + if (bDecl) + o << indent() << "ppTypeRef = "; + else + o << indent(); + + o << "getCUnoType_" << type.replace('/', '_') << "()"; + + if (bDecl) + o << ";\n" << indent() << "typelib_typedescriptionreference_release( *ppTypeRef );\n"; + } + } else + { + if (isBaseType(type)) + { + return; + } else + { + if (eDeclFlag == CUNOTYPEDECL_NOINTERFACES && + m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) + return; + + if ( type.equals("type") ) + return; + + if (bDecl) + o << indent() << "ppTypeRef = "; + else + o << indent(); + + o << indent() << "getCUnoType_" << type.replace('/', '_') << "()"; + } + if (bDecl) + o << ";\n" << indent() << "typelib_typedescriptionreference_release( *ppTypeRef );\n"; + } +} + +void CunoType::dumpTypeInit(FileStream& o, const OString& typeName) +{ + OString type(checkSpecialCunoType(typeName)); + + BASETYPE baseType = isBaseType(type); + + switch (baseType) + { + case BT_BOOLEAN: + o << "(sal_False)"; + return; + break; + case BT_ANY: + case BT_STRING: + o << "()"; + return; + break; + case BT_INVALID: + break; + default: + o << "(("; + dumpType(o, type); + o << ")" << "0)"; + return; + } + + RTTypeClass typeClass = m_typeMgr.getTypeClass(type); + + if (typeClass == RT_TYPE_ENUM) + { + RegistryTypeReaderLoader aReaderLoader; + + if (aReaderLoader.isLoaded()) + { + TypeReader reader(m_typeMgr.getTypeReader(type)); + + if ( reader.isValid() ) + { + sal_Int32 i = type.lastIndexOf('/'); + o << "(" << shortScopedName("", type, sal_False) + << "::" << type.copy( i != -1 ? i+1 :0 ) + << "_" << reader.getFieldName(0) << ")"; + return; + } + } + } + + o << "()"; +} + +BASETYPE CunoType::isBaseType(const OString& type) +{ + if (type.equals("long")) + return BT_LONG; + if (type.equals("short")) + return BT_SHORT; + if (type.equals("hyper")) + return BT_HYPER; + if (type.equals("string")) + return BT_STRING; + if (type.equals("boolean")) + return BT_BOOLEAN; + if (type.equals("char")) + return BT_CHAR; + if (type.equals("byte")) + return BT_BYTE; + if (type.equals("any")) + return BT_ANY; + if (type.equals("float")) + return BT_FLOAT; + if (type.equals("double")) + return BT_DOUBLE; + if (type.equals("void")) + return BT_VOID; + if (type.equals("unsigned long")) + return BT_UNSIGNED_LONG; + if (type.equals("unsigned short")) + return BT_UNSIGNED_SHORT; + if (type.equals("unsigned hyper")) + return BT_UNSIGNED_HYPER; + + return BT_INVALID; +} + +OString CunoType::typeToIdentifier(const OString& type) +{ + sal_uInt32 index = type.lastIndexOf(']'); + sal_uInt32 seqNum = (index > 0 ? ((index+1) / 2) : 0); + + OString relType = (index > 0 ? ((OString)type).copy(index+1) : type); + OString sIdentifier; + + while( seqNum > 0 ) + { + sIdentifier += OString("seq"); + + if ( --seqNum == 0 ) + { + sIdentifier += OString("_"); + } + } + + if ( isBaseType(relType) ) + { + sIdentifier += relType.replace(' ', '_'); + } else + { + sIdentifier += relType.replace('/', '_'); + } + + + return sIdentifier; +} + +OString CunoType::checkSpecialCunoType(const OString& type) +{ + OString baseType(type); + + RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader(); + + RegistryKey key; + sal_uInt8* pBuffer=NULL; + RTTypeClass typeClass; + sal_Bool isTypeDef = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); + TypeReader reader; + + while (isTypeDef) + { + reader = m_typeMgr.getTypeReader(baseType); + + if (reader.isValid()) + { + typeClass = reader.getTypeClass(); + + if (typeClass == RT_TYPE_TYPEDEF) + baseType = reader.getSuperTypeName(); + else + isTypeDef = sal_False; + } else + { + break; + } + } + + return baseType; +} + +sal_Bool CunoType::isSeqType(const OString& type, OString& baseType, OString& seqPrefix) +{ + if ( type.getStr()[0] == '[' ) + { + sal_uInt32 index = type.lastIndexOf(']'); + baseType = ((OString)type).copy(index+1); + seqPrefix = ((OString)type).copy(0, index+1); + return sal_True; + } else + { + baseType = type; + seqPrefix = OString(); + } + return sal_False; +} + +sal_Bool CunoType::isArrayType(const OString& type, OString& baseType, OString& arrayPrefix) +{ + if ( type.getStr()[type.getLength()-1] == ']' ) + { + sal_uInt32 index = type.indexOf('['); + baseType = ((OString)type).copy(0, index-1); + arrayPrefix = ((OString)type).copy(index); + return sal_True; + } else + { + baseType = type; + arrayPrefix = OString(); + } + return sal_False; +} + +OString CunoType::checkRealBaseType(const OString& type, sal_Bool bResolveTypeOnly) +{ + OString realType; + OString baseType; + OString completePrefix; + OString prefix; + sal_Bool bSeqType = sal_True; + + if ( !isSeqType(type, baseType, completePrefix) ) + isArrayType(type, baseType, completePrefix); + + RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader(); + + RegistryKey key; + sal_uInt8* pBuffer=NULL; + RTTypeClass typeClass; + sal_Bool mustBeChecked = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); + TypeReader reader; + while (mustBeChecked) + { + reader = m_typeMgr.getTypeReader(baseType); + + if (reader.isValid()) + { + typeClass = reader.getTypeClass(); + + if (typeClass == RT_TYPE_TYPEDEF) + { + realType = reader.getSuperTypeName(); + if ( isSeqType(realType, baseType, prefix) || + isArrayType(realType, baseType, prefix) ) + { + completePrefix += prefix; + } + } else + mustBeChecked = sal_False; + } else + { + break; + } + } + + if ( bResolveTypeOnly ) + { + if ( completePrefix.getLength() > 0 ) + { + baseType = bSeqType ? (completePrefix + baseType) : ( baseType + completePrefix); + } + } + return baseType; +} + +void CunoType::dumpConstantValue(FileStream& o, sal_uInt16 index) +{ + RTConstValue constValue = m_reader.getFieldConstValue(index); + + switch (constValue.m_type) + { + case RT_TYPE_BOOL: + if (constValue.m_value.aBool) + o << "sal_True"; + else + o << "sal_False"; + break; + case RT_TYPE_BYTE: + { + char tmp[16]; + snprintf(tmp, sizeof(tmp), "0x%x", (sal_Int8)constValue.m_value.aByte); + o << "(sal_Int8)" << tmp; + } + break; + case RT_TYPE_INT16: + o << "(sal_Int16)" << constValue.m_value.aShort; + break; + case RT_TYPE_UINT16: + o << "(sal_uInt16)" << constValue.m_value.aUShort; + break; + case RT_TYPE_INT32: + o << "(sal_Int32)" << constValue.m_value.aLong; + break; + case RT_TYPE_UINT32: + o << "(sal_uInt32)" << constValue.m_value.aULong; + break; + case RT_TYPE_INT64: + { + ::rtl::OString tmp( OString::valueOf(constValue.m_value.aHyper) ); + o << "(sal_Int64)" << tmp.getStr() << "L"; + } + break; + case RT_TYPE_UINT64: + { + ::rtl::OString tmp( OString::valueOf((sal_Int64)constValue.m_value.aUHyper) ); + o << "(sal_uInt64)" << tmp.getStr() << "L"; + } + break; + case RT_TYPE_FLOAT: + { + ::rtl::OString tmp( OString::valueOf(constValue.m_value.aFloat) ); + o << "(float)" << tmp.getStr(); + } + break; + case RT_TYPE_DOUBLE: + { + ::rtl::OString tmp( OString::valueOf(constValue.m_value.aDouble) ); + o << "(double)" << tmp.getStr(); + } + break; + case RT_TYPE_STRING: + { + ::rtl::OUString aUStr(constValue.m_value.aString); + ::rtl::OString aStr = ::rtl::OUStringToOString(aUStr, RTL_TEXTENCODING_ASCII_US); + o << "::rtl::OUString::createFromAscii(\"" << aStr.getStr() << "\")"; + } + break; + } +} + +void CunoType::inc(sal_uInt32 num) +{ + m_indentLength += num; +} + +void CunoType::dec(sal_uInt32 num) +{ + if (m_indentLength - num < 0) + m_indentLength = 0; + else + m_indentLength -= num; +} + +OString CunoType::indent() +{ + OStringBuffer tmp(m_indentLength); + + for (sal_uInt32 i=0; i < m_indentLength; i++) + { + tmp.append(' '); + } + return tmp.makeStringAndClear(); +} + +OString CunoType::indent(sal_uInt32 num) +{ + OStringBuffer tmp(m_indentLength + num); + + for (sal_uInt32 i=0; i < m_indentLength + num; i++) + { + tmp.append(' '); + } + return tmp.makeStringAndClear(); +} + +//************************************************************************* +// InterfaceType +//************************************************************************* +InterfaceType::InterfaceType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : CunoType(typeReader, typeName, typeMgr, typeDependencies) +{ + m_inheritedMemberCount = 0; + m_hasAttributes = sal_False; + m_hasMethods = sal_False; +} + +InterfaceType::~InterfaceType() +{ + +} + +sal_Bool InterfaceType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "H")); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "h"); + o << "\n"; + dumpOpenExternC(o); + + o << "#ifndef " << m_name.toAsciiUpperCase() << "\n"; + o << "#define " << m_name.toAsciiUpperCase() << "\n"; + o << "struct _" << m_name << "_ftab;\n" + << "typedef struct _" << m_name << "_ftab * " << m_name << ";\n"; + o << "#endif\n\n"; + + dumpDeclaration(o); + + if ( m_cunoTypeLib ) + { + o << "#ifdef CUNO_TYPELIB\n" + << "typelib_TypeDescriptionReference * SAL_CALL getCUnoType_" << m_name << "() SAL_THROW( () );\n" + << "#endif\n\n"; + } + +/* + if (getNestedTypeNames().getLength() > 0) + { + o << indent() << "// nested types\n\n"; + for (sal_uInt32 i = 0; i < getNestedTypeNames().getLength(); i++) + { + OUString s(getNestedTypeNames().getElement(i)); + + OString nestedName(s.getStr(), s.getLength(), RTL_TEXTENCODING_UTF8); + + nestedName = checkRealBaseType(nestedName.copy(5)); + + if (nestedName.lastIndexOf(']') < 0) + { + o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCunoType( "; + dumpType(o, nestedName, sal_True, sal_False); + o << "* ) SAL_THROW( () );\n\n"; + } + } + } +*/ + dumpCloseExternC(o); + + o << "#endif /* "<< headerDefine << " */\n"; + return sal_True; +} + +void InterfaceType::dumpInheritedFunctions(FileStream& o, rtl::OString& superType) +{ + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + + OString baseType(aSuperReader.getSuperTypeName()); + if (baseType.getLength() > 0) + { + dumpInheritedFunctions(o, baseType); + } + + dumpAttributes(o, superType.replace('/', '_'), aSuperReader); + dumpMethods(o, superType.replace('/', '_'), aSuperReader); +} + +sal_Bool InterfaceType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ + o << "typedef struct _" << m_name << "_ftab\n" << indent() << "{"; + inc(); + + OString superType(m_reader.getSuperTypeName()); + if (superType.getLength() > 0) + dumpInheritedFunctions(o, superType); +/* + if (getNestedTypeNames().getLength() > 0) + { + inc(); + o << indent() << "// nested types\n\n"; + for (sal_uInt32 i = 0; i < getNestedTypeNames().getLength(); i++) + { + OUString s(getNestedTypeNames().getElement(i)); + + OString nestedName(s.getStr(), s.getLength(), RTL_TEXTENCODING_UTF8); + + nestedName = nestedName.copy(5); + + o << indent() << "// " << nestedName.getStr() << "\n"; + + TypeReader reader(m_typeMgr.getTypeReader(nestedName)); + + if (reader.isValid()) + { + RTTypeClass typeClass = reader.getTypeClass(); + switch (typeClass) { + case RT_TYPE_INTERFACE: + { + InterfaceType iType(reader, nestedName, m_typeMgr, m_dependencies); + iType.dumpDeclaration(o); + } + break; + case RT_TYPE_STRUCT: + { + StructureType sType(reader, nestedName, m_typeMgr, m_dependencies); + sType.dumpDeclaration(o); + } + break; + case RT_TYPE_ENUM: + { + EnumType enType(reader, nestedName, m_typeMgr, m_dependencies); + enType.dumpDeclaration(o); + } + break; + case RT_TYPE_EXCEPTION: + { + ExceptionType eType(reader, nestedName, m_typeMgr, m_dependencies); + eType.dumpDeclaration(o); + } + break; + case RT_TYPE_TYPEDEF: + { + TypeDefType tdType(reader, nestedName, m_typeMgr, m_dependencies); + tdType.dumpDeclaration(o); + } + break; + default: + break; + } + } + } + dec(); + } +*/ + dumpAttributes(o, m_name, m_reader); + dumpMethods(o, m_name, m_reader); + + dec(); + o << "} " << m_name << "_ftab;\n\n"; + + return sal_True; +} + +sal_Bool InterfaceType::dumpCFile(FileStream& o) + throw( CannotDumpException ) +{ + dumpInclude(o, m_typeName, "h"); + o << "\n"; + dumpDefaultCIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "h"); + o << "\n"; + dumpGetCunoType(o); +/* + if (getNestedTypeNames().getLength() > 0) + { + o << indent() << "// nested types\n\n"; + for (sal_uInt32 i = 0; i < getNestedTypeNames().getLength(); i++) + { + OUString s(getNestedTypeNames().getElement(i)); + + OString nestedName(s.getStr(), s.getLength(), RTL_TEXTENCODING_UTF8); + + nestedName = nestedName.copy(5); + + o << indent() << "// " << nestedName.getStr() << "\n"; + + TypeReader reader(m_typeMgr.getTypeReader(nestedName)); + + if (reader.isValid()) + { + RTTypeClass typeClass = reader.getTypeClass(); + switch (typeClass) { + case RT_TYPE_INTERFACE: + { + InterfaceType iType(reader, nestedName, m_typeMgr, m_dependencies); + iType.dumpGetCunoType(o); + } + break; + case RT_TYPE_STRUCT: + { + StructureType sType(reader, nestedName, m_typeMgr, m_dependencies); + sType.dumpGetCunoType(o); + } + break; + case RT_TYPE_ENUM: + { + EnumType enType(reader, nestedName, m_typeMgr, m_dependencies); + enType.dumpGetCunoType(o); + } + break; + case RT_TYPE_EXCEPTION: + { + ExceptionType eType(reader, nestedName, m_typeMgr, m_dependencies); + eType.dumpGetCunoType(o); + } + break; + case RT_TYPE_TYPEDEF: + { + TypeDefType tdType(reader, nestedName, m_typeMgr, m_dependencies); + tdType.dumpGetCunoType(o); + } + break; + default: + break; + } + } + } + } +*/ + return sal_True; +} + +void InterfaceType::dumpAttributes(FileStream& o, const OString& interfaceType, TypeReader& reader ) +{ + sal_uInt32 fieldCount = reader.getFieldCount(); + sal_Bool first=sal_True; + + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = reader.getFieldName(i); + fieldType = reader.getFieldType(i); + + if (first) + { + first = sal_False; + o << "\n" << indent() << "/* Attributes of " << interfaceType << " */\n"; + } + + o << indent() << "cuno_ErrorCode (SAL_CALL *get" << fieldName << ")( " + << interfaceType << " *, uno_Any *, "; + dumpType(o, fieldType, sal_False, sal_True); + o << " );\n"; + + if (access != RT_ACCESS_READONLY) + { + OString relType = checkSpecialCunoType(fieldType); + sal_Bool bParam = sal_False; + + if ( m_typeMgr.getTypeClass(relType) == RT_TYPE_STRUCT || + m_typeMgr.getTypeClass(relType) == RT_TYPE_EXCEPTION || + (isBaseType(relType) && relType.equals("any"))) + { + bParam = sal_True; + } else + { + bParam = sal_False; + } + + o << indent() << "cuno_ErrorCode (SAL_CALL *set" << fieldName << ")( " + << interfaceType << " *, uno_Any *, "; + dumpType(o, fieldType, sal_False, sal_False, bParam); + o << " );\n"; + } + } +} + +void InterfaceType::dumpMethods(FileStream& o, const OString& interfaceType, TypeReader& reader ) +{ + sal_uInt32 methodCount = reader.getMethodCount(); + sal_Bool first=sal_True; + + OString methodName, returnType, paramType, paramName; + sal_uInt32 paramCount = 0; + sal_uInt32 excCount = 0; + RTMethodMode methodMode = RT_MODE_INVALID; + RTParamMode paramMode = RT_PARAM_INVALID; + + sal_Bool bPointer = sal_False; + sal_Bool bParam = sal_False; + sal_Bool bWithRunTimeExcp = sal_True; + + for (sal_uInt16 i=0; i < methodCount; i++) + { + methodName = reader.getMethodName(i); + returnType = reader.getMethodReturnType(i); + paramCount = reader.getMethodParamCount(i); + excCount = reader.getMethodExcCount(i); + methodMode = reader.getMethodMode(i); + + if ( methodName.equals("queryInterface") ) + { + first = sal_False; + o << "\n" << indent() << "/* Methods of " << interfaceType << " */\n"; + o << indent() << "cuno_ErrorCode (SAL_CALL *queryInterface)( com_sun_star_uno_XInterface *, " + << "uno_Any *, com_sun_star_uno_XInterface **, typelib_TypeDescriptionReference * );\n"; + continue; + } + + if ( methodName.equals("acquire") || methodName.equals("release") ) + { + bWithRunTimeExcp = sal_False; + } + + if (first) + { + first = sal_False; + o << "\n" << indent() << "/* Methods of " << interfaceType << " */\n"; + } + + o << indent() << "cuno_ErrorCode (SAL_CALL *" << methodName << ")( " + << interfaceType << " *"; + if ( excCount || bWithRunTimeExcp ) + { + o << ", uno_Any *"; + } + if ( !isVoid(returnType) ) + { + o << ", "; + dumpType(o, returnType, sal_False, sal_True); + } + + sal_uInt16 j; + for (j=0; j < paramCount; j++) + { + paramName = reader.getMethodParamName(i, j); + paramType = reader.getMethodParamType(i, j); + paramMode = reader.getMethodParamMode(i, j); + + if (j < (sal_uInt16)paramCount) o << ", "; + + switch (paramMode) + { + case RT_PARAM_IN: + { + OString relType = checkSpecialCunoType(paramType); + if (m_typeMgr.getTypeClass(relType) == RT_TYPE_STRUCT || + m_typeMgr.getTypeClass(relType) == RT_TYPE_EXCEPTION || + (isBaseType(relType) && relType.equals("any"))) + { + bParam = sal_True; + } else + { + bParam = sal_False; + } + break; + } + case RT_PARAM_OUT: + case RT_PARAM_INOUT: + bPointer = sal_True; + break; + } + + dumpType(o, paramType, sal_False, bPointer, bParam); + } + o << " );\n"; + } +} + +void InterfaceType::dumpGetCunoType(FileStream& o) +{ + OString typeName(m_typeName.replace('/', '_')); + + if ( m_cunoTypeLeak ) + { + dumpLGetCunoType(o); + return; + } + if ( !m_cunoTypeDynamic ) + { + dumpCGetCunoType(o); + return; + } + + dumpOpenExternC(o); + + if ( !m_typeName.equals("com/sun/star/uno/XInterface") ) + { + o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << "#endif\n\n"; + } + + o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n"; + inc(); + + if ( m_typeName.equals("com/sun/star/uno/XInterface") ) + { + o << indent() << "return typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE );\n"; + } else + { + o << indent() << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << indent() << "#endif\n\n"; + + o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n"; + inc(); + OString superType(m_reader.getSuperTypeName()); + sal_Bool bWithBase = sal_False; + if (superType.getLength() > 0 && !superType.equals("com/sun/star/uno/XInterface")) + { + bWithBase = sal_True; + o << indent() << "typelib_TypeDescriptionReference * pSuperType = 0;\n" + << indent() << "typelib_typedescriptionreference_newByAsciiName(&pSuperType, typelib_TypeClass_INTERFACE, \"" + << superType.replace('/', '.') << "\" );\n"; + } + + o << indent() << "typelib_static_interface_type_init( &s_pType_" << typeName + << ", \"" << m_typeName.replace('/', '.') << "\", "; + + if ( bWithBase ) + { + o << "pSuperType );\n"; + } else + { + o << "0 );\n"; + } + + dec(); + o << indent() << "}\n" + << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName << " );\n" + << indent() << "return &s_pType_" << typeName <<" );\n"; + } + dec(); + o << indent() << "}\n"; + + dumpCloseExternC(o); +} + +void InterfaceType::dumpCGetCunoType(FileStream& o) +{ + OString typeName(m_typeName.replace('/', '_')); + + dumpOpenExternC(o); + + o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << "#endif\n\n"; + + o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n"; + inc(); + + o << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << "#endif\n\n"; + + o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n"; + inc(); + o << indent() << "oslMutex * pMutex = osl_getGlobalMutex();\n" + << indent() << "osl_acquireMutex( pMutex );\n"; + + o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n"; + inc(); + o << indent() << "rtl_uString * pTypeName = 0;\n" + << indent() << "typelib_InterfaceTypeDescription * pTD = 0;\n"; + + OString superType(m_reader.getSuperTypeName()); + sal_uInt32 count = getMemberCount(); + + if (superType.getLength() > 0) + o << indent() << "typelib_TypeDescriptionReference * pSuperType = 0;\n"; + + if (count) + { + o << indent() << "typelib_TypeDescriptionReference * pMembers[" << count << "] = { "; + for (sal_uInt32 i = 0; i < count; i++) + { + o << "0"; + if (i+1 < count) + o << ","; + else + o << " };\n"; + } + + dumpCUnoAttributeTypeNames(o); + dumpCUnoMethodTypeNames(o); + } + + o << indent() << "rtl_uString_newFromAscii( &pTypeName, \"" << m_typeName.replace('/', '.') << "\" );\n"; + + if (superType.getLength() > 0) + { + o << indent() << "typelib_typedescriptionreference_newByAsciiName(&pSuperType, typelib_TypeClass_INTERFACE, \"" + << superType.replace('/', '.') << "\" );\n"; + } + + if (count) + { + sal_uInt32 index = 0; + dumpCUnoAttributeRefs(o, index); + dumpCUnoMethodRefs(o, index); + } + + o << "\n" << indent() << "typelib_typedescription_newInterface(\n"; + inc(); + o << indent() << "&pTD,\n" + << indent() << "pTypeName, "; + + RTUik uik; + m_reader.getUik(uik); + sal_Char buffer[53]; + snprintf(buffer, sizeof(buffer), "0x%.8x, 0x%.4x, 0x%.4x, 0x%.8x, 0x%.8x,\n", + uik.m_Data1, uik.m_Data2, uik.m_Data3, uik.m_Data4, uik.m_Data5); + o << buffer; + + if (superType.getLength() > 0) + o << indent() << "pSuperType,\n"; + else + o << indent() << "0,\n"; + + if ( count ) + { + o << indent() << count << ",\n" << indent() << "pMembers );\n\n"; + } else + { + o << indent() << count << ",\n" << indent() << "0 );\n\n"; + } + dec(); + + o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pTD );\n"; + if ( count ) + { + for (sal_uInt16 i=0; i < count; i++) + { + o << indent() << "typelib_typedescriptionreference_release( pMembers[" + << i << "] );\n"; + } + } + o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pTD );\n"; + + if (superType.getLength() > 0) + o << indent() << "typelib_typedescription_release( pSuperType );\n\n"; + else + o << "\n"; + + o << indent() << "typelib_typedescriptionreference_new( &s_pType_ " << typeName + << "typelib_TypeClass_INTERFACE, (typelib_TypeDescription*)pTD);\n\n"; + + o << indent() << "typelib_TypeDescriptionReference ** ppTypeRef = 0;\n"; + StringSet aTypes; + // type for RuntimeException is always needed + OString sRunTimeExceptionType("com/sun/star/uno/RuntimeException"); + aTypes.insert(sRunTimeExceptionType); + dumpCppuGetType(o, sRunTimeExceptionType, sal_True, CUNOTYPEDECL_ALLTYPES); + + dumpAttributesCppuDecl(o, &aTypes, CUNOTYPEDECL_ALLTYPES); + dumpMethodsCppuDecl(o, &aTypes, CUNOTYPEDECL_ALLTYPES); + + if (count) + { + sal_uInt32 index = getInheritedMemberCount(); + dumpCUnoAttributes(o, index); + dumpCUnoMethods(o, index); + } + + // release strings for names + dumpCUnoAttributeTypeNames(o, sal_True); + dumpCUnoMethodTypeNames(o, sal_True); + + dec(); + o << indent() << "}\n"; + o << indent() << "osl_releaseMutex( pMutex );\n"; + dec(); + o << indent() << "}\n\n" + << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName << " );\n" + << indent() << "return &s_pType_" << typeName << ";\n"; + + dec(); + o << "}\n"; + + dumpCloseExternC(o); +} + +void InterfaceType::dumpCUnoAttributeTypeNames(FileStream&o, sal_Bool bRelease) +{ + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + if ( bRelease ) + { + o << indent() << "rtl_uString_release( pAttributeName" << i << " );\n"; + } else + { + o << indent() << "rtl_uString * pAttributeName" << i << " = 0;\n"; + } + } +} + +void InterfaceType::dumpCUnoMethodTypeNames(FileStream&o, sal_Bool bRelease) +{ + sal_uInt32 methodCount = m_reader.getMethodCount(); + + for (sal_uInt16 i = 0; i < methodCount; i++) + { + if ( bRelease ) + { + o << indent() << "rtl_uString_release( pMethodName" << i << " );\n"; + } else + { + o << indent() << "rtl_uString * pMethodName" << i << " = 0;\n"; + } + } +} + +void InterfaceType::dumpCUnoAttributeRefs(FileStream& o, sal_uInt32& index) +{ + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString scope = m_typeName.replace('/', '.'); + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + fieldName = m_reader.getFieldName(i); + + o << indent() << "rtl_uString_newFromAscii( &pAttributeName" << i << ", \"" + << scope << "::" << fieldName << "\" );\n"; + o << indent() << "typelib_typedescriptionreference_new( &pMembers[" + << index << "],\n"; + inc(38); + o << indent() << "typelib_TypeClass_INTERFACE_ATTRIBUTE,\n" + << indent() << "pAttributeName" << i << " );\n"; + dec(38); + index++; + } +} + +void InterfaceType::dumpCUnoMethodRefs(FileStream& o, sal_uInt32& index) +{ + sal_uInt32 methodCount = m_reader.getMethodCount(); + OString methodName; //, returnType, paramType, paramName; + OString scope = m_typeName.replace('/', '.'); + + for (sal_uInt16 i = 0; i < methodCount; i++) + { + methodName = m_reader.getMethodName(i); + + o << indent() << "rtl_uString_newFromAscii( &pMethodName" << i << ", \"" + << scope.replace('/', '.') << "::" << methodName << "\" );\n"; + o << indent() << "typelib_typedescriptionreference_new( &pMembers[" + << index << "],\n"; + inc(38); + o << indent() << "typelib_TypeClass_INTERFACE_METHOD,\n" + << indent() << "pMethodName" << i << " );\n"; + dec(38); + index++; + } +} + +sal_uInt32 InterfaceType::getMemberCount() +{ + sal_uInt32 count = m_reader.getMethodCount(); + + if (count) + m_hasMethods = sal_True; + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + { + m_hasAttributes = sal_True; + count++; + } + } + return count; +} + +sal_uInt32 InterfaceType::checkInheritedMemberCount(const TypeReader* pReader) +{ + sal_uInt32 cout = 0; + sal_Bool bSelfCheck = sal_True; + if (!pReader) + { + bSelfCheck = sal_False; + pReader = &m_reader; + } + + sal_uInt32 count = 0; + OString superType(pReader->getSuperTypeName()); + if (superType.getLength() > 0) + { + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + if (aSuperReader.isValid()) + { + count = checkInheritedMemberCount(&aSuperReader); + } + } + + if (bSelfCheck) + { + count += pReader->getMethodCount(); + sal_uInt32 fieldCount = pReader->getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = pReader->getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + { + count++; + } + } + } + + return count; +} + +sal_uInt32 InterfaceType::getInheritedMemberCount() +{ + if (m_inheritedMemberCount == 0) + { + m_inheritedMemberCount = checkInheritedMemberCount(0); + } + + return m_inheritedMemberCount; +} + +void InterfaceType::dumpCUnoAttributes(FileStream& o, sal_uInt32& index) +{ + sal_uInt32 fieldCount = m_reader.getFieldCount(); + + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldType; + + sal_uInt32 absoluteIndex = index; + + if (m_hasAttributes) + { + o << "\n" << indent() << "{\n" << indent() << "typelib_InterfaceAttributeTypeDescription * pAttribute = 0;\n"; + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldType = checkRealBaseType(m_reader.getFieldType(i), sal_True); + o << indent() << "{\n"; + o << indent() << "rtl_uString * pAttributeType" << i << " = 0;\n"; + o << indent() << "rtl_uString_newFromAscii( &pAttributeType" << i << ", \"" + << fieldType.replace('/', '.') << "\" );\n"; + o << indent() << "typelib_typedescription_newInterfaceAttribute( &pAttribute,\n"; + inc(); + o << indent() << absoluteIndex++ << ", pAttributeName" << i << ",\n"; + o << indent() << getTypeClass(fieldType, sal_True) << ", pAttributeType" << i << ",\n"; + if (access == RT_ACCESS_READONLY) + o << indent() << "sal_True );\n"; + else + o << indent() << "sal_False );\n"; + dec(); + o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pAttribute );\n\n"; + o << indent() << "}\n"; + } + o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pAttribute );\n"; + o << indent() << "}\n"; + index = absoluteIndex; + } +} + +void InterfaceType::dumpCUnoMethods(FileStream& o, sal_uInt32& index) +{ + sal_uInt32 methodCount = m_reader.getMethodCount(); + OString methodName, returnType, paramType, paramName; + sal_uInt32 paramCount = 0; + sal_uInt32 excCount = 0; + RTMethodMode methodMode = RT_MODE_INVALID; + RTParamMode paramMode = RT_PARAM_INVALID; + sal_Bool bWithRuntimeException = sal_True; + + sal_uInt32 absoluteIndex = index; + + if (m_hasMethods) + { + o << "\n" << indent() << "{\n" << indent() << "typelib_InterfaceMethodTypeDescription * pMethod = 0;\n"; + + for (sal_uInt16 i=0; i < methodCount; i++) + { + methodName = m_reader.getMethodName(i); + returnType = checkRealBaseType(m_reader.getMethodReturnType(i), sal_True); + paramCount = m_reader.getMethodParamCount(i); + excCount = m_reader.getMethodExcCount(i); + methodMode = m_reader.getMethodMode(i); + + if ( methodName.equals("acquire") || methodName.equals("release") ) + { + bWithRuntimeException = sal_False; + } + o << indent() << "{\n"; + inc(); + + if (paramCount) + { + o << indent() << "typelib_Parameter_Init pParameters[" << paramCount << "];\n"; + } + if ( excCount || bWithRuntimeException ) + { + o << indent() << "rtl_uString * pExceptions[" << excCount + 1 << "];\n"; + } + o << indent() << "rtl_uString * pReturnType" << i << " = 0;\n"; + + sal_uInt16 j; + for (j=0; j < paramCount; j++) + { + o << indent() << "rtl_uString * pParamName" << j << " = 0;\n" + << indent() << "rtl_uString * pParamType" << j << " = 0;\n"; + } + + for (j=0; j < excCount; j++) + { + o << indent() << "rtl_uString * pExceptionName" << j << " = 0;\n"; + } + if ( excCount || bWithRuntimeException ) + { + o << indent() << "rtl_uString * pExceptionName" << excCount << " = 0;\n"; + } + for (j=0; j < paramCount; j++) + { + paramName = m_reader.getMethodParamName(i, j); + paramType = checkRealBaseType(m_reader.getMethodParamType(i, j), sal_True); + paramMode = m_reader.getMethodParamMode(i, j); + o << indent() << "rtl_uString_newFromAscii( &pParamName" << j << ", \"" + << paramName << "\" );\n"; + o << indent() << "rtl_uString_newFromAscii( &pParamType" << j << ", \"" + << paramType.replace('/', '.') << "\" );\n"; + o << indent() << "pParameters[" << j << "].pParamName = pParamName" << j << ";\n"; + o << indent() << "pParameters[" << j << "].eTypeClass = " + << getTypeClass(paramType, sal_True) << ";\n"; + o << indent() << "pParameters[" << j << "].pTypeName = sParamType" << j << ";\n"; + + if (paramMode == RT_PARAM_IN || paramMode == RT_PARAM_INOUT) + o << indent() << "pParameters[" << j << "].bIn = sal_True;\n"; + else + o << indent() << "pParameters[" << j << "].bIn = sal_False;\n"; + + if (paramMode == RT_PARAM_OUT || paramMode == RT_PARAM_INOUT) + o << indent() << "pParameters[" << j << "].bOut = sal_True;\n"; + else + o << indent() << "pParameters[" << j << "].bOut = sal_False;\n"; + } + + for (j=0; j < excCount; j++) + { + if (!m_reader.getMethodExcType(i, j).equals("com/sun/star/uno/RuntimeException")) + { + o << indent() << "rtl_uString_newFromAscii( & pExceptionName" << j << ", \"" + << OString(m_reader.getMethodExcType(i, j)).replace('/', '.') << "\" );\n"; + o << indent() << "pExceptions[" << j << "] = pExceptionName" << j << ";\n"; + } + } + if ( excCount || bWithRuntimeException ) + { + o << indent() << "rtl_uString_newFromAscii( & pExceptionName" << excCount + << ", \"com.sun.star.uno.RuntimeException\") );\n"; + o << indent() << "pExceptions[" << excCount << "] = pExceptionName" << excCount << ";\n"; + } + o << indent() << "rtl_uString_newFromAscii( &pReturnType" << i << ", \"" + << returnType.replace('/', '.') << "\" );\n"; + o << indent() << "typelib_typedescription_newInterfaceMethod( &pMethod,\n"; + inc(); + o << indent() << absoluteIndex++ << ", "; + if (methodMode == RT_MODE_ONEWAY || methodMode == RT_MODE_ONEWAY_CONST) + o << "sal_True,\n"; + else + o << "sal_False,\n"; + o << indent() << "pMethodName" << i << ",\n"; + o << indent() << getTypeClass(returnType, sal_True) << ", pReturnType" << i << ",\n"; + if (paramCount) + o << indent() << paramCount << ", pParameters,\n"; + else + o << indent() << "0, 0,\n"; + + if ( excCount || bWithRuntimeException ) + { + o << indent() << excCount + 1 << ", pExceptions );\n"; + } else + { + o << indent() << "0, 0 );\n"; + } + + dec(); + o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );\n"; + + o << indent() << "rtl_uString_release( pReturnType );\n"; + for (j=0; j < paramCount; j++) + { + o << indent() << "rtl_uString_release( pParamName" << j << " );\n" + << indent() << "rtl_uString_release( pParamType" << j << " );\n"; + } + + for (j=0; j < excCount; j++) + { + o << indent() << "rtl_uString_release( pExceptionName" << j << " );\n"; + } + if ( excCount || bWithRuntimeException ) + { + o << indent() << "rtl_uString_release( pExceptionName" << excCount << " );\n"; + } + dec(); + o << indent() << "}\n"; + } + o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pMethod );\n"; + + o << indent() << "}\n"; + index = absoluteIndex; + } +} + +void InterfaceType::dumpAttributesCppuDecl(FileStream& o, StringSet* pFinishedTypes, CunoTypeDecl eDeclFlag) +{ + sal_uInt32 fieldCount = m_reader.getFieldCount(); + + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + + if (pFinishedTypes->count(fieldType) == 0) + { + pFinishedTypes->insert(fieldType); + dumpCppuGetType(o, fieldType, sal_True, eDeclFlag); + } + } +} + +void InterfaceType::dumpMethodsCppuDecl(FileStream& o, StringSet* pFinishedTypes, CunoTypeDecl eDeclFlag) +{ + sal_uInt32 methodCount = m_reader.getMethodCount(); + OString returnType, paramType, excType; + sal_uInt32 paramCount = 0; + sal_uInt32 excCount = 0; + + for (sal_uInt16 i=0; i < methodCount; i++) + { + returnType = m_reader.getMethodReturnType(i); + paramCount = m_reader.getMethodParamCount(i); + excCount = m_reader.getMethodExcCount(i); + + if (pFinishedTypes->count(returnType) == 0) + { + pFinishedTypes->insert(returnType); + dumpCppuGetType(o, returnType, sal_True, eDeclFlag); + } + sal_uInt16 j; + for (j=0; j < paramCount; j++) + { + paramType = m_reader.getMethodParamType(i, j); + + if (pFinishedTypes->count(paramType) == 0) + { + pFinishedTypes->insert(paramType); + dumpCppuGetType(o, paramType, sal_True, eDeclFlag); + } + } + + for (j=0; j < excCount; j++) + { + excType = m_reader.getMethodExcType(i, j); + if (pFinishedTypes->count(excType) == 0) + { + pFinishedTypes->insert(excType); + dumpCppuGetType(o, excType, sal_True, eDeclFlag); + } + } + } +} + +//************************************************************************* +// ModuleType +//************************************************************************* +ModuleType::ModuleType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : CunoType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +ModuleType::~ModuleType() +{ + +} + +sal_Bool ModuleType::dump(CunoOptions* pOptions) + throw( CannotDumpException ) +{ + sal_Bool ret = sal_False; + + if (pOptions->isValid("-U")) + m_cunoTypeDynamic = sal_True; + + OString outPath; + if (pOptions->isValid("-O")) + outPath = pOptions->getOption("-O"); + + OString tmpName(m_typeName); + + if (tmpName.equals("/")) + tmpName = "global"; + else +// tmpName += "/" + m_typeName.getToken(m_typeName.getTokenCount('/') - 1, '/'); + tmpName += "/" + m_name; + + OString tmpFileName; + OString hFileName = createFileNameFromType(outPath, tmpName, ".hdl"); + + sal_Bool bFileExists = sal_False; + sal_Bool bFileCheck = sal_False; + + if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) + { + bFileExists = fileExists( hFileName ); + ret = sal_True; + } + + if ( bFileExists && pOptions->isValid("-Gc") ) + { + tmpFileName = createFileNameFromType(outPath, m_typeName, ".tml"); + bFileCheck = sal_True; + } + + if ( !bFileExists || bFileCheck ) + { + FileStream hFile; + + if ( bFileCheck ) + hFile.open(tmpFileName); + else + hFile.open(hFileName); + + if(!hFile.isValid()) + { + OString message("cannot open "); + message += hFileName + " for writing"; + throw CannotDumpException(message); + } + + ret = dumpHFile(hFile); + + hFile.close(); + if (ret && bFileCheck) + { + ret = checkFileContent(hFileName, tmpFileName); + } + } +/* + bFileExists = sal_False; + bFileCheck = sal_False; + OString cFileName = createFileNameFromType(outPath, tmpName, ".c"); + + if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) + { + bFileExists = fileExists( cFileName ); + ret = sal_True; + } + + if ( bFileExists && pOptions->isValid("-Gc") ) + { + tmpFileName = createFileNameFromType(outPath, m_typeName, ".tmc"); + bFileCheck = sal_True; + } + + + if ( !bFileExists || bFileCheck ) + { + FileStream hxxFile; + + if ( bFileCheck ) + cFile.open(tmpFileName); + else + cFile.open(cFileName); + + if(!cFile.isValid()) + { + OString message("cannot open "); + message += cFileName + " for writing"; + throw CannotDumpException(message); + } + + ret = dumpCFile(cFile); + + cFile.close(); + if (ret && bFileCheck) + { + ret = checkFileContent(cFileName, tmpFileName); + } + } +*/ + return ret; +} + +sal_Bool ModuleType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + sal_Bool bSpecialDefine = sal_True; + + if (m_reader.getTypeClass() == RT_TYPE_CONSTANTS) + { + bSpecialDefine = sal_False; + } + + OString headerDefine(dumpHeaderDefine(o, "H", bSpecialDefine)); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "h"); + o << "\n"; + + dumpOpenExternC(o); + dumpDeclaration(o); + o << "\n"; + dumpCloseExternC(o); + + o << "\n#endif /* "<< headerDefine << " */\n"; + + return sal_True; +} + +sal_Bool ModuleType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST) + { + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + + o << "static const "; + dumpType(o, fieldType); + o << " " << m_name << "_" << fieldName << " = "; + dumpConstantValue(o, i); + o << ";\n"; + } + } + + return sal_True; +} + +sal_Bool ModuleType::hasConstants() +{ + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST) + return sal_True; + } + + return sal_False; +} + +sal_Bool ModuleType::dumpCFile(FileStream& o) + throw( CannotDumpException ) +{ + return sal_True; +} + +//************************************************************************* +// ConstantsType +//************************************************************************* +ConstantsType::ConstantsType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : ModuleType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +ConstantsType::~ConstantsType() +{ + +} + +sal_Bool ConstantsType::dump(CunoOptions* pOptions) + throw( CannotDumpException ) +{ + sal_Bool ret = sal_False; + + if (pOptions->isValid("-U")) + m_cunoTypeDynamic = sal_True; + + OString outPath; + if (pOptions->isValid("-O")) + outPath = pOptions->getOption("-O"); + + OString tmpFileName; + OString hFileName = createFileNameFromType(outPath, m_typeName, ".h"); + + sal_Bool bFileExists = sal_False; + sal_Bool bFileCheck = sal_False; + + if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) + { + bFileExists = fileExists( hFileName ); + ret = sal_True; + } + + if ( bFileExists && pOptions->isValid("-Gc") ) + { + tmpFileName = createFileNameFromType(outPath, m_typeName, ".tmh"); + bFileCheck = sal_True; + } + + if ( !bFileExists || bFileCheck ) + { + FileStream hFile; + + if ( bFileCheck ) + hFile.open(tmpFileName); + else + hFile.open(hFileName); + + if(!hFile.isValid()) + { + OString message("cannot open "); + message += hFileName + " for writing"; + throw CannotDumpException(message); + } + + ret = dumpHFile(hFile); + + hFile.close(); + if (ret && bFileCheck) + { + ret = checkFileContent(hFileName, tmpFileName); + } + } +/* + bFileExists = sal_False; + bFileCheck = sal_False; + OString cFileName = createFileNameFromType(outPath, m_typeName, ".c"); + + if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) + { + bFileExists = fileExists( cFileName ); + ret = sal_True; + } + + if ( bFileExists && pOptions->isValid("-Gc") ) + { + tmpFileName = createFileNameFromType(outPath, m_typeName, ".tmc"); + bFileCheck = sal_True; + } + + if ( !bFileExists || bFileCheck ) + { + FileStream cFile; + + if ( bFileCheck ) + cFile.open(tmpFileName); + else + cFile.open(cFileName); + + if(!cFile.isValid()) + { + OString message("cannot open "); + message += cFileName + " for writing"; + throw CannotDumpException(message); + } + + ret = dumpCFile(cFile); + + cFile.close(); + if (ret && bFileCheck) + { + ret = checkFileContent(cFileName, tmpFileName); + } + } +*/ + return ret; +} + +//************************************************************************* +// StructureType +//************************************************************************* +StructureType::StructureType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : CunoType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +StructureType::~StructureType() +{ + +} + +sal_Bool StructureType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "H")); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "h"); + o << "\n"; + + dumpOpenExternC(o); + + dumpDeclaration(o); + + if ( m_cunoTypeLib ) + { + o << "#ifdef CUNO_TYPELIB\n" + << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () );\n" + << "#endif\n\n"; + } + + dumpCloseExternC(o); + + o << "#endif /* "<< headerDefine << " */\n"; + + return sal_True; +} + +sal_Bool StructureType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ + o << "#ifdef SAL_W32\n" + << "# pragma pack(push, 8)\n" + << "#elif defined(SAL_OS2)\n" + << "# pragma pack(8)\n" + << "#endif\n\n"; + + o << "typedef struct _" << m_name << "\n{\n"; + inc(); + + OString superType(m_reader.getSuperTypeName()); + if (superType.getLength() > 0) + o << indent() << superType.replace('/', '_').getStr() << " _Base;\n"; + //dumpInheritedMembers(o, superType); + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + sal_uInt16 i=0; + + for (i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + + o << indent(); + dumpType(o, fieldType); + o << " " << fieldName << ";\n"; + } + + dec(); + o << "} " << m_name << ";\n\n"; + + o << "#ifdef SAL_W32\n" + << "# pragma pack(pop)\n" + << "#elif defined(SAL_OS2)\n" + << "# pragma pack()\n" + << "#endif\n\n"; + + return sal_True; +} + +sal_Bool StructureType::dumpCFile(FileStream& o) + throw( CannotDumpException ) +{ + dumpInclude(o, m_typeName, "h"); + o << "\n"; + dumpDefaultCIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "h"); + o << "\n"; + + dumpGetCunoType(o); + + return sal_True; +} + +//************************************************************************* +// ExceptionType +//************************************************************************* +ExceptionType::ExceptionType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : CunoType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +ExceptionType::~ExceptionType() +{ + +} + +sal_Bool ExceptionType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "H")); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "h"); + o << "\n"; + + dumpOpenExternC(o); + + dumpDeclaration(o); + + if ( m_cunoTypeLib ) + { + o << "#ifdef CUNO_TYPELIB\n" + << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () );\n" + << "#endif\n\n"; + } + + dumpCloseExternC(o); + + o << "#endif /* "<< headerDefine << " */\n"; + + return sal_True; +} + +sal_Bool ExceptionType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ + o << "#ifdef SAL_W32\n" + << "# pragma pack(push, 8)\n" + << "#elif defined(SAL_OS2)\n" + << "# pragma pack(8)\n" + << "#endif\n\n"; + + o << "\n/* Exception type */\ntypedef struct _" << m_name << "\n{\n"; + inc(); + + OString superType(m_reader.getSuperTypeName()); + if (superType.getLength() > 0) + o << indent() << superType.replace('/', '_').getStr() << " _Base;\n"; + //dumpInheritedMembers(o, superType); + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + sal_uInt16 i = 0; + + for (i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + + o << indent(); + dumpType(o, fieldType); + o << " " << fieldName << ";\n"; + } + + dec(); + o << "} " << m_name << ";\n\n"; + + o << "#ifdef SAL_W32\n" + << "# pragma pack(pop)\n" + << "#elif defined(SAL_OS2)\n" + << "# pragma pack()\n" + << "#endif\n\n"; + + return sal_True; +} + +sal_Bool ExceptionType::dumpCFile(FileStream& o) + throw( CannotDumpException ) +{ + dumpInclude(o, m_typeName, "h"); + o << "\n"; + dumpDefaultCIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "h"); + o << "\n"; + + dumpGetCunoType(o); + + return sal_True; +} + + +//************************************************************************* +// EnumType +//************************************************************************* +EnumType::EnumType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : CunoType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +EnumType::~EnumType() +{ + +} + +sal_Bool EnumType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "H")); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + dumpOpenExternC(o); + + dumpDeclaration(o); + + if ( m_cunoTypeLib ) + { + o << "#ifdef CUNO_TYPELIB\n" + << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () );\n" + << "#endif\n\n"; + } + + dumpCloseExternC(o); + + o << "#endif /* "<< headerDefine << " */\n"; + + return sal_True; +} + +sal_Bool EnumType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ + o << "\ntypedef enum _" << m_name << "\n{\n"; + inc(); + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + RTConstValue constValue; + OString fieldName; + sal_Int32 value=0; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access != RT_ACCESS_CONST) + continue; + + fieldName = m_reader.getFieldName(i); + constValue = m_reader.getFieldConstValue(i); + + if (constValue.m_type == RT_TYPE_INT32) + value = constValue.m_value.aLong; + else + value++; + + o << indent() << m_name << "_" << fieldName << " = " << value << ",\n"; + } + + o << indent() << m_name << "_MAKE_FIXED_SIZE = SAL_MAX_ENUM\n"; + + dec(); + o << "} " << m_name << ";\n\n"; + + return sal_True; +} + +sal_Bool EnumType::dumpCFile(FileStream& o) + throw( CannotDumpException ) +{ + dumpInclude(o, m_typeName, "h"); + o << "\n"; + dumpDefaultCIncludes(o); + o << "\n"; + dumpGetCunoType(o); + return sal_True; +} + +void EnumType::dumpGetCunoType(FileStream& o) +{ + OString typeName(m_typeName.replace('/', '_')); + + if ( m_cunoTypeLeak ) + { + dumpLGetCunoType(o); + return; + } + if ( !m_cunoTypeDynamic ) + { + dumpCGetCunoType(o); + return; + } + + dumpOpenExternC(o); + + o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << "#endif\n\n"; + + o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n"; + inc(); + + o << indent() << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << indent() << "#endif\n\n"; + + o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n"; + inc(); + + o << indent() << "typelib_static_enum_type_init( &s_pType_" << typeName << ",\n"; + inc(31); + o << indent() << "\"" << m_typeName.replace('/', '.') << "\",\n" + << indent() << m_name << "_" << m_reader.getFieldName(0) << " );\n"; + dec(31); + dec(); + o << indent() << "}\n" + << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName <<" );\n" + << indent() << "return &s_pType_" << typeName <<" );\n"; + dec(); + o << indent() << "}\n"; + + dumpCloseExternC(o); +} + +void EnumType::dumpCGetCunoType(FileStream& o) +{ + OString typeName(m_typeName.replace('/', '_')); + + dumpOpenExternC(o); + + o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << "#endif\n\n"; + + o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n"; + inc(); + + o << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n" + << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n" + << "#endif\n\n"; + + o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n"; + inc(); + o << indent() << "oslMutex * pMutex = osl_getGlobalMutex();\n" + << indent() << "osl_acquireMutex( pMutex );\n"; + + o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n"; + inc(); + o << indent() << "rtl_uString * pTypeName = 0;\n" + << indent() << "_typelib_TypeDescription * pTD = 0;\n"; + + sal_uInt32 count = m_reader.getFieldCount(); + o << indent() << "rtl_uString* enumValueNames[" << count << "];\n" + << indent() << "sal_Int32 enumValues[" << count << "];\n"; + sal_uInt32 i; + for (i = 0; i < count; i++) + { + o << indent() << "rtl_uString * pEnumValue" << i << " = 0;\n"; + } + + o << indent() << "rtl_uString_newFromAscii( &pTypeName, \"" + << m_typeName.replace('/', '.') << "\") );\n\n"; + + for (i = 0; i < count; i++) + { + o << indent() << "rtl_uString_newFromAscii( &pEnumValue" << i << ", \"" + << m_reader.getFieldName((sal_uInt16)i) << "\" );\n"; + o << indent() << "enumValueNames[" << i << "] = pEnumValue" << i << ";\n"; + } + + RTConstValue constValue; + sal_Int32 value=0; + for (i = 0; i < count; i++) + { + o << indent() << "enumValues[" << i << "] = "; + constValue = m_reader.getFieldConstValue((sal_uInt16)i); + if (constValue.m_type == RT_TYPE_INT32) + value = constValue.m_value.aLong; + else + value++; + o << value << ";\n"; + } + + o << "\n" << indent() << "typelib_typedescription_newEnum( &pTD,\n"; + inc(); + o << indent() << "pTypeName,\n" + << indent() << "(sal_Int32)" << m_name << "_" << m_reader.getFieldName(0) << ",\n" + << indent() << count << ", enumValueNames, enumValues );\n\n"; + dec(); + + o << indent() << "typelib_typedescription_register( &pTD );\n"; + + o << indent() << "typelib_typedescriptionreference_new( &s_pType_ " << typeName + << getTypeClass(OString(), sal_True) << ", pTD);\n\n"; + + o << indent() << "typelib_typedescription_release( pTD );\n" + << indent() << "rtl_uString_release( pTypeName );\n"; + for (i = 0; i < count; i++) + { + o << indent() << "rtl_uString_release( pEnumValue" << i << " );\n"; + } + + dec(); + o << indent() << "}\n"; + o << indent() << "osl_releaseMutex( pMutex );\n"; + dec(); + o << indent() << "}\n\n" + << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName <<" );\n" + << indent() << "return &s_pType_" << typeName <<" );\n"; + + dec(); + o << "}\n"; + + dumpCloseExternC(o); +} + +//************************************************************************* +// TypeDefType +//************************************************************************* +TypeDefType::TypeDefType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : CunoType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +TypeDefType::~TypeDefType() +{ + +} + +sal_Bool TypeDefType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "H")); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "h"); + o << "\n"; + + dumpOpenExternC(o); + + dumpDeclaration(o); + + if ( m_cunoTypeLib ) + { + o << "#ifdef CUNO_TYPELIB\n" + << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () );\n" + << "#endif\n\n"; + } + + dumpCloseExternC(o); + + o << "#endif /* "<< headerDefine << " */\n"; + + return sal_True; +} + +sal_Bool TypeDefType::dumpDeclaration(FileStream& o) + throw( CannotDumpException ) +{ + o << "\ntypedef "; + dumpType(o, m_reader.getSuperTypeName()); + o << " " << m_name << ";\n\n"; + + return sal_True; +} + +sal_Bool TypeDefType::dumpCFile(FileStream& o) + throw( CannotDumpException ) +{ + dumpInclude(o, m_typeName, "h"); + o << "\n"; + dumpDefaultCIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "h"); + o << "\n"; + dumpGetCunoType(o); + return sal_True; +} + +void TypeDefType::dumpGetCunoType(FileStream& o) +{ + if ( m_cunoTypeLeak ) + { + dumpLGetCunoType(o); + return; + } + if ( !m_cunoTypeDynamic ) + { + dumpCGetCunoType(o); + return; + } +} + +void TypeDefType::dumpCGetCunoType(FileStream& o) +{ +} + +void TypeDefType::dumpLGetCunoType(FileStream& o) +{ +} + +//************************************************************************* +// produceType +//************************************************************************* +sal_Bool produceType(const OString& typeName, + TypeManager& typeMgr, + TypeDependency& typeDependencies, + CunoOptions* pOptions) + throw( CannotDumpException ) +{ + if (typeDependencies.isGenerated(typeName)) + return sal_True; + + TypeReader reader(typeMgr.getTypeReader(typeName)); + + if (!reader.isValid()) + { + if (typeName.equals("/")) + return sal_True; + else + return sal_False; + } + + if( !checkTypeDependencies(typeMgr, typeDependencies, typeName)) + return sal_False; + + RTTypeClass typeClass = reader.getTypeClass(); + sal_Bool ret = sal_False; + switch (typeClass) + { + case RT_TYPE_INTERFACE: + { + InterfaceType iType(reader, typeName, typeMgr, typeDependencies); + ret = iType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); + ret = iType.dumpDependedTypes(pOptions); + } + break; + case RT_TYPE_MODULE: + { + ModuleType mType(reader, typeName, typeMgr, typeDependencies); + if (mType.hasConstants()) + { + ret = mType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); +// ret = mType.dumpDependedTypes(pOptions); + } else + { + typeDependencies.setGenerated(typeName); + ret = sal_True; + } + } + break; + case RT_TYPE_STRUCT: + { + StructureType sType(reader, typeName, typeMgr, typeDependencies); + ret = sType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); + ret = sType.dumpDependedTypes(pOptions); + } + break; + case RT_TYPE_ENUM: + { + EnumType enType(reader, typeName, typeMgr, typeDependencies); + ret = enType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); + ret = enType.dumpDependedTypes(pOptions); + } + break; + case RT_TYPE_EXCEPTION: + { + ExceptionType eType(reader, typeName, typeMgr, typeDependencies); + ret = eType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); + ret = eType.dumpDependedTypes(pOptions); + } + break; + case RT_TYPE_TYPEDEF: + { + TypeDefType tdType(reader, typeName, typeMgr, typeDependencies); + ret = tdType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); + ret = tdType.dumpDependedTypes(pOptions); + } + break; + case RT_TYPE_CONSTANTS: + { + ConstantsType cType(reader, typeName, typeMgr, typeDependencies); + if (cType.hasConstants()) + { + ret = cType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); +// ret = cType.dumpDependedTypes(pOptions); + } else + { + typeDependencies.setGenerated(typeName); + ret = sal_True; + } + } + break; + case RT_TYPE_SERVICE: + case RT_TYPE_OBJECT: + ret = sal_True; + break; + } + + return ret; +} + +//************************************************************************* +// scopedName +//************************************************************************* +OString scopedName(const OString& scope, const OString& type, + sal_Bool bNoNameSpace) +{ + sal_Int32 nPos = type.lastIndexOf( '/' ); + if (nPos == -1) + return type; + + if (bNoNameSpace) + return type.copy(nPos+1); + + OStringBuffer tmpBuf(type.getLength()*2); + nPos = 0; + do + { + tmpBuf.append("::"); + tmpBuf.append(type.getToken(0, '/', nPos)); + } while( nPos != -1 ); + + return tmpBuf.makeStringAndClear(); +} + +//************************************************************************* +// shortScopedName +//************************************************************************* +OString shortScopedName(const OString& scope, const OString& type, + sal_Bool bNoNameSpace) +{ + sal_Int32 nPos = type.lastIndexOf( '/' ); + if( nPos == -1 ) + return OString(); + + if (bNoNameSpace) + return OString(); + + // scoped name only if the namespace is not equal + if (scope.lastIndexOf('/') > 0) + { + OString tmpScp(scope.copy(0, scope.lastIndexOf('/'))); + OString tmpScp2(type.copy(0, nPos)); + + if (tmpScp == tmpScp2) + return OString(); + } + + OString aScope( type.copy( 0, nPos ) ); + OStringBuffer tmpBuf(aScope.getLength()*2); + + nPos = 0; + do + { + tmpBuf.append("::"); + tmpBuf.append(aScope.getToken(0, '/', nPos)); + } while( nPos != -1 ); + + return tmpBuf.makeStringAndClear(); +} + + diff --git a/codemaker/source/cunomaker/cunotype.hxx b/codemaker/source/cunomaker/cunotype.hxx new file mode 100644 index 000000000000..81d55270833a --- /dev/null +++ b/codemaker/source/cunomaker/cunotype.hxx @@ -0,0 +1,309 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_SOURCE_CUNOMAKER_CUNOTYPE_HXX_ +#define INCLUDED_CODEMAKER_SOURCE_CUNOMAKER_CUNOTYPE_HXX + +#include <codemaker/typemanager.hxx> +#include <codemaker/dependency.hxx> + +enum BASETYPE +{ + BT_INVALID, + BT_VOID, + BT_ANY, + BT_TYPE, + BT_BOOLEAN, + BT_CHAR, + BT_STRING, + BT_FLOAT, + BT_DOUBLE, + BT_OCTET, + BT_BYTE, + BT_SHORT, + BT_LONG, + BT_HYPER, + BT_UNSIGNED_SHORT, + BT_UNSIGNED_LONG, + BT_UNSIGNED_HYPER +}; + + +enum CunoTypeDecl +{ + CUNOTYPEDECL_ALLTYPES, + CUNOTYPEDECL_NOINTERFACES, + CUNOTYPEDECL_ONLYINTERFACES +}; + +class CunoOptions; +class FileStream; + +class CunoType +{ +public: + CunoType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~CunoType(); + + virtual sal_Bool dump(CunoOptions* pOptions) throw( CannotDumpException ); + virtual sal_Bool dumpDependedTypes(CunoOptions* pOptions) throw( CannotDumpException ); + virtual sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ) = 0; + virtual sal_Bool dumpCFile(FileStream& o) throw( CannotDumpException ) = 0; + + virtual ::rtl::OString dumpHeaderDefine(FileStream& o, sal_Char* prefix, sal_Bool bExtended=sal_False); + virtual void dumpDefaultHIncludes(FileStream& o); + virtual void dumpDefaultCIncludes(FileStream& o); + virtual void dumpInclude(FileStream& o, const ::rtl::OString& typeName, sal_Char* prefix, sal_Bool bExtended=sal_False, sal_Bool bCaseSensitive=sal_False); + virtual void dumpDepIncludes(FileStream& o, const ::rtl::OString& typeName, sal_Char* prefix); + + virtual void dumpOpenExternC(FileStream& o); + virtual void dumpCloseExternC(FileStream& o); + + virtual void dumpGetCunoType(FileStream& o); + virtual void dumpCGetCunoType(FileStream& o); + virtual void dumpLGetCunoType(FileStream& o); + + virtual void dumpType(FileStream& o, const ::rtl::OString& type, sal_Bool bConst=sal_False, + sal_Bool bPointer=sal_False, sal_Bool bParam=sal_False) + throw( CannotDumpException ); + ::rtl::OString getTypeClass(const ::rtl::OString& type="", sal_Bool bCStyle=sal_False); + ::rtl::OString getBaseType(const ::rtl::OString& type); + void dumpCppuGetType(FileStream& o, const ::rtl::OString& type, sal_Bool bDecl=sal_False, CunoTypeDecl eDeclFlag=CUNOTYPEDECL_ALLTYPES); + void dumpTypeInit(FileStream& o, const ::rtl::OString& type); + BASETYPE isBaseType(const ::rtl::OString& type); + + ::rtl::OString typeToIdentifier(const ::rtl::OString& type); + + void dumpConstantValue(FileStream& o, sal_uInt16 index); + + virtual sal_uInt32 getMemberCount(); + virtual sal_uInt32 getInheritedMemberCount(); + void dumpInheritedMembers(FileStream& o, rtl::OString& superType); + + sal_Bool isSeqType(const ::rtl::OString& type, ::rtl::OString& baseType, ::rtl::OString& seqPrefix); + sal_Bool isArrayType(const ::rtl::OString& type, ::rtl::OString& baseType, ::rtl::OString& arrayPrefix); + sal_Bool isVoid(const ::rtl::OString& type) + { return type.equals("void"); } + void inc(sal_uInt32 num=4); + void dec(sal_uInt32 num=4); + ::rtl::OString indent(); + ::rtl::OString indent(sal_uInt32 num); +protected: + virtual sal_uInt32 checkInheritedMemberCount(const TypeReader* pReader); + + ::rtl::OString checkSpecialCunoType(const ::rtl::OString& type); + ::rtl::OString checkRealBaseType(const ::rtl::OString& type, sal_Bool bResolveTypeOnly = sal_False); + void dumpCppuGetTypeMemberDecl(FileStream& o, CunoTypeDecl eDeclFlag); + + sal_Bool isNestedType() + { return m_bIsNestedType; }; + + RegistryKeyNames& getNestedTypeNames() + { return m_nestedTypeNames; }; + + sal_Bool isNestedTypeByName(const ::rtl::OString& type); + sal_Bool hasNestedType(const ::rtl::OString& type); + +protected: + sal_uInt32 m_inheritedMemberCount; + + sal_Bool m_cunoTypeLib; + sal_Bool m_cunoTypeLeak; + sal_Bool m_cunoTypeDynamic; + sal_uInt32 m_indentLength; + ::rtl::OString m_typeName; + ::rtl::OString m_name; + TypeReader m_reader; + TypeManager& m_typeMgr; + TypeDependency m_dependencies; + sal_Bool m_bIsNestedType; + RegistryKeyNames m_nestedTypeNames; +}; + +class InterfaceType : public CunoType +{ +public: + InterfaceType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~InterfaceType(); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpCFile(FileStream& o) throw( CannotDumpException ); + + void dumpInheritedFunctions(FileStream& o, rtl::OString& superType); + void dumpAttributes(FileStream& o, const ::rtl::OString& interfaceType, TypeReader& reader ); + void dumpMethods(FileStream& o, const ::rtl::OString& interfaceType, TypeReader& reader ); + void dumpGetCunoType(FileStream& o); + void dumpCGetCunoType(FileStream& o); + void dumpCUnoAttributeTypeNames(FileStream& o, sal_Bool bRelease=sal_False); + void dumpCUnoMethodTypeNames(FileStream& o, sal_Bool bRelease=sal_False); + void dumpCUnoAttributeRefs(FileStream& o, sal_uInt32& index); + void dumpCUnoMethodRefs(FileStream& o, sal_uInt32& index); + void dumpCUnoAttributes(FileStream& o, sal_uInt32& index); + void dumpCUnoMethods(FileStream& o, sal_uInt32& index); + void dumpAttributesCppuDecl(FileStream& o, StringSet* pFinishedTypes, CunoTypeDecl eDeclFlag); + void dumpMethodsCppuDecl(FileStream& o, StringSet* pFinishedTypes, CunoTypeDecl eDeclFlag ); + + sal_uInt32 getMemberCount(); + sal_uInt32 getInheritedMemberCount(); + +protected: + sal_uInt32 checkInheritedMemberCount(const TypeReader* pReader); + +protected: + sal_uInt32 m_inheritedMemberCount; + sal_Bool m_hasAttributes; + sal_Bool m_hasMethods; +}; + +class ModuleType : public CunoType +{ +public: + ModuleType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~ModuleType(); + + virtual sal_Bool dump(CunoOptions* pOptions) throw( CannotDumpException ); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpCFile(FileStream& o) throw( CannotDumpException ); + sal_Bool hasConstants(); +}; + +class ConstantsType : public ModuleType +{ +public: + ConstantsType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~ConstantsType(); + + virtual sal_Bool dump(CunoOptions* pOptions) throw( CannotDumpException ); +}; + +class StructureType : public CunoType +{ +public: + StructureType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~StructureType(); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpCFile(FileStream& o) throw( CannotDumpException ); +}; + +class ExceptionType : public CunoType +{ +public: + ExceptionType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~ExceptionType(); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpCFile(FileStream& o) throw( CannotDumpException ); +}; + +class EnumType : public CunoType +{ +public: + EnumType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~EnumType(); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpCFile(FileStream& o) throw( CannotDumpException ); + + void dumpGetCunoType(FileStream& o); + void dumpCGetCunoType(FileStream& o); +}; + +class TypeDefType : public CunoType +{ +public: + TypeDefType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~TypeDefType(); + + sal_Bool dumpDeclaration(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); + sal_Bool dumpCFile(FileStream& o) throw( CannotDumpException ); + + void dumpGetCunoType(FileStream& o); + void dumpLGetCunoType(FileStream& o); + void dumpCGetCunoType(FileStream& o); +}; + + +sal_Bool produceType(const ::rtl::OString& typeName, + TypeManager& typeMgr, + TypeDependency& typeDependencies, + CunoOptions* pOptions) + throw( CannotDumpException ); + +/** + * This function returns a C++ scoped name, represents the namespace + * scoping of this type, e.g. com:.sun::star::uno::XInterface. If the scope of + * the type is equal scope, the relativ name will be used. + */ +::rtl::OString scopedName(const ::rtl::OString& scope, const ::rtl::OString& type, + sal_Bool bNoNameSpace=sal_False); + +::rtl::OString shortScopedName(const ::rtl::OString& scope, const ::rtl::OString& type, + sal_Bool bNoNameSpace=sal_False); + + +#endif // INCLUDED_CODEMAKER_SOURCE_CUNOMAKER_CUNOTYPE_HXX + diff --git a/codemaker/source/cunomaker/makefile.mk b/codemaker/source/cunomaker/makefile.mk new file mode 100644 index 000000000000..5cc3bc99db8f --- /dev/null +++ b/codemaker/source/cunomaker/makefile.mk @@ -0,0 +1,61 @@ +#************************************************************************* +# +# 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=cunomaker +TARGETTYPE=CUI +LIBTARGET=NO + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +CXXFILES= cunomaker.cxx \ + cunooptions.cxx \ + cunotype.cxx + + +APP1TARGET= $(TARGET) + +APP1OBJS= $(OBJ)$/cunomaker.obj \ + $(OBJ)$/cunooptions.obj \ + $(OBJ)$/cunotype.obj + +APP1STDLIBS= \ + $(SALLIB) \ + $(SALHELPERLIB) \ + $(REGLIB) \ + +APP1LIBS= \ + $(LB)$/codemaker.lib + +.INCLUDE : target.mk diff --git a/codemaker/source/idlmaker/idlmaker.cxx b/codemaker/source/idlmaker/idlmaker.cxx new file mode 100644 index 000000000000..278bac63e4bd --- /dev/null +++ b/codemaker/source/idlmaker/idlmaker.cxx @@ -0,0 +1,186 @@ +/************************************************************************* + * + * 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 <stdio.h> + +#include "sal/main.h" + +#include <codemaker/typemanager.hxx> +#include <codemaker/dependency.hxx> + +#include "idloptions.hxx" +#include "idltype.hxx" + +using namespace rtl; + +sal_Bool produceAllTypes(const OString& typeName, + TypeManager& typeMgr, + TypeDependency& typeDependencies, + IdlOptions* pOptions, + sal_Bool bFullScope) + throw( CannotDumpException ) +{ + if (!produceType(typeName, typeMgr, typeDependencies, pOptions)) + { + fprintf(stderr, "%s ERROR: %s\n", + pOptions->getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + + RegistryKey typeKey = typeMgr.getTypeKey(typeName); + RegistryKeyNames subKeys; + + if (typeKey.getKeyNames(OUString(), subKeys)) + return sal_False; + + OString tmpName; + for (sal_uInt32 i=0; i < subKeys.getLength(); i++) + { + tmpName = OUStringToOString(subKeys.getElement(i), RTL_TEXTENCODING_UTF8); + + if (pOptions->isValid("-B")) + tmpName = tmpName.copy(tmpName.indexOf('/', 1) + 1); + else + tmpName = tmpName.copy(1); + + if (bFullScope) + { + if (!produceAllTypes(tmpName, typeMgr, typeDependencies, pOptions, sal_True)) + return sal_False; + } else + { + if (!produceType(tmpName, typeMgr, typeDependencies, pOptions)) + return sal_False; + } + } + + return sal_True; +} + +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) +{ + IdlOptions options; + + try + { + if (!options.initOptions(argc, argv)) + { + exit(1); + } + } + catch( IllegalArgument& e) + { + fprintf(stderr, "Illegal option: %s\n", e.m_message.getStr()); + exit(99); + } + + RegistryTypeManager typeMgr; + TypeDependency typeDependencies; + + if (!typeMgr.init(!options.isValid("-T"), options.getInputFiles())) + { + fprintf(stderr, "%s : init registries failed, check your registry files.\n", options.getProgramName().getStr()); + exit(99); + } + + if (options.isValid("-B")) + { + typeMgr.setBase(options.getOption("-B")); + } + + try + { + if (options.isValid("-T")) + { + OString tOption(options.getOption("-T")); + + OString typeName, tmpName; + sal_Bool ret = sal_False; + sal_Int32 nIndex = 0; + do + { + typeName = tOption.getToken(0, ';', nIndex); + + sal_Int32 nPos = typeName.lastIndexOf( '.' ); + tmpName = typeName.copy( nPos != -1 ? nPos+1 : 0 ); + if (tmpName == "*") + { + // produce this type and his scope, but the scope is not recursively generated. + if (typeName.equals("*")) + { + tmpName = "/"; + } else + { + tmpName = typeName.copy(0, typeName.lastIndexOf('.')).replace('.', '/'); + if (tmpName.getLength() == 0) + tmpName = "/"; + else + tmpName.replace('.', '/'); + } + ret = produceAllTypes(tmpName, typeMgr, typeDependencies, &options, sal_False); + } else + { + // produce only this type + ret = produceType(typeName.replace('.', '/'), typeMgr, typeDependencies, &options); + } + + if (!ret) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + } while( nIndex != -1 ); + } else + { + // produce all types + if (!produceAllTypes("/", typeMgr, typeDependencies, &options, sal_True)) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + "an error occurs while dumping all types."); + exit(99); + } + } + } + catch( CannotDumpException& e) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + e.m_message.getStr()); + exit(99); + } + + return 0; +} + + diff --git a/codemaker/source/idlmaker/idloptions.cxx b/codemaker/source/idlmaker/idloptions.cxx new file mode 100644 index 000000000000..306e43293223 --- /dev/null +++ b/codemaker/source/idlmaker/idloptions.cxx @@ -0,0 +1,251 @@ +/************************************************************************* + * + * 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 <stdio.h> + +#include "idloptions.hxx" + +using namespace rtl; + +sal_Bool IdlOptions::initOptions(int ac, char* av[], sal_Bool bCmdFile) + throw( IllegalArgument ) +{ + sal_Bool ret = sal_True; + sal_uInt16 i=0; + + if (!bCmdFile) + { + bCmdFile = sal_True; + + m_program = av[0]; + + if (ac < 2) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } + + i = 1; + } else + { + i = 0; + } + + char *s=NULL; + for (i; i < ac; i++) + { + if (av[i][0] == '-') + { + switch (av[i][1]) + { + case 'O': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-O', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_options["-O"] = OString(s); + break; + case 'B': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-B', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_options["-B"] = OString(s); + break; + case 'T': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-T', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + if (m_options.count("-T") > 0) + { + OString tmp(m_options["-T"]); + tmp = tmp + ";" + s; + m_options["-T"] = tmp; + } else + { + m_options["-T"] = OString(s); + } + break; + case 'G': + if (av[i][2] == 'c') + { + if (av[i][3] != '\0') + { + OString tmp("'-Gc', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + m_options["-Gc"] = OString(""); + break; + } else + if (av[i][2] != '\0') + { + OString tmp("'-G', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + m_options["-G"] = OString(""); + break; + default: + throw IllegalArgument("the option is unknown" + OString(av[i])); + break; + } + } else + { + if (av[i][0] == '@') + { + FILE* cmdFile = fopen(av[i]+1, "r"); + if( cmdFile == NULL ) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } else + { + int rargc=0; + char* rargv[512]; + char buffer[512]; + + while ( fscanf(cmdFile, "%s", buffer) != EOF ) + { + rargv[rargc]= strdup(buffer); + rargc++; + } + fclose(cmdFile); + + ret = initOptions(rargc, rargv, bCmdFile); + + for (long i=0; i < rargc; i++) + { + free(rargv[i]); + } + } + } else + { + m_inputFiles.push_back(av[i]); + } + } + } + + return ret; +} + +OString IdlOptions::prepareHelp() +{ + OString help("\nusing: "); + help += m_program + " [-options] file_1 ... file_n\nOptions:\n"; + help += " -O<path> = path describes the root directory for the generated output.\n"; + help += " The output directory tree is generated under this directory.\n"; + help += " -T<name> = name specifies a type or a list of types. The output for this\n"; + help += " [t1;...] type is generated. If no '-T' option is specified,\n"; + help += " then output for all types is generated.\n"; + help += " Example: 'com.sun.star.uno.XInterface' is a valid type.\n"; + help += " -B<name> = name specifies the base node. All types are searched under this\n"; + help += " node. Default is the root '/' of the registry files.\n"; + help += " -G = generate only target files which does not exists.\n"; + help += " -Gc = generate only target files which content will be changed.\n"; + help += "IMPORTANT: You lose enum values and struct, exception inheritance!\n"; + help += " Parameter name Object is translated to _Object!\n"; + help += " The type type is translated to CORBA::TypeCode!\n"; + help += " Sequences are expanded to a typedef name Sequence_..._\"name\"!\n"; + help += prepareVersion(); + + return help; +} + +OString IdlOptions::prepareVersion() +{ + OString version("\nSun Microsystems (R) "); + version += m_program + " Version 2.0\n\n"; + + return version; +} + + diff --git a/codemaker/source/idlmaker/idloptions.hxx b/codemaker/source/idlmaker/idloptions.hxx new file mode 100644 index 000000000000..6ad5e47daa4d --- /dev/null +++ b/codemaker/source/idlmaker/idloptions.hxx @@ -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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_SOURCE_IDLMAKER_IDLOPTIONS_HXX +#define INCLUDED_CODEMAKER_SOURCE_IDLMAKER_IDLOPTIONS_HXX + +#include <codemaker/options.hxx> + +class IdlOptions : public Options +{ +public: + IdlOptions() + : Options() {} + + ~IdlOptions() {} + + sal_Bool initOptions(int ac, char* av[], sal_Bool bCmdFile=sal_False) + throw( IllegalArgument ); + + ::rtl::OString prepareHelp(); + + ::rtl::OString prepareVersion(); + +protected: +}; + +#endif // INCLUDED_CODEMAKER_SOURCE_IDLMAKER_IDLOPTIONS_HXX diff --git a/codemaker/source/idlmaker/idltype.cxx b/codemaker/source/idlmaker/idltype.cxx new file mode 100644 index 000000000000..8ffa32543100 --- /dev/null +++ b/codemaker/source/idlmaker/idltype.cxx @@ -0,0 +1,1752 @@ +/************************************************************************* + * + * 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 <stdio.h> +#include <rtl/alloc.h> +#include <rtl/ustring.hxx> +#include <rtl/strbuf.hxx> + +#include "idltype.hxx" +#include "idloptions.hxx" + +using namespace rtl; + +//************************************************************************* +// IdlType +//************************************************************************* +IdlType::IdlType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : m_inheritedMemberCount(0) + , m_indentLength(0) + , m_typeName(typeName) + , m_reader(typeReader) + , m_typeMgr((TypeManager&)typeMgr) + , m_dependencies(typeDependencies) +{ + sal_Int32 i = typeName.lastIndexOf('/'); + m_name = typeName.copy( i != -1 ? i+1 : 0 ); +} + +IdlType::~IdlType() +{ + +} + +sal_Bool IdlType::dump(IdlOptions* pOptions) + throw( CannotDumpException ) +{ + sal_Bool ret = sal_False; + + OString outPath; + if (pOptions->isValid("-O")) + outPath = pOptions->getOption("-O"); + + OString tmpFileName; + OString hFileName = createFileNameFromType(outPath, m_typeName, ".idl"); + + sal_Bool bFileExists = sal_False; + sal_Bool bFileCheck = sal_False; + + if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) + { + bFileExists = fileExists( hFileName ); + ret = sal_True; + } + + if ( bFileExists && pOptions->isValid("-Gc") ) + { + tmpFileName = createFileNameFromType(outPath, m_typeName, ".tml"); + bFileCheck = sal_True; + } + + if ( !bFileExists || bFileCheck ) + { + FileStream hFile; + + if ( bFileCheck ) + hFile.open(tmpFileName); + else + hFile.open(hFileName); + + if(!hFile.isValid()) + { + OString message("cannot open "); + message += hFileName + " for writing"; + throw CannotDumpException(message); + } + + ret = dumpHFile(hFile); + + hFile.close(); + if (ret && bFileCheck) + { + ret = checkFileContent(hFileName, tmpFileName); + } + } + + return ret; +} +sal_Bool IdlType::dumpDependedTypes(IdlOptions* pOptions) + throw( CannotDumpException ) +{ + sal_Bool ret = sal_True; + + TypeUsingSet usingSet(m_dependencies.getDependencies(m_typeName)); + + TypeUsingSet::const_iterator iter = usingSet.begin(); + OString typeName; + sal_uInt32 index = 0; + while (iter != usingSet.end()) + { + typeName = (*iter).m_type; + if ((index = typeName.lastIndexOf(']')) > 0) + typeName = typeName.copy(index + 1); + + if (getBaseType(typeName).getLength() == 0) + { + if (!produceType(typeName, + m_typeMgr, + m_dependencies, + pOptions)) + { + fprintf(stderr, "%s ERROR: %s\n", + pOptions->getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + } + ++iter; + } + + return ret; +} + +OString IdlType::dumpHeaderDefine(FileStream& o, sal_Char* prefix ) +{ + if (m_typeName.equals("/")) + { + m_typeName = "global"; + } + + sal_uInt32 length = 3 + m_typeName.getLength() + strlen(prefix); + + OStringBuffer tmpBuf(length); + + tmpBuf.append('_'); + tmpBuf.append(m_typeName); + tmpBuf.append('_'); + tmpBuf.append(prefix); + tmpBuf.append('_'); + + OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase()); + + o << "#ifndef " << tmp << "\n#define " << tmp << "\n"; + + return tmp; +} + +void IdlType::dumpDefaultHIncludes(FileStream& o) +{ +} + +void IdlType::dumpInclude(FileStream& o, const OString& genTypeName, const OString& typeName, sal_Char* prefix ) +{ + sal_uInt32 length = 3+ m_typeName.getLength() + strlen(prefix); + + OStringBuffer tmpBuf(length); + + tmpBuf.append('_'); + tmpBuf.append(typeName); + tmpBuf.append('_'); + tmpBuf.append(prefix); + tmpBuf.append('_'); + + OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase()); + + length = 1 + typeName.getLength() + strlen(prefix); + + tmpBuf.ensureCapacity(length); + tmpBuf.append(typeName); + tmpBuf.append('.'); + tmpBuf.append(prefix); + + o << "#ifndef " << tmp << "\n#include <"; + tmp = tmpBuf.makeStringAndClear(); + + sal_Int32 nIndex = 0; + do + { + genTypeName.getToken(0, '/', nIndex); + o << "../"; + } while( nIndex != -1 ); + +// sal_Int32 nSlashes = genTypeName.getTokenCount( '/'); +// for( sal_Int32 i = 1; i < nSlashes; i++ ) +// o << "../"; + o << tmp; + o << ">\n#endif\n"; +} + +void IdlType::dumpDepIncludes(FileStream& o, const OString& typeName, sal_Char* prefix) +{ + TypeUsingSet usingSet(m_dependencies.getDependencies(typeName)); + + TypeUsingSet::const_iterator iter = usingSet.begin(); + + OString sPrefix(OString(prefix).toAsciiUpperCase()); + sal_uInt32 index = 0; + sal_uInt32 seqNum = 0; + OString relType; + while (iter != usingSet.end()) + { + index = (*iter).m_type.lastIndexOf(']'); + seqNum = (index > 0 ? ((index+1) / 2) : 0); + + relType = (*iter).m_type; + if (index > 0) + relType = relType.copy(index+1); + + + OString defPrefix("IDL"); + + if (getBaseType(relType).getLength() == 0 && + m_typeName != relType) + { + if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) + { + if (!((*iter).m_use & TYPEUSE_SUPER)) + { + o << "\n"; + dumpNameSpace(o, sal_True, sal_False, relType); + o << "\ninterface " << scopedName(m_typeName, relType, sal_True) << ";\n"; + dumpNameSpace(o, sal_False, sal_False, relType); + o << "\n\n"; + } + } + dumpInclude(o, typeName, relType, prefix); + } + else if (relType == "type") + { + o << "module CORBA {\n" + << "\tinterface TypeCode;\n" + << "};\n\n"; + } + + if( seqNum != 0 ) + { + // write typedef for sequences to support Rational Rose 2000 import + OString aST = relType; + OString aScope; + dumpNameSpace( o, sal_True, sal_False, relType ); + for( sal_uInt32 i = 0; i < seqNum; i++ ) + { + o << "typedef sequence< " << scopedName("", aST) << " > "; + + if( i == 0 ) + { + aST = aST.replace( '/', '_' ); + aST = aST.replace( ' ', '_' ); + } + aST = aST + "_Sequence" ; + o << aST << ";\n"; + } + dumpNameSpace( o, sal_False, sal_False, relType ); + } + ++iter; + } +} + +void IdlType::dumpNameSpace(FileStream& o, sal_Bool bOpen, sal_Bool bFull, const OString& type) +{ + OString typeName(type); + sal_Bool bOneLine = sal_True; + if (typeName.getLength() == 0) + { + typeName = m_typeName; + bOneLine = sal_False; + } + + if (typeName == "/") + return; + + if (typeName.indexOf( '/' ) == -1 && !bFull) + return; + + if (!bFull) + typeName = typeName.copy( 0, typeName.lastIndexOf( '/' ) ); + + if (bOpen) + { + sal_Int32 nIndex = 0; + do + { + o << "module " << typeName.getToken(0, '/', nIndex); + if (bOneLine) + o << " { "; + else + o << "\n{\n"; + } while( nIndex != -1 ); + } else + { + sal_Int32 nPos = 0; + do + { + nPos = typeName.lastIndexOf( '/' ); + o << "};"; + if( bOneLine ) + o << " "; + else + o << " /* " << typeName.copy( nPos+1 ) << " */\n"; + if( nPos != -1 ) + typeName = typeName.copy( 0, nPos ); + } while( nPos != -1 ); + } +} + + +sal_uInt32 IdlType::getMemberCount() +{ + sal_uInt32 count = m_reader.getMethodCount(); + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + count++; + } + return count; +} + +sal_uInt32 IdlType::checkInheritedMemberCount(const TypeReader* pReader) +{ + sal_Bool bSelfCheck = sal_True; + if (!pReader) + { + bSelfCheck = sal_False; + pReader = &m_reader; + } + + sal_uInt32 count = 0; + OString superType(pReader->getSuperTypeName()); + if (superType.getLength() > 0) + { + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + if ( aSuperReader.isValid() ) + { + count = checkInheritedMemberCount(&aSuperReader); + } + } + + if (bSelfCheck) + { + count += pReader->getMethodCount(); + sal_uInt32 fieldCount = pReader->getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = pReader->getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + { + count++; + } + } + } + + return count; +} + +sal_uInt32 IdlType::getInheritedMemberCount() +{ + if (m_inheritedMemberCount == 0) + { + m_inheritedMemberCount = checkInheritedMemberCount(0); + } + + return m_inheritedMemberCount; +} + + +void IdlType::dumpType(FileStream& o, const OString& type ) + throw( CannotDumpException ) +{ + OString sType(checkRealBaseType(type, sal_True)); + sal_uInt32 index = sType.lastIndexOf(']'); + sal_uInt32 seqNum = (index > 0 ? ((index+1) / 2) : 0); + + OString relType = (index > 0 ? (sType).copy(index+1) : type); + + RTTypeClass typeClass = m_typeMgr.getTypeClass(relType); + + sal_uInt32 i; +/* + for (i=0; i < seqNum; i++) + { + //o << "sequence< "; + } +*/ + switch (typeClass) + { + case RT_TYPE_INVALID: + { + OString tmp(getBaseType(relType)); + if (tmp.getLength() > 0) + { + tmp = tmp.replace( ' ', '_' ); + o << tmp; + } else + throw CannotDumpException("Unknown type '" + relType + "', incomplete type library."); + } + break; + case RT_TYPE_INTERFACE: + case RT_TYPE_STRUCT: + case RT_TYPE_ENUM: + case RT_TYPE_TYPEDEF: + case RT_TYPE_EXCEPTION: + if( seqNum ) + { + OString aST = relType.replace( '/', '_' ); + aST = aST.replace( ' ', '_' ); + o << aST; + } + else + o << scopedName(m_typeName, relType); + break; + } + + for (i=0; i < seqNum; i++) + { + //o << " >"; + // use typedef for sequences to support Rational Rose 2000 import + o << "_Sequence"; + } +} + +OString IdlType::getBaseType(const OString& type) +{ + if (type.equals("long")) + return type; + if (type.equals("short")) + return type; + if (type.equals("hyper")) + return "long long"; + if (type.equals("string")) + return "string"; + if (type.equals("boolean")) + return type; + if (type.equals("char")) + return "char"; + if (type.equals("byte")) + return "byte"; + if (type.equals("any")) + return type; + if (type.equals("type")) + return "CORBA::TypeCode"; + if (type.equals("float")) + return type; + if (type.equals("double")) + return type; + if (type.equals("octet")) + return type; + if (type.equals("void")) + return type; + if (type.equals("unsigned long")) + return type; + if (type.equals("unsigned short")) + return type; + if (type.equals("unsigned hyper")) + return "unsigned long long"; + + return OString(); +} + +void IdlType::dumpIdlGetType(FileStream& o, const OString& type, sal_Bool bDecl, IdlTypeDecl eDeclFlag) +{ + OString sType( checkRealBaseType(type, sal_True) ); + sal_uInt32 index = sType.lastIndexOf(']'); + OString relType = (index > 0 ? (sType).copy(index+1) : type); + + if (eDeclFlag == CPPUTYPEDECL_ONLYINTERFACES) + { + if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) + { + o << indent() << "getIdlType( ("; + dumpType(o, type); + o << "*)0 )"; + + if (bDecl) + o << ";\n"; + } + } else + { + if (isBaseType(type)) + { + return; + } else + { + if (eDeclFlag == CPPUTYPEDECL_NOINTERFACES && + m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) + return; + +// if (m_typeMgr.getTypeClass(type) == RT_TYPE_TYPEDEF) +// { +// o << indent() << "get_" << type.replace('/', '_') << "_Type()"; +// } else +// { + o << indent() << "getIdlType( ("; + dumpType(o, type); + o << "*)0 )"; +// } + } + if (bDecl) + o << ";\n"; + } +} + +BASETYPE IdlType::isBaseType(const OString& type) +{ + if (type.equals("long")) + return BT_LONG; + if (type.equals("short")) + return BT_SHORT; + if (type.equals("hyper")) + return BT_HYPER; + if (type.equals("string")) + return BT_STRING; + if (type.equals("boolean")) + return BT_BOOLEAN; + if (type.equals("char")) + return BT_CHAR; + if (type.equals("byte")) + return BT_BYTE; + if (type.equals("any")) + return BT_ANY; + if (type.equals("float")) + return BT_FLOAT; + if (type.equals("double")) + return BT_DOUBLE; + if (type.equals("void")) + return BT_VOID; + if (type.equals("unsigned long")) + return BT_UNSIGNED_LONG; + if (type.equals("unsigned short")) + return BT_UNSIGNED_SHORT; + if (type.equals("unsigned hyper")) + return BT_UNSIGNED_HYPER; + + return BT_INVALID; +} + +OString IdlType::checkSpecialIdlType(const OString& type) +{ + OString baseType(type); + + RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader(); + + RegistryKey key; + sal_uInt8* pBuffer=NULL; + RTTypeClass typeClass; + sal_Bool isTypeDef = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); + TypeReader reader; + + while (isTypeDef) + { + reader = m_typeMgr.getTypeReader(baseType); + + if (reader.isValid()) + { + typeClass = reader.getTypeClass(); + + if (typeClass == RT_TYPE_TYPEDEF) + baseType = reader.getSuperTypeName(); + else + isTypeDef = sal_False; + } else + { + break; + } + } + + return baseType; +} + +OString IdlType::checkRealBaseType(const OString& type, sal_Bool bResolveTypeOnly) +{ + sal_uInt32 index = type.lastIndexOf(']'); + OString baseType = (index > 0 ? ((OString)type).copy(index+1) : type); + OString seqPrefix = (index > 0 ? ((OString)type).copy(0, index+1) : OString()); + + RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader(); + + RegistryKey key; + sal_uInt8* pBuffer=NULL; + RTTypeClass typeClass; + sal_Bool mustBeChecked = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); + TypeReader reader; + + while (mustBeChecked) + { + reader = m_typeMgr.getTypeReader(baseType); + + if (reader.isValid()) + { + typeClass = reader.getTypeClass(); + + if (typeClass == RT_TYPE_TYPEDEF) + { + baseType = reader.getSuperTypeName(); + index = baseType.lastIndexOf(']'); + if (index > 0) + { + seqPrefix += baseType.copy(0, index+1); + baseType = baseType.copy(index+1); + } + } else + mustBeChecked = sal_False; + } else + { + break; + } + } + + if ( bResolveTypeOnly ) + baseType = seqPrefix + baseType; + + return baseType; +} + +void IdlType::dumpConstantValue(FileStream& o, sal_uInt16 index) +{ + RTConstValue constValue = m_reader.getFieldConstValue(index); + + switch (constValue.m_type) + { + case RT_TYPE_BOOL: + if (constValue.m_value.aBool) + o << "true"; + else + o << "false"; + break; + case RT_TYPE_BYTE: + { + char tmp[16]; + snprintf(tmp, sizeof(tmp), "0x%x", (sal_Int8)constValue.m_value.aByte); + o << tmp; + } + break; + case RT_TYPE_INT16: + o << constValue.m_value.aShort; + break; + case RT_TYPE_UINT16: + o << constValue.m_value.aUShort; + break; + case RT_TYPE_INT32: + o << constValue.m_value.aLong; + break; + case RT_TYPE_UINT32: + o << constValue.m_value.aULong; + break; + case RT_TYPE_INT64: + { + ::rtl::OString tmp( OString::valueOf(constValue.m_value.aHyper) ); + o << tmp.getStr(); + } + break; + case RT_TYPE_UINT64: + { + ::rtl::OString tmp( OString::valueOf((sal_Int64)constValue.m_value.aUHyper) ); + o << tmp.getStr(); + } + break; + case RT_TYPE_FLOAT: + { + ::rtl::OString tmp( OString::valueOf(constValue.m_value.aFloat) ); + o << tmp.getStr(); + } + break; + case RT_TYPE_DOUBLE: + { + ::rtl::OString tmp( OString::valueOf(constValue.m_value.aDouble) ); + o << tmp.getStr(); + } + break; + case RT_TYPE_STRING: + { + ::rtl::OUString aUStr(constValue.m_value.aString); + ::rtl::OString aStr = ::rtl::OUStringToOString(aUStr, RTL_TEXTENCODING_ASCII_US); + o << "\"" << aStr.getStr() << "\")"; + } + break; + } +} + +void IdlType::inc(sal_uInt32 num) +{ + m_indentLength += num; +} + +void IdlType::dec(sal_uInt32 num) +{ + if (m_indentLength - num < 0) + m_indentLength = 0; + else + m_indentLength -= num; +} + +OString IdlType::indent() +{ + OStringBuffer tmp(m_indentLength); + + for (sal_uInt32 i=0; i < m_indentLength; i++) + { + tmp.append(' '); + } + return tmp.makeStringAndClear(); +} + +OString IdlType::indent(sal_uInt32 num) +{ + OStringBuffer tmp(m_indentLength + num); + + for (sal_uInt32 i=0; i < m_indentLength + num; i++) + { + tmp.append(' '); + } + return tmp.makeStringAndClear(); +} + +//************************************************************************* +// InterfaceType +//************************************************************************* +InterfaceType::InterfaceType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : IdlType(typeReader, typeName, typeMgr, typeDependencies) +{ + m_inheritedMemberCount = 0; + m_hasAttributes = sal_False; + m_hasMethods = sal_False; +} + +InterfaceType::~InterfaceType() +{ + +} + +sal_Bool InterfaceType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "IDL")); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "idl"); + o << "\n"; + dumpNameSpace(o); + + // write documentation + OString aDoc = m_reader.getDoku(); + if( aDoc.getLength() ) + o << "/**\n" << aDoc << "\n*/"; + o << "\ninterface " << m_name; + + OString superType(m_reader.getSuperTypeName()); + if (superType.getLength() > 0) + o << " : " << scopedName(m_typeName, superType); + + o << "\n{\n"; + inc(); + + dumpAttributes(o); + dumpMethods(o); + + dec(); + o << "};\n\n"; + + dumpNameSpace(o, sal_False); + +// o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n" +// << "class Type;\n} } } }\n\n"; + + o << "#endif /* "<< headerDefine << "*/" << "\n"; + return sal_True; +} + +void InterfaceType::dumpAttributes(FileStream& o) +{ + sal_uInt32 fieldCount = m_reader.getFieldCount(); + sal_Bool first=sal_True; + + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + + if (first) + { + first = sal_False; + o << "\n"; + } + + // write documentation + OString aDoc = m_reader.getFieldDoku(i); + if( aDoc.getLength() ) + o << "/**\n" << aDoc << "\n*/\n"; + + if (access == RT_ACCESS_READONLY) + o << indent() << "readonly attribute "; + else + o << indent() << "attribute "; + dumpType(o, fieldType); + o << " " << fieldName << ";\n"; + } +} + +void InterfaceType::dumpMethods(FileStream& o) +{ + sal_uInt32 methodCount = m_reader.getMethodCount(); + + OString methodName, returnType, paramType, paramName; + sal_uInt32 paramCount = 0; + sal_uInt32 excCount = 0; + RTMethodMode methodMode = RT_MODE_INVALID; + RTParamMode paramMode = RT_PARAM_INVALID; + + sal_Bool bRef = sal_False; + sal_Bool bConst = sal_False; + sal_Bool bWithRunTimeExcp = sal_True; + + for (sal_Int16 i=0; i < methodCount; i++) + { + methodName = m_reader.getMethodName(i); + returnType = m_reader.getMethodReturnType(i); + paramCount = m_reader.getMethodParamCount(i); + excCount = m_reader.getMethodExcCount(i); + methodMode = m_reader.getMethodMode(i); + + if ( methodName.equals("acquire") || methodName.equals("release") ) + { + bWithRunTimeExcp = sal_False; + } + + // write documentation + OString aDoc = m_reader.getMethodDoku(i); + if( aDoc.getLength() ) + o << "/**\n" << aDoc << "\n*/\n"; + + o << indent(); + dumpType(o, returnType); + o << " " << methodName << "( "; + sal_uInt16 j; + for (j=0; j < paramCount; j++) + { + paramName = m_reader.getMethodParamName(i, j); + paramType = m_reader.getMethodParamType(i, j); + paramMode = m_reader.getMethodParamMode(i, j); + + switch (paramMode) + { + case RT_PARAM_IN: + o << "in "; + break; + case RT_PARAM_OUT: + o << "out "; + break; + case RT_PARAM_INOUT: + o << "inout "; + break; + break; + } + + dumpType(o, paramType); + if( paramName == "Object" ) + o << " _Object"; + else + o << " " << paramName; + + if (j+1 < paramCount) o << ", "; + } + o << " )"; + + if( excCount ) + { + o << " raises("; + OString excpName; + sal_Bool bWriteComma = sal_False; + sal_Bool bRTExceptionWritten = sal_False; + for (j=0; j < excCount; j++) + { + excpName = m_reader.getMethodExcType(i, j); + if( bWriteComma ) + o << ", "; + o << scopedName(m_typeName, excpName); + bWriteComma = sal_True; + + if(excpName == "com/sun/star/uno/RuntimeException") + bRTExceptionWritten = sal_True; + } + + if ( bWithRunTimeExcp && !bRTExceptionWritten ) + { + if( bWriteComma ) + o << ", "; + o << "::com::sun::star::uno::RuntimeException"; + } + + o << ");\n"; + } + else if ( bWithRunTimeExcp ) + { + o << "raises( ::com::sun::star::uno::RuntimeException );\n"; + } + else + { + o << ";\n"; + } + } +} + + +sal_uInt32 InterfaceType::getMemberCount() +{ + sal_uInt32 count = m_reader.getMethodCount(); + + if (count) + m_hasMethods = sal_True; + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + { + m_hasAttributes = sal_True; + count++; + } + } + return count; +} + +sal_uInt32 InterfaceType::checkInheritedMemberCount(const TypeReader* pReader) +{ + sal_uInt32 cout = 0; + sal_Bool bSelfCheck = sal_True; + if (!pReader) + { + bSelfCheck = sal_False; + pReader = &m_reader; + } + + sal_uInt32 count = 0; + OString superType(pReader->getSuperTypeName()); + if (superType.getLength() > 0) + { + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + if (aSuperReader.isValid()) + { + count = checkInheritedMemberCount(&aSuperReader); + } + } + + if (bSelfCheck) + { + count += pReader->getMethodCount(); + sal_uInt32 fieldCount = pReader->getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = pReader->getFieldAccess(i); + + if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) + { + count++; + } + } + } + + return count; +} + +sal_uInt32 InterfaceType::getInheritedMemberCount() +{ + if (m_inheritedMemberCount == 0) + { + m_inheritedMemberCount = checkInheritedMemberCount(0); + } + + return m_inheritedMemberCount; +} + + + +//************************************************************************* +// ModuleType +//************************************************************************* +ModuleType::ModuleType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : IdlType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +ModuleType::~ModuleType() +{ + +} + +sal_Bool ModuleType::dump(IdlOptions* pOptions) + throw( CannotDumpException ) +{ + sal_Bool ret = sal_False; + + OString outPath; + if (pOptions->isValid("-O")) + outPath = pOptions->getOption("-O"); + + OString tmpName(m_typeName); + + if (tmpName.equals("/")) + tmpName = "global"; + else +// tmpName += "/" + m_typeName.getToken(m_typeName.getTokenCount('/') - 1, '/'); + tmpName += "/" + m_name; + + OString tmpFileName; + OString hFileName = createFileNameFromType(outPath, tmpName, ".idl"); + + sal_Bool bFileExists = sal_False; + sal_Bool bFileCheck = sal_False; + + if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) + { + bFileExists = fileExists( hFileName ); + ret = sal_True; + } + + if ( bFileExists && pOptions->isValid("-Gc") ) + { + tmpFileName = createFileNameFromType(outPath, m_typeName, ".tml"); + bFileCheck = sal_True; + } + + if ( !bFileExists || bFileCheck ) + { + FileStream hFile; + + if ( bFileCheck ) + hFile.open(tmpFileName); + else + hFile.open(hFileName); + + if(!hFile.isValid()) + { + OString message("cannot open "); + message += hFileName + " for writing"; + throw CannotDumpException(message); + } + + ret = dumpHFile(hFile); + + hFile.close(); + if (ret && bFileCheck) + { + ret = checkFileContent(hFileName, tmpFileName); + } + } + + return ret; +} + +sal_Bool ModuleType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "IDL")); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "idl"); + o << "\n"; + + dumpNameSpace(o, sal_True, sal_True); + o << "\n"; + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST) + { + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + + o << "const "; + dumpType(o, fieldType); + o << " " << fieldName << " = "; + dumpConstantValue(o, i); + o << ";\n"; + } + } + + o << "\n"; + dumpNameSpace(o, sal_False, sal_True); + o << "\n#endif /* "<< headerDefine << "*/" << "\n"; + + return sal_True; +} + +sal_Bool ModuleType::hasConstants() +{ + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST) + return sal_True; + } + + return sal_False; +} + +//************************************************************************* +// ConstantsType +//************************************************************************* +ConstantsType::ConstantsType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : ModuleType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +ConstantsType::~ConstantsType() +{ + +} + +sal_Bool ConstantsType::dump(IdlOptions* pOptions) + throw( CannotDumpException ) +{ + sal_Bool ret = sal_False; + + OString outPath; + if (pOptions->isValid("-O")) + outPath = pOptions->getOption("-O"); + + OString tmpFileName; + OString hFileName = createFileNameFromType(outPath, m_typeName, ".idl"); + + sal_Bool bFileExists = sal_False; + sal_Bool bFileCheck = sal_False; + + if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) + { + bFileExists = fileExists( hFileName ); + ret = sal_True; + } + + if ( bFileExists && pOptions->isValid("-Gc") ) + { + tmpFileName = createFileNameFromType(outPath, m_typeName, ".tml"); + bFileCheck = sal_True; + } + + if ( !bFileExists || bFileCheck ) + { + FileStream hFile; + + if ( bFileCheck ) + hFile.open(tmpFileName); + else + hFile.open(hFileName); + + if(!hFile.isValid()) + { + OString message("cannot open "); + message += hFileName + " for writing"; + throw CannotDumpException(message); + } + + ret = dumpHFile(hFile); + + hFile.close(); + if (ret && bFileCheck) + { + ret = checkFileContent(hFileName, tmpFileName); + } + } + + return ret; +} + +//************************************************************************* +// StructureType +//************************************************************************* +StructureType::StructureType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : IdlType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +StructureType::~StructureType() +{ + +} + +sal_Bool StructureType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "IDL")); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "idl"); + o << "\n"; + + dumpNameSpace(o); + + // write documentation + OString aDoc = m_reader.getDoku(); + if( aDoc.getLength() ) + o << "/**\n" << aDoc << "\n*/"; + + o << "\nstruct " << m_name; + o << "\n{\n"; + inc(); + + OString superType(m_reader.getSuperTypeName()); + if (superType.getLength() > 0) + dumpSuperMember(o, superType); + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + sal_uInt16 i=0; + + for (i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + + // write documentation + OString aDoc = m_reader.getFieldDoku(i); + if( aDoc.getLength() ) + o << "/**\n" << aDoc << "\n*/"; + + o << indent(); + dumpType(o, fieldType); + o << " " << fieldName << ";\n"; + } + + dec(); + o << "};\n\n"; + + dumpNameSpace(o, sal_False); + + o << "#endif /* "<< headerDefine << "*/" << "\n"; + + return sal_True; +} + +void StructureType::dumpSuperMember(FileStream& o, const OString& superType) +{ + if (superType.getLength() > 0) + { + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + + if (aSuperReader.isValid()) + { + dumpSuperMember(o, aSuperReader.getSuperTypeName()); + + sal_uInt32 fieldCount = aSuperReader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = aSuperReader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = aSuperReader.getFieldName(i); + fieldType = aSuperReader.getFieldType(i); + + // write documentation + OString aDoc = aSuperReader.getFieldDoku(i); + if( aDoc.getLength() ) + o << "/**\n" << aDoc << "\n*/"; + + o << indent(); + dumpType(o, fieldType); + o << " "; + o << fieldName << ";\n"; + } + } + } +} + +//************************************************************************* +// ExceptionType +//************************************************************************* +ExceptionType::ExceptionType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : IdlType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +ExceptionType::~ExceptionType() +{ + +} + +sal_Bool ExceptionType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "IDL")); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "idl"); + o << "\n"; + + dumpNameSpace(o); + + // write documentation + OString aDoc = m_reader.getDoku(); + if( aDoc.getLength() ) + o << "/**\n" << aDoc << "\n*/"; + + o << "\nexception " << m_name; + o << "\n{\n"; + inc(); + + // Write extra member for derived exceptions + o << indent() << "/*extra member to hold a derived exception */\n"; + o << indent() << "any _derivedException;\n"; + OString superType(m_reader.getSuperTypeName()); + if (superType.getLength() > 0) + dumpSuperMember(o, superType); + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + sal_uInt16 i = 0; + + for (i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = m_reader.getFieldName(i); + fieldType = m_reader.getFieldType(i); + + // write documentation + OString aDoc = m_reader.getFieldDoku(i); + if( aDoc.getLength() ) + o << "/**\n" << aDoc << "\n*/"; + + o << indent(); + dumpType(o, fieldType); + o << " " << fieldName << ";\n"; + } + + + dec(); + o << "};\n\n"; + + dumpNameSpace(o, sal_False); + + o << "#endif /* "<< headerDefine << "*/" << "\n"; + + return sal_True; +} + +void ExceptionType::dumpSuperMember(FileStream& o, const OString& superType) +{ + if (superType.getLength() > 0) + { + TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); + + if (aSuperReader.isValid()) + { + dumpSuperMember(o, aSuperReader.getSuperTypeName()); + + sal_uInt32 fieldCount = aSuperReader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + OString fieldName; + OString fieldType; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = aSuperReader.getFieldAccess(i); + + if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) + continue; + + fieldName = aSuperReader.getFieldName(i); + fieldType = aSuperReader.getFieldType(i); + + // write documentation + OString aDoc = aSuperReader.getFieldDoku(i); + if( aDoc.getLength() ) + o << "/**\n" << aDoc << "\n*/"; + + o << indent(); + dumpType(o, fieldType); + o << " "; + o << fieldName << ";\n"; + } + } + } +} + +//************************************************************************* +// EnumType +//************************************************************************* +EnumType::EnumType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : IdlType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +EnumType::~EnumType() +{ + +} + +sal_Bool EnumType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "IDL")); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + + dumpNameSpace(o); + + // write documentation + OString aDoc = m_reader.getDoku(); + if( aDoc.getLength() ) + o << "/**\n" << aDoc << "\n*/"; + + o << "\nenum " << m_name << "\n{\n"; + inc(); + + sal_uInt32 fieldCount = m_reader.getFieldCount(); + RTFieldAccess access = RT_ACCESS_INVALID; + RTConstValue constValue; + OString fieldName; + sal_uInt32 value=0; + for (sal_uInt16 i=0; i < fieldCount; i++) + { + access = m_reader.getFieldAccess(i); + + if (access != RT_ACCESS_CONST) + continue; + + fieldName = m_reader.getFieldName(i); + constValue = m_reader.getFieldConstValue(i); + + if (constValue.m_type == RT_TYPE_INT32) + value = constValue.m_value.aLong; + else + value++; + + /* doesn't work with rational rose 2000 + // write documentation + OString aDoc = m_reader.getFieldDoku(i); + if( aDoc.getLength() ) + */ + // o << "/**\n" << aDoc << "\n*/\n"; + o << indent() << fieldName; + if( i +1 < fieldCount ) + o << ",\n"; + } + + dec(); + o << "\n};\n\n"; + + dumpNameSpace(o, sal_False); + + o << "#endif /* "<< headerDefine << "*/" << "\n"; + + return sal_True; +} + + +//************************************************************************* +// TypeDefType +//************************************************************************* +TypeDefType::TypeDefType(TypeReader& typeReader, + const OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies) + : IdlType(typeReader, typeName, typeMgr, typeDependencies) +{ +} + +TypeDefType::~TypeDefType() +{ + +} + +sal_Bool TypeDefType::dumpHFile(FileStream& o) + throw( CannotDumpException ) +{ + OString headerDefine(dumpHeaderDefine(o, "IDL")); + o << "\n"; + + dumpDefaultHIncludes(o); + o << "\n"; + dumpDepIncludes(o, m_typeName, "idl"); + o << "\n"; + + dumpNameSpace(o); + + o << "\ntypedef "; + dumpType(o, m_reader.getSuperTypeName()); + o << " " << m_name << ";\n\n"; + + dumpNameSpace(o, sal_False); + + o << "#endif /* "<< headerDefine << "*/" << "\n"; + + return sal_True; +} + + +//************************************************************************* +// produceType +//************************************************************************* +sal_Bool produceType(const OString& typeName, + TypeManager& typeMgr, + TypeDependency& typeDependencies, + IdlOptions* pOptions) + throw( CannotDumpException ) +{ + if (typeDependencies.isGenerated(typeName)) + return sal_True; + + TypeReader reader(typeMgr.getTypeReader(typeName)); + + if (!reader.isValid()) + { + if (typeName.equals("/")) + return sal_True; + else + return sal_False; + } + + if( !checkTypeDependencies(typeMgr, typeDependencies, typeName)) + return sal_False; + + RTTypeClass typeClass = reader.getTypeClass(); + sal_Bool ret = sal_False; + switch (typeClass) + { + case RT_TYPE_INTERFACE: + { + InterfaceType iType(reader, typeName, typeMgr, typeDependencies); + ret = iType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); + ret = iType.dumpDependedTypes(pOptions); + } + break; + case RT_TYPE_MODULE: + { + ModuleType mType(reader, typeName, typeMgr, typeDependencies); + if (mType.hasConstants()) + { + ret = mType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); +// ret = mType.dumpDependedTypes(pOptions); + } else + { + typeDependencies.setGenerated(typeName); + ret = sal_True; + } + } + break; + case RT_TYPE_STRUCT: + { + StructureType sType(reader, typeName, typeMgr, typeDependencies); + ret = sType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); + ret = sType.dumpDependedTypes(pOptions); + } + break; + case RT_TYPE_ENUM: + { + EnumType enType(reader, typeName, typeMgr, typeDependencies); + ret = enType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); + ret = enType.dumpDependedTypes(pOptions); + } + break; + case RT_TYPE_EXCEPTION: + { + ExceptionType eType(reader, typeName, typeMgr, typeDependencies); + ret = eType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); + ret = eType.dumpDependedTypes(pOptions); + } + break; + case RT_TYPE_TYPEDEF: + { + TypeDefType tdType(reader, typeName, typeMgr, typeDependencies); + ret = tdType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); + ret = tdType.dumpDependedTypes(pOptions); + } + break; + case RT_TYPE_CONSTANTS: + { + ConstantsType cType(reader, typeName, typeMgr, typeDependencies); + if (cType.hasConstants()) + { + ret = cType.dump(pOptions); + if (ret) typeDependencies.setGenerated(typeName); +// ret = cType.dumpDependedTypes(pOptions); + } else + { + typeDependencies.setGenerated(typeName); + ret = sal_True; + } + } + break; + case RT_TYPE_SERVICE: + case RT_TYPE_OBJECT: + ret = sal_True; + break; + } + + return ret; +} + +//************************************************************************* +// scopedName +//************************************************************************* +OString scopedName(const OString& scope, const OString& type, + sal_Bool bNoNameSpace) +{ + sal_Int32 nPos = type.lastIndexOf( '/' ); + if (nPos == -1) + return type; + + if (bNoNameSpace) + return type.copy(nPos+1); + + OStringBuffer tmpBuf(type.getLength()*2); + nPos = 0; + do + { + tmpBuf.append("::"); + tmpBuf.append(type.getToken(0, '/', nPos)); + } while( nPos != -1 ); + + return tmpBuf.makeStringAndClear(); +} + +//************************************************************************* +// shortScopedName +//************************************************************************* +OString scope(const OString& scope, const OString& type ) +{ + sal_Int32 nPos = type.lastIndexOf( '/' ); + if( nPos == -1 ) + return OString(); + + // scoped name only if the namespace is not equal + if (scope.lastIndexOf('/') > 0) + { + OString tmpScp(scope.copy(0, scope.lastIndexOf('/'))); + OString tmpScp2(type.copy(0, nPos)); + + if (tmpScp == tmpScp2) + return OString(); + } + + OString aScope( type.copy( 0, nPos ) ); + OStringBuffer tmpBuf(aScope.getLength()*2); + + nPos = 0; + do + { + tmpBuf.append("::"); + tmpBuf.append(aScope.getToken(0, '/', nPos)); + } while( nPos != -1 ); + + return tmpBuf.makeStringAndClear(); +} + + diff --git a/codemaker/source/idlmaker/idltype.hxx b/codemaker/source/idlmaker/idltype.hxx new file mode 100644 index 000000000000..307ea4290edb --- /dev/null +++ b/codemaker/source/idlmaker/idltype.hxx @@ -0,0 +1,249 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_SOURCE_IDLMAKER_IDLTYPE_HXX +#define INCLUDED_CODEMAKER_SOURCE_IDLMAKER_IDLTYPE_HXX + +#include <codemaker/typemanager.hxx> +#include <codemaker/dependency.hxx> + +enum BASETYPE +{ + BT_INVALID, + BT_VOID, + BT_ANY, + BT_TYPE, + BT_BOOLEAN, + BT_CHAR, + BT_STRING, + BT_FLOAT, + BT_DOUBLE, + BT_OCTET, + BT_BYTE, + BT_SHORT, + BT_LONG, + BT_HYPER, + BT_UNSIGNED_SHORT, + BT_UNSIGNED_LONG, + BT_UNSIGNED_HYPER +}; + + +enum IdlTypeDecl +{ + CPPUTYPEDECL_ALLTYPES, + CPPUTYPEDECL_NOINTERFACES, + CPPUTYPEDECL_ONLYINTERFACES +}; + +class IdlOptions; +class FileStream; + +class IdlType +{ +public: + IdlType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~IdlType(); + + virtual sal_Bool dump(IdlOptions* pOptions) throw( CannotDumpException ); + virtual sal_Bool dumpDependedTypes(IdlOptions* pOptions) throw( CannotDumpException ); + virtual sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ) = 0; + + virtual ::rtl::OString dumpHeaderDefine(FileStream& o, sal_Char* prefix ); + virtual void dumpDefaultHIncludes(FileStream& o); + virtual void dumpInclude(FileStream& o, const ::rtl::OString& genTypeName, const ::rtl::OString& typeName, sal_Char* prefix ); + + virtual void dumpDepIncludes(FileStream& o, const ::rtl::OString& typeName, sal_Char* prefix); + + virtual void dumpNameSpace(FileStream& o, sal_Bool bOpen = sal_True, sal_Bool bFull = sal_False, const ::rtl::OString& type=""); + + virtual void dumpType(FileStream& o, const ::rtl::OString& type) + throw( CannotDumpException ); + ::rtl::OString getBaseType(const ::rtl::OString& type); + void dumpIdlGetType(FileStream& o, const ::rtl::OString& type, sal_Bool bDecl=sal_False, IdlTypeDecl eDeclFlag=CPPUTYPEDECL_ALLTYPES); + BASETYPE isBaseType(const ::rtl::OString& type); + + void dumpConstantValue(FileStream& o, sal_uInt16 index); + + virtual sal_uInt32 getMemberCount(); + virtual sal_uInt32 getInheritedMemberCount(); + + void inc(sal_uInt32 num=4); + void dec(sal_uInt32 num=4); + ::rtl::OString indent(); + ::rtl::OString indent(sal_uInt32 num); +protected: + virtual sal_uInt32 checkInheritedMemberCount(const TypeReader* pReader); + + ::rtl::OString checkSpecialIdlType(const ::rtl::OString& type); + ::rtl::OString checkRealBaseType(const ::rtl::OString& type, sal_Bool bResolveTypeOnly = sal_False); + +protected: + sal_uInt32 m_inheritedMemberCount; + + sal_uInt32 m_indentLength; + ::rtl::OString m_typeName; + ::rtl::OString m_name; + TypeReader m_reader; + TypeManager& m_typeMgr; + TypeDependency m_dependencies; +}; + +class InterfaceType : public IdlType +{ +public: + InterfaceType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~InterfaceType(); + + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); + + void dumpAttributes(FileStream& o); + void dumpMethods(FileStream& o); + + sal_uInt32 getMemberCount(); + sal_uInt32 getInheritedMemberCount(); + +protected: + sal_uInt32 checkInheritedMemberCount(const TypeReader* pReader); + +protected: + sal_uInt32 m_inheritedMemberCount; + sal_Bool m_hasAttributes; + sal_Bool m_hasMethods; +}; + +class ModuleType : public IdlType +{ +public: + ModuleType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~ModuleType(); + + virtual sal_Bool dump(IdlOptions* pOptions) throw( CannotDumpException ); + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); + sal_Bool hasConstants(); +}; + +class ConstantsType : public ModuleType +{ +public: + ConstantsType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~ConstantsType(); + + virtual sal_Bool dump(IdlOptions* pOptions) throw( CannotDumpException ); +}; + +class StructureType : public IdlType +{ +public: + StructureType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~StructureType(); + + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); + + void dumpSuperMember(FileStream& o, const ::rtl::OString& super); +}; + +class ExceptionType : public IdlType +{ +public: + ExceptionType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~ExceptionType(); + + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); + + void dumpSuperMember(FileStream& o, const ::rtl::OString& super); +}; + +class EnumType : public IdlType +{ +public: + EnumType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~EnumType(); + + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); +}; + +class TypeDefType : public IdlType +{ +public: + TypeDefType(TypeReader& typeReader, + const ::rtl::OString& typeName, + const TypeManager& typeMgr, + const TypeDependency& typeDependencies); + + virtual ~TypeDefType(); + + sal_Bool dumpHFile(FileStream& o) throw( CannotDumpException ); +}; + + +sal_Bool produceType(const ::rtl::OString& typeName, + TypeManager& typeMgr, + TypeDependency& typeDependencies, + IdlOptions* pOptions) + throw( CannotDumpException ); + +/** + * This function returns a C++ scoped name, represents the namespace + * scoping of this type, e.g. com:.sun::star::uno::XInterface. If the scope of + * the type is equal scope, the relativ name will be used. + */ +::rtl::OString scopedName(const ::rtl::OString& scope, const ::rtl::OString& type, sal_Bool bNoNameSpace = sal_False ); + +::rtl::OString scope(const ::rtl::OString& scope, const ::rtl::OString& type ); + + +#endif // INCLUDED_CODEMAKER_SOURCE_IDLMAKER_IDLTYPE_HXX + diff --git a/codemaker/source/idlmaker/makefile.mk b/codemaker/source/idlmaker/makefile.mk new file mode 100644 index 000000000000..cd447262e24d --- /dev/null +++ b/codemaker/source/idlmaker/makefile.mk @@ -0,0 +1,62 @@ +#************************************************************************* +# +# 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=idlmaker +TARGETTYPE=CUI +LIBTARGET=NO + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +CXXFILES= idlmaker.cxx \ + idloptions.cxx \ + idltype.cxx + + +APP1TARGET= $(TARGET) + +APP1OBJS= $(OBJ)$/idlmaker.obj \ + $(OBJ)$/idloptions.obj \ + $(OBJ)$/idltype.obj + +APP1STDLIBS= \ + $(SALLIB) \ + $(SALHELPERLIB) \ + $(REGLIB) \ + $(STDLIBCPP) + +APP1LIBS= \ + $(LB)$/codemaker.lib + +.INCLUDE : target.mk diff --git a/codemaker/source/javamaker/classfile.cxx b/codemaker/source/javamaker/classfile.cxx new file mode 100644 index 000000000000..05c473256738 --- /dev/null +++ b/codemaker/source/javamaker/classfile.cxx @@ -0,0 +1,903 @@ +/************************************************************************* + * + * 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 "classfile.hxx" + +#include "codemaker/global.hxx" +#include "codemaker/options.hxx" +#include "codemaker/unotype.hxx" + +#include "boost/static_assert.hpp" +#include "osl/diagnose.h" +#include "rtl/string.h" +#include "rtl/string.hxx" +#include "sal/types.h" + +#include <map> +#include <utility> +#include <vector> + +using codemaker::javamaker::ClassFile; + +namespace { + +void appendU1(std::vector< unsigned char > & stream, sal_uInt8 data) { + stream.push_back(static_cast< unsigned char >(data)); +} + +void appendU2(std::vector< unsigned char > & stream, sal_uInt16 data) { + stream.push_back(static_cast< unsigned char >(data >> 8)); + stream.push_back(static_cast< unsigned char >(data & 0xFF)); +} + +void appendU4(std::vector< unsigned char > & stream, sal_uInt32 data) { + stream.push_back(static_cast< unsigned char >(data >> 24)); + stream.push_back(static_cast< unsigned char >((data >> 16) & 0xFF)); + stream.push_back(static_cast< unsigned char >((data >> 8) & 0xFF)); + stream.push_back(static_cast< unsigned char >(data & 0xFF)); +} + +void appendU8(std::vector< unsigned char > & stream, sal_uInt64 data) { + stream.push_back(static_cast< unsigned char >(data >> 56)); + stream.push_back(static_cast< unsigned char >((data >> 48) & 0xFF)); + stream.push_back(static_cast< unsigned char >((data >> 40) & 0xFF)); + stream.push_back(static_cast< unsigned char >((data >> 32) & 0xFF)); + stream.push_back(static_cast< unsigned char >((data >> 24) & 0xFF)); + stream.push_back(static_cast< unsigned char >((data >> 16) & 0xFF)); + stream.push_back(static_cast< unsigned char >((data >> 8) & 0xFF)); + stream.push_back(static_cast< unsigned char >(data & 0xFF)); +} + +void appendStream( + std::vector< unsigned char > & stream, + std::vector< unsigned char > const & data) +{ + stream.insert(stream.end(), data.begin(), data.end()); +} + +void write(FileStream & file, void const * buffer, sal_uInt64 size) { + if (!file.write(buffer, size)) { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Error writing file"))); + } +} + +void writeU1(FileStream & file, sal_uInt8 data) { + unsigned char buf[] = { static_cast< unsigned char >(data) }; + write(file, &buf, sizeof buf); +} + +void writeU2(FileStream & file, sal_uInt16 data) { + unsigned char buf[] = { + static_cast< unsigned char >(data >> 8), + static_cast< unsigned char >(data & 0xFF) }; + write(file, buf, sizeof buf); +} + +void writeU4(FileStream & file, sal_uInt32 data) { + unsigned char buf[] = { + static_cast< unsigned char >(data >> 24), + static_cast< unsigned char >((data >> 16) & 0xFF), + static_cast< unsigned char >((data >> 8) & 0xFF), + static_cast< unsigned char >(data & 0xFF) }; + write(file, buf, sizeof buf); +} + +void writeStream(FileStream & file, std::vector< unsigned char > const & stream) +{ + std::vector< unsigned char >::size_type n = stream.size(); + BOOST_STATIC_ASSERT( + sizeof (std::vector< unsigned char >::size_type) + <= sizeof (sal_uInt64)); + // both unsigned integral, so sizeof is a practically sufficient + // approximation of std::numeric_limits<T1>::max() <= + // std::numeric_limits<T2>::max() + if (n != 0) { + write(file, &stream[0], static_cast< sal_uInt64 >(n)); + } +} + +} + +ClassFile::Code::~Code() {} + +void ClassFile::Code::instrAastore() { + // aastore: + appendU1(m_code, 0x53); +} + +void ClassFile::Code::instrAconstNull() { + // aconst_null: + appendU1(m_code, 0x01); +} + +void ClassFile::Code::instrAnewarray(rtl::OString const & type) { + // anewarray <indexbyte1> <indexbyte2>: + appendU1(m_code, 0xBD); + appendU2(m_code, m_classFile.addClassInfo(type)); +} + +void ClassFile::Code::instrAreturn() { + // areturn: + appendU1(m_code, 0xB0); +} + +void ClassFile::Code::instrAthrow() { + // athrow: + appendU1(m_code, 0xBF); +} + +void ClassFile::Code::instrCheckcast(rtl::OString const & type) { + // checkcast <indexbyte1> <indexbyte2>: + appendU1(m_code, 0xC0); + appendU2(m_code, m_classFile.addClassInfo(type)); +} + +void ClassFile::Code::instrDup() { + // dup: + appendU1(m_code, 0x59); +} + +void ClassFile::Code::instrGetstatic( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor) +{ + // getstatic <indexbyte1> <indexbyte2>: + appendU1(m_code, 0xB2); + appendU2(m_code, m_classFile.addFieldrefInfo(type, name, descriptor)); +} + +ClassFile::Code::Branch ClassFile::Code::instrIfAcmpne() { + // if_acmpne <branchbyte1> <branchbyte2>: + Branch branch = m_code.size(); + appendU1(m_code, 0xA6); + appendU2(m_code, 0); + return branch; +} + +ClassFile::Code::Branch ClassFile::Code::instrIfeq() { + // ifeq <branchbyte1> <branchbyte2>: + Branch branch = m_code.size(); + appendU1(m_code, 0x99); + appendU2(m_code, 0); + return branch; +} + +ClassFile::Code::Branch ClassFile::Code::instrIfnull() { + // ifnull <branchbyte1> <branchbyte2>: + Branch branch = m_code.size(); + appendU1(m_code, 0xC6); + appendU2(m_code, 0); + return branch; +} + +void ClassFile::Code::instrInstanceof(rtl::OString const & type) { + // instanceof <indexbyte1> <indexbyte2>: + appendU1(m_code, 0xC1); + appendU2(m_code, m_classFile.addClassInfo(type)); +} + +void ClassFile::Code::instrInvokeinterface( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor, sal_uInt8 args) +{ + // invokeinterface <indexbyte1> <indexbyte2> <nargs> 0: + appendU1(m_code, 0xB9); + appendU2( + m_code, m_classFile.addInterfaceMethodrefInfo(type, name, descriptor)); + appendU1(m_code, args); + appendU1(m_code, 0); +} + +void ClassFile::Code::instrInvokespecial( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor) +{ + // invokespecial <indexbyte1> <indexbyte2>: + appendU1(m_code, 0xB7); + appendU2(m_code, m_classFile.addMethodrefInfo(type, name, descriptor)); +} + +void ClassFile::Code::instrInvokestatic( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor) +{ + // invokestatic <indexbyte1> <indexbyte2>: + appendU1(m_code, 0xB8); + appendU2(m_code, m_classFile.addMethodrefInfo(type, name, descriptor)); +} + +void ClassFile::Code::instrInvokevirtual( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor) +{ + // invokevirtual <indexbyte1> <indexbyte2>: + appendU1(m_code, 0xB6); + appendU2(m_code, m_classFile.addMethodrefInfo(type, name, descriptor)); +} + +void ClassFile::Code::instrLookupswitch( + Code const * defaultBlock, + std::list< std::pair< sal_Int32, Code * > > const & blocks) +{ + // lookupswitch <0--3 byte pad> <defaultbyte1> <defaultbyte2> <defaultbyte3> + // <defaultbyte4> <npairs1> <npairs2> <npairs3> <npairs4> + // <match--offset pairs...>: + std::list< std::pair< sal_Int32, Code * > >::size_type size = blocks.size(); + if (size > SAL_MAX_INT32) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Lookup-switch too large for Java class file format"))); + } + Position pos1 = m_code.size(); + appendU1(m_code, 0xAB); + int pad = (pos1 + 1) % 4; + {for (int i = 0; i < pad; ++i) { + appendU1(m_code, 0); + }} + Position pos2 = pos1 + 1 + pad + 8 + blocks.size() * 8; //FIXME: overflow + appendU4(m_code, static_cast< sal_uInt32 >(pos2 - pos1)); //FIXME: overflow + pos2 += defaultBlock->m_code.size(); //FIXME: overflow + appendU4(m_code, static_cast< sal_uInt32 >(size)); + {for (std::list< std::pair< sal_Int32, Code * > >::const_iterator i( + blocks.begin()); + i != blocks.end(); ++i) + { + appendU4(m_code, static_cast< sal_uInt32 >(i->first)); + appendU4(m_code, static_cast< sal_uInt32 >(pos2 - pos1)); + //FIXME: overflow + pos2 += i->second->m_code.size(); //FIXME: overflow + }} + appendStream(m_code, defaultBlock->m_code); + {for (std::list< std::pair< sal_Int32, Code * > >::const_iterator i( + blocks.begin()); + i != blocks.end(); ++i) + { + appendStream(m_code, i->second->m_code); + }} +} + +void ClassFile::Code::instrNew(rtl::OString const & type) { + // new <indexbyte1> <indexbyte2>: + appendU1(m_code, 0xBB); + appendU2(m_code, m_classFile.addClassInfo(type)); +} + +void ClassFile::Code::instrNewarray(codemaker::UnoType::Sort sort) { + OSL_ASSERT( + sort >= codemaker::UnoType::SORT_BOOLEAN + && sort <= codemaker::UnoType::SORT_CHAR); + // newarray <atype>: + appendU1(m_code, 0xBC); + static sal_uInt8 const atypes[codemaker::UnoType::SORT_CHAR] = { + 0x04, 0x08, 0x09, 0x09, 0x0A, 0x0A, 0x0B, 0x0B, 0x06, 0x07, 0x05 }; + appendU1(m_code, atypes[sort - 1]); +} + +void ClassFile::Code::instrPop() { + // pop: + appendU1(m_code, 0x57); +} + +void ClassFile::Code::instrPutfield( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor) +{ + // putfield <indexbyte1> <indexbyte2>: + appendU1(m_code, 0xB5); + appendU2(m_code, m_classFile.addFieldrefInfo(type, name, descriptor)); +} + +void ClassFile::Code::instrPutstatic( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor) +{ + // putstatic <indexbyte1> <indexbyte2>: + appendU1(m_code, 0xB3); + appendU2(m_code, m_classFile.addFieldrefInfo(type, name, descriptor)); +} + +void ClassFile::Code::instrReturn() { + // return: + appendU1(m_code, 0xB1); +} + +void ClassFile::Code::instrSwap() { + // swap: + appendU1(m_code, 0x5F); +} + +void ClassFile::Code::instrTableswitch( + Code const * defaultBlock, sal_Int32 low, + std::list< Code * > const & blocks) +{ + // tableswitch <0--3 byte pad> <defaultbyte1> <defaultbyte2> <defaultbyte3> + // <defaultbyte4> <lowbyte1> <lowbyte2> <lowbyte3> <lowbyte4> <highbyte1> + // <highbyte2> <highbyte3> <highbyte4> <jump offsets...>: + Position pos1 = m_code.size(); + appendU1(m_code, 0xAA); + int pad = (pos1 + 1) % 4; + {for (int i = 0; i < pad; ++i) { + appendU1(m_code, 0); + }} + std::list< Code * >::size_type size = blocks.size(); + Position pos2 = pos1 + 1 + pad + 12 + size * 4; //FIXME: overflow + sal_uInt32 defaultOffset = static_cast< sal_uInt32 >(pos2 - pos1); + //FIXME: overflow + appendU4(m_code, defaultOffset); + pos2 += defaultBlock->m_code.size(); //FIXME: overflow + appendU4(m_code, static_cast< sal_uInt32 >(low)); + appendU4(m_code, static_cast< sal_uInt32 >(low + (size - 1))); + {for (std::list< Code * >::const_iterator i(blocks.begin()); + i != blocks.end(); ++i) + { + if (*i == 0) { + appendU4(m_code, defaultOffset); + } else { + appendU4(m_code, static_cast< sal_uInt32 >(pos2 - pos1)); + //FIXME: overflow + pos2 += (*i)->m_code.size(); //FIXME: overflow + } + }} + appendStream(m_code, defaultBlock->m_code); + {for (std::list< Code * >::const_iterator i(blocks.begin()); + i != blocks.end(); ++i) + { + if (*i != 0) { + appendStream(m_code, (*i)->m_code); + } + }} +} + +void ClassFile::Code::loadIntegerConstant(sal_Int32 value) { + if (value >= -1 && value <= 5) { + // iconst_<i>: + appendU1(m_code, static_cast< sal_uInt8 >(0x02 + value + 1)); + } else if (value >= -128 && value <= 127) { + // bipush <byte>: + appendU1(m_code, 0x10); + appendU1(m_code, static_cast< sal_uInt8 >(value)); + } else if (value >= -32768 && value <= 32767) { + // sipush <byte1> <byte2>: + appendU1(m_code, 0x11); + appendU2(m_code, static_cast< sal_uInt16 >(value)); + } else { + ldc(m_classFile.addIntegerInfo(value)); + } +} + +void ClassFile::Code::loadStringConstant(rtl::OString const & value) { + ldc(m_classFile.addStringInfo(value)); +} + +void ClassFile::Code::loadLocalInteger(sal_uInt16 index) { + accessLocal(index, 0x1A, 0x15); // iload_<n>, iload +} + +void ClassFile::Code::loadLocalLong(sal_uInt16 index) { + accessLocal(index, 0x1E, 0x16); // load_<n>, load +} + +void ClassFile::Code::loadLocalFloat(sal_uInt16 index) { + accessLocal(index, 0x22, 0x17); // load_<n>, load +} + +void ClassFile::Code::loadLocalDouble(sal_uInt16 index) { + accessLocal(index, 0x26, 0x18); // load_<n>, load +} + +void ClassFile::Code::loadLocalReference(sal_uInt16 index) { + accessLocal(index, 0x2A, 0x19); // aload_<n>, aload +} + +void ClassFile::Code::storeLocalReference(sal_uInt16 index) { + accessLocal(index, 0x4B, 0x3A); // astore_<n>, astore +} + +void ClassFile::Code::branchHere(Branch branch) { + std::vector< unsigned char >::size_type n = m_code.size(); + OSL_ASSERT(n > branch && n - branch <= SAL_MAX_INT16); + n -= branch; + m_code[branch + 1] = static_cast< sal_uInt8 >(n >> 8); + m_code[branch + 2] = static_cast< sal_uInt8 >(n & 0xFF); +} + +void ClassFile::Code::addException( + Position start, Position end, Position handler, rtl::OString const & type) +{ + OSL_ASSERT(start < end && end <= m_code.size() && handler <= m_code.size()); + if (m_exceptionTableLength == SAL_MAX_UINT16) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Too many exception handlers for Java class file format"))); + } + ++m_exceptionTableLength; + appendU2(m_exceptionTable, static_cast< sal_uInt16 >(start)); + //FIXME: overflow + appendU2(m_exceptionTable, static_cast< sal_uInt16 >(end)); + //FIXME: overflow + appendU2(m_exceptionTable, static_cast< sal_uInt16 >(handler)); + //FIXME: overflow + appendU2(m_exceptionTable, m_classFile.addClassInfo(type)); +} + +ClassFile::Code::Position ClassFile::Code::getPosition() const { + return m_code.size(); +} + +ClassFile::Code::Code(ClassFile & classFile): + m_classFile(classFile), m_exceptionTableLength(0) +{} + +void ClassFile::Code::ldc(sal_uInt16 index) { + if (index <= 0xFF) { + // ldc <index>: + appendU1(m_code, 0x12); + appendU1(m_code, static_cast< sal_uInt8 >(index)); + } else { + // ldc_w <indexbyte1> <indexbyte2>: + appendU1(m_code, 0x13); + appendU2(m_code, index); + } +} + +void ClassFile::Code::accessLocal( + sal_uInt16 index, sal_uInt8 fastOp, sal_uInt8 normalOp) +{ + if (index <= 3) { + // ...load/store_<n>: + appendU1(m_code, static_cast< sal_uInt8 >(fastOp + index)); + } else if (index <= 0xFF) { + // ...load/store <index>: + appendU1(m_code, normalOp); + appendU1(m_code, static_cast< sal_uInt8 >(index)); + } else { + // wide ...load/store <indexbyte1> <indexbyte2>: + appendU1(m_code, 0xC4); + appendU1(m_code, normalOp); + appendU2(m_code, index); + } +} + +ClassFile::ClassFile( + AccessFlags accessFlags, rtl::OString const & thisClass, + rtl::OString const & superClass, rtl::OString const & signature): + m_constantPoolCount(1), m_accessFlags(accessFlags), m_interfacesCount(0), + m_fieldsCount(0), m_methodsCount(0), m_attributesCount(0) +{ + m_thisClass = addClassInfo(thisClass); + m_superClass = addClassInfo(superClass); + if (signature.getLength() != 0) { + ++m_attributesCount; + appendU2( + m_attributes, + addUtf8Info(rtl::OString(RTL_CONSTASCII_STRINGPARAM("Signature")))); + appendU4(m_attributes, 2); + appendU2(m_attributes, addUtf8Info(signature)); + } +} + +ClassFile::~ClassFile() {} + +ClassFile::Code * ClassFile::newCode() { + return new Code(*this); +} + +sal_uInt16 ClassFile::addIntegerInfo(sal_Int32 value) { + std::map< sal_Int32, sal_uInt16 >::iterator i(m_integerInfos.find(value)); + if (i != m_integerInfos.end()) { + return i->second; + } + sal_uInt16 index = nextConstantPoolIndex(1); + appendU1(m_constantPool, 3); + appendU4(m_constantPool, static_cast< sal_uInt32 >(value)); + if (!m_integerInfos.insert( + std::map< sal_Int32, sal_uInt16 >::value_type(value, index)).second) + { + OSL_ASSERT(false); + } + return index; +} + +sal_uInt16 ClassFile::addFloatInfo(float value) { + std::map< float, sal_uInt16 >::iterator i(m_floatInfos.find(value)); + if (i != m_floatInfos.end()) { + return i->second; + } + sal_uInt16 index = nextConstantPoolIndex(1); + appendU1(m_constantPool, 4); + union { float floatBytes; sal_uInt32 uint32Bytes; } bytes; + bytes.floatBytes = value; + appendU4(m_constantPool, bytes.uint32Bytes); + if (!m_floatInfos.insert( + std::map< float, sal_uInt16 >::value_type(value, index)).second) + { + OSL_ASSERT(false); + } + return index; +} + +sal_uInt16 ClassFile::addLongInfo(sal_Int64 value) { + std::map< sal_Int64, sal_uInt16 >::iterator i(m_longInfos.find(value)); + if (i != m_longInfos.end()) { + return i->second; + } + sal_uInt16 index = nextConstantPoolIndex(2); + appendU1(m_constantPool, 5); + appendU8(m_constantPool, static_cast< sal_uInt64 >(value)); + if (!m_longInfos.insert( + std::map< sal_Int64, sal_uInt16 >::value_type(value, index)).second) + { + OSL_ASSERT(false); + } + return index; +} + +sal_uInt16 ClassFile::addDoubleInfo(double value) { + std::map< double, sal_uInt16 >::iterator i(m_doubleInfos.find(value)); + if (i != m_doubleInfos.end()) { + return i->second; + } + sal_uInt16 index = nextConstantPoolIndex(2); + appendU1(m_constantPool, 6); + union { double doubleBytes; sal_uInt64 uint64Bytes; } bytes; + bytes.doubleBytes = value; + appendU8(m_constantPool, bytes.uint64Bytes); + if (!m_doubleInfos.insert( + std::map< double, sal_uInt16 >::value_type(value, index)).second) + { + OSL_ASSERT(false); + } + return index; +} + +void ClassFile::addInterface(rtl::OString const & interface) { + if (m_interfacesCount == SAL_MAX_UINT16) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Too many interfaces for Java class file format"))); + } + ++m_interfacesCount; + appendU2(m_interfaces, addClassInfo(interface)); +} + +void ClassFile::addField( + AccessFlags accessFlags, rtl::OString const & name, + rtl::OString const & descriptor, sal_uInt16 constantValueIndex, + rtl::OString const & signature) +{ + if (m_fieldsCount == SAL_MAX_UINT16) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Too many fields for Java class file format"))); + } + ++m_fieldsCount; + appendU2(m_fields, static_cast< sal_uInt16 >(accessFlags)); + appendU2(m_fields, addUtf8Info(name)); + appendU2(m_fields, addUtf8Info(descriptor)); + appendU2( + m_fields, + ((constantValueIndex == 0 ? 0 : 1) + + (signature.getLength() == 0 ? 0 : 1))); + if (constantValueIndex != 0) { + appendU2( + m_fields, + addUtf8Info( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("ConstantValue")))); + appendU4(m_fields, 2); + appendU2(m_fields, constantValueIndex); + } + appendSignatureAttribute(m_fields, signature); +} + +void ClassFile::addMethod( + AccessFlags accessFlags, rtl::OString const & name, + rtl::OString const & descriptor, Code const * code, + std::vector< rtl::OString > const & exceptions, + rtl::OString const & signature) +{ + if (m_methodsCount == SAL_MAX_UINT16) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Too many methods for Java class file format"))); + } + ++m_methodsCount; + appendU2(m_methods, static_cast< sal_uInt16 >(accessFlags)); + appendU2(m_methods, addUtf8Info(name)); + appendU2(m_methods, addUtf8Info(descriptor)); + std::vector< rtl::OString >::size_type excs = exceptions.size(); + if (excs > SAL_MAX_UINT16) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Too many exception specifications for Java class file" + " format"))); + } + appendU2( + m_methods, + ((code == 0 ? 0 : 1) + (exceptions.empty() ? 0 : 1) + + (signature.getLength() == 0 ? 0 : 1))); + if (code != 0) { + std::vector< unsigned char >::size_type codeSize = code->m_code.size(); + std::vector< unsigned char >::size_type exceptionTableSize + = code->m_exceptionTable.size(); + if (codeSize > SAL_MAX_UINT32 - (2 + 2 + 4 + 2 + 2) + || (exceptionTableSize + > (SAL_MAX_UINT32 - (2 + 2 + 4 + 2 + 2) + - static_cast< sal_uInt32 >(codeSize)))) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Code block is too big for Java class file format"))); + } + appendU2( + m_methods, + addUtf8Info(rtl::OString(RTL_CONSTASCII_STRINGPARAM("Code")))); + appendU4( + m_methods, + (2 + 2 + 4 + static_cast< sal_uInt32 >(codeSize) + 2 + + static_cast< sal_uInt32 >(exceptionTableSize) + 2)); + appendU2(m_methods, code->m_maxStack); + appendU2(m_methods, code->m_maxLocals); + appendU4(m_methods, static_cast< sal_uInt32 >(codeSize)); + appendStream(m_methods, code->m_code); + appendU2(m_methods, code->m_exceptionTableLength); + appendStream(m_methods, code->m_exceptionTable); + appendU2(m_methods, 0); + } + if (!exceptions.empty()) { + appendU2( + m_methods, + addUtf8Info( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Exceptions")))); + appendU4( + m_methods, + static_cast< sal_uInt32 >(2 + 2 * static_cast< sal_uInt32 >(excs))); + appendU2(m_methods, static_cast< sal_uInt16 >(excs)); + for (std::vector< rtl::OString >::const_iterator i(exceptions.begin()); + i != exceptions.end(); ++i) + { + appendU2(m_methods, addClassInfo(*i)); + } + } + appendSignatureAttribute(m_methods, signature); +} + +void ClassFile::write(FileStream & file) const { + writeU4(file, 0xCAFEBABE); + writeU2(file, 0); + writeU2(file, 46); + writeU2(file, m_constantPoolCount); + writeStream(file, m_constantPool); + writeU2(file, static_cast< sal_uInt16 >(m_accessFlags)); + writeU2(file, m_thisClass); + writeU2(file, m_superClass); + writeU2(file, m_interfacesCount); + writeStream(file, m_interfaces); + writeU2(file, m_fieldsCount); + writeStream(file, m_fields); + writeU2(file, m_methodsCount); + writeStream(file, m_methods); + writeU2(file, m_attributesCount); + writeStream(file, m_attributes); +} + +sal_uInt16 ClassFile::nextConstantPoolIndex(sal_uInt16 width) { + OSL_ASSERT(width == 1 || width == 2); + if (m_constantPoolCount > SAL_MAX_UINT16 - width) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Too many constant pool items for Java class file" + " format"))); + } + sal_uInt16 index = m_constantPoolCount; + m_constantPoolCount = m_constantPoolCount + width; + return index; +} + +sal_uInt16 ClassFile::addUtf8Info(rtl::OString const & value) { + std::map< rtl::OString, sal_uInt16 >::iterator i(m_utf8Infos.find(value)); + if (i != m_utf8Infos.end()) { + return i->second; + } + if (value.getLength() > SAL_MAX_UINT16) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "UTF-8 string too long for Java class file format"))); + } + sal_uInt16 index = nextConstantPoolIndex(1); + appendU1(m_constantPool, 1); + appendU2(m_constantPool, static_cast< sal_uInt16 >(value.getLength())); + for (sal_Int32 j = 0; j < value.getLength(); ++j) { + appendU1(m_constantPool, static_cast< sal_uInt8 >(value[j])); + } + if (!m_utf8Infos.insert( + std::map< rtl::OString, sal_uInt16 >::value_type(value, index)). + second) + { + OSL_ASSERT(false); + } + return index; +} + +sal_uInt16 ClassFile::addClassInfo(rtl::OString const & type) { + sal_uInt16 nameIndex = addUtf8Info(type); + std::map< sal_uInt16, sal_uInt16 >::iterator i( + m_classInfos.find(nameIndex)); + if (i != m_classInfos.end()) { + return i->second; + } + sal_uInt16 index = nextConstantPoolIndex(1); + appendU1(m_constantPool, 7); + appendU2(m_constantPool, nameIndex); + if (!m_classInfos.insert( + std::map< sal_uInt16, sal_uInt16 >::value_type(nameIndex, index)). + second) + { + OSL_ASSERT(false); + } + return index; +} + +sal_uInt16 ClassFile::addStringInfo(rtl::OString const & value) { + sal_uInt16 stringIndex = addUtf8Info(value); + std::map< sal_uInt16, sal_uInt16 >::iterator i( + m_stringInfos.find(stringIndex)); + if (i != m_stringInfos.end()) { + return i->second; + } + sal_uInt16 index = nextConstantPoolIndex(1); + appendU1(m_constantPool, 8); + appendU2(m_constantPool, stringIndex); + if (!m_stringInfos.insert( + std::map< sal_uInt16, sal_uInt16 >::value_type(stringIndex, index)). + second) + { + OSL_ASSERT(false); + } + return index; +} + +sal_uInt16 ClassFile::addFieldrefInfo( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor) +{ + sal_uInt16 classIndex = addClassInfo(type); + sal_uInt16 nameAndTypeIndex = addNameAndTypeInfo(name, descriptor); + sal_uInt32 key = (static_cast< sal_uInt32 >(classIndex) << 16) + | nameAndTypeIndex; + std::map< sal_uInt32, sal_uInt16 >::iterator i(m_fieldrefInfos.find(key)); + if (i != m_fieldrefInfos.end()) { + return i->second; + } + sal_uInt16 index = nextConstantPoolIndex(1); + appendU1(m_constantPool, 9); + appendU2(m_constantPool, classIndex); + appendU2(m_constantPool, nameAndTypeIndex); + if (!m_fieldrefInfos.insert( + std::map< sal_uInt32, sal_uInt16 >::value_type(key, index)).second) + { + OSL_ASSERT(false); + } + return index; +} + +sal_uInt16 ClassFile::addMethodrefInfo( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor) +{ + sal_uInt16 classIndex = addClassInfo(type); + sal_uInt16 nameAndTypeIndex = addNameAndTypeInfo(name, descriptor); + sal_uInt32 key = (static_cast< sal_uInt32 >(classIndex) << 16) + | nameAndTypeIndex; + std::map< sal_uInt32, sal_uInt16 >::iterator i(m_methodrefInfos.find(key)); + if (i != m_methodrefInfos.end()) { + return i->second; + } + sal_uInt16 index = nextConstantPoolIndex(1); + appendU1(m_constantPool, 10); + appendU2(m_constantPool, classIndex); + appendU2(m_constantPool, nameAndTypeIndex); + if (!m_methodrefInfos.insert( + std::map< sal_uInt32, sal_uInt16 >::value_type(key, index)).second) + { + OSL_ASSERT(false); + } + return index; +} + +sal_uInt16 ClassFile::addInterfaceMethodrefInfo( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor) +{ + sal_uInt16 classIndex = addClassInfo(type); + sal_uInt16 nameAndTypeIndex = addNameAndTypeInfo(name, descriptor); + sal_uInt32 key = (static_cast< sal_uInt32 >(classIndex) << 16) + | nameAndTypeIndex; + std::map< sal_uInt32, sal_uInt16 >::iterator i( + m_interfaceMethodrefInfos.find(key)); + if (i != m_interfaceMethodrefInfos.end()) { + return i->second; + } + sal_uInt16 index = nextConstantPoolIndex(1); + appendU1(m_constantPool, 11); + appendU2(m_constantPool, classIndex); + appendU2(m_constantPool, nameAndTypeIndex); + if (!m_interfaceMethodrefInfos.insert( + std::map< sal_uInt32, sal_uInt16 >::value_type(key, index)).second) + { + OSL_ASSERT(false); + } + return index; +} + +sal_uInt16 ClassFile::addNameAndTypeInfo( + rtl::OString const & name, rtl::OString const & descriptor) +{ + sal_uInt16 nameIndex = addUtf8Info(name); + sal_uInt16 descriptorIndex = addUtf8Info(descriptor); + sal_uInt32 key = (static_cast< sal_uInt32 >(nameIndex) << 16) + | descriptorIndex; + std::map< sal_uInt32, sal_uInt16 >::iterator i( + m_nameAndTypeInfos.find(key)); + if (i != m_nameAndTypeInfos.end()) { + return i->second; + } + sal_uInt16 index = nextConstantPoolIndex(1); + appendU1(m_constantPool, 12); + appendU2(m_constantPool, nameIndex); + appendU2(m_constantPool, descriptorIndex); + if (!m_nameAndTypeInfos.insert( + std::map< sal_uInt32, sal_uInt16 >::value_type(key, index)).second) + { + OSL_ASSERT(false); + } + return index; +} + +void ClassFile::appendSignatureAttribute( + std::vector< unsigned char > & stream, rtl::OString const & signature) +{ + if (signature.getLength() != 0) { + appendU2( + stream, + addUtf8Info(rtl::OString(RTL_CONSTASCII_STRINGPARAM("Signature")))); + appendU4(stream, 2); + appendU2(stream, addUtf8Info(signature)); + } +} diff --git a/codemaker/source/javamaker/classfile.hxx b/codemaker/source/javamaker/classfile.hxx new file mode 100644 index 000000000000..6a0018ac38d0 --- /dev/null +++ b/codemaker/source/javamaker/classfile.hxx @@ -0,0 +1,274 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_CLASSFILE_HXX +#define INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_CLASSFILE_HXX + +#include "codemaker/unotype.hxx" +#include "sal/types.h" + +#include <list> +#include <map> +#include <utility> +#include <vector> + +class FileStream; +namespace rtl { class OString; } + +namespace codemaker { namespace javamaker { + +class ClassFile { +public: + enum AccessFlags { + ACC_PUBLIC = 0x0001, + ACC_PRIVATE = 0x0002, + ACC_STATIC = 0x0008, + ACC_FINAL = 0x0010, + ACC_SUPER = 0x0020, + ACC_VARARGS = 0x0080, + ACC_INTERFACE = 0x0200, + ACC_ABSTRACT = 0x0400, + ACC_SYNTHETIC = 0x1000 + }; + + class Code { + public: + typedef std::vector< unsigned char >::size_type Branch; + typedef std::vector< unsigned char >::size_type Position; + + ~Code(); + + void instrAastore(); + + void instrAconstNull(); + + void instrAnewarray(rtl::OString const & type); + + void instrAreturn(); + + void instrAthrow(); + + void instrCheckcast(rtl::OString const & type); + + void instrDup(); + + void instrGetstatic( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor); + + Branch instrIfAcmpne(); + + Branch instrIfeq(); + + Branch instrIfnull(); + + void instrInstanceof(rtl::OString const & type); + + void instrInvokeinterface( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor, sal_uInt8 args); + + void instrInvokespecial( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor); + + void instrInvokestatic( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor); + + void instrInvokevirtual( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor); + + void instrLookupswitch( + Code const * defaultBlock, + std::list< std::pair< sal_Int32, Code * > > const & blocks); + + void instrNew(rtl::OString const & type); + + void instrNewarray(codemaker::UnoType::Sort sort); + + void instrPop(); + + void instrPutfield( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor); + + void instrPutstatic( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor); + + void instrReturn(); + + void instrSwap(); + + void instrTableswitch( + Code const * defaultBlock, sal_Int32 low, + std::list< Code * > const & blocks); + + void loadIntegerConstant(sal_Int32 value); + + void loadStringConstant(rtl::OString const & value); + + void loadLocalInteger(sal_uInt16 index); + + void loadLocalLong(sal_uInt16 index); + + void loadLocalFloat(sal_uInt16 index); + + void loadLocalDouble(sal_uInt16 index); + + void loadLocalReference(sal_uInt16 index); + + void storeLocalReference(sal_uInt16 index); + + void branchHere(Branch branch); + + void addException( + Position start, Position end, Position handler, + rtl::OString const & type); + + void setMaxStackAndLocals(sal_uInt16 maxStack, sal_uInt16 maxLocals) + { m_maxStack = maxStack; m_maxLocals = maxLocals; } + + Position getPosition() const; + + private: + Code(Code &); // not implemented + void operator =(Code); // not implemented + + Code(ClassFile & classFile); + + void ldc(sal_uInt16 index); + + void accessLocal( + sal_uInt16 index, sal_uInt8 fastOp, sal_uInt8 normalOp); + + ClassFile & m_classFile; + sal_uInt16 m_maxStack; + sal_uInt16 m_maxLocals; + std::vector< unsigned char > m_code; + sal_uInt16 m_exceptionTableLength; + std::vector< unsigned char > m_exceptionTable; + + friend class ClassFile; + }; + + ClassFile( + AccessFlags accessFlags, rtl::OString const & thisClass, + rtl::OString const & superClass, rtl::OString const & signature); + + ~ClassFile(); + + Code * newCode(); + + sal_uInt16 addIntegerInfo(sal_Int32 value); + + sal_uInt16 addFloatInfo(float value); + + sal_uInt16 addLongInfo(sal_Int64 value); + + sal_uInt16 addDoubleInfo(double value); + + void addInterface(rtl::OString const & interface); + + void addField( + AccessFlags accessFlags, rtl::OString const & name, + rtl::OString const & descriptor, sal_uInt16 constantValueIndex, + rtl::OString const & signature); + + void addMethod( + AccessFlags accessFlags, rtl::OString const & name, + rtl::OString const & descriptor, Code const * code, + std::vector< rtl::OString > const & exceptions, + rtl::OString const & signature); + + void write(FileStream & file) const; //TODO + +private: + typedef std::map< rtl::OString, sal_uInt16 > Map; + + ClassFile(ClassFile &); // not implemented + void operator =(ClassFile); // not implemented + + sal_uInt16 nextConstantPoolIndex(sal_uInt16 width); + + sal_uInt16 addUtf8Info(rtl::OString const & value); + + sal_uInt16 addClassInfo(rtl::OString const & type); + + sal_uInt16 addStringInfo(rtl::OString const & value); + + sal_uInt16 addFieldrefInfo( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor); + + sal_uInt16 addMethodrefInfo( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor); + + sal_uInt16 addInterfaceMethodrefInfo( + rtl::OString const & type, rtl::OString const & name, + rtl::OString const & descriptor); + + sal_uInt16 addNameAndTypeInfo( + rtl::OString const & name, rtl::OString const & descriptor); + + void appendSignatureAttribute( + std::vector< unsigned char > & stream, rtl::OString const & signature); + + sal_uInt16 m_constantPoolCount; + std::vector< unsigned char > m_constantPool; + std::map< rtl::OString, sal_uInt16 > m_utf8Infos; + std::map< sal_Int32, sal_uInt16 > m_integerInfos; + std::map< sal_Int64, sal_uInt16 > m_longInfos; + std::map< float, sal_uInt16 > m_floatInfos; + std::map< double, sal_uInt16 > m_doubleInfos; + std::map< sal_uInt16, sal_uInt16 > m_classInfos; + std::map< sal_uInt16, sal_uInt16 > m_stringInfos; + std::map< sal_uInt32, sal_uInt16 > m_fieldrefInfos; + std::map< sal_uInt32, sal_uInt16 > m_methodrefInfos; + std::map< sal_uInt32, sal_uInt16 > m_interfaceMethodrefInfos; + std::map< sal_uInt32, sal_uInt16 > m_nameAndTypeInfos; + AccessFlags m_accessFlags; + sal_uInt16 m_thisClass; + sal_uInt16 m_superClass; + sal_uInt16 m_interfacesCount; + std::vector< unsigned char > m_interfaces; + sal_uInt16 m_fieldsCount; + std::vector< unsigned char > m_fields; + sal_uInt16 m_methodsCount; + std::vector< unsigned char > m_methods; + sal_uInt16 m_attributesCount; + std::vector< unsigned char > m_attributes; + + friend class Code; +}; + +} } + +#endif // INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_CLASSFILE_HXX diff --git a/codemaker/source/javamaker/javamaker.cxx b/codemaker/source/javamaker/javamaker.cxx new file mode 100644 index 000000000000..b4e612d55823 --- /dev/null +++ b/codemaker/source/javamaker/javamaker.cxx @@ -0,0 +1,247 @@ +/************************************************************************* + * + * 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 <stdio.h> + +#include "sal/main.h" + +#include "codemaker/typemanager.hxx" +#include "codemaker/generatedtypeset.hxx" +#include "javaoptions.hxx" +#include "javatype.hxx" + +using namespace rtl; + +sal_Bool produceAllTypes(RegistryKey& rTypeKey, sal_Bool bIsExtraType, + TypeManager const & typeMgr, + codemaker::GeneratedTypeSet & generated, + JavaOptions* pOptions, + sal_Bool bFullScope) + throw( CannotDumpException ) +{ + OString typeName = typeMgr.getTypeName(rTypeKey); + + if (!produceType(rTypeKey, bIsExtraType, typeMgr, generated, pOptions)) + { + fprintf(stderr, "%s ERROR: %s\n", + pOptions->getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + + RegistryKeyList typeKeys = typeMgr.getTypeKeys(typeName); + RegistryKeyList::const_iterator iter = typeKeys.begin(); + RegistryKey key, subKey; + RegistryKeyArray subKeys; + + while (iter != typeKeys.end()) + { + key = (*iter).first; + + if (!(*iter).second && !key.openSubKeys(OUString(), subKeys)) + { + for (sal_uInt32 i = 0; i < subKeys.getLength(); i++) + { + subKey = subKeys.getElement(i); + if (bFullScope) + { + if (!produceAllTypes( + subKey, (*iter).second, + typeMgr, generated, pOptions, sal_True)) + return sal_False; + } else + { + if (!produceType(subKey, (*iter).second, + typeMgr, generated, pOptions)) + return sal_False; + } + } + } + + ++iter; + } + + return sal_True; +} + +sal_Bool produceAllTypes(const OString& typeName, + TypeManager const & typeMgr, + codemaker::GeneratedTypeSet & generated, + JavaOptions* pOptions, + sal_Bool bFullScope) + throw( CannotDumpException ) +{ + if (!produceType(typeName, typeMgr, generated, pOptions)) + { + fprintf(stderr, "%s ERROR: %s\n", + pOptions->getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + + RegistryKeyList typeKeys = typeMgr.getTypeKeys(typeName); + RegistryKeyList::const_iterator iter = typeKeys.begin(); + RegistryKey key, subKey; + RegistryKeyArray subKeys; + + while (iter != typeKeys.end()) + { + key = (*iter).first; + if (!(*iter).second && !key.openSubKeys(OUString(), subKeys)) + { + for (sal_uInt32 i = 0; i < subKeys.getLength(); i++) + { + subKey = subKeys.getElement(i); + if (bFullScope) + { + if (!produceAllTypes( + subKey, (*iter).second, + typeMgr, generated, pOptions, sal_True)) + return sal_False; + } else + { + if (!produceType(subKey, (*iter).second, + typeMgr, generated, pOptions)) + return sal_False; + } + } + } + + ++iter; + } + + return sal_True; +} + +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) +{ + JavaOptions options; + + try + { + if (!options.initOptions(argc, argv)) + { + exit(1); + } + } + catch( IllegalArgument& e) + { + fprintf(stderr, "Illegal option: %s\n", e.m_message.getStr()); + exit(99); + } + + RegistryTypeManager typeMgr; + + if (!typeMgr.init(options.getInputFiles(), options.getExtraInputFiles())) + { + fprintf(stderr, "%s : init registries failed, check your registry files.\n", options.getProgramName().getStr()); + exit(99); + } + + if (options.isValid("-B")) + { + typeMgr.setBase(options.getOption("-B")); + } + + try + { + if (options.isValid("-T")) + { + OString tOption(options.getOption("-T")); + sal_Int32 nIndex = 0; + + codemaker::GeneratedTypeSet generated; + OString typeName, tmpName; + sal_Bool ret = sal_False; + do + { + typeName = tOption.getToken(0, ';', nIndex); + + sal_Int32 nPos = typeName.lastIndexOf( '.' ); + tmpName = typeName.copy( nPos != -1 ? nPos+1 : 0 ); + if (tmpName == "*") + { + // produce this type and his scope. + if (typeName.equals("*")) + { + tmpName = "/"; + } else + { + tmpName = typeName.copy(0, typeName.lastIndexOf('.')).replace('.', '/'); + if (tmpName.getLength() == 0) + tmpName = "/"; + else + tmpName.replace('.', '/'); + } + // related to task #116780# the scope is recursively + // generated. bFullScope = true + ret = produceAllTypes( + tmpName, typeMgr, generated, &options, sal_True); + } else + { + // produce only this type + ret = produceType( + typeName.replace('.', '/'), typeMgr, generated, + &options); + } + + if (!ret) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + OString("cannot dump Type '" + typeName + "'").getStr()); + exit(99); + } + } while( nIndex != -1 ); + } else + { + // produce all types + codemaker::GeneratedTypeSet generated; + if (!produceAllTypes("/", typeMgr, generated, &options, sal_True)) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + "an error occurs while dumping all types."); + exit(99); + } + } + } + catch( CannotDumpException& e) + { + fprintf(stderr, "%s ERROR: %s\n", + options.getProgramName().getStr(), + e.m_message.getStr()); + exit(99); + } + + return 0; +} + + diff --git a/codemaker/source/javamaker/javaoptions.cxx b/codemaker/source/javamaker/javaoptions.cxx new file mode 100644 index 000000000000..24b9b1509cfc --- /dev/null +++ b/codemaker/source/javamaker/javaoptions.cxx @@ -0,0 +1,299 @@ +/************************************************************************* + * + * 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 <stdio.h> +#include <string.h> +#include "javaoptions.hxx" +#include "osl/process.h" +#include "osl/thread.h" + +using namespace rtl; + +sal_Bool JavaOptions::initOptions(int ac, char* av[], sal_Bool bCmdFile) + throw( IllegalArgument ) +{ + sal_Bool ret = sal_True; + sal_uInt16 i=0; + + if (!bCmdFile) + { + bCmdFile = sal_True; + + m_program = av[0]; + + if (ac < 2) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } + + i = 1; + } else + { + i = 0; + } + + char *s=NULL; + for( ; i < ac; i++) + { + if (av[i][0] == '-') + { + switch (av[i][1]) + { + case 'O': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-O', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_options["-O"] = OString(s); + break; + case 'B': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-B', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_options["-B"] = OString(s); + break; + case 'n': + if (av[i][2] != 'D' || av[i][3] != '\0') + { + OString tmp("'-nD', please check"); + tmp += " your input '" + OString(av[i]) + "'"; + throw IllegalArgument(tmp); + } + + m_options["-nD"] = OString(""); + break; + case 'T': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-T', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + if (m_options.count("-T") > 0) + { + OString tmp(m_options["-T"]); + tmp = tmp + ";" + s; + m_options["-T"] = tmp; + } else + { + m_options["-T"] = OString(s); + } + break; + case 'G': + if (av[i][2] == 'c') + { + if (av[i][3] != '\0') + { + OString tmp("'-Gc', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + m_options["-Gc"] = OString(""); + break; + } else + if (av[i][2] != '\0') + { + OString tmp("'-G', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i]) + "'"; + } + + throw IllegalArgument(tmp); + } + + m_options["-G"] = OString(""); + break; + case 'X': // support for eXtra type rdbs + { + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + OString tmp("'-X', please check"); + if (i <= ac - 1) + { + tmp += " your input '" + OString(av[i+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[i] + 2; + } + + m_extra_input_files.push_back( s ); + break; + } + + default: + throw IllegalArgument("the option is unknown" + OString(av[i])); + } + } else + { + if (av[i][0] == '@') + { + FILE* cmdFile = fopen(av[i]+1, "r"); + if( cmdFile == NULL ) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } else + { + int rargc=0; + char* rargv[512]; + char buffer[512]; + + while ( fscanf(cmdFile, "%s", buffer) != EOF ) + { + rargv[rargc]= strdup(buffer); + rargc++; + } + fclose(cmdFile); + + ret = initOptions(rargc, rargv, bCmdFile); + + for (long j=0; j < rargc; j++) + { + free(rargv[j]); + } + } + } else + { + if (bCmdFile) + { + m_inputFiles.push_back(av[i]); + } else + { + OUString system_filepath; + if (osl_getCommandArg( i-1, &system_filepath.pData ) + != osl_Process_E_None) + { + OSL_ASSERT(false); + } + m_inputFiles.push_back(OUStringToOString(system_filepath, osl_getThreadTextEncoding())); + } + } + } + } + + return ret; +} + +OString JavaOptions::prepareHelp() +{ + OString help("\nusing: "); + help += m_program + " [-options] file_1 ... file_n -Xfile_n+1 -Xfile_n+2\nOptions:\n"; + help += " -O<path> = path describes the root directory for the generated output.\n"; + help += " The output directory tree is generated under this directory.\n"; + help += " -T<name> = name specifies a type or a list of types. The output for this\n"; + help += " [t1;...] type and all dependent types are generated. If no '-T' option is \n"; + help += " specified, then output for all types is generated.\n"; + help += " Example: 'com.sun.star.uno.XInterface' is a valid type.\n"; + help += " -B<name> = name specifies the base node. All types are searched under this\n"; + help += " node. Default is the root '/' of the registry files.\n"; + help += " -nD = no dependent types are generated.\n"; + help += " -G = generate only target files which does not exists.\n"; + help += " -Gc = generate only target files which content will be changed.\n"; + help += " -X<file> = extra types which will not be taken into account for generation.\n"; + help += prepareVersion(); + + return help; +} + +OString JavaOptions::prepareVersion() +{ + OString version("\nSun Microsystems (R) "); + version += m_program + " Version 2.0\n\n"; + + return version; +} + + diff --git a/codemaker/source/javamaker/javaoptions.hxx b/codemaker/source/javamaker/javaoptions.hxx new file mode 100644 index 000000000000..8bcc04150370 --- /dev/null +++ b/codemaker/source/javamaker/javaoptions.hxx @@ -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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_JAVAOPTIONS_HXX +#define INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_JAVAOPTIONS_HXX + +#include "codemaker/options.hxx" + +class JavaOptions : public Options +{ +public: + JavaOptions() + : Options() {} + + ~JavaOptions() {} + + sal_Bool initOptions(int ac, char* av[], sal_Bool bCmdFile=sal_False) + throw( IllegalArgument ); + + ::rtl::OString prepareHelp(); + + ::rtl::OString prepareVersion(); + +protected: +}; + +#endif // INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_JAVAOPTIONS_HXX diff --git a/codemaker/source/javamaker/javatype.cxx b/codemaker/source/javamaker/javatype.cxx new file mode 100644 index 000000000000..7820a419a205 --- /dev/null +++ b/codemaker/source/javamaker/javatype.cxx @@ -0,0 +1,3374 @@ +/************************************************************************* + * + * 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 "javatype.hxx" + +#include "classfile.hxx" +#include "javaoptions.hxx" + +#include "codemaker/exceptiontree.hxx" +#include "codemaker/generatedtypeset.hxx" +#include "codemaker/global.hxx" +#include "codemaker/options.hxx" +#include "codemaker/typemanager.hxx" +#include "codemaker/unotype.hxx" +#include "codemaker/commonjava.hxx" + +#include "osl/diagnose.h" +#include "registry/reader.hxx" +#include "registry/refltype.hxx" +#include "registry/types.h" +#include "rtl/strbuf.hxx" +#include "rtl/string.h" +#include "rtl/string.hxx" +#include "rtl/textcvt.h" +#include "rtl/textenc.h" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "sal/types.h" + +#include <algorithm> +#include <list> +#include <map> +#include <memory> +#include <set> +#include <utility> +#include <vector> + +using codemaker::javamaker::ClassFile; + +namespace { + +void checkNoTypeArguments(std::vector< rtl::OString > const & arguments) { + if (!arguments.empty()) { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } +} + +// helper function for createUnoName +void appendUnoName( + TypeManager const & manager, rtl::OString const & nucleus, sal_Int32 rank, + std::vector< rtl::OString > const & arguments, rtl::OStringBuffer * buffer) +{ + OSL_ASSERT(rank >= 0 && buffer != 0); + for (sal_Int32 i = 0; i < rank; ++i) { + buffer->append(RTL_CONSTASCII_STRINGPARAM("[]")); + } + buffer->append(nucleus.replace('/', '.')); + if (!arguments.empty()) { + buffer->append('<'); + for (std::vector< rtl::OString >::const_iterator i(arguments.begin()); + i != arguments.end(); ++i) + { + if (i != arguments.begin()) { + buffer->append(','); + } + RTTypeClass argTypeClass; + rtl::OString argNucleus; + sal_Int32 argRank; + std::vector< rtl::OString > argArgs; + codemaker::decomposeAndResolve( + manager, *i, true, false, false, &argTypeClass, &argNucleus, + &argRank, &argArgs); + appendUnoName(manager, argNucleus, argRank, argArgs, buffer); + } + buffer->append('>'); + } +} + +// Translate the name of a UNO type registry entity (enum type, plain struct +// type, polymorphic struct type template, or interface type, decomposed into +// nucleus, rank, and arguments) into a core UNO type name: +rtl::OString createUnoName( + TypeManager const & manager, rtl::OString const & nucleus, sal_Int32 rank, + std::vector< rtl::OString > const & arguments) +{ + rtl::OStringBuffer buf; + appendUnoName(manager, nucleus, rank, arguments, &buf); + return buf.makeStringAndClear(); +} + +/** + Set of UTF-8--encoded names of UNO type registry entities a given UNO type + registry entity depends on. + + UNO type registry entities are enum types, plain struct types, polymorphic + struct type templates, exception types, interface types, typedefs, modules, + constant groupds, single-interface--based services, accumulation-based + services, interface-based singletons, and service-based singletons. + */ +typedef std::set< rtl::OString > Dependencies; + +enum SpecialType { + SPECIAL_TYPE_NONE, + SPECIAL_TYPE_ANY, + SPECIAL_TYPE_UNSIGNED, + SPECIAL_TYPE_INTERFACE +}; + +bool isSpecialType(SpecialType special) { + return special >= SPECIAL_TYPE_UNSIGNED; +} + +rtl::OString translateUnoTypeToJavaFullyQualifiedName( + rtl::OString const & type, rtl::OString const & prefix) +{ + sal_Int32 i = type.lastIndexOf('/') + 1; + return type.copy(0, i) + + codemaker::java::translateUnoToJavaIdentifier(type.copy(i), prefix); +} + +struct PolymorphicUnoType { + PolymorphicUnoType(): kind(KIND_NONE) {} + + enum Kind { KIND_NONE, KIND_STRUCT, KIND_SEQUENCE }; + Kind kind; + rtl::OString name; +}; + +SpecialType translateUnoTypeToDescriptor( + TypeManager const & manager, rtl::OString const & type, bool array, + bool classType, Dependencies * dependencies, + rtl::OStringBuffer * descriptor, rtl::OStringBuffer * signature, + bool * needsSignature, PolymorphicUnoType * polymorphicUnoType); + +SpecialType translateUnoTypeToDescriptor( + TypeManager const & manager, codemaker::UnoType::Sort sort, + RTTypeClass typeClass, rtl::OString const & nucleus, sal_Int32 rank, + std::vector< rtl::OString > const & arguments, bool array, bool classType, + Dependencies * dependencies, rtl::OStringBuffer * descriptor, + rtl::OStringBuffer * signature, bool * needsSignature, + PolymorphicUnoType * polymorphicUnoType) +{ + OSL_ASSERT(rank >= 0 && (signature == 0) == (needsSignature == 0)); + if (rank > 0xFF - (array ? 1 : 0)) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Too many array dimensions for Java class file format"))); + } + if (array) { + ++rank; + } + for (sal_Int32 i = 0; i < rank; ++i) { + if (descriptor != 0) { + descriptor->append('['); + } + if (signature != 0) { + signature->append('['); + } + } + if (sort == codemaker::UnoType::SORT_COMPLEX) { + //TODO: check that nucleus is a valid (Java-modified UTF-8) identifier + rtl::OString superClass; + if (typeClass == RT_TYPE_INTERFACE + && (nucleus + == rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XInterface")))) + { + if (descriptor != 0) { + descriptor->append( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;"))); + } + if (signature != 0) { + signature->append( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;"))); + } + if (polymorphicUnoType != 0) { + polymorphicUnoType->kind = PolymorphicUnoType::KIND_NONE; + } + return SPECIAL_TYPE_INTERFACE; + } else { + if (dependencies != 0) { + dependencies->insert(nucleus); + } + if (descriptor != 0) { + descriptor->append('L'); + descriptor->append(nucleus); + descriptor->append(';'); + } + if (signature != 0) { + signature->append('L'); + signature->append(nucleus); + if (!arguments.empty()) { + signature->append('<'); + for (std::vector< rtl::OString >::const_iterator i( + arguments.begin()); + i != arguments.end(); ++i) + { + translateUnoTypeToDescriptor( + manager, *i, false, true, dependencies, 0, + signature, needsSignature, 0); + } + signature->append('>'); + *needsSignature = true; + } + signature->append(';'); + } + if (polymorphicUnoType != 0) { + if (arguments.empty()) { + polymorphicUnoType->kind = PolymorphicUnoType::KIND_NONE; + } else { + polymorphicUnoType->kind = rank == 0 + ? PolymorphicUnoType::KIND_STRUCT + : PolymorphicUnoType::KIND_SEQUENCE; + polymorphicUnoType->name = createUnoName( + manager, nucleus, rank, arguments); + } + } + return SPECIAL_TYPE_NONE; + } + } else { + static rtl::OString const + simpleTypeDescriptors[codemaker::UnoType::SORT_ANY + 1][2] = { + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("V")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Void;")) + }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("Z")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Boolean;")) + }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("B")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Byte;")) + }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("S")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Short;")) + }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("S")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Short;")) + }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("I")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Integer;")) + }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("I")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Integer;")) + }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("J")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Long;")) + }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("J")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Long;")) + }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("F")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Float;")) + }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("D")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Double;")) + }, + { rtl::OString(RTL_CONSTASCII_STRINGPARAM("C")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Character;")) + }, + { rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/String;")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/String;")) + }, + { rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;")) + }, + { rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;")) + } }; + rtl::OString const & s + = simpleTypeDescriptors[sort][rank == 0 && classType]; + if (descriptor != 0) { + descriptor->append(s); + } + if (signature != 0) { + signature->append(s); + } + if (polymorphicUnoType != 0) { + polymorphicUnoType->kind = PolymorphicUnoType::KIND_NONE; + } + static SpecialType const + simpleTypeSpecials[codemaker::UnoType::SORT_ANY + 1] = { + SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE, + SPECIAL_TYPE_NONE, SPECIAL_TYPE_UNSIGNED, SPECIAL_TYPE_NONE, + SPECIAL_TYPE_UNSIGNED, SPECIAL_TYPE_NONE, SPECIAL_TYPE_UNSIGNED, + SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE, + SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE, SPECIAL_TYPE_ANY }; + return simpleTypeSpecials[sort]; + } +} + +SpecialType translateUnoTypeToDescriptor( + TypeManager const & manager, rtl::OString const & type, bool array, + bool classType, Dependencies * dependencies, + rtl::OStringBuffer * descriptor, rtl::OStringBuffer * signature, + bool * needsSignature, PolymorphicUnoType * polymorphicUnoType) +{ + RTTypeClass typeClass; + rtl::OString nucleus; + sal_Int32 rank; + std::vector< rtl::OString > args; + codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve( + manager, type, true, true, false, &typeClass, &nucleus, &rank, &args); + OSL_ASSERT(rank < SAL_MAX_INT32); + return translateUnoTypeToDescriptor( + manager, sort, typeClass, nucleus, rank, args, array, classType, + dependencies, descriptor, signature, needsSignature, + polymorphicUnoType); +} + +SpecialType getFieldDescriptor( + TypeManager const & manager, Dependencies * dependencies, + rtl::OString const & type, rtl::OString * descriptor, + rtl::OString * signature, PolymorphicUnoType * polymorphicUnoType) +{ + OSL_ASSERT(dependencies != 0 && descriptor != 0); + rtl::OStringBuffer desc; + rtl::OStringBuffer sig; + bool needsSig = false; + SpecialType specialType = translateUnoTypeToDescriptor( + manager, type, false, false, dependencies, &desc, &sig, &needsSig, + polymorphicUnoType); + *descriptor = desc.makeStringAndClear(); + if (signature != 0) { + if (needsSig) { + *signature = sig.makeStringAndClear(); + } else { + *signature = rtl::OString(); + } + } + return specialType; +} + +class MethodDescriptor { +public: + MethodDescriptor( + TypeManager const & manager, Dependencies * dependencies, + rtl::OString const & returnType, SpecialType * specialReturnType, + PolymorphicUnoType * polymorphicUnoType); + + SpecialType addParameter( + rtl::OString const & type, bool array, bool dependency, + PolymorphicUnoType * polymorphicUnoType); + + void addTypeParameter(rtl::OString const & name); + + rtl::OString getDescriptor() const; + + rtl::OString getSignature() const; + +private: + TypeManager const & m_manager; + Dependencies * m_dependencies; + rtl::OStringBuffer m_descriptorStart; + rtl::OString m_descriptorEnd; + rtl::OStringBuffer m_signatureStart; + rtl::OString m_signatureEnd; + bool m_needsSignature; +}; + +MethodDescriptor::MethodDescriptor( + TypeManager const & manager, Dependencies * dependencies, + rtl::OString const & returnType, SpecialType * specialReturnType, + PolymorphicUnoType * polymorphicUnoType): + m_manager(manager), m_dependencies(dependencies), m_needsSignature(false) +{ + OSL_ASSERT(dependencies != 0); + m_descriptorStart.append('('); + m_signatureStart.append('('); + rtl::OStringBuffer descEnd; + descEnd.append(')'); + rtl::OStringBuffer sigEnd; + sigEnd.append(')'); + SpecialType special = translateUnoTypeToDescriptor( + m_manager, returnType, false, false, m_dependencies, &descEnd, &sigEnd, + &m_needsSignature, polymorphicUnoType); + m_descriptorEnd = descEnd.makeStringAndClear(); + m_signatureEnd = sigEnd.makeStringAndClear(); + if (specialReturnType != 0) { + *specialReturnType = special; + } +} + +SpecialType MethodDescriptor::addParameter( + rtl::OString const & type, bool array, bool dependency, + PolymorphicUnoType * polymorphicUnoType) +{ + return translateUnoTypeToDescriptor( + m_manager, type, array, false, dependency ? m_dependencies : 0, + &m_descriptorStart, &m_signatureStart, &m_needsSignature, + polymorphicUnoType); +} + +void MethodDescriptor::addTypeParameter(rtl::OString const & name) { + m_descriptorStart.append(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;")); + m_signatureStart.append('T'); + m_signatureStart.append(name); + m_signatureStart.append(';'); + m_needsSignature = true; +} + +rtl::OString MethodDescriptor::getDescriptor() const { + rtl::OStringBuffer buf(m_descriptorStart); + buf.append(m_descriptorEnd); + return buf.makeStringAndClear(); +} + +rtl::OString MethodDescriptor::getSignature() const { + if (m_needsSignature) { + rtl::OStringBuffer buf(m_signatureStart); + buf.append(m_signatureEnd); + return buf.makeStringAndClear(); + } else { + return rtl::OString(); + } +} + +class TypeInfo { +public: + enum Kind { KIND_MEMBER, KIND_ATTRIBUTE, KIND_METHOD, KIND_PARAMETER }; + + // Same values as in com/sun/star/lib/uno/typeinfo/TypeInfo.java: + enum Flags { + FLAG_READONLY = 0x008, FLAG_BOUND = 0x100, FLAG_ONEWAY = 0x010 + }; + + // KIND_MEMBER: + TypeInfo( + rtl::OString const & name, SpecialType specialType, sal_Int32 index, + PolymorphicUnoType const & polymorphicUnoType, + sal_Int32 typeParameterIndex); + + // KIND_ATTRIBUTE/METHOD: + TypeInfo( + Kind kind, rtl::OString const & name, SpecialType specialType, + Flags flags, sal_Int32 index, + PolymorphicUnoType const & polymorphicUnoType); + + // KIND_PARAMETER: + TypeInfo( + rtl::OString const & parameterName, SpecialType specialType, + bool inParameter, bool outParameter, rtl::OString const & methodName, + sal_Int32 index, PolymorphicUnoType const & polymorphicUnoType); + + sal_uInt16 generateCode(ClassFile::Code & code, Dependencies * dependencies) + const; + + void generatePolymorphicUnoTypeCode( + ClassFile::Code & code, Dependencies * dependencies) const; + +private: + Kind m_kind; + rtl::OString m_name; + sal_Int32 m_flags; + sal_Int32 m_index; + rtl::OString m_methodName; + PolymorphicUnoType m_polymorphicUnoType; + sal_Int32 m_typeParameterIndex; +}; + +sal_Int32 translateSpecialTypeFlags( + SpecialType specialType, bool inParameter, bool outParameter) +{ + static sal_Int32 const specialTypeFlags[SPECIAL_TYPE_INTERFACE + 1] = { + 0, 0x0040 /* ANY */, 0x0004 /* UNSIGNED */, 0x0080 /* INTERFACE */ }; + sal_Int32 flags = specialTypeFlags[specialType]; + if (inParameter) { + flags |= 0x0001; /* IN */ + } + if (outParameter) { + flags |= 0x0002; /* OUT */ + } + return flags; +} + +TypeInfo::TypeInfo( + rtl::OString const & name, SpecialType specialType, sal_Int32 index, + PolymorphicUnoType const & polymorphicUnoType, + sal_Int32 typeParameterIndex): + m_kind(KIND_MEMBER), m_name(name), + m_flags(translateSpecialTypeFlags(specialType, false, false)), + m_index(index), m_polymorphicUnoType(polymorphicUnoType), + m_typeParameterIndex(typeParameterIndex) +{ + OSL_ASSERT( + polymorphicUnoType.kind == PolymorphicUnoType::KIND_NONE + ? typeParameterIndex >= -1 : typeParameterIndex == -1); +} + +TypeInfo::TypeInfo( + Kind kind, rtl::OString const & name, SpecialType specialType, + Flags flags, sal_Int32 index, + PolymorphicUnoType const & polymorphicUnoType): + m_kind(kind), m_name(name), + m_flags(flags | translateSpecialTypeFlags(specialType, false, false)), + m_index(index), m_polymorphicUnoType(polymorphicUnoType) +{ + OSL_ASSERT(kind == KIND_ATTRIBUTE || kind == KIND_METHOD); +} + +TypeInfo::TypeInfo( + rtl::OString const & parameterName, SpecialType specialType, + bool inParameter, bool outParameter, rtl::OString const & methodName, + sal_Int32 index, PolymorphicUnoType const & polymorphicUnoType): + m_kind(KIND_PARAMETER), m_name(parameterName), + m_flags(translateSpecialTypeFlags(specialType, inParameter, outParameter)), + m_index(index), m_methodName(methodName), + m_polymorphicUnoType(polymorphicUnoType) +{} + +sal_uInt16 TypeInfo::generateCode( + ClassFile::Code & code, Dependencies * dependencies) const +{ + OSL_ASSERT(dependencies != 0); + switch (m_kind) { + case KIND_MEMBER: + code.instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/MemberTypeInfo"))); + code.instrDup(); + code.loadStringConstant(m_name); + code.loadIntegerConstant(m_index); + code.loadIntegerConstant(m_flags); + if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) { + generatePolymorphicUnoTypeCode(code, dependencies); + code.loadIntegerConstant(m_typeParameterIndex); + code.instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/MemberTypeInfo")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;IILcom/sun/star/uno/Type;I)V"))); + return 8; + } else if (m_typeParameterIndex >= 0) { + code.instrAconstNull(); + code.loadIntegerConstant(m_typeParameterIndex); + code.instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/MemberTypeInfo")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;IILcom/sun/star/uno/Type;I)V"))); + return 6; + } else { + code.instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/MemberTypeInfo")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;II)V"))); + return 4; + } + + case KIND_ATTRIBUTE: + code.instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/AttributeTypeInfo"))); + code.instrDup(); + code.loadStringConstant(m_name); + code.loadIntegerConstant(m_index); + code.loadIntegerConstant(m_flags); + if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) { + generatePolymorphicUnoTypeCode(code, dependencies); + code.instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/AttributeTypeInfo")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;IILcom/sun/star/uno/Type;)V"))); + return 8; + } else { + code.instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/AttributeTypeInfo")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;II)V"))); + return 4; + } + + case KIND_METHOD: + code.instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/MethodTypeInfo"))); + code.instrDup(); + code.loadStringConstant(m_name); + code.loadIntegerConstant(m_index); + code.loadIntegerConstant(m_flags); + if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) { + generatePolymorphicUnoTypeCode(code, dependencies); + code.instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/MethodTypeInfo")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;IILcom/sun/star/uno/Type;)V"))); + return 8; + } else { + code.instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/MethodTypeInfo")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;II)V"))); + return 4; + } + + case KIND_PARAMETER: + code.instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/ParameterTypeInfo"))); + code.instrDup(); + code.loadStringConstant(m_name); + code.loadStringConstant(m_methodName); + code.loadIntegerConstant(m_index); + code.loadIntegerConstant(m_flags); + if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) { + generatePolymorphicUnoTypeCode(code, dependencies); + code.instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/ParameterTypeInfo")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;Ljava/lang/String;II" + "Lcom/sun/star/uno/Type;)V"))); + return 9; + } else { + code.instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/ParameterTypeInfo")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;Ljava/lang/String;II)V"))); + return 5; + } + + default: + OSL_ASSERT(false); + return 0; + } +} + +void TypeInfo::generatePolymorphicUnoTypeCode( + ClassFile::Code & code, Dependencies * dependencies) const +{ + OSL_ASSERT( + dependencies != 0 + && m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE); + code.instrNew( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type"))); + code.instrDup(); + code.loadStringConstant(m_polymorphicUnoType.name); + if (m_polymorphicUnoType.kind == PolymorphicUnoType::KIND_STRUCT) { + code.instrGetstatic( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("STRUCT")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/TypeClass;"))); + } else { + code.instrGetstatic( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("SEQUENCE")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/TypeClass;"))); + } + dependencies->insert( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass"))); + code.instrInvokespecial( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V"))); +} + +void writeClassFile( + JavaOptions /*TODO const*/ & options, rtl::OString const & type, + ClassFile const & classFile) +{ + rtl::OString path; + if (options.isValid(rtl::OString(RTL_CONSTASCII_STRINGPARAM("-O")))) { + path = options.getOption( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("-O"))); + } + rtl::OString filename( + createFileNameFromType( + path, type, rtl::OString(RTL_CONSTASCII_STRINGPARAM(".class")))); + bool check = false; + if (fileExists(filename)) { + if (options.isValid(rtl::OString(RTL_CONSTASCII_STRINGPARAM("-G")))) { + return; + } + check = options.isValid( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("-Gc"))); + } + FileStream tempfile; + tempfile.createTempFile(getTempDir(filename)); + if (!tempfile.isValid()) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Cannot create temporary file for ")) + + filename); + } + rtl::OString tempname(tempfile.getName()); + try { + classFile.write(tempfile); + } catch (...) { + // Remove existing file for consistency: + if (fileExists(filename)) { + removeTypeFile(filename); + } + tempfile.close(); + removeTypeFile(tempname); + throw; + } + tempfile.close(); + if (!makeValidTypeFile(filename, tempname, check)) { + rtl::OStringBuffer msg; + msg.append(RTL_CONSTASCII_STRINGPARAM("Cannot create ")); + msg.append(filename); + msg.append(RTL_CONSTASCII_STRINGPARAM(" from temporary file ")); + msg.append(tempname); + throw CannotDumpException(msg.makeStringAndClear()); + } +} + +void addTypeInfo( + rtl::OString const & className, std::vector< TypeInfo > const & typeInfo, + Dependencies * dependencies, ClassFile * classFile) +{ + OSL_ASSERT(dependencies != 0 && classFile != 0); + std::vector< TypeInfo >::size_type typeInfos = typeInfo.size(); + if (typeInfos > SAL_MAX_INT32) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "UNOTYPEINFO array too big for Java class file format"))); + } + if (typeInfos != 0) { + classFile->addField( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC + | ClassFile::ACC_FINAL), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("UNOTYPEINFO")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "[Lcom/sun/star/lib/uno/typeinfo/TypeInfo;")), + 0, rtl::OString()); + std::auto_ptr< ClassFile::Code > code(classFile->newCode()); + code->loadIntegerConstant(static_cast< sal_Int32 >(typeInfos)); + code->instrAnewarray( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lib/uno/typeinfo/TypeInfo"))); + sal_Int32 index = 0; + sal_uInt16 stack = 0; + for (std::vector< TypeInfo >::const_iterator i(typeInfo.begin()); + i != typeInfo.end(); ++i) + { + code->instrDup(); + code->loadIntegerConstant(index++); + stack = std::max(stack, i->generateCode(*code, dependencies)); + code->instrAastore(); + } + code->instrPutstatic( + className, rtl::OString(RTL_CONSTASCII_STRINGPARAM("UNOTYPEINFO")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "[Lcom/sun/star/lib/uno/typeinfo/TypeInfo;"))); + code->instrReturn(); + if (stack > SAL_MAX_UINT16 - 4) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Stack too big for Java class file format"))); + } + code->setMaxStackAndLocals(static_cast< sal_uInt16 >(stack + 4), 0); + classFile->addMethod( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<clinit>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("()V")), code.get(), + std::vector< rtl::OString >(), rtl::OString()); + } +} + +typedef void (* handleUnoTypeRegistryEntityFunction)( + TypeManager const & manager, JavaOptions /*TODO const*/ & options, + typereg::Reader const & reader, Dependencies * dependencies); + +void handleEnumType( + TypeManager const &, JavaOptions /*TODO const*/ & options, + typereg::Reader const & reader, Dependencies *) +{ + sal_uInt16 fields = reader.getFieldCount(); + if (fields == 0 || reader.getSuperTypeCount() != 0 + || reader.getMethodCount() != 0 || reader.getReferenceCount() != 0) + { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + rtl::OString className(codemaker::convertString(reader.getTypeName())); + std::auto_ptr< ClassFile > cf( + new ClassFile( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_FINAL + | ClassFile::ACC_SUPER), + className, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Enum")), + rtl::OString())); + rtl::OStringBuffer buf; + buf.append('L'); + buf.append(className); + buf.append(';'); + rtl::OString classDescriptor(buf.makeStringAndClear()); + {for (sal_uInt16 i = 0; i < fields; ++i) { + RTConstValue fieldValue(reader.getFieldValue(i)); + if (fieldValue.m_type != RT_TYPE_INT32 + || reader.getFieldFlags(i) != RT_ACCESS_CONST + || reader.getFieldTypeName(i).getLength() != 0) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + rtl::OString fieldName( + codemaker::convertString(reader.getFieldName(i))); + cf->addField( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC + | ClassFile::ACC_FINAL), + fieldName, classDescriptor, 0, rtl::OString()); + cf->addField( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC + | ClassFile::ACC_FINAL), + fieldName + rtl::OString(RTL_CONSTASCII_STRINGPARAM("_value")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("I")), + cf->addIntegerInfo(fieldValue.m_value.aLong), rtl::OString()); + }} + std::auto_ptr< ClassFile::Code > code(cf->newCode()); + code->loadLocalReference(0); + code->loadLocalInteger(1); + code->instrInvokespecial( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Enum")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)V"))); + code->instrReturn(); + code->setMaxStackAndLocals(2, 2); + cf->addMethod( + ClassFile::ACC_PRIVATE, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)V")), code.get(), + std::vector< rtl::OString >(), rtl::OString()); + code.reset(cf->newCode()); + code->instrGetstatic( + className, + codemaker::convertString(reader.getFieldName(0)), classDescriptor); + code->instrAreturn(); + code->setMaxStackAndLocals(1, 0); + cf->addMethod( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("getDefault")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("()")) + classDescriptor, + code.get(), std::vector< rtl::OString >(), rtl::OString()); + code.reset(cf->newCode()); + code->loadLocalInteger(0); + std::map< sal_Int32, rtl::OString > map; + sal_Int32 min = SAL_MAX_INT32; + sal_Int32 max = SAL_MIN_INT32; + {for (sal_uInt16 i = 0; i < fields; ++i) { + sal_Int32 value = reader.getFieldValue(i).m_value.aLong; + min = std::min(min, value); + max = std::max(max, value); + map.insert( + std::map< sal_Int32, rtl::OString >::value_type( + value, codemaker::convertString(reader.getFieldName(i)))); + }} + sal_uInt64 size = static_cast< sal_uInt64 >(map.size()); + if ((static_cast< sal_uInt64 >(max) - static_cast< sal_uInt64 >(min) + <= 2 * size) + || size > SAL_MAX_INT32) + { + std::auto_ptr< ClassFile::Code > defCode(cf->newCode()); + defCode->instrAconstNull(); + defCode->instrAreturn(); + std::list< ClassFile::Code * > blocks; + //FIXME: pointers contained in blocks may leak + sal_Int32 last = SAL_MAX_INT32; + for (std::map< sal_Int32, rtl::OString >::iterator i(map.begin()); + i != map.end(); ++i) + { + sal_Int32 value = i->first; + if (last != SAL_MAX_INT32) { + for (sal_Int32 j = last + 1; j < value; ++j) { + blocks.push_back(0); + } + } + last = value; + std::auto_ptr< ClassFile::Code > blockCode(cf->newCode()); + blockCode->instrGetstatic(className, i->second, classDescriptor); + blockCode->instrAreturn(); + blocks.push_back(blockCode.get()); + blockCode.release(); + } + code->instrTableswitch(defCode.get(), min, blocks); + {for (std::list< ClassFile::Code * >::iterator i(blocks.begin()); + i != blocks.end(); ++i) + { + delete *i; + }} + } else { + std::auto_ptr< ClassFile::Code > defCode(cf->newCode()); + defCode->instrAconstNull(); + defCode->instrAreturn(); + std::list< std::pair< sal_Int32, ClassFile::Code * > > blocks; + //FIXME: pointers contained in blocks may leak + for (std::map< sal_Int32, rtl::OString >::iterator i(map.begin()); + i != map.end(); ++i) + { + std::auto_ptr< ClassFile::Code > blockCode(cf->newCode()); + blockCode->instrGetstatic(className, i->second, classDescriptor); + blockCode->instrAreturn(); + blocks.push_back(std::make_pair(i->first, blockCode.get())); + blockCode.release(); + } + code->instrLookupswitch(defCode.get(), blocks); + {for (std::list< std::pair< sal_Int32, ClassFile::Code * > >::iterator + i(blocks.begin()); + i != blocks.end(); ++i) + { + delete i->second; + }} + } + code->setMaxStackAndLocals(1, 1); + cf->addMethod( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("fromInt")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)")) + classDescriptor, + code.get(), std::vector< rtl::OString >(), rtl::OString()); + code.reset(cf->newCode()); + {for (sal_uInt16 i = 0; i < fields; ++i) { + code->instrNew(className); + code->instrDup(); + code->loadIntegerConstant(reader.getFieldValue(i).m_value.aLong); + code->instrInvokespecial( + className, rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)V"))); + code->instrPutstatic( + className, + codemaker::convertString(reader.getFieldName(i)), + classDescriptor); + }} + code->instrReturn(); + code->setMaxStackAndLocals(3, 0); + cf->addMethod( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<clinit>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("()V")), code.get(), + std::vector< rtl::OString >(), rtl::OString()); + writeClassFile(options, className, *cf.get()); +} + +void addField( + TypeManager const & manager, Dependencies * dependencies, + ClassFile * classFile, std::vector< TypeInfo > * typeInfo, + sal_Int32 typeParameterIndex, rtl::OString const & type, + rtl::OString const & name, sal_Int32 index) +{ + OSL_ASSERT(dependencies != 0 && classFile != 0 && typeInfo != 0); + rtl::OString descriptor; + rtl::OString signature; + SpecialType specialType; + PolymorphicUnoType polymorphicUnoType; + if (typeParameterIndex >= 0) { + descriptor = rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;")); + rtl::OStringBuffer buf; + buf.append('T'); + buf.append(type); + buf.append(';'); + signature = buf.makeStringAndClear(); + specialType = SPECIAL_TYPE_NONE; //TODO: SPECIAL_TYPE_TYPE_PARAMETER? + } else { + specialType = getFieldDescriptor( + manager, dependencies, type, &descriptor, &signature, + &polymorphicUnoType); + } + classFile->addField(ClassFile::ACC_PUBLIC, name, descriptor, 0, signature); + typeInfo->push_back( + TypeInfo( + name, specialType, index, polymorphicUnoType, typeParameterIndex)); +} + +sal_uInt16 addFieldInit( + TypeManager const & manager, rtl::OString const & className, + rtl::OString const & fieldName, bool typeParameter, + rtl::OString const & fieldType, Dependencies * dependencies, + ClassFile::Code * code) +{ + OSL_ASSERT(dependencies != 0 && code != 0); + if (typeParameter) { + return 0; + } else { + RTTypeClass typeClass; + rtl::OString nucleus; + sal_Int32 rank; + std::vector< rtl::OString > args; + codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve( + manager, fieldType, true, false, false, &typeClass, &nucleus, &rank, + &args); + if (rank == 0) { + switch (sort) { + case codemaker::UnoType::SORT_STRING: + code->loadLocalReference(0); + code->loadStringConstant(rtl::OString()); + code->instrPutfield( + className, fieldName, + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/String;"))); + return 2; + + case codemaker::UnoType::SORT_TYPE: + code->loadLocalReference(0); + code->instrGetstatic( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("VOID")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;"))); + code->instrPutfield( + className, fieldName, + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;"))); + return 2; + + case codemaker::UnoType::SORT_ANY: + code->loadLocalReference(0); + code->instrGetstatic( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("VOID")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Any;"))); + code->instrPutfield( + className, fieldName, + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;"))); + return 2; + + case codemaker::UnoType::SORT_COMPLEX: + switch (typeClass) { + case RT_TYPE_ENUM: + { + code->loadLocalReference(0); + typereg::Reader reader(manager.getTypeReader(nucleus)); + if (reader.getFieldCount() == 0) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Bad type information"))); //TODO + } + rtl::OStringBuffer descBuf; + translateUnoTypeToDescriptor( + manager, sort, typeClass, nucleus, 0, + std::vector< rtl::OString >(), false, false, + dependencies, &descBuf, 0, 0, 0); + rtl::OString desc(descBuf.makeStringAndClear()); + code->instrGetstatic( + nucleus, + codemaker::convertString(reader.getFieldName(0)), + desc); + code->instrPutfield(className, fieldName, desc); + return 2; + } + + case RT_TYPE_STRUCT: + { + code->loadLocalReference(0); + code->instrNew(nucleus); + code->instrDup(); + code->instrInvokespecial( + nucleus, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("()V"))); + rtl::OStringBuffer desc; + translateUnoTypeToDescriptor( + manager, sort, typeClass, nucleus, 0, + std::vector< rtl::OString >(), false, false, + dependencies, &desc, 0, 0, 0); + code->instrPutfield( + className, fieldName, desc.makeStringAndClear()); + return 3; + } + + default: + OSL_ASSERT(typeClass == RT_TYPE_INTERFACE); + return 0; + } + + default: + return 0; + } + } else { + code->loadLocalReference(0); + code->loadIntegerConstant(0); + if (rank == 1) { + if (sort >= codemaker::UnoType::SORT_BOOLEAN + && sort <= codemaker::UnoType::SORT_CHAR) + { + code->instrNewarray(sort); + } else { + code->instrAnewarray( + codemaker::java::translateUnoToJavaType(sort, typeClass, + nucleus, 0)); + } + } else { + rtl::OStringBuffer desc; + translateUnoTypeToDescriptor( + manager, sort, typeClass, nucleus, rank - 1, + std::vector< rtl::OString >(), false, false, dependencies, + &desc, 0, 0, 0); + code->instrAnewarray(desc.makeStringAndClear()); + } + rtl::OStringBuffer desc; + translateUnoTypeToDescriptor( + manager, sort, typeClass, nucleus, rank, + std::vector< rtl::OString >(), false, false, dependencies, + &desc, 0, 0, 0); + code->instrPutfield( + className, fieldName, desc.makeStringAndClear()); + return 2; + } + } +} + +sal_uInt16 addLoadLocal( + TypeManager const & manager, ClassFile::Code * code, sal_uInt16 * index, + bool typeParameter, rtl::OString const & type, bool any, + Dependencies * dependencies) +{ + OSL_ASSERT( + code != 0 && index != 0 && !(typeParameter && any) + && dependencies != 0); + sal_uInt16 stack = 1; + sal_uInt16 size = 1; + if (typeParameter) { + code->loadLocalReference(*index); + stack = size = 1; + } else { + RTTypeClass typeClass; + rtl::OString nucleus; + sal_Int32 rank; + std::vector< rtl::OString > args; + codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve( + manager, type, true, false, false, &typeClass, &nucleus, &rank, &args); + if (rank == 0) { + switch (sort) { + case codemaker::UnoType::SORT_BOOLEAN: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Boolean"))); + code->instrDup(); + code->loadLocalInteger(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Boolean")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(Z)V"))); + stack = 3; + } else { + code->loadLocalInteger(*index); + stack = 1; + } + size = 1; + break; + + case codemaker::UnoType::SORT_BYTE: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Byte"))); + code->instrDup(); + code->loadLocalInteger(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Byte")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(B)V"))); + stack = 3; + } else { + code->loadLocalInteger(*index); + stack = 1; + } + size = 1; + break; + + case codemaker::UnoType::SORT_SHORT: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Short"))); + code->instrDup(); + code->loadLocalInteger(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Short")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(S)V"))); + stack = 3; + } else { + code->loadLocalInteger(*index); + stack = 1; + } + size = 1; + break; + + case codemaker::UnoType::SORT_UNSIGNED_SHORT: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Any"))); + code->instrDup(); + code->instrGetstatic( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Type")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("UNSIGNED_SHORT")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Lcom/sun/star/uno/Type;"))); + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Short"))); + code->instrDup(); + code->loadLocalInteger(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Short")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(S)V"))); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)" + "V"))); + stack = 6; + } else { + code->loadLocalInteger(*index); + stack = 1; + } + size = 1; + break; + + case codemaker::UnoType::SORT_LONG: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Integer"))); + code->instrDup(); + code->loadLocalInteger(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Integer")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)V"))); + stack = 3; + } else { + code->loadLocalInteger(*index); + stack = 1; + } + size = 1; + break; + + case codemaker::UnoType::SORT_UNSIGNED_LONG: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Any"))); + code->instrDup(); + code->instrGetstatic( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Type")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("UNSIGNED_LONG")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Lcom/sun/star/uno/Type;"))); + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Integer"))); + code->instrDup(); + code->loadLocalInteger(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Integer")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)V"))); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)" + "V"))); + stack = 6; + } else { + code->loadLocalInteger(*index); + stack = 1; + } + size = 1; + break; + + case codemaker::UnoType::SORT_HYPER: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Long"))); + code->instrDup(); + code->loadLocalLong(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Long")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(J)V"))); + stack = 4; + } else { + code->loadLocalLong(*index); + stack = 2; + } + size = 2; + break; + + case codemaker::UnoType::SORT_UNSIGNED_HYPER: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Any"))); + code->instrDup(); + code->instrGetstatic( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Type")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("UNSIGNED_HYPER")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Lcom/sun/star/uno/Type;"))); + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Long"))); + code->instrDup(); + code->loadLocalLong(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Long")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(J)V"))); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)" + "V"))); + stack = 7; + } else { + code->loadLocalLong(*index); + stack = 2; + } + size = 2; + break; + + case codemaker::UnoType::SORT_FLOAT: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Float"))); + code->instrDup(); + code->loadLocalFloat(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Float")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(F)V"))); + stack = 3; + } else { + code->loadLocalFloat(*index); + stack = 1; + } + size = 1; + break; + + case codemaker::UnoType::SORT_DOUBLE: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Double"))); + code->instrDup(); + code->loadLocalDouble(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Double")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(D)V"))); + stack = 4; + } else { + code->loadLocalDouble(*index); + stack = 2; + } + size = 2; + break; + + case codemaker::UnoType::SORT_CHAR: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Character"))); + code->instrDup(); + code->loadLocalInteger(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Character")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(C)V"))); + stack = 3; + } else { + code->loadLocalInteger(*index); + stack = 1; + } + size = 1; + break; + + case codemaker::UnoType::SORT_STRING: + case codemaker::UnoType::SORT_TYPE: + case codemaker::UnoType::SORT_ANY: + code->loadLocalReference(*index); + stack = size = 1; + break; + + case codemaker::UnoType::SORT_COMPLEX: + switch (typeClass) { + case RT_TYPE_ENUM: + // Assuming that no Java types are derived from Java types + // that are directly derived from com.sun.star.uno.Enum: + code->loadLocalReference(*index); + stack = size = 1; + break; + + case RT_TYPE_STRUCT: + if (any) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Any"))); + code->instrDup(); + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Type"))); + code->instrDup(); + code->loadStringConstant( + createUnoName(manager, nucleus, rank, args)); + code->instrGetstatic( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/TypeClass")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("STRUCT")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Lcom/sun/star/uno/TypeClass;"))); + dependencies->insert( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/TypeClass"))); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Type")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;" + "Lcom/sun/star/uno/TypeClass;)V"))); + code->loadLocalReference(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Any")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Lcom/sun/star/uno/Type;" + "Ljava/lang/Object;)V"))); + stack = 6; + } else { + code->loadLocalReference(*index); + stack = 1; + } + size = 1; + break; + + case RT_TYPE_INTERFACE: + if (any + && (nucleus + != rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/XInterface")))) + { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Any"))); + code->instrDup(); + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Type"))); + code->instrDup(); + code->loadStringConstant(nucleus.replace('/', '.')); + code->instrGetstatic( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/TypeClass")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("INTERFACE")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Lcom/sun/star/uno/TypeClass;"))); + dependencies->insert( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/TypeClass"))); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Type")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;" + "Lcom/sun/star/uno/TypeClass;)V"))); + code->loadLocalReference(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/Any")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Lcom/sun/star/uno/Type;" + "Ljava/lang/Object;)V"))); + stack = 6; + } else { + code->loadLocalReference(*index); + stack = 1; + } + size = 1; + break; + + default: + OSL_ASSERT(false); + break; + } + break; + + default: + OSL_ASSERT(false); + break; + } + } else { + bool wrap = false; + if (any) { + switch (sort) { + case codemaker::UnoType::SORT_BOOLEAN: + case codemaker::UnoType::SORT_BYTE: + case codemaker::UnoType::SORT_SHORT: + case codemaker::UnoType::SORT_LONG: + case codemaker::UnoType::SORT_HYPER: + 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: + // assuming that no Java types are derived from + // com.sun.star.uno.Type + break; + + case codemaker::UnoType::SORT_UNSIGNED_SHORT: + case codemaker::UnoType::SORT_UNSIGNED_LONG: + case codemaker::UnoType::SORT_UNSIGNED_HYPER: + case codemaker::UnoType::SORT_ANY: + wrap = true; + break; + + case codemaker::UnoType::SORT_COMPLEX: + switch (typeClass) { + case RT_TYPE_ENUM: + // assuming that no Java types are derived from Java + // types that are directly derived from + // com.sun.star.uno.Enum + break; + + case RT_TYPE_STRUCT: + case RT_TYPE_INTERFACE: + wrap = true; + break; + + default: + OSL_ASSERT(false); + break; + } + break; + + default: + OSL_ASSERT(false); + break; + } + } + if (wrap) { + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any"))); + code->instrDup(); + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type"))); + code->instrDup(); + code->loadStringConstant( + createUnoName(manager, nucleus, rank, args)); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;)V"))); + code->loadLocalReference(*index); + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V"))); + stack = 5; + } else { + code->loadLocalReference(*index); + stack = 1; + } + size = 1; + } + } + if (*index > SAL_MAX_UINT16 - size) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Too many local variables for Java class file format"))); + } + *index = *index + size; + return stack; +} + +void addBaseArguments( + TypeManager const & manager, Dependencies * dependencies, + MethodDescriptor * methodDescriptor, ClassFile::Code * code, + RTTypeClass typeClass, rtl::OString const & type, sal_uInt16 * index) +{ + OSL_ASSERT( + dependencies != 0 && methodDescriptor != 0 && code != 0 && index != 0); + typereg::Reader reader(manager.getTypeReader(type)); + if (!reader.isValid() || reader.getTypeClass() != typeClass + || codemaker::convertString(reader.getTypeName()) != type + || reader.getMethodCount() != 0 || reader.getReferenceCount() != 0) + { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + sal_uInt16 superTypes = reader.getSuperTypeCount(); + sal_uInt16 fields = reader.getFieldCount(); + sal_uInt16 firstField = 0; + if (type + == rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Exception"))) + { + if (typeClass != RT_TYPE_EXCEPTION || superTypes != 0 || fields != 2) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + firstField = 1; + } else { + if ( + (typeClass == RT_TYPE_STRUCT && (superTypes > 1 || fields == 0)) || + (typeClass == RT_TYPE_EXCEPTION && superTypes != 1) + ) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + if (superTypes == 1) { + addBaseArguments( + manager, dependencies, methodDescriptor, code, typeClass, + codemaker::convertString(reader.getSuperTypeName(0)), index); + } + } + for (sal_uInt16 i = firstField; i < fields; ++i) { + if (reader.getFieldFlags(i) != RT_ACCESS_READWRITE + || reader.getFieldValue(i).m_type != RT_TYPE_NONE) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + rtl::OString fieldType( + codemaker::convertString(reader.getFieldTypeName(i))); + methodDescriptor->addParameter(fieldType, false, true, 0); + addLoadLocal( + manager, code, index, false, fieldType, false, dependencies); + } +} + +sal_uInt16 addDirectArgument( + TypeManager const & manager, Dependencies * dependencies, + MethodDescriptor * methodDescriptor, ClassFile::Code * code, + sal_uInt16 * index, rtl::OString const & className, + rtl::OString const & fieldName, bool typeParameter, + rtl::OString const & fieldType) +{ + OSL_ASSERT( + dependencies != 0 && methodDescriptor != 0 && code != 0 && index != 0); + rtl::OString desc; + if (typeParameter) { + methodDescriptor->addTypeParameter(fieldType); + desc = rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;")); + } else { + methodDescriptor->addParameter(fieldType, false, true, 0); + getFieldDescriptor(manager, dependencies, fieldType, &desc, 0, 0); + } + code->loadLocalReference(0); + sal_uInt16 stack = addLoadLocal( + manager, code, index, typeParameter, fieldType, false, dependencies); + code->instrPutfield(className, fieldName, desc); + return stack + 1; +} + +void handleAggregatingType( + TypeManager const & manager, JavaOptions /*TODO const*/ & options, + typereg::Reader const & reader, Dependencies * dependencies) +{ + OSL_ASSERT(dependencies != 0); + if (reader.getMethodCount() != 0) + { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + RTTypeClass typeClass = reader.getTypeClass(); + rtl::OString className(codemaker::convertString(reader.getTypeName())); + sal_uInt16 superTypes = reader.getSuperTypeCount(); + sal_uInt16 fields = reader.getFieldCount(); + sal_uInt16 firstField = 0; + sal_uInt16 references = reader.getReferenceCount(); + bool runtimeException = false; + rtl::OString superClass; + if (className + == rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Exception"))) + { + if (typeClass != RT_TYPE_EXCEPTION || superTypes != 0 || fields != 2 + || references != 0) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + firstField = 1; + superClass = rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Exception")); + } else if (className + == rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/RuntimeException"))) + { + if (typeClass != RT_TYPE_EXCEPTION || superTypes != 1 || fields != 0 + || references != 0) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + superTypes = 0; + superClass = rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/RuntimeException")); + runtimeException = true; + } else { + if ( + ( + typeClass == RT_TYPE_STRUCT && + ( + fields == 0 || + (references == 0 ? superTypes > 1 : superTypes != 0) + ) + ) || + (typeClass == RT_TYPE_EXCEPTION && superTypes != 1) + ) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + if (superTypes == 0) { + superClass = rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/lang/Object")); + } else { + superClass = codemaker::convertString(reader.getSuperTypeName(0)); + dependencies->insert(superClass); + } + } + rtl::OString sig; + std::map< rtl::OString, sal_Int32 > typeParameters; + if (references != 0) { + rtl::OStringBuffer buf; + buf.append('<'); + for (sal_uInt16 i = 0; i < references; ++i) { + if (reader.getReferenceFlags(i) != RT_ACCESS_INVALID + || reader.getReferenceSort(i) != RT_REF_TYPE_PARAMETER) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + rtl::OString name( + codemaker::convertString(reader.getReferenceTypeName(i))); + buf.append(name); + buf.append(RTL_CONSTASCII_STRINGPARAM(":Ljava/lang/Object;")); + if (!typeParameters.insert( + std::map< rtl::OString, sal_Int32 >::value_type(name, i)). + second) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + } + buf.append(RTL_CONSTASCII_STRINGPARAM(">Ljava/lang/Object;")); + sig = buf.makeStringAndClear(); + } + std::auto_ptr< ClassFile > cf( + new ClassFile( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_SUPER), + className, superClass, sig)); + std::vector< TypeInfo > typeInfo; + {for (sal_uInt16 i = firstField; i < fields; ++i) { + RTFieldAccess flags = reader.getFieldFlags(i); + if ((flags != RT_ACCESS_READWRITE + && flags != (RT_ACCESS_READWRITE | RT_ACCESS_PARAMETERIZED_TYPE)) + || ((flags & RT_ACCESS_PARAMETERIZED_TYPE) != 0 && references == 0) + || reader.getFieldValue(i).m_type != RT_TYPE_NONE) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + rtl::OString type( + codemaker::convertString(reader.getFieldTypeName(i))); + sal_Int32 typeParameterIndex; + if ((flags & RT_ACCESS_PARAMETERIZED_TYPE) == 0) { + typeParameterIndex = -1; + } else { + std::map< rtl::OString, sal_Int32 >::iterator it( + typeParameters.find(type)); + if (it == typeParameters.end()) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + typeParameterIndex = it->second; + } + addField( + manager, dependencies, cf.get(), &typeInfo, typeParameterIndex, + type, codemaker::convertString(reader.getFieldName(i)), i - firstField); + }} + if (runtimeException) { + addField( + manager, dependencies, cf.get(), &typeInfo, -1, + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XInterface")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Context")), 0); + } + std::auto_ptr< ClassFile::Code > code(cf->newCode()); + code->loadLocalReference(0); + code->instrInvokespecial( + superClass, rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("()V"))); + sal_uInt16 stack = 0; + {for (sal_uInt16 i = firstField; i < fields; ++i) { + stack = std::max( + stack, + addFieldInit( + manager, className, + codemaker::convertString(reader.getFieldName(i)), + (reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0, + codemaker::convertString(reader.getFieldTypeName(i)), + dependencies, code.get())); + }} + if (runtimeException) { + stack = std::max( + stack, + addFieldInit( + manager, className, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Context")), false, + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XInterface")), + dependencies, code.get())); + } + code->instrReturn(); + code->setMaxStackAndLocals(stack + 1, 1); + cf->addMethod( + ClassFile::ACC_PUBLIC, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("()V")), code.get(), + std::vector< rtl::OString >(), rtl::OString()); + if (typeClass == RT_TYPE_EXCEPTION) { + code.reset(cf->newCode()); + code->loadLocalReference(0); + code->loadLocalReference(1); + code->instrInvokespecial( + superClass, rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;)V"))); + stack = 0; + for (sal_uInt16 i = firstField; i < fields; ++i) { + stack = std::max( + stack, + addFieldInit( + manager, className, + codemaker::convertString(reader.getFieldName(i)), + ((reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) + != 0), + codemaker::convertString(reader.getFieldTypeName(i)), + dependencies, code.get())); + } + if (runtimeException) { + stack = std::max( + stack, + addFieldInit( + manager, className, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Context")), false, + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/XInterface")), + dependencies, code.get())); + } + code->instrReturn(); + code->setMaxStackAndLocals(stack + 2, 2); + cf->addMethod( + ClassFile::ACC_PUBLIC, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;)V")), + code.get(), std::vector< rtl::OString >(), rtl::OString()); + } + MethodDescriptor desc( + manager, dependencies, rtl::OString(RTL_CONSTASCII_STRINGPARAM("void")), + 0, 0); + code.reset(cf->newCode()); + code->loadLocalReference(0); + sal_uInt16 index = 1; + if (typeClass == RT_TYPE_EXCEPTION) { + desc.addParameter( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("string")), false, true, 0); + code->loadLocalReference(index++); + } + if (superTypes != 0) { + addBaseArguments( + manager, dependencies, &desc, code.get(), typeClass, superClass, + &index); + } + code->instrInvokespecial( + superClass, rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + desc.getDescriptor()); + sal_uInt16 maxSize = index; + {for (sal_uInt16 i = firstField; i < fields; ++i) { + maxSize = std::max( + maxSize, + addDirectArgument( + manager, dependencies, &desc, code.get(), &index, className, + codemaker::convertString(reader.getFieldName(i)), + (reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0, + codemaker::convertString(reader.getFieldTypeName(i)))); + }} + if (runtimeException) { + maxSize = std::max( + maxSize, + addDirectArgument( + manager, dependencies, &desc, code.get(), &index, className, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Context")), false, + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/XInterface")))); + } + code->instrReturn(); + code->setMaxStackAndLocals(maxSize, index); + cf->addMethod( + ClassFile::ACC_PUBLIC, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + desc.getDescriptor(), code.get(), std::vector< rtl::OString >(), + desc.getSignature()); + addTypeInfo(className, typeInfo, dependencies, cf.get()); + writeClassFile(options, className, *cf.get()); +} + +void createExceptionsAttribute( + TypeManager const & manager, typereg::Reader const & reader, + sal_uInt16 methodIndex, Dependencies * dependencies, + std::vector< rtl::OString > * exceptions, codemaker::ExceptionTree * tree) +{ + OSL_ASSERT(dependencies != 0 && exceptions != 0); + sal_uInt16 n = reader.getMethodExceptionCount(methodIndex); + for (sal_uInt16 i = 0; i < n; ++i) { + rtl::OString type( + codemaker::convertString( + reader.getMethodExceptionTypeName(methodIndex, i))); + dependencies->insert(type); + exceptions->push_back(type); + if (tree != 0) { + tree->add(type, manager); + } + } +} + +void handleInterfaceType( + TypeManager const & manager, JavaOptions /*TODO const*/ & options, + typereg::Reader const & reader, Dependencies * dependencies) +{ + OSL_ASSERT(dependencies != 0); + + rtl::OString className(codemaker::convertString(reader.getTypeName())); + sal_uInt16 superTypes = reader.getSuperTypeCount(); + sal_uInt16 fields = reader.getFieldCount(); + sal_uInt16 methods = reader.getMethodCount(); + if (className + == rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XInterface"))) + { + if (superTypes != 0 || fields != 0 || methods != 3) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + methods = 0; + } else if (superTypes == 0) { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + std::auto_ptr< ClassFile > cf( + new ClassFile( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_INTERFACE + | ClassFile::ACC_ABSTRACT), + className, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")), + rtl::OString())); + {for (sal_uInt16 i = 0; i < superTypes; ++i) { + rtl::OString t(codemaker::convertString(reader.getSuperTypeName(i))); + dependencies->insert(t); + cf->addInterface(t); + }} + // As a special case, let com.sun.star.lang.XEventListener extend + // java.util.EventListener ("A tagging interface that all event listener + // interfaces must extend"): + if (className == + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/lang/XEventListener"))) + { + cf->addInterface( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("java/util/EventListener"))); + } + std::vector< TypeInfo > typeInfo; + sal_Int32 index = 0; + {for (sal_uInt16 i = 0; i < fields; ++i) { + RTFieldAccess flags = reader.getFieldFlags(i); + //TODO: ok if both READONLY and BOUND? + if (((((flags & RT_ACCESS_READWRITE) != 0) + ^ ((flags & RT_ACCESS_READONLY) != 0)) + == 0) + || ((flags + & ~(RT_ACCESS_READWRITE | RT_ACCESS_READONLY + | RT_ACCESS_BOUND)) + != 0) + || reader.getFieldValue(i).m_type != RT_TYPE_NONE) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + //TODO: exploit the fact that attribute getter/setter methods preceed + // real methods + rtl::OUString attrNameUtf16(reader.getFieldName(i)); + sal_uInt16 getter = SAL_MAX_UINT16; + sal_uInt16 setter = SAL_MAX_UINT16; + for (sal_uInt16 j = 0; j < methods; ++j) { + RTMethodMode mflags = reader.getMethodFlags(j); + if ((mflags == RT_MODE_ATTRIBUTE_GET + || mflags == RT_MODE_ATTRIBUTE_SET) + && reader.getMethodName(j) == attrNameUtf16) + { + if (!reader.getMethodReturnTypeName(j).equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("void")) + || reader.getMethodParameterCount(j) != 0 + || (mflags == RT_MODE_ATTRIBUTE_GET + ? getter != SAL_MAX_UINT16 + : (setter != SAL_MAX_UINT16 + || (flags & RT_ACCESS_READONLY) != 0))) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Bad type information"))); //TODO + } + OSL_ASSERT(j != SAL_MAX_UINT16); + (mflags == RT_MODE_ATTRIBUTE_GET ? getter : setter) = j; + } + } + rtl::OString fieldType( + codemaker::convertString(reader.getFieldTypeName(i))); + SpecialType specialType; + PolymorphicUnoType polymorphicUnoType; + MethodDescriptor gdesc( + manager, dependencies, fieldType, &specialType, + &polymorphicUnoType); + std::vector< rtl::OString > exc; + if (getter != SAL_MAX_UINT16) { + createExceptionsAttribute( + manager, reader, getter, dependencies, &exc, 0); + } + rtl::OString attrName(codemaker::convertString(attrNameUtf16)); + cf->addMethod( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("get")) + attrName, + gdesc.getDescriptor(), 0, exc, gdesc.getSignature()); + if ((flags & RT_ACCESS_READONLY) == 0) { + MethodDescriptor sdesc( + manager, dependencies, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("void")), 0, 0); + sdesc.addParameter(fieldType, false, true, 0); + std::vector< rtl::OString > exc2; + if (setter != SAL_MAX_UINT16) { + createExceptionsAttribute( + manager, reader, setter, dependencies, &exc2, 0); + } + cf->addMethod( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("set")) + attrName, + sdesc.getDescriptor(), 0, exc2, sdesc.getSignature()); + } + typeInfo.push_back( + TypeInfo( + TypeInfo::KIND_ATTRIBUTE, attrName, specialType, + static_cast< TypeInfo::Flags >( + ((flags & RT_ACCESS_READONLY) == 0 + ? 0 : TypeInfo::FLAG_READONLY) + | ((flags & RT_ACCESS_BOUND) == 0 + ? 0 : TypeInfo::FLAG_BOUND)), + index, polymorphicUnoType)); + index += ((flags & RT_ACCESS_READONLY) == 0 ? 2 : 1); + }} + {for (sal_uInt16 i = 0; i < methods; ++i) { + RTMethodMode flags = reader.getMethodFlags(i); + switch (flags) { + case RT_MODE_ONEWAY: + case RT_MODE_TWOWAY: + { + rtl::OString methodName( + codemaker::convertString(reader.getMethodName(i))); + SpecialType specialReturnType; + PolymorphicUnoType polymorphicUnoReturnType; + MethodDescriptor desc( + manager, dependencies, + codemaker::convertString( + reader.getMethodReturnTypeName(i)), + &specialReturnType, &polymorphicUnoReturnType); + typeInfo.push_back( + TypeInfo( + TypeInfo::KIND_METHOD, methodName, specialReturnType, + static_cast< TypeInfo::Flags >( + flags == RT_MODE_ONEWAY + ? TypeInfo::FLAG_ONEWAY : 0), + index++, polymorphicUnoReturnType)); + for (sal_uInt16 j = 0; j < reader.getMethodParameterCount(i); + ++j) + { + bool in; + bool out; + switch (reader.getMethodParameterFlags(i, j)) { + case RT_PARAM_IN: + in = true; + out = false; + break; + + case RT_PARAM_OUT: + in = false; + out = true; + break; + + case RT_PARAM_INOUT: + in = true; + out = true; + break; + + default: + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Bad type information"))); //TODO + } + PolymorphicUnoType polymorphicUnoType; + SpecialType specialType = desc.addParameter( + codemaker::convertString( + reader.getMethodParameterTypeName(i, j)), + out, true, &polymorphicUnoType); + if (out || isSpecialType(specialType) + || (polymorphicUnoType.kind + != PolymorphicUnoType::KIND_NONE)) + { + typeInfo.push_back( + TypeInfo( + codemaker::convertString( + reader.getMethodParameterName(i, j)), + specialType, in, out, methodName, j, + polymorphicUnoType)); + } + } + std::vector< rtl::OString > exc2; + createExceptionsAttribute( + manager, reader, i, dependencies, &exc2, 0); + cf->addMethod( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT), + methodName, desc.getDescriptor(), 0, exc2, + desc.getSignature()); + break; + } + + case RT_MODE_ATTRIBUTE_GET: + case RT_MODE_ATTRIBUTE_SET: + { + //TODO: exploit the fact that attribute getter/setter methods + // are ordered the same way as the attribute fields themselves + rtl::OUString methodNameUtf16(reader.getMethodName(i)); + bool found = false; + for (sal_uInt16 j = 0; j < fields; ++j) { + if (reader.getFieldName(j) == methodNameUtf16) { + found = true; + break; + } + } + if (found) { + break; + } + } + default: + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + }} + addTypeInfo(className, typeInfo, dependencies, cf.get()); + writeClassFile(options, className, *cf.get()); +} + +void handleTypedef( + TypeManager const & manager, JavaOptions /*TODO const*/ &, + typereg::Reader const & reader, Dependencies * dependencies) +{ + OSL_ASSERT(dependencies != 0); + if (reader.getSuperTypeCount() != 1 || reader.getFieldCount() != 0 + || reader.getMethodCount() != 0 || reader.getReferenceCount() != 0) + { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + RTTypeClass typeClass; + rtl::OString nucleus; + sal_Int32 rank; + std::vector< rtl::OString > args; + if (codemaker::decomposeAndResolve( + manager, codemaker::convertString(reader.getSuperTypeName(0)), + false, false, false, &typeClass, &nucleus, &rank, &args) + == codemaker::UnoType::SORT_COMPLEX) + { + switch (typeClass) { + case RT_TYPE_STRUCT: + if (!args.empty()) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + case RT_TYPE_ENUM: + case RT_TYPE_INTERFACE: + case RT_TYPE_TYPEDEF: + dependencies->insert(nucleus); + break; + + default: + OSL_ASSERT(false); + break; + } + } +} + +void addConstant( + TypeManager const & manager, typereg::Reader const & reader, + bool publishable, sal_uInt16 index, Dependencies * dependencies, + ClassFile * classFile) +{ + OSL_ASSERT(dependencies != 0 && classFile != 0); + RTFieldAccess flags = reader.getFieldFlags(index); + if (flags != RT_ACCESS_CONST + && (!publishable || flags != (RT_ACCESS_CONST | RT_ACCESS_PUBLISHED))) + { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + RTConstValue fieldValue(reader.getFieldValue(index)); + sal_uInt16 valueIndex; + RTTypeClass typeClass; + rtl::OString nucleus; + sal_Int32 rank; + std::vector< rtl::OString > args; + switch (codemaker::decomposeAndResolve( + manager, + codemaker::convertString(reader.getFieldTypeName(index)), + true, false, false, &typeClass, &nucleus, &rank, &args)) + { + case codemaker::UnoType::SORT_BOOLEAN: + if (fieldValue.m_type != RT_TYPE_BOOL) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + valueIndex = classFile->addIntegerInfo(fieldValue.m_value.aBool); + break; + + case codemaker::UnoType::SORT_BYTE: + if (fieldValue.m_type != RT_TYPE_BYTE) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + valueIndex = classFile->addIntegerInfo(fieldValue.m_value.aByte); + break; + + case codemaker::UnoType::SORT_SHORT: + if (fieldValue.m_type != RT_TYPE_INT16) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + valueIndex = classFile->addIntegerInfo(fieldValue.m_value.aShort); + break; + + case codemaker::UnoType::SORT_UNSIGNED_SHORT: + case codemaker::UnoType::SORT_CHAR: + if (fieldValue.m_type != RT_TYPE_UINT16) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + valueIndex = classFile->addIntegerInfo(fieldValue.m_value.aUShort); + break; + + case codemaker::UnoType::SORT_LONG: + if (fieldValue.m_type != RT_TYPE_INT32) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + valueIndex = classFile->addIntegerInfo(fieldValue.m_value.aLong); + break; + + case codemaker::UnoType::SORT_UNSIGNED_LONG: + if (fieldValue.m_type != RT_TYPE_UINT32) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + valueIndex = classFile->addIntegerInfo( + static_cast< sal_Int32 >(fieldValue.m_value.aULong)); + break; + + case codemaker::UnoType::SORT_HYPER: + if (fieldValue.m_type != RT_TYPE_INT64) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + valueIndex = classFile->addLongInfo(fieldValue.m_value.aHyper); + break; + + case codemaker::UnoType::SORT_UNSIGNED_HYPER: + if (fieldValue.m_type != RT_TYPE_UINT64) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + valueIndex = classFile->addLongInfo( + static_cast< sal_Int64 >(fieldValue.m_value.aUHyper)); + break; + + case codemaker::UnoType::SORT_FLOAT: + if (fieldValue.m_type != RT_TYPE_FLOAT) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + valueIndex = classFile->addFloatInfo(fieldValue.m_value.aFloat); + break; + + case codemaker::UnoType::SORT_DOUBLE: + if (fieldValue.m_type != RT_TYPE_DOUBLE) { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO + } + valueIndex = classFile->addDoubleInfo(fieldValue.m_value.aDouble); + break; + + default: + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + rtl::OString desc; + rtl::OString sig; + getFieldDescriptor( + manager, dependencies, + codemaker::convertString(reader.getFieldTypeName(index)), + &desc, &sig, 0); + classFile->addField( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC + | ClassFile::ACC_FINAL), + codemaker::convertString(reader.getFieldName(index)), + desc, valueIndex, sig); +} + +void handleConstantGroup( + TypeManager const & manager, JavaOptions /*TODO const*/ & options, + typereg::Reader const & reader, Dependencies * dependencies) +{ + OSL_ASSERT(dependencies != 0); + if (reader.getSuperTypeCount() != 0 || reader.getMethodCount() != 0 + || reader.getReferenceCount() != 0) + { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + rtl::OString className(codemaker::convertString(reader.getTypeName())); + std::auto_ptr< ClassFile > cf( + new ClassFile( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_INTERFACE + | ClassFile::ACC_ABSTRACT), + className, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")), + rtl::OString())); + sal_uInt16 fields = reader.getFieldCount(); + for (sal_uInt16 i = 0; i < fields; ++i) { + addConstant(manager, reader, false, i, dependencies, cf.get()); + } + writeClassFile(options, className, *cf.get()); +} + +void handleModule( + TypeManager const & manager, JavaOptions /*TODO const*/ & options, + typereg::Reader const & reader, Dependencies * dependencies) +{ + OSL_ASSERT(dependencies != 0); + if (reader.getSuperTypeCount() != 0 || reader.getMethodCount() != 0 + || reader.getReferenceCount() != 0) + { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + rtl::OStringBuffer buf(codemaker::convertString(reader.getTypeName())); + buf.append('/'); + rtl::OString prefix(buf.makeStringAndClear()); + sal_uInt16 fields = reader.getFieldCount(); + for (sal_uInt16 i = 0; i < fields; ++i) { + rtl::OString className( + prefix + codemaker::convertString(reader.getFieldName(i))); + std::auto_ptr< ClassFile > cf( + new ClassFile( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_INTERFACE + | ClassFile::ACC_ABSTRACT), + className, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")), + rtl::OString())); + addConstant(manager, reader, true, i, dependencies, cf.get()); + writeClassFile(options, className, *cf.get()); + } +} + +void addExceptionHandlers( + codemaker::ExceptionTreeNode const * node, + ClassFile::Code::Position start, ClassFile::Code::Position end, + ClassFile::Code::Position handler, ClassFile::Code * code) +{ + OSL_ASSERT(node != 0 && code != 0); + if (node->present) { + code->addException(start, end, handler, node->name); + } else { + for (codemaker::ExceptionTreeNode::Children::const_iterator i( + node->children.begin()); + i != node->children.end(); ++i) + { + addExceptionHandlers(*i, start, end, handler, code); + } + } +} + +void addConstructor( + TypeManager const & manager, rtl::OString const & realJavaBaseName, + rtl::OString const & unoName, rtl::OString const & className, + typereg::Reader const & reader, sal_uInt16 methodIndex, + rtl::OString const & methodName, rtl::OString const & returnType, + bool defaultConstructor, Dependencies * dependencies, ClassFile * classFile) +{ + OSL_ASSERT(dependencies != 0 && classFile != 0); + MethodDescriptor desc(manager, dependencies, returnType, 0, 0); + desc.addParameter( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XComponentContext")), + false, false, 0); + std::auto_ptr< ClassFile::Code > code(classFile->newCode()); + code->loadLocalReference(0); + // stack: context + code->instrInvokestatic( + className, rtl::OString(RTL_CONSTASCII_STRINGPARAM("$getFactory")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Lcom/sun/star/uno/XComponentContext;)" + "Lcom/sun/star/lang/XMultiComponentFactory;"))); + // stack: factory + code->loadStringConstant(unoName); + // stack: factory serviceName + codemaker::ExceptionTree tree; + ClassFile::Code::Position tryStart; + ClassFile::Code::Position tryEnd; + std::vector< rtl::OString > exc; + sal_uInt16 stack; + sal_uInt16 localIndex = 1; + ClassFile::AccessFlags access = static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC); + if (defaultConstructor) { + code->loadLocalReference(0); + // stack: factory serviceName context + tryStart = code->getPosition(); + code->instrInvokeinterface( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lang/XMultiComponentFactory")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "createInstanceWithContext")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;Lcom/sun/star/uno/XComponentContext;)" + "Ljava/lang/Object;")), + 3); + tryEnd = code->getPosition(); + // stack: instance + stack = 3; + } else { + sal_uInt16 parameters = reader.getMethodParameterCount(methodIndex); + if (parameters == 1 + && (reader.getMethodParameterFlags(methodIndex, 0) + == (RT_PARAM_IN | RT_PARAM_REST)) + && (reader.getMethodParameterTypeName(methodIndex, 0) + == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("any")))) + { + desc.addParameter( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("any")), true, true, 0); + code->loadLocalReference(localIndex++); + // stack: factory serviceName args + stack = 4; + access = static_cast< ClassFile::AccessFlags >( + access | ClassFile::ACC_VARARGS); + } else { + code->loadIntegerConstant(parameters); + // stack: factory serviceName N + code->instrAnewarray( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object"))); + // stack: factory serviceName args + stack = 0; + for (sal_uInt16 i = 0; i < parameters; ++i) { + RTParamMode flags = reader.getMethodParameterFlags( + methodIndex, i); + rtl::OString paramType( + codemaker::convertString( + reader.getMethodParameterTypeName(methodIndex, i))); + if ((flags != RT_PARAM_IN + && flags != (RT_PARAM_IN | RT_PARAM_REST)) + || ((flags & RT_PARAM_REST) != 0 + && (parameters != 1 + || (paramType + != rtl::OString( + RTL_CONSTASCII_STRINGPARAM("any")))))) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Bad type information"))); //TODO + } + desc.addParameter(paramType, false, true, 0); + code->instrDup(); + // stack: factory serviceName args args + code->loadIntegerConstant(i); + // stack: factory serviceName args args i + stack = std::max( + stack, + addLoadLocal( + manager, code.get(), &localIndex, false, paramType, + true, dependencies)); + // stack: factory serviceName args args i any + code->instrAastore(); + // stack: factory serviceName args + } + stack += 5; + } + code->loadLocalReference(0); + // stack: factory serviceName args context + tryStart = code->getPosition(); + code->instrInvokeinterface( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lang/XMultiComponentFactory")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "createInstanceWithArgumentsAndContext")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;[Ljava/lang/Object;" + "Lcom/sun/star/uno/XComponentContext;)Ljava/lang/Object;")), + 4); + tryEnd = code->getPosition(); + // stack: instance + createExceptionsAttribute( + manager, reader, methodIndex, dependencies, &exc, &tree); + } + code->loadLocalReference(0); + // stack: instance context + code->instrInvokestatic( + className, rtl::OString(RTL_CONSTASCII_STRINGPARAM("$castInstance")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/Object;Lcom/sun/star/uno/XComponentContext;)" + "Ljava/lang/Object;"))); + // stack: instance + code->instrCheckcast(returnType); + // stack: instance + code->instrAreturn(); + if (!tree.getRoot()->present) { + ClassFile::Code::Position pos1 = code->getPosition(); + // stack: e + code->instrInvokevirtual( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Throwable")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("toString")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("()Ljava/lang/String;"))); + // stack: str + localIndex = std::max< sal_uInt16 >(localIndex, 2); + code->storeLocalReference(1); + // stack: - + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/DeploymentException"))); + // stack: ex + code->instrDup(); + // stack: ex ex + rtl::OStringBuffer msg; + msg.append( + RTL_CONSTASCII_STRINGPARAM( + "component context fails to supply service ")); + msg.append(unoName); + msg.append(RTL_CONSTASCII_STRINGPARAM(" of type ")); + msg.append(realJavaBaseName); + msg.append(RTL_CONSTASCII_STRINGPARAM(": ")); + code->loadStringConstant(msg.makeStringAndClear()); + // stack: ex ex "..." + code->loadLocalReference(1); + // stack: ex ex "..." str + code->instrInvokevirtual( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/String")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("concat")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;)Ljava/lang/String;"))); + // stack: ex ex "..." + code->loadLocalReference(0); + // stack: ex ex "..." context + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/DeploymentException")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;Ljava/lang/Object;)V"))); + // stack: ex + ClassFile::Code::Position pos2 = code->getPosition(); + code->instrAthrow(); + addExceptionHandlers( + tree.getRoot(), tryStart, tryEnd, pos2, code.get()); + code->addException( + tryStart, tryEnd, pos1, + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Exception"))); + dependencies->insert( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Exception"))); + stack = std::max< sal_uInt16 >(stack, 4); + } + code->setMaxStackAndLocals(stack, localIndex); + classFile->addMethod( + access, methodName, desc.getDescriptor(), code.get(), exc, + desc.getSignature()); +} + +void handleService( + TypeManager const & manager, JavaOptions /*TODO const*/ & options, + typereg::Reader const & reader, Dependencies * dependencies) +{ + OSL_ASSERT(dependencies != 0); + sal_uInt16 superTypes = reader.getSuperTypeCount(); + sal_uInt16 methods = reader.getMethodCount(); + if (superTypes == 0 + ? methods != 0 + : (superTypes != 1 || reader.getFieldCount() != 0 + || reader.getReferenceCount() != 0)) + { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + if (superTypes == 0) { + return; + } + rtl::OString unoName(codemaker::convertString(reader.getTypeName())); + rtl::OString className( + translateUnoTypeToJavaFullyQualifiedName( + unoName, rtl::OString(RTL_CONSTASCII_STRINGPARAM("service")))); + unoName = unoName.replace('/', '.'); + std::auto_ptr< ClassFile > cf( + new ClassFile( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_FINAL + | ClassFile::ACC_SUPER), + className, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")), + rtl::OString())); + if (methods > 0) { + rtl::OString base(codemaker::convertString( + reader.getSuperTypeName(0))); + rtl::OString realJavaBaseName(base.replace('/', '.')); + dependencies->insert(base); + dependencies->insert( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/lang/XMultiComponentFactory"))); + dependencies->insert( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/DeploymentException"))); + dependencies->insert( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass"))); + dependencies->insert( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/XComponentContext"))); + for (sal_uInt16 i = 0; i < methods; ++i) { + rtl::OString name(codemaker::convertString( + reader.getMethodName(i))); + bool defaultCtor = name.getLength() == 0; + if (reader.getMethodFlags(i) != RT_MODE_TWOWAY + || (!reader.getMethodReturnTypeName(i).equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("void"))) + || (defaultCtor + && (methods != 1 || reader.getMethodParameterCount(i) != 0 + || reader.getMethodExceptionCount(i) != 0))) + { + throw CannotDumpException( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + if (defaultCtor) { + name = rtl::OString(RTL_CONSTASCII_STRINGPARAM("create")); + } else { + name = codemaker::java::translateUnoToJavaIdentifier( + name, rtl::OString(RTL_CONSTASCII_STRINGPARAM("method"))); + } + addConstructor( + manager, realJavaBaseName, unoName, className, reader, i, name, + base, defaultCtor, dependencies, cf.get()); + } + // Synthetic getFactory method: + { + std::auto_ptr< ClassFile::Code > code(cf->newCode()); + code->loadLocalReference(0); + // stack: context + code->instrInvokeinterface( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/XComponentContext")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("getServiceManager")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "()Lcom/sun/star/lang/XMultiComponentFactory;")), + 1); + // stack: factory + code->instrDup(); + // stack: factory factory + ClassFile::Code::Branch branch = code->instrIfnull(); + // stack: factory + code->instrAreturn(); + code->branchHere(branch); + code->instrPop(); + // stack: - + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/DeploymentException"))); + // stack: ex + code->instrDup(); + // stack: ex ex + code->loadStringConstant( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "component context fails to supply service manager"))); + // stack: ex ex "..." + code->loadLocalReference(0); + // stack: ex ex "..." context + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/DeploymentException")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;Ljava/lang/Object;)V"))); + // stack: ex + code->instrAthrow(); + code->setMaxStackAndLocals(4, 1); + cf->addMethod( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC + | ClassFile::ACC_SYNTHETIC), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("$getFactory")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Lcom/sun/star/uno/XComponentContext;)" + "Lcom/sun/star/lang/XMultiComponentFactory;")), + code.get(), std::vector< rtl::OString >(), rtl::OString()); + } + // Synthetic castInstance method: + { + std::auto_ptr< ClassFile::Code > code(cf->newCode()); + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type"))); + // stack: type + code->instrDup(); + // stack: type type + code->loadStringConstant(realJavaBaseName); + // stack: type type "..." + code->instrGetstatic( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("INTERFACE")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "Lcom/sun/star/uno/TypeClass;"))); + // stack: type type "..." INTERFACE + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V"))); + // stack: type + code->loadLocalReference(0); + // stack: type instance + code->instrInvokestatic( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/UnoRuntime")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("queryInterface")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)" + "Ljava/lang/Object;"))); + // stack: instance + code->instrDup(); + // stack: instance instance + ClassFile::Code::Branch branch = code->instrIfnull(); + // stack: instance + code->instrAreturn(); + code->branchHere(branch); + code->instrPop(); + // stack: - + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/DeploymentException"))); + // stack: ex + code->instrDup(); + // stack: ex ex + rtl::OStringBuffer msg; + msg.append( + RTL_CONSTASCII_STRINGPARAM( + "component context fails to supply service ")); + msg.append(unoName); + msg.append(RTL_CONSTASCII_STRINGPARAM(" of type ")); + msg.append(realJavaBaseName); + code->loadStringConstant(msg.makeStringAndClear()); + // stack: ex ex "..." + code->loadLocalReference(1); + // stack: ex ex "..." context + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/DeploymentException")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;Ljava/lang/Object;)V"))); + // stack: ex + code->instrAthrow(); + code->setMaxStackAndLocals(4, 2); + cf->addMethod( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC + | ClassFile::ACC_SYNTHETIC), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("$castInstance")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/Object;Lcom/sun/star/uno/" + "XComponentContext;)Ljava/lang/Object;")), + code.get(), std::vector< rtl::OString >(), rtl::OString()); + } + } + writeClassFile(options, className, *cf.get()); +} + +void handleSingleton( + TypeManager const & manager, JavaOptions /*TODO const*/ & options, + typereg::Reader const & reader, Dependencies * dependencies) +{ + OSL_ASSERT(dependencies != 0); + if (reader.getSuperTypeCount() != 1 || reader.getFieldCount() != 0 + || reader.getMethodCount() != 0 || reader.getReferenceCount() != 0) + { + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + rtl::OString base(codemaker::convertString(reader.getSuperTypeName(0))); + rtl::OString realJavaBaseName(base.replace('/', '.')); + switch (manager.getTypeReader(base).getTypeClass()) { + case RT_TYPE_INTERFACE: + break; + + case RT_TYPE_SERVICE: + return; + + default: + throw CannotDumpException( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); + //TODO + } + dependencies->insert(base); + rtl::OString unoName(codemaker::convertString(reader.getTypeName())); + rtl::OString className( + translateUnoTypeToJavaFullyQualifiedName( + unoName, rtl::OString(RTL_CONSTASCII_STRINGPARAM("singleton")))); + unoName = unoName.replace('/', '.'); + dependencies->insert( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/DeploymentException"))); + dependencies->insert( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass"))); + dependencies->insert( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XComponentContext"))); + std::auto_ptr< ClassFile > cf( + new ClassFile( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_FINAL + | ClassFile::ACC_SUPER), + className, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")), + rtl::OString())); + MethodDescriptor desc(manager, dependencies, base, 0, 0); + desc.addParameter( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XComponentContext")), + false, false, 0); + std::auto_ptr< ClassFile::Code > code(cf->newCode()); + code->loadLocalReference(0); + // stack: context + code->loadStringConstant( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("/singletons/")) + unoName); + // stack: context "..." + code->instrInvokeinterface( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XComponentContext")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("getValueByName")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;)Ljava/lang/Object;")), + 2); + // stack: value + code->instrDup(); + // stack: value value + code->instrInstanceof( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any"))); + // stack: value 0/1 + ClassFile::Code::Branch branch1 = code->instrIfeq(); + // stack: value + code->instrCheckcast( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any"))); + // stack: value + code->instrDup(); + // stack: value value + code->instrInvokevirtual( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("getType")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("()Lcom/sun/star/uno/Type;"))); + // stack: value type + code->instrInvokevirtual( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("getTypeClass")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("()Lcom/sun/star/uno/TypeClass;"))); + // stack: value typeClass + code->instrGetstatic( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("INTERFACE")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/TypeClass;"))); + // stack: value typeClass INTERFACE + ClassFile::Code::Branch branch2 = code->instrIfAcmpne(); + // stack: value + code->instrInvokevirtual( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("getObject")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("()Ljava/lang/Object;"))); + // stack: value + code->branchHere(branch1); + code->instrNew( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type"))); + // stack: value type + code->instrDup(); + // stack: value type type + code->loadStringConstant(realJavaBaseName); + // stack: value type type "..." + code->instrGetstatic( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("INTERFACE")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/TypeClass;"))); + // stack: value type type "..." INTERFACE + code->instrInvokespecial( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V"))); + // stack: value type + code->instrSwap(); + // stack: type value + code->instrInvokestatic( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/UnoRuntime")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("queryInterface")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)" + "Ljava/lang/Object;"))); + // stack: instance + code->instrDup(); + // stack: instance instance + ClassFile::Code::Branch branch3 = code->instrIfnull(); + // stack: instance + code->instrCheckcast(base); + // stack: instance + code->instrAreturn(); + code->branchHere(branch2); + code->branchHere(branch3); + code->instrPop(); + // stack: - + code->instrNew( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "com/sun/star/uno/DeploymentException"))); + // stack: ex + code->instrDup(); + // stack: ex ex + rtl::OStringBuffer msg; + msg.append( + RTL_CONSTASCII_STRINGPARAM( + "component context fails to supply singleton ")); + msg.append(unoName); + msg.append(RTL_CONSTASCII_STRINGPARAM(" of type ")); + msg.append(realJavaBaseName); + code->loadStringConstant(msg.makeStringAndClear()); + // stack: ex ex "..." + code->loadLocalReference(0); + // stack: ex ex "..." context + code->instrInvokespecial( + rtl::OString( + RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/DeploymentException")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")), + rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "(Ljava/lang/String;Ljava/lang/Object;)V"))); + // stack: ex + code->instrAthrow(); + code->setMaxStackAndLocals(5, 1); + cf->addMethod( + static_cast< ClassFile::AccessFlags >( + ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("get")), desc.getDescriptor(), + code.get(), std::vector< rtl::OString >(), desc.getSignature()); + writeClassFile(options, className, *cf.get()); +} + +} + +bool produceType( + rtl::OString const & type, TypeManager const & manager, + codemaker::GeneratedTypeSet & generated, JavaOptions * options) +{ + OSL_ASSERT(options != 0); + if (type.equals("/") + || type.equals(manager.getBase()) + || generated.contains(type)) + { + return true; + } + sal_Bool extra = sal_False; + typereg::Reader reader(manager.getTypeReader(type, &extra)); + if (extra) { + generated.add(type); + return true; + } + if (!reader.isValid()) { + return false; + } + + handleUnoTypeRegistryEntityFunction handler; + switch (reader.getTypeClass()) { + case RT_TYPE_ENUM: + handler = handleEnumType; + break; + + case RT_TYPE_STRUCT: + case RT_TYPE_EXCEPTION: + handler = handleAggregatingType; + break; + + case RT_TYPE_INTERFACE: + handler = handleInterfaceType; + break; + + case RT_TYPE_TYPEDEF: + handler = handleTypedef; + break; + + case RT_TYPE_CONSTANTS: + handler = handleConstantGroup; + break; + + case RT_TYPE_MODULE: + handler = handleModule; + break; + + case RT_TYPE_SERVICE: + handler = handleService; + break; + + case RT_TYPE_SINGLETON: + handler = handleSingleton; + break; + + default: + return false; + } + Dependencies deps; + handler(manager, *options, reader, &deps); + generated.add(type); + if (!options->isValid(rtl::OString(RTL_CONSTASCII_STRINGPARAM("-nD")))) { + for (Dependencies::iterator i(deps.begin()); i != deps.end(); ++i) { + if (!produceType(*i, manager, generated, options)) { + return false; + } + } + } + return true; +} + +bool produceType( + RegistryKey & rTypeKey, bool bIsExtraType, TypeManager const & manager, + codemaker::GeneratedTypeSet & generated, JavaOptions * options) +{ + ::rtl::OString typeName = manager.getTypeName(rTypeKey); + + OSL_ASSERT(options != 0); + if (typeName.equals("/") + || typeName.equals(manager.getBase()) + || generated.contains(typeName)) + { + return true; + } + typereg::Reader reader(manager.getTypeReader(rTypeKey)); + if (bIsExtraType) { + generated.add(typeName); + return true; + } + if (!reader.isValid()) { + return false; + } + handleUnoTypeRegistryEntityFunction handler; + switch (reader.getTypeClass()) { + case RT_TYPE_ENUM: + handler = handleEnumType; + break; + + case RT_TYPE_STRUCT: + case RT_TYPE_EXCEPTION: + handler = handleAggregatingType; + break; + + case RT_TYPE_INTERFACE: + handler = handleInterfaceType; + break; + + case RT_TYPE_TYPEDEF: + handler = handleTypedef; + break; + + case RT_TYPE_CONSTANTS: + handler = handleConstantGroup; + break; + + case RT_TYPE_MODULE: + handler = handleModule; + break; + + case RT_TYPE_SERVICE: + handler = handleService; + break; + + case RT_TYPE_SINGLETON: + handler = handleSingleton; + break; + + default: + return false; + } + Dependencies deps; + handler(manager, *options, reader, &deps); + generated.add(typeName); + if (!options->isValid(rtl::OString(RTL_CONSTASCII_STRINGPARAM("-nD")))) { + for (Dependencies::iterator i(deps.begin()); i != deps.end(); ++i) { + if (!produceType(*i, manager, generated, options)) { + return false; + } + } + } + return true; +} diff --git a/codemaker/source/javamaker/javatype.hxx b/codemaker/source/javamaker/javatype.hxx new file mode 100644 index 000000000000..fd08ee286fb6 --- /dev/null +++ b/codemaker/source/javamaker/javatype.hxx @@ -0,0 +1,45 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_JAVATYPE_HXX +#define INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_JAVATYPE_HXX + +namespace codemaker { class GeneratedTypeSet; } +namespace rtl { class OString; } +class JavaOptions; +class TypeManager; +class RegistryKey; + +bool produceType( + rtl::OString const & type, TypeManager const & manager, + codemaker::GeneratedTypeSet & generated, JavaOptions * pOptions); + +bool produceType(RegistryKey& typeName, bool bIsExtraType, TypeManager const & typeMgr, + codemaker::GeneratedTypeSet & generated, + JavaOptions* pOptions); + +#endif // INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_JAVATYPE_HXX diff --git a/codemaker/source/javamaker/makefile.mk b/codemaker/source/javamaker/makefile.mk new file mode 100644 index 000000000000..297f35bd0329 --- /dev/null +++ b/codemaker/source/javamaker/makefile.mk @@ -0,0 +1,58 @@ +#************************************************************************* +# +# 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=javamaker +TARGETTYPE=CUI +LIBTARGET=NO + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/codemaker.pmk + +# --- Files -------------------------------------------------------- + +OBJFILES = \ + $(OBJ)$/classfile.obj \ + $(OBJ)$/javamaker.obj \ + $(OBJ)$/javaoptions.obj \ + $(OBJ)$/javatype.obj + +APP1TARGET= $(TARGET) +APP1RPATH=SDK +APP1OBJS = $(OBJFILES) + +APP1DEPN= $(OUT)$/lib$/$(CODEMAKERLIBDEPN) $(OUT)$/lib$/$(COMMONJAVALIBDEPN) +APP1STDLIBS= $(SALLIB) $(SALHELPERLIB) $(REGLIB) $(CODEMAKERLIBST) $(COMMONJAVALIBST) + +.INCLUDE : target.mk + diff --git a/codemaker/test/cppumaker/makefile.mk b/codemaker/test/cppumaker/makefile.mk new file mode 100644 index 000000000000..964ae166cdf5 --- /dev/null +++ b/codemaker/test/cppumaker/makefile.mk @@ -0,0 +1,73 @@ +#************************************************************************* +# +# 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 := test_codemaker_cppumaker + +ENABLE_EXCEPTIONS := TRUE + +.INCLUDE: settings.mk + +CFLAGSCXX += $(CPPUNIT_CFLAGS) + +DLLPRE = # no leading "lib" on .so files + +INCPRE += $(MISC)$/$(TARGET)$/inc + +SHL1TARGET = $(TARGET) +SHL1OBJS = $(SLO)$/test_codemaker_cppumaker.obj +SHL1STDLIBS = $(CPPULIB) $(CPPUNITLIB) $(SALLIB) $(TESTSHL2LIB) +SHL1VERSIONMAP = version.map +SHL1IMPLIB = i$(SHL1TARGET) +DEF1NAME = $(SHL1TARGET) + +SLOFILES = $(SHL1OBJS) + +.INCLUDE: target.mk + +ALLTAR: test + +$(SHL1OBJS): $(MISC)$/$(TARGET).cppumaker.flag + +$(MISC)$/$(TARGET).cppumaker.flag: $(BIN)$/cppumaker$(EXECPOST) +$(MISC)$/$(TARGET).cppumaker.flag: $(MISC)$/$(TARGET).rdb + - $(MKDIRHIER) $(MISC)$/$(TARGET)$/inc + $(AUGMENT_LIBRARY_PATH) $(BIN)$/cppumaker$(EXECPOST) \ + -O$(MISC)$/$(TARGET)$/inc -BUCR -C $< $(SOLARBINDIR)$/udkapi.rdb + $(TOUCH) $@ + +$(MISC)$/$(TARGET).rdb: $(MISC)$/$(TARGET)$/types.urd + - rm $@ + $(REGMERGE) $@ /UCR $< + +$(MISC)$/$(TARGET)$/types.urd: types.idl + - $(MKDIR) $(MISC)$/$(TARGET) + $(IDLC) -O$(MISC)$/$(TARGET) -I$(SOLARIDLDIR) -cid -we $< + +test .PHONY: $(SHL1TARGETN) + $(AUGMENT_LIBRARY_PATH) testshl2 $< diff --git a/codemaker/test/cppumaker/test_codemaker_cppumaker.cxx b/codemaker/test/cppumaker/test_codemaker_cppumaker.cxx new file mode 100644 index 000000000000..38ea5bb50444 --- /dev/null +++ b/codemaker/test/cppumaker/test_codemaker_cppumaker.cxx @@ -0,0 +1,567 @@ +/************************************************************************* + * + * 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 "FILE.hpp" +#include "lconv.hpp" +#include "tm.hpp" +#include "std.hpp" +#include "test/codemaker/cppumaker/XTest.hpp" +#include "test/codemaker/cppumaker/S1.hpp" +#include "test/codemaker/cppumaker/services/asm.hpp" +#include "test/codemaker/cppumaker/services/auto.hpp" +#include "test/codemaker/cppumaker/services/bool.hpp" +#include "test/codemaker/cppumaker/services/break.hpp" +//TODO: #include "test/codemaker/cppumaker/services/case.hpp" +#include "test/codemaker/cppumaker/services/catch.hpp" +//TODO: #include "test/codemaker/cppumaker/services/char.hpp" +#include "test/codemaker/cppumaker/services/class.hpp" +//TODO: #include "test/codemaker/cppumaker/services/const.hpp" +#include "test/codemaker/cppumaker/services/continue.hpp" +//TODO: #include "test/codemaker/cppumaker/services/default.hpp" +#include "test/codemaker/cppumaker/services/delete.hpp" +#include "test/codemaker/cppumaker/services/do.hpp" +//TODO: #include "test/codemaker/cppumaker/services/double.hpp" +#include "test/codemaker/cppumaker/services/else.hpp" +//TODO: #include "test/codemaker/cppumaker/services/enum.hpp" +#include "test/codemaker/cppumaker/services/explicit.hpp" +#include "test/codemaker/cppumaker/services/export.hpp" +#include "test/codemaker/cppumaker/services/extern.hpp" +#include "test/codemaker/cppumaker/services/false.hpp" +//TODO: #include "test/codemaker/cppumaker/services/float.hpp" +#include "test/codemaker/cppumaker/services/for.hpp" +#include "test/codemaker/cppumaker/services/friend.hpp" +#include "test/codemaker/cppumaker/services/goto.hpp" +#include "test/codemaker/cppumaker/services/if.hpp" +#include "test/codemaker/cppumaker/services/inline.hpp" +#include "test/codemaker/cppumaker/services/int.hpp" +//TODO: #include "test/codemaker/cppumaker/services/long.hpp" +#include "test/codemaker/cppumaker/services/mutable.hpp" +#include "test/codemaker/cppumaker/services/namespace.hpp" +#include "test/codemaker/cppumaker/services/new.hpp" +#include "test/codemaker/cppumaker/services/operator.hpp" +#include "test/codemaker/cppumaker/services/private.hpp" +#include "test/codemaker/cppumaker/services/protected.hpp" +#include "test/codemaker/cppumaker/services/public.hpp" +#include "test/codemaker/cppumaker/services/register.hpp" +#include "test/codemaker/cppumaker/services/return.hpp" +//TODO: #include "test/codemaker/cppumaker/services/short.hpp" +#include "test/codemaker/cppumaker/services/signed.hpp" +#include "test/codemaker/cppumaker/services/sizeof.hpp" +#include "test/codemaker/cppumaker/services/static.hpp" +//TODO: #include "test/codemaker/cppumaker/services/struct.hpp" +//TODO: #include "test/codemaker/cppumaker/services/switch.hpp" +#include "test/codemaker/cppumaker/services/template.hpp" +#include "test/codemaker/cppumaker/services/this.hpp" +#include "test/codemaker/cppumaker/services/throw.hpp" +#include "test/codemaker/cppumaker/services/true.hpp" +#include "test/codemaker/cppumaker/services/try.hpp" +//TODO: #include "test/codemaker/cppumaker/services/typedef.hpp" +#include "test/codemaker/cppumaker/services/typeid.hpp" +#include "test/codemaker/cppumaker/services/typename.hpp" +//TODO: #include "test/codemaker/cppumaker/services/union.hpp" +//TODO: #include "test/codemaker/cppumaker/services/unsigned.hpp" +#include "test/codemaker/cppumaker/services/using.hpp" +#include "test/codemaker/cppumaker/services/virtual.hpp" +//TODO: #include "test/codemaker/cppumaker/services/void.hpp" +#include "test/codemaker/cppumaker/services/volatile.hpp" +#include "test/codemaker/cppumaker/services/while.hpp" +#include "test/codemaker/cppumaker/services/and.hpp" +#include "test/codemaker/cppumaker/services/bitand.hpp" +#include "test/codemaker/cppumaker/services/bitor.hpp" +#include "test/codemaker/cppumaker/services/compl.hpp" +#include "test/codemaker/cppumaker/services/not.hpp" +#include "test/codemaker/cppumaker/services/or.hpp" +#include "test/codemaker/cppumaker/services/xor.hpp" +#include "test/codemaker/cppumaker/services/BUFSIZ.hpp" +#include "test/codemaker/cppumaker/services/CLOCKS_PER_SEC.hpp" +#include "test/codemaker/cppumaker/services/EDOM.hpp" +#include "test/codemaker/cppumaker/services/EOF.hpp" +#include "test/codemaker/cppumaker/services/ERANGE.hpp" +#include "test/codemaker/cppumaker/services/EXIT_FAILURE.hpp" +#include "test/codemaker/cppumaker/services/EXIT_SUCCESS.hpp" +#include "test/codemaker/cppumaker/services/FILENAME_MAX.hpp" +#include "test/codemaker/cppumaker/services/FOPEN_MAX.hpp" +#include "test/codemaker/cppumaker/services/HUGE_VAL.hpp" +#include "test/codemaker/cppumaker/services/LC_ALL.hpp" +#include "test/codemaker/cppumaker/services/LC_COLLATE.hpp" +#include "test/codemaker/cppumaker/services/LC_CTYPE.hpp" +#include "test/codemaker/cppumaker/services/LC_MONETARY.hpp" +#include "test/codemaker/cppumaker/services/LC_NUMERIC.hpp" +#include "test/codemaker/cppumaker/services/LC_TIME.hpp" +#include "test/codemaker/cppumaker/services/L_tmpnam.hpp" +#include "test/codemaker/cppumaker/services/MB_CUR_MAX.hpp" +#include "test/codemaker/cppumaker/services/NULL.hpp" +#include "test/codemaker/cppumaker/services/RAND_MAX.hpp" +#include "test/codemaker/cppumaker/services/SEEK_CUR.hpp" +#include "test/codemaker/cppumaker/services/SEEK_END.hpp" +#include "test/codemaker/cppumaker/services/SEEK_SET.hpp" +#include "test/codemaker/cppumaker/services/SIGABRT.hpp" +#include "test/codemaker/cppumaker/services/SIGFPE.hpp" +#include "test/codemaker/cppumaker/services/SIGILL.hpp" +#include "test/codemaker/cppumaker/services/SIGINT.hpp" +#include "test/codemaker/cppumaker/services/SIGSEGV.hpp" +#include "test/codemaker/cppumaker/services/SIGTERM.hpp" +#include "test/codemaker/cppumaker/services/SIG_DFL.hpp" +#include "test/codemaker/cppumaker/services/SIG_ERR.hpp" +#include "test/codemaker/cppumaker/services/SIG_IGN.hpp" +#include "test/codemaker/cppumaker/services/TMP_MAX.hpp" +#include "test/codemaker/cppumaker/services/WCHAR_MAX.hpp" +#include "test/codemaker/cppumaker/services/WCHAR_MIN.hpp" +#include "test/codemaker/cppumaker/services/WEOF.hpp" +#include "test/codemaker/cppumaker/services/assert.hpp" +#include "test/codemaker/cppumaker/services/errno.hpp" +#include "test/codemaker/cppumaker/services/offsetof.hpp" +#include "test/codemaker/cppumaker/services/setjmp.hpp" +#include "test/codemaker/cppumaker/services/stderr.hpp" +#include "test/codemaker/cppumaker/services/stdin.hpp" +#include "test/codemaker/cppumaker/services/stdout.hpp" +#include "test/codemaker/cppumaker/services/CHAR_BIT.hpp" +#include "test/codemaker/cppumaker/services/CHAR_MAX.hpp" +#include "test/codemaker/cppumaker/services/CHAR_MIN.hpp" +#include "test/codemaker/cppumaker/services/DBL_DIG.hpp" +#include "test/codemaker/cppumaker/services/DBL_EPSILON.hpp" +#include "test/codemaker/cppumaker/services/DBL_MANT_DIG.hpp" +#include "test/codemaker/cppumaker/services/DBL_MAX.hpp" +#include "test/codemaker/cppumaker/services/DBL_MAX_10_EXP.hpp" +#include "test/codemaker/cppumaker/services/DBL_MAX_EXP.hpp" +#include "test/codemaker/cppumaker/services/DBL_MIN.hpp" +#include "test/codemaker/cppumaker/services/DBL_MIN_10_EXP.hpp" +#include "test/codemaker/cppumaker/services/DBL_MIN_EXP.hpp" +#include "test/codemaker/cppumaker/services/FLT_DIG.hpp" +#include "test/codemaker/cppumaker/services/FLT_EPSILON.hpp" +#include "test/codemaker/cppumaker/services/FLT_MANT_DIG.hpp" +#include "test/codemaker/cppumaker/services/FLT_MAX.hpp" +#include "test/codemaker/cppumaker/services/FLT_MAX_10_EXP.hpp" +#include "test/codemaker/cppumaker/services/FLT_MAX_EXP.hpp" +#include "test/codemaker/cppumaker/services/FLT_MIN.hpp" +#include "test/codemaker/cppumaker/services/FLT_MIN_10_EXP.hpp" +#include "test/codemaker/cppumaker/services/FLT_MIN_EXP.hpp" +#include "test/codemaker/cppumaker/services/FLT_RADIX.hpp" +#include "test/codemaker/cppumaker/services/FLT_ROUNDS.hpp" +#include "test/codemaker/cppumaker/services/INT_MAX.hpp" +#include "test/codemaker/cppumaker/services/INT_MIN.hpp" +#include "test/codemaker/cppumaker/services/LDBL_DIG.hpp" +#include "test/codemaker/cppumaker/services/LDBL_EPSILON.hpp" +#include "test/codemaker/cppumaker/services/LDBL_MANT_DIG.hpp" +#include "test/codemaker/cppumaker/services/LDBL_MAX.hpp" +#include "test/codemaker/cppumaker/services/LDBL_MAX_10_EXP.hpp" +#include "test/codemaker/cppumaker/services/LDBL_MAX_EXP.hpp" +#include "test/codemaker/cppumaker/services/LDBL_MIN.hpp" +#include "test/codemaker/cppumaker/services/LDBL_MIN_10_EXP.hpp" +#include "test/codemaker/cppumaker/services/LDBL_MIN_EXP.hpp" +#include "test/codemaker/cppumaker/services/LONG_MAX.hpp" +#include "test/codemaker/cppumaker/services/LONG_MIN.hpp" +#include "test/codemaker/cppumaker/services/MB_LEN_MAX.hpp" +#include "test/codemaker/cppumaker/services/SCHAR_MAX.hpp" +#include "test/codemaker/cppumaker/services/SCHAR_MIN.hpp" +#include "test/codemaker/cppumaker/services/SHRT_MAX.hpp" +#include "test/codemaker/cppumaker/services/SHRT_MIN.hpp" +#include "test/codemaker/cppumaker/services/UCHAR_MAX.hpp" +#include "test/codemaker/cppumaker/services/UINT_MAX.hpp" +#include "test/codemaker/cppumaker/services/ULONG_MAX.hpp" +#include "test/codemaker/cppumaker/services/USHRT_MAX.hpp" +#include "test/codemaker/cppumaker/services/FILE.hpp" +#include "test/codemaker/cppumaker/services/lconv.hpp" +#include "test/codemaker/cppumaker/services/tm.hpp" +#include "test/codemaker/cppumaker/services/std.hpp" +#include "test/codemaker/cppumaker/services/NDEBUG.hpp" +#include "test/codemaker/cppumaker/services/create.hpp" +#include "test/codemaker/cppumaker/singletons/asm.hpp" +#include "test/codemaker/cppumaker/singletons/auto.hpp" +#include "test/codemaker/cppumaker/singletons/bool.hpp" +#include "test/codemaker/cppumaker/singletons/break.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/case.hpp" +#include "test/codemaker/cppumaker/singletons/catch.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/char.hpp" +#include "test/codemaker/cppumaker/singletons/class.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/const.hpp" +#include "test/codemaker/cppumaker/singletons/continue.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/default.hpp" +#include "test/codemaker/cppumaker/singletons/delete.hpp" +#include "test/codemaker/cppumaker/singletons/do.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/double.hpp" +#include "test/codemaker/cppumaker/singletons/else.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/enum.hpp" +#include "test/codemaker/cppumaker/singletons/explicit.hpp" +#include "test/codemaker/cppumaker/singletons/export.hpp" +#include "test/codemaker/cppumaker/singletons/extern.hpp" +#include "test/codemaker/cppumaker/singletons/false.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/float.hpp" +#include "test/codemaker/cppumaker/singletons/for.hpp" +#include "test/codemaker/cppumaker/singletons/friend.hpp" +#include "test/codemaker/cppumaker/singletons/goto.hpp" +#include "test/codemaker/cppumaker/singletons/if.hpp" +#include "test/codemaker/cppumaker/singletons/inline.hpp" +#include "test/codemaker/cppumaker/singletons/int.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/long.hpp" +#include "test/codemaker/cppumaker/singletons/mutable.hpp" +#include "test/codemaker/cppumaker/singletons/namespace.hpp" +#include "test/codemaker/cppumaker/singletons/new.hpp" +#include "test/codemaker/cppumaker/singletons/operator.hpp" +#include "test/codemaker/cppumaker/singletons/private.hpp" +#include "test/codemaker/cppumaker/singletons/protected.hpp" +#include "test/codemaker/cppumaker/singletons/public.hpp" +#include "test/codemaker/cppumaker/singletons/register.hpp" +#include "test/codemaker/cppumaker/singletons/return.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/short.hpp" +#include "test/codemaker/cppumaker/singletons/signed.hpp" +#include "test/codemaker/cppumaker/singletons/sizeof.hpp" +#include "test/codemaker/cppumaker/singletons/static.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/struct.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/switch.hpp" +#include "test/codemaker/cppumaker/singletons/template.hpp" +#include "test/codemaker/cppumaker/singletons/this.hpp" +#include "test/codemaker/cppumaker/singletons/throw.hpp" +#include "test/codemaker/cppumaker/singletons/true.hpp" +#include "test/codemaker/cppumaker/singletons/try.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/typedef.hpp" +#include "test/codemaker/cppumaker/singletons/typeid.hpp" +#include "test/codemaker/cppumaker/singletons/typename.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/union.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/unsigned.hpp" +#include "test/codemaker/cppumaker/singletons/using.hpp" +#include "test/codemaker/cppumaker/singletons/virtual.hpp" +//TODO: #include "test/codemaker/cppumaker/singletons/void.hpp" +#include "test/codemaker/cppumaker/singletons/volatile.hpp" +#include "test/codemaker/cppumaker/singletons/while.hpp" +#include "test/codemaker/cppumaker/singletons/and.hpp" +#include "test/codemaker/cppumaker/singletons/bitand.hpp" +#include "test/codemaker/cppumaker/singletons/bitor.hpp" +#include "test/codemaker/cppumaker/singletons/compl.hpp" +#include "test/codemaker/cppumaker/singletons/not.hpp" +#include "test/codemaker/cppumaker/singletons/or.hpp" +#include "test/codemaker/cppumaker/singletons/xor.hpp" +#include "test/codemaker/cppumaker/singletons/BUFSIZ.hpp" +#include "test/codemaker/cppumaker/singletons/CLOCKS_PER_SEC.hpp" +#include "test/codemaker/cppumaker/singletons/EDOM.hpp" +#include "test/codemaker/cppumaker/singletons/EOF.hpp" +#include "test/codemaker/cppumaker/singletons/ERANGE.hpp" +#include "test/codemaker/cppumaker/singletons/EXIT_FAILURE.hpp" +#include "test/codemaker/cppumaker/singletons/EXIT_SUCCESS.hpp" +#include "test/codemaker/cppumaker/singletons/FILENAME_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/FOPEN_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/HUGE_VAL.hpp" +#include "test/codemaker/cppumaker/singletons/LC_ALL.hpp" +#include "test/codemaker/cppumaker/singletons/LC_COLLATE.hpp" +#include "test/codemaker/cppumaker/singletons/LC_CTYPE.hpp" +#include "test/codemaker/cppumaker/singletons/LC_MONETARY.hpp" +#include "test/codemaker/cppumaker/singletons/LC_NUMERIC.hpp" +#include "test/codemaker/cppumaker/singletons/LC_TIME.hpp" +#include "test/codemaker/cppumaker/singletons/L_tmpnam.hpp" +#include "test/codemaker/cppumaker/singletons/MB_CUR_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/NULL.hpp" +#include "test/codemaker/cppumaker/singletons/RAND_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/SEEK_CUR.hpp" +#include "test/codemaker/cppumaker/singletons/SEEK_END.hpp" +#include "test/codemaker/cppumaker/singletons/SEEK_SET.hpp" +#include "test/codemaker/cppumaker/singletons/SIGABRT.hpp" +#include "test/codemaker/cppumaker/singletons/SIGFPE.hpp" +#include "test/codemaker/cppumaker/singletons/SIGILL.hpp" +#include "test/codemaker/cppumaker/singletons/SIGINT.hpp" +#include "test/codemaker/cppumaker/singletons/SIGSEGV.hpp" +#include "test/codemaker/cppumaker/singletons/SIGTERM.hpp" +#include "test/codemaker/cppumaker/singletons/SIG_DFL.hpp" +#include "test/codemaker/cppumaker/singletons/SIG_ERR.hpp" +#include "test/codemaker/cppumaker/singletons/SIG_IGN.hpp" +#include "test/codemaker/cppumaker/singletons/TMP_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/WCHAR_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/WCHAR_MIN.hpp" +#include "test/codemaker/cppumaker/singletons/WEOF.hpp" +#include "test/codemaker/cppumaker/singletons/assert.hpp" +#include "test/codemaker/cppumaker/singletons/errno.hpp" +#include "test/codemaker/cppumaker/singletons/offsetof.hpp" +#include "test/codemaker/cppumaker/singletons/setjmp.hpp" +#include "test/codemaker/cppumaker/singletons/stderr.hpp" +#include "test/codemaker/cppumaker/singletons/stdin.hpp" +#include "test/codemaker/cppumaker/singletons/stdout.hpp" +#include "test/codemaker/cppumaker/singletons/CHAR_BIT.hpp" +#include "test/codemaker/cppumaker/singletons/CHAR_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/CHAR_MIN.hpp" +#include "test/codemaker/cppumaker/singletons/DBL_DIG.hpp" +#include "test/codemaker/cppumaker/singletons/DBL_EPSILON.hpp" +#include "test/codemaker/cppumaker/singletons/DBL_MANT_DIG.hpp" +#include "test/codemaker/cppumaker/singletons/DBL_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/DBL_MAX_10_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/DBL_MAX_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/DBL_MIN.hpp" +#include "test/codemaker/cppumaker/singletons/DBL_MIN_10_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/DBL_MIN_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/FLT_DIG.hpp" +#include "test/codemaker/cppumaker/singletons/FLT_EPSILON.hpp" +#include "test/codemaker/cppumaker/singletons/FLT_MANT_DIG.hpp" +#include "test/codemaker/cppumaker/singletons/FLT_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/FLT_MAX_10_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/FLT_MAX_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/FLT_MIN.hpp" +#include "test/codemaker/cppumaker/singletons/FLT_MIN_10_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/FLT_MIN_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/FLT_RADIX.hpp" +#include "test/codemaker/cppumaker/singletons/FLT_ROUNDS.hpp" +#include "test/codemaker/cppumaker/singletons/INT_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/INT_MIN.hpp" +#include "test/codemaker/cppumaker/singletons/LDBL_DIG.hpp" +#include "test/codemaker/cppumaker/singletons/LDBL_EPSILON.hpp" +#include "test/codemaker/cppumaker/singletons/LDBL_MANT_DIG.hpp" +#include "test/codemaker/cppumaker/singletons/LDBL_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/LDBL_MAX_10_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/LDBL_MAX_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/LDBL_MIN.hpp" +#include "test/codemaker/cppumaker/singletons/LDBL_MIN_10_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/LDBL_MIN_EXP.hpp" +#include "test/codemaker/cppumaker/singletons/LONG_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/LONG_MIN.hpp" +#include "test/codemaker/cppumaker/singletons/MB_LEN_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/SCHAR_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/SCHAR_MIN.hpp" +#include "test/codemaker/cppumaker/singletons/SHRT_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/SHRT_MIN.hpp" +#include "test/codemaker/cppumaker/singletons/UCHAR_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/UINT_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/ULONG_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/USHRT_MAX.hpp" +#include "test/codemaker/cppumaker/singletons/FILE.hpp" +#include "test/codemaker/cppumaker/singletons/lconv.hpp" +#include "test/codemaker/cppumaker/singletons/tm.hpp" +#include "test/codemaker/cppumaker/singletons/std.hpp" +#include "test/codemaker/cppumaker/singletons/NDEBUG.hpp" +#include "test/codemaker/cppumaker/singletons/get.hpp" +#include "test/codemaker/cppumaker/HelperEnum.hpp" +#include "test/codemaker/cppumaker/HelperStruct.hpp" +#include "test/codemaker/cppumaker/BigStruct.hpp" +#include "test/codemaker/cppumaker/Struct.hpp" +#include "test/codemaker/cppumaker/StructUsage.hpp" +#include "test/codemaker/cppumaker/AlignmentDerivedStruct.hpp" +#include "test/codemaker/cppumaker/TestException1.hpp" +#include "test/codemaker/cppumaker/TestException2.hpp" +#include "test/codemaker/cppumaker/Constants.hpp" + +#include "boost/scoped_array.hpp" +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Type.hxx" +#include "com/sun/star/uno/TypeClass.hpp" +#include "testshl/simpleheader.hxx" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" + +#include <cstddef> +#include <iostream> + +namespace { + +class Test: public CppUnit::TestFixture { +public: + void testBigStruct(); + + void testPolyStruct(); + + void testExceptions(); + + void testConstants(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testBigStruct); + CPPUNIT_TEST(testPolyStruct); + CPPUNIT_TEST(testExceptions); + CPPUNIT_TEST(testConstants); + CPPUNIT_TEST_SUITE_END(); +}; + +struct Guard { + explicit Guard(void * buffer): + p(new(buffer) test::codemaker::cppumaker::BigStruct) {} + + ~Guard() { p->test::codemaker::cppumaker::BigStruct::~BigStruct(); } + + test::codemaker::cppumaker::BigStruct * const p; +}; + +void Test::testBigStruct() { + // Default-initialize a BigStruct instance on top of a memory buffer filled + // with random data, and make sure that all members are default-initialized: + boost::scoped_array< char > buffer( + new char[sizeof (test::codemaker::cppumaker::BigStruct)]); + for (std::size_t i = 0; i < sizeof (test::codemaker::cppumaker::BigStruct); + ++i) + { + buffer[i] = '\x56'; + } + Guard guard(buffer.get()); + CPPUNIT_ASSERT_EQUAL(guard.p->m1, sal_False); + CPPUNIT_ASSERT_EQUAL(guard.p->m2, static_cast< sal_Int8 >(0)); + CPPUNIT_ASSERT_EQUAL(guard.p->m3, static_cast< sal_Int16 >(0)); + CPPUNIT_ASSERT_EQUAL(guard.p->m4, static_cast< sal_uInt16 >(0)); + CPPUNIT_ASSERT_EQUAL(guard.p->m5, static_cast< sal_Int32 >(0)); + CPPUNIT_ASSERT_EQUAL(guard.p->m6, static_cast< sal_uInt32 >(0)); + CPPUNIT_ASSERT_EQUAL(guard.p->m7, static_cast< sal_Int64 >(0)); + CPPUNIT_ASSERT_EQUAL(guard.p->m8, static_cast< sal_uInt64 >(0)); + CPPUNIT_ASSERT_EQUAL(guard.p->m9, 0.0f); + CPPUNIT_ASSERT_EQUAL(guard.p->m10, 0.0); + CPPUNIT_ASSERT_EQUAL(guard.p->m11, static_cast< sal_Unicode >(0)); + CPPUNIT_ASSERT_EQUAL(guard.p->m12.getLength(), static_cast< sal_Int32 >(0)); + CPPUNIT_ASSERT_EQUAL( + guard.p->m13.getTypeClass(), com::sun::star::uno::TypeClass_VOID); + CPPUNIT_ASSERT_EQUAL(guard.p->m14.hasValue(), sal_False); + CPPUNIT_ASSERT_EQUAL(guard.p->m15.getLength(), static_cast< sal_Int32 >(0)); + CPPUNIT_ASSERT_EQUAL( + guard.p->m16, test::codemaker::cppumaker::HelperEnum_ZERO); + CPPUNIT_ASSERT_EQUAL(guard.p->m17.m1, sal_False); + CPPUNIT_ASSERT_EQUAL(guard.p->m17.m2.is(), sal_False); + CPPUNIT_ASSERT_EQUAL(guard.p->m18.is(), sal_False); + CPPUNIT_ASSERT_EQUAL(guard.p->m19, static_cast< sal_Int8 >(0)); + CPPUNIT_ASSERT_EQUAL( + guard.p->m20, test::codemaker::cppumaker::HelperEnum_ZERO); + CPPUNIT_ASSERT_EQUAL(guard.p->m21.getLength(), static_cast< sal_Int32 >(0)); + CPPUNIT_ASSERT_EQUAL(guard.p->m22.getLength(), static_cast< sal_Int32 >(0)); + CPPUNIT_ASSERT_EQUAL(guard.p->m23.getLength(), static_cast< sal_Int32 >(0)); + +#if defined __GNUC__ && __GNUC__ >= 3 // see CPPU_GCC3_ALIGN + CPPUNIT_ASSERT_EQUAL( +#if defined X86_64 + static_cast< std::size_t >(24), +#else + static_cast< std::size_t >(16), +#endif + sizeof (test::codemaker::cppumaker::AlignmentDerivedStruct)); +#endif + + com::sun::star::uno::Type t( + cppu::UnoType< test::codemaker::cppumaker::BigStruct >::get()); + typelib_TypeDescription * td = NULL; + t.getDescription(&td); + typelib_typedescription_complete(&td); + fprintf(stdout, "#### 1\n"); + CPPUNIT_ASSERT(td != NULL); + CPPUNIT_ASSERT_EQUAL(typelib_TypeClass_STRUCT, td->eTypeClass); + typelib_StructTypeDescription * std = + reinterpret_cast< typelib_StructTypeDescription * >(td); + CPPUNIT_ASSERT_EQUAL(typelib_TypeClass_UNSIGNED_SHORT, std->aBase.ppTypeRefs[3]->eTypeClass); // unsigned short m4; + CPPUNIT_ASSERT_EQUAL(typelib_TypeClass_CHAR, std->aBase.ppTypeRefs[10]->eTypeClass); // char m11; +} + +void Test::testPolyStruct() { + CPPUNIT_ASSERT_EQUAL( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "test.codemaker.cppumaker.Struct<char,short>")), + (com::sun::star::uno::makeAny( + test::codemaker::cppumaker::Struct< sal_Unicode, sal_Int16 >()). + getValueType().getTypeName())); + CPPUNIT_ASSERT_EQUAL( + (test::codemaker::cppumaker::make_Struct< sal_uInt32, sal_Bool >(5, 0). + member1), + static_cast< sal_uInt32 >(5)); +} + +namespace { + +bool operator ==( + test::codemaker::cppumaker::TestException1 const & e1, + test::codemaker::cppumaker::TestException1 const & e2) +{ + return e1.Message == e2.Message && e1.Context == e2.Context + && e1.m1 == e2.m1 && e1.m2 == e2.m2 && e1.m3 == e2.m3 + && e1.m4.member1 == e2.m4.member1 && e1.m4.member2 == e2.m4.member2; +} + +std::ostream & operator <<( + std::ostream & out, com::sun::star::uno::Exception const &) +{ + return out << "<UNO exception>"; +} + +} + +void Test::testExceptions() { + test::codemaker::cppumaker::TestException1 e11( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("abc")), 0, 1, + com::sun::star::uno::makeAny(123.0), + test::codemaker::cppumaker::HelperEnum_ONE, + test::codemaker::cppumaker::Struct<sal_Int32, sal_Int32>(5, 0), 2); + test::codemaker::cppumaker::TestException1 e12(e11); + CPPUNIT_ASSERT_EQUAL(e11, e12); + test::codemaker::cppumaker::TestException1 e13; + e13 = e11; + CPPUNIT_ASSERT_EQUAL(e11, e13); + test::codemaker::cppumaker::TestException2 e21( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("abc")), 0, 1, + com::sun::star::uno::makeAny(123.0), + test::codemaker::cppumaker::HelperEnum_ONE, + test::codemaker::cppumaker::Struct<sal_Int32, sal_Int32>(5, 0), 2); + test::codemaker::cppumaker::TestException2 e22(e21); + CPPUNIT_ASSERT_EQUAL(e21, e22); + test::codemaker::cppumaker::TestException2 e23; + e23 = e21; + CPPUNIT_ASSERT_EQUAL(e21, e23); +} + +void Test::testConstants() { + CPPUNIT_ASSERT_EQUAL( + SAL_MIN_INT8, test::codemaker::cppumaker::Constants::byteMin); + CPPUNIT_ASSERT_EQUAL( + SAL_MAX_INT8, test::codemaker::cppumaker::Constants::byteMax); + CPPUNIT_ASSERT_EQUAL( + static_cast< sal_Int8 >(-1), + test::codemaker::cppumaker::Constants::byteNeg); + CPPUNIT_ASSERT_EQUAL( + SAL_MIN_INT16, test::codemaker::cppumaker::Constants::shortMin); + CPPUNIT_ASSERT_EQUAL( + SAL_MAX_INT16, test::codemaker::cppumaker::Constants::shortMax); + CPPUNIT_ASSERT_EQUAL( + static_cast< sal_uInt16 >(0), + test::codemaker::cppumaker::Constants::unsignedShortMin); + CPPUNIT_ASSERT_EQUAL( + SAL_MAX_UINT16, + test::codemaker::cppumaker::Constants::unsignedShortMax); + CPPUNIT_ASSERT_EQUAL( + SAL_MIN_INT32, test::codemaker::cppumaker::Constants::longMin); + CPPUNIT_ASSERT_EQUAL( + SAL_MAX_INT32, test::codemaker::cppumaker::Constants::longMax); + CPPUNIT_ASSERT_EQUAL( + static_cast< sal_uInt32 >(0), + test::codemaker::cppumaker::Constants::unsignedLongMin); + CPPUNIT_ASSERT_EQUAL( + SAL_MAX_UINT32, test::codemaker::cppumaker::Constants::unsignedLongMax); + CPPUNIT_ASSERT_EQUAL( + SAL_MIN_INT64, test::codemaker::cppumaker::Constants::hyperMin); + CPPUNIT_ASSERT_EQUAL( + SAL_MAX_INT64, test::codemaker::cppumaker::Constants::hyperMax); + CPPUNIT_ASSERT_EQUAL( + static_cast< sal_uInt64 >(0), + test::codemaker::cppumaker::Constants::unsignedHyperMin); + CPPUNIT_ASSERT_EQUAL( + SAL_MAX_UINT64, + test::codemaker::cppumaker::Constants::unsignedHyperMax); +} + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(Test, "alltests"); + +} + +NOADDITIONAL; diff --git a/codemaker/test/cppumaker/types.idl b/codemaker/test/cppumaker/types.idl new file mode 100644 index 000000000000..9d9c70234ae3 --- /dev/null +++ b/codemaker/test/cppumaker/types.idl @@ -0,0 +1,717 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +/*TODO: Do not depend on types for which C++ header files are only generated + later in the build process in offuh: */ +#include "com/sun/star/lang/ClassNotFoundException.idl" +#include "com/sun/star/lang/IllegalAccessException.idl" +#include "com/sun/star/lang/Locale.idl" +#include "com/sun/star/uno/DeploymentException.idl" +#include "com/sun/star/uno/Exception.idl" +#include "com/sun/star/uno/RuntimeException.idl" +#include "com/sun/star/uno/XInterface.idl" +#include "com/sun/star/uno/XNamingService.idl" + +singleton FILE: com::sun::star::uno::XInterface; +singleton lconv: com::sun::star::uno::XInterface; +singleton tm: com::sun::star::uno::XInterface; + +singleton std: com::sun::star::uno::XInterface; + +module test { module codemaker { module cppumaker { + +interface XTest { + boolean test(); + + [attribute, bound] long A1; + [attribute, bound, readonly] long A2; + [attribute] long A3 { + get raises + (com::sun::star::uno::Exception, + com::sun::star::lang::ClassNotFoundException); + set raises (com::sun::star::uno::RuntimeException); + }; + [attribute, readonly] long A4 { + get raises (com::sun::star::uno::DeploymentException); + }; +}; + +typedef boolean Boolean; +typedef byte Byte; +typedef short Short; +typedef unsigned short UnsignedShort; +typedef long Long; +typedef unsigned long UnsignedLong; +typedef hyper Hyper; +typedef unsigned hyper UnsignedHyper; +typedef float Float; +typedef double Double; +typedef char Char; +typedef string String; +typedef type Type; +typedef any Any; +typedef com::sun::star::lang::Locale Locale; +typedef com::sun::star::uno::XInterface XInterface; +typedef com::sun::star::uno::XNamingService XNamingService; + +typedef sequence< Boolean > SequenceBoolean; +typedef sequence< Byte > SequenceByte; +typedef sequence< Short > SequenceShort; +typedef sequence< UnsignedShort > SequenceUnsignedShort; +typedef sequence< Long > SequenceLong; +typedef sequence< UnsignedLong > SequenceUnsignedLong; +typedef sequence< Hyper > SequenceHyper; +typedef sequence< UnsignedHyper > SequenceUnsignedHyper; +typedef sequence< Float > SequenceFloat; +typedef sequence< Double > SequenceDouble; +typedef sequence< Char > SequenceChar; +typedef sequence< String > SequenceString; +typedef sequence< Type > SequenceType; +typedef sequence< Any > SequenceAny; +typedef sequence< Locale > SequenceLocale; +typedef sequence< XInterface > SequenceXInterface; +typedef sequence< XNamingService > SequenceXNamingService; + +service S1: XTest { + create1(); + + create2([in] any... create2) + raises (com::sun::star::uno::RuntimeException, + com::sun::star::lang::ClassNotFoundException, + com::sun::star::uno::Exception, + com::sun::star::lang::IllegalAccessException, + com::sun::star::uno::DeploymentException); + + create3([in] sequence<any> S1) + raises (com::sun::star::uno::RuntimeException, + com::sun::star::lang::ClassNotFoundException, + com::sun::star::lang::IllegalAccessException, + com::sun::star::uno::DeploymentException); + + create4([in] long javamaker, [in] long S1, [in] long create4); + + create5( + [in] boolean p1, + [in] byte p2, + [in] short p3, + [in] unsigned short p4, + [in] long p5, + [in] unsigned long p6, + [in] hyper p7, + [in] unsigned hyper p8, + [in] float p9, + [in] double p10, + [in] char p11, + [in] string p12, + [in] type p13, + [in] any p14, + [in] com::sun::star::lang::Locale p15, + [in] com::sun::star::uno::XInterface p16, + [in] com::sun::star::uno::XNamingService p17, + [in] Boolean t1, + [in] Byte t2, + [in] Short t3, + [in] UnsignedShort t4, + [in] Long t5, + [in] UnsignedLong t6, + [in] Hyper t7, + [in] UnsignedHyper t8, + [in] Float t9, + [in] Double t10, + [in] Char t11, + [in] String t12, + [in] Type t13, + [in] Any t14, + [in] Locale t15, + [in] XInterface t16, + [in] XNamingService t17, + [in] sequence< sequence< boolean > > a1, + [in] sequence< sequence< byte > > a2, + [in] sequence< sequence< short > > a3, + [in] sequence< sequence< unsigned short > > a4, + [in] sequence< sequence< long > > a5, + [in] sequence< sequence< unsigned long > > a6, + [in] sequence< sequence< hyper > > a7, + [in] sequence< sequence< unsigned hyper > > a8, + [in] sequence< sequence< float > > a9, + [in] sequence< sequence< double > > a10, + [in] sequence< sequence< char > > a11, + [in] sequence< sequence< string > > a12, + [in] sequence< sequence< type > > a13, + [in] sequence< sequence< any > > a14, + [in] sequence< sequence< com::sun::star::lang::Locale > > a15, + [in] sequence< sequence< com::sun::star::uno::XInterface > > a16, + [in] sequence< sequence< + com::sun::star::uno::XNamingService > > a17, + [in] sequence< SequenceBoolean > at1, + [in] sequence< SequenceByte > at2, + [in] sequence< SequenceShort > at3, + [in] sequence< SequenceUnsignedShort > at4, + [in] sequence< SequenceLong > at5, + [in] sequence< SequenceUnsignedLong > at6, + [in] sequence< SequenceHyper > at7, + [in] sequence< SequenceUnsignedHyper > at8, + [in] sequence< SequenceFloat > at9, + [in] sequence< SequenceDouble > at10, + [in] sequence< SequenceChar > at11, + [in] sequence< SequenceString > at12, + [in] sequence< SequenceType > at13, + [in] sequence< SequenceAny > at14, + [in] sequence< SequenceLocale > at15, + [in] sequence< SequenceXInterface > at16, + [in] sequence< SequenceXNamingService > at17); +}; + +service S2: XTest; + +service S3 { interface XTest; }; + +singleton S4 { service S2; }; + +module services { + +service asm: com::sun::star::uno::XInterface { asm([in] long asm); }; +service auto: com::sun::star::uno::XInterface { auto([in] long auto); }; +service bool: com::sun::star::uno::XInterface { bool([in] long bool); }; +service break: com::sun::star::uno::XInterface { break([in] long break); }; +//TODO: service case: com::sun::star::uno::XInterface { case([in] long case); }; +service catch: com::sun::star::uno::XInterface { catch([in] long catch); }; +//TODO: service char: com::sun::star::uno::XInterface { char([in] long char); }; +service class: com::sun::star::uno::XInterface { class([in] long class); }; +//TODO: service const: com::sun::star::uno::XInterface { +// const([in] long const); }; +service continue: com::sun::star::uno::XInterface { + continue([in] long continue); }; +//TODO: service default: com::sun::star::uno::XInterface { +// default([in] long default); }; +service delete: com::sun::star::uno::XInterface { delete([in] long delete); }; +service do: com::sun::star::uno::XInterface { do([in] long do); }; +//TODO: service double: com::sun::star::uno::XInterface { +// double([in] long double); }; +service else: com::sun::star::uno::XInterface { else([in] long else); }; +//TODO: service enum: com::sun::star::uno::XInterface { enum([in] long enum); }; +service explicit: com::sun::star::uno::XInterface { + explicit([in] long explicit); }; +service export: com::sun::star::uno::XInterface { export([in] long export); }; +service extern: com::sun::star::uno::XInterface { extern([in] long extern); }; +service false: com::sun::star::uno::XInterface { false([in] long false); }; +//TODO: service float: com::sun::star::uno::XInterface { +// float([in] long float); }; +service for: com::sun::star::uno::XInterface { for([in] long for); }; +service friend: com::sun::star::uno::XInterface { friend([in] long friend); }; +service goto: com::sun::star::uno::XInterface { goto([in] long goto); }; +service if: com::sun::star::uno::XInterface { if([in] long if); }; +service inline: com::sun::star::uno::XInterface { inline([in] long inline); }; +service int: com::sun::star::uno::XInterface { int([in] long int); }; +//TODO: service long: com::sun::star::uno::XInterface { long([in] long long); }; +service mutable: com::sun::star::uno::XInterface { + mutable([in] long mutable); }; +service namespace: com::sun::star::uno::XInterface { + namespace([in] long namespace); }; +service new: com::sun::star::uno::XInterface { new([in] long new); }; +service operator: com::sun::star::uno::XInterface { + operator([in] long operator); }; +service private: com::sun::star::uno::XInterface { + private([in] long private); }; +service protected: com::sun::star::uno::XInterface { + protected([in] long protected); }; +service public: com::sun::star::uno::XInterface { public([in] long public); }; +service register: com::sun::star::uno::XInterface { + register([in] long register); }; +service return: com::sun::star::uno::XInterface { return([in] long return); }; +//TODO: service short: com::sun::star::uno::XInterface { +// short([in] long short); }; +service signed: com::sun::star::uno::XInterface { signed([in] long signed); }; +service sizeof: com::sun::star::uno::XInterface { sizeof([in] long sizeof); }; +service static: com::sun::star::uno::XInterface { static([in] long static); }; +//TODO: service struct: com::sun::star::uno::XInterface { +// struct([in] long struct); }; +//TODO: service switch: com::sun::star::uno::XInterface { +// switch([in] long switch); }; +service template: com::sun::star::uno::XInterface { + template([in] long template); }; +service this: com::sun::star::uno::XInterface { this([in] long this); }; +service throw: com::sun::star::uno::XInterface { throw([in] long throw); }; +service true: com::sun::star::uno::XInterface { true([in] long true); }; +service try: com::sun::star::uno::XInterface { try([in] long try); }; +//TODO: service typedef: com::sun::star::uno::XInterface { +// typedef([in] long typedef); }; +service typeid: com::sun::star::uno::XInterface { typeid([in] long typeid); }; +service typename: com::sun::star::uno::XInterface { + typename([in] long typename); }; +//TODO: service union: com::sun::star::uno::XInterface { +// union([in] long union); }; +//TODO: service unsigned: com::sun::star::uno::XInterface { +// unsigned([in] long unsigned); }; +service using: com::sun::star::uno::XInterface { using([in] long using); }; +service virtual: com::sun::star::uno::XInterface { + virtual([in] long virtual); }; +//TODO: service void: com::sun::star::uno::XInterface { void([in] long void); }; +service volatile: com::sun::star::uno::XInterface { + volatile([in] long volatile); }; +service while: com::sun::star::uno::XInterface { while([in] long while); }; + +service and: com::sun::star::uno::XInterface { and([in] long and); }; +service bitand: com::sun::star::uno::XInterface { bitand([in] long bitand); }; +service bitor: com::sun::star::uno::XInterface { bitor([in] long bitor); }; +service compl: com::sun::star::uno::XInterface { compl([in] long compl); }; +service not: com::sun::star::uno::XInterface { not([in] long not); }; +service or: com::sun::star::uno::XInterface { or([in] long or); }; +service xor: com::sun::star::uno::XInterface { xor([in] long xor); }; + +service BUFSIZ: com::sun::star::uno::XInterface { BUFSIZ([in] long BUFSIZ); }; +service CLOCKS_PER_SEC: com::sun::star::uno::XInterface { + CLOCKS_PER_SEC([in] long CLOCKS_PER_SEC); }; +service EDOM: com::sun::star::uno::XInterface { EDOM([in] long EDOM); }; +service EOF: com::sun::star::uno::XInterface { EOF([in] long EOF); }; +service ERANGE: com::sun::star::uno::XInterface { ERANGE([in] long ERANGE); }; +service EXIT_FAILURE: com::sun::star::uno::XInterface { + EXIT_FAILURE([in] long EXIT_FAILURE); }; +service EXIT_SUCCESS: com::sun::star::uno::XInterface { + EXIT_SUCCESS([in] long EXIT_SUCCESS); }; +service FILENAME_MAX: com::sun::star::uno::XInterface { + FILENAME_MAX([in] long FILENAME_MAX); }; +service FOPEN_MAX: com::sun::star::uno::XInterface { + FOPEN_MAX([in] long FOPEN_MAX); }; +service HUGE_VAL: com::sun::star::uno::XInterface { + HUGE_VAL([in] long HUGE_VAL); }; +service LC_ALL: com::sun::star::uno::XInterface { LC_ALL([in] long LC_ALL); }; +service LC_COLLATE: com::sun::star::uno::XInterface { + LC_COLLATE([in] long LC_COLLATE); }; +service LC_CTYPE: com::sun::star::uno::XInterface { + LC_CTYPE([in] long LC_CTYPE); }; +service LC_MONETARY: com::sun::star::uno::XInterface { + LC_MONETARY([in] long LC_MONETARY); }; +service LC_NUMERIC: com::sun::star::uno::XInterface { + LC_NUMERIC([in] long LC_NUMERIC); }; +service LC_TIME: com::sun::star::uno::XInterface { + LC_TIME([in] long LC_TIME); }; +service L_tmpnam: com::sun::star::uno::XInterface { + L_tmpnam([in] long L_tmpnam); }; +service MB_CUR_MAX: com::sun::star::uno::XInterface { + MB_CUR_MAX([in] long MB_CUR_MAX); }; +service NULL: com::sun::star::uno::XInterface { NULL([in] long NULL); }; +service RAND_MAX: com::sun::star::uno::XInterface { + RAND_MAX([in] long RAND_MAX); }; +service SEEK_CUR: com::sun::star::uno::XInterface { + SEEK_CUR([in] long SEEK_CUR); }; +service SEEK_END: com::sun::star::uno::XInterface { + SEEK_END([in] long SEEK_END); }; +service SEEK_SET: com::sun::star::uno::XInterface { + SEEK_SET([in] long SEEK_SET); }; +service SIGABRT: com::sun::star::uno::XInterface { + SIGABRT([in] long SIGABRT); }; +service SIGFPE: com::sun::star::uno::XInterface { SIGFPE([in] long SIGFPE); }; +service SIGILL: com::sun::star::uno::XInterface { SIGILL([in] long SIGILL); }; +service SIGINT: com::sun::star::uno::XInterface { SIGINT([in] long SIGINT); }; +service SIGSEGV: com::sun::star::uno::XInterface { + SIGSEGV([in] long SIGSEGV); }; +service SIGTERM: com::sun::star::uno::XInterface { + SIGTERM([in] long SIGTERM); }; +service SIG_DFL: com::sun::star::uno::XInterface { + SIG_DFL([in] long SIG_DFL); }; +service SIG_ERR: com::sun::star::uno::XInterface { + SIG_ERR([in] long SIG_ERR); }; +service SIG_IGN: com::sun::star::uno::XInterface { + SIG_IGN([in] long SIG_IGN); }; +service TMP_MAX: com::sun::star::uno::XInterface { + TMP_MAX([in] long TMP_MAX); }; +service WCHAR_MAX: com::sun::star::uno::XInterface { + WCHAR_MAX([in] long WCHAR_MAX); }; +service WCHAR_MIN: com::sun::star::uno::XInterface { + WCHAR_MIN([in] long WCHAR_MIN); }; +service WEOF: com::sun::star::uno::XInterface { WEOF([in] long WEOF); }; +service assert: com::sun::star::uno::XInterface { assert([in] long assert); }; +service errno: com::sun::star::uno::XInterface { errno([in] long errno); }; +service offsetof: com::sun::star::uno::XInterface { + offsetof([in] long offsetof); }; +service setjmp: com::sun::star::uno::XInterface { setjmp([in] long setjmp); }; +service stderr: com::sun::star::uno::XInterface { stderr([in] long stderr); }; +service stdin: com::sun::star::uno::XInterface { stdin([in] long stdin); }; +service stdout: com::sun::star::uno::XInterface { stdout([in] long stdout); }; + +service CHAR_BIT: com::sun::star::uno::XInterface { + CHAR_BIT([in] long CHAR_BIT); }; +service CHAR_MAX: com::sun::star::uno::XInterface { + CHAR_MAX([in] long CHAR_MAX); }; +service CHAR_MIN: com::sun::star::uno::XInterface { + CHAR_MIN([in] long CHAR_MIN); }; +service DBL_DIG: com::sun::star::uno::XInterface { + DBL_DIG([in] long DBL_DIG); }; +service DBL_EPSILON: com::sun::star::uno::XInterface { + DBL_EPSILON([in] long DBL_EPSILON); }; +service DBL_MANT_DIG: com::sun::star::uno::XInterface { + DBL_MANT_DIG([in] long DBL_MANT_DIG); }; +service DBL_MAX: com::sun::star::uno::XInterface { + DBL_MAX([in] long DBL_MAX); }; +service DBL_MAX_10_EXP: com::sun::star::uno::XInterface { + DBL_MAX_10_EXP([in] long DBL_MAX_10_EXP); }; +service DBL_MAX_EXP: com::sun::star::uno::XInterface { + DBL_MAX_EXP([in] long DBL_MAX_EXP); }; +service DBL_MIN: com::sun::star::uno::XInterface { + DBL_MIN([in] long DBL_MIN); }; +service DBL_MIN_10_EXP: com::sun::star::uno::XInterface { + DBL_MIN_10_EXP([in] long DBL_MIN_10_EXP); }; +service DBL_MIN_EXP: com::sun::star::uno::XInterface { + DBL_MIN_EXP([in] long DBL_MIN_EXP); }; +service FLT_DIG: com::sun::star::uno::XInterface { + FLT_DIG([in] long FLT_DIG); }; +service FLT_EPSILON: com::sun::star::uno::XInterface { + FLT_EPSILON([in] long FLT_EPSILON); }; +service FLT_MANT_DIG: com::sun::star::uno::XInterface { + FLT_MANT_DIG([in] long FLT_MANT_DIG); }; +service FLT_MAX: com::sun::star::uno::XInterface { + FLT_MAX([in] long FLT_MAX); }; +service FLT_MAX_10_EXP: com::sun::star::uno::XInterface { + FLT_MAX_10_EXP([in] long FLT_MAX_10_EXP); }; +service FLT_MAX_EXP: com::sun::star::uno::XInterface { + FLT_MAX_EXP([in] long FLT_MAX_EXP); }; +service FLT_MIN: com::sun::star::uno::XInterface { + FLT_MIN([in] long FLT_MIN); }; +service FLT_MIN_10_EXP: com::sun::star::uno::XInterface { + FLT_MIN_10_EXP([in] long FLT_MIN_10_EXP); }; +service FLT_MIN_EXP: com::sun::star::uno::XInterface { + FLT_MIN_EXP([in] long FLT_MIN_EXP); }; +service FLT_RADIX: com::sun::star::uno::XInterface { + FLT_RADIX([in] long FLT_RADIX); }; +service FLT_ROUNDS: com::sun::star::uno::XInterface { + FLT_ROUNDS([in] long FLT_ROUNDS); }; +service INT_MAX: com::sun::star::uno::XInterface { + INT_MAX([in] long INT_MAX); }; +service INT_MIN: com::sun::star::uno::XInterface { + INT_MIN([in] long INT_MIN); }; +service LDBL_DIG: com::sun::star::uno::XInterface { + LDBL_DIG([in] long LDBL_DIG); }; +service LDBL_EPSILON: com::sun::star::uno::XInterface { + LDBL_EPSILON([in] long LDBL_EPSILON); }; +service LDBL_MANT_DIG: com::sun::star::uno::XInterface { + LDBL_MANT_DIG([in] long LDBL_MANT_DIG); }; +service LDBL_MAX: com::sun::star::uno::XInterface { + LDBL_MAX([in] long LDBL_MAX); }; +service LDBL_MAX_10_EXP: com::sun::star::uno::XInterface { + LDBL_MAX_10_EXP([in] long LDBL_MAX_10_EXP); }; +service LDBL_MAX_EXP: com::sun::star::uno::XInterface { + LDBL_MAX_EXP([in] long LDBL_MAX_EXP); }; +service LDBL_MIN: com::sun::star::uno::XInterface { + LDBL_MIN([in] long LDBL_MIN); }; +service LDBL_MIN_10_EXP: com::sun::star::uno::XInterface { + LDBL_MIN_10_EXP([in] long LDBL_MIN_10_EXP); }; +service LDBL_MIN_EXP: com::sun::star::uno::XInterface { + LDBL_MIN_EXP([in] long LDBL_MIN_EXP); }; +service LONG_MAX: com::sun::star::uno::XInterface { + LONG_MAX([in] long LONG_MAX); }; +service LONG_MIN: com::sun::star::uno::XInterface { + LONG_MIN([in] long LONG_MIN); }; +service MB_LEN_MAX: com::sun::star::uno::XInterface { + MB_LEN_MAX([in] long MB_LEN_MAX); }; +service SCHAR_MAX: com::sun::star::uno::XInterface { + SCHAR_MAX([in] long SCHAR_MAX); }; +service SCHAR_MIN: com::sun::star::uno::XInterface { + SCHAR_MIN([in] long SCHAR_MIN); }; +service SHRT_MAX: com::sun::star::uno::XInterface { + SHRT_MAX([in] long SHRT_MAX); }; +service SHRT_MIN: com::sun::star::uno::XInterface { + SHRT_MIN([in] long SHRT_MIN); }; +service UCHAR_MAX: com::sun::star::uno::XInterface { + UCHAR_MAX([in] long UCHAR_MAX); }; +service UINT_MAX: com::sun::star::uno::XInterface { + UINT_MAX([in] long UINT_MAX); }; +service ULONG_MAX: com::sun::star::uno::XInterface { + ULONG_MAX([in] long ULONG_MAX); }; +service USHRT_MAX: com::sun::star::uno::XInterface { + USHRT_MAX([in] long USHRT_MAX); }; + +service FILE: com::sun::star::uno::XInterface { FILE([in] long FILE); }; +service lconv: com::sun::star::uno::XInterface { lconv([in] long lconv); }; +service tm: com::sun::star::uno::XInterface { tm([in] long tm); }; + +service std: com::sun::star::uno::XInterface { std([in] long std); }; + +service NDEBUG: com::sun::star::uno::XInterface { NDEBUG([in] long NDEBUG); }; + +service create: com::sun::star::uno::XInterface; + +}; + +module singletons { + +singleton asm: com::sun::star::uno::XInterface; +singleton auto: com::sun::star::uno::XInterface; +singleton bool: com::sun::star::uno::XInterface; +singleton break: com::sun::star::uno::XInterface; +//TODO: singleton case: com::sun::star::uno::XInterface; +singleton catch: com::sun::star::uno::XInterface; +//TODO: singleton char: com::sun::star::uno::XInterface; +singleton class: com::sun::star::uno::XInterface; +//TODO: singleton const: com::sun::star::uno::XInterface; +singleton continue: com::sun::star::uno::XInterface; +//TODO: singleton default: com::sun::star::uno::XInterface; +singleton delete: com::sun::star::uno::XInterface; +singleton do: com::sun::star::uno::XInterface; +//TODO: singleton double: com::sun::star::uno::XInterface; +singleton else: com::sun::star::uno::XInterface; +//TODO: singleton enum: com::sun::star::uno::XInterface; +singleton explicit: com::sun::star::uno::XInterface; +singleton export: com::sun::star::uno::XInterface; +singleton extern: com::sun::star::uno::XInterface; +singleton false: com::sun::star::uno::XInterface; +//TODO: singleton float: com::sun::star::uno::XInterface; +singleton for: com::sun::star::uno::XInterface; +singleton friend: com::sun::star::uno::XInterface; +singleton goto: com::sun::star::uno::XInterface; +singleton if: com::sun::star::uno::XInterface; +singleton inline: com::sun::star::uno::XInterface; +singleton int: com::sun::star::uno::XInterface; +//TODO: singleton long: com::sun::star::uno::XInterface; +singleton mutable: com::sun::star::uno::XInterface; +singleton namespace: com::sun::star::uno::XInterface; +singleton new: com::sun::star::uno::XInterface; +singleton operator: com::sun::star::uno::XInterface; +singleton private: com::sun::star::uno::XInterface; +singleton protected: com::sun::star::uno::XInterface; +singleton public: com::sun::star::uno::XInterface; +singleton register: com::sun::star::uno::XInterface; +singleton return: com::sun::star::uno::XInterface; +//TODO: singleton short: com::sun::star::uno::XInterface; +singleton signed: com::sun::star::uno::XInterface; +singleton sizeof: com::sun::star::uno::XInterface; +singleton static: com::sun::star::uno::XInterface; +//TODO: singleton struct: com::sun::star::uno::XInterface; +//TODO: singleton switch: com::sun::star::uno::XInterface; +singleton template: com::sun::star::uno::XInterface; +singleton this: com::sun::star::uno::XInterface; +singleton throw: com::sun::star::uno::XInterface; +singleton true: com::sun::star::uno::XInterface; +singleton try: com::sun::star::uno::XInterface; +//TODO: singleton typedef: com::sun::star::uno::XInterface; +singleton typeid: com::sun::star::uno::XInterface; +singleton typename: com::sun::star::uno::XInterface; +//TODO: singleton union: com::sun::star::uno::XInterface; +//TODO: singleton unsigned: com::sun::star::uno::XInterface; +singleton using: com::sun::star::uno::XInterface; +singleton virtual: com::sun::star::uno::XInterface; +//TODO: singleton void: com::sun::star::uno::XInterface; +singleton volatile: com::sun::star::uno::XInterface; +singleton while: com::sun::star::uno::XInterface; + +singleton and: com::sun::star::uno::XInterface; +singleton bitand: com::sun::star::uno::XInterface; +singleton bitor: com::sun::star::uno::XInterface; +singleton compl: com::sun::star::uno::XInterface; +singleton not: com::sun::star::uno::XInterface; +singleton or: com::sun::star::uno::XInterface; +singleton xor: com::sun::star::uno::XInterface; + +singleton BUFSIZ: com::sun::star::uno::XInterface; +singleton CLOCKS_PER_SEC: com::sun::star::uno::XInterface; +singleton EDOM: com::sun::star::uno::XInterface; +singleton EOF: com::sun::star::uno::XInterface; +singleton ERANGE: com::sun::star::uno::XInterface; +singleton EXIT_FAILURE: com::sun::star::uno::XInterface; +singleton EXIT_SUCCESS: com::sun::star::uno::XInterface; +singleton FILENAME_MAX: com::sun::star::uno::XInterface; +singleton FOPEN_MAX: com::sun::star::uno::XInterface; +singleton HUGE_VAL: com::sun::star::uno::XInterface; +singleton LC_ALL: com::sun::star::uno::XInterface; +singleton LC_COLLATE: com::sun::star::uno::XInterface; +singleton LC_CTYPE: com::sun::star::uno::XInterface; +singleton LC_MONETARY: com::sun::star::uno::XInterface; +singleton LC_NUMERIC: com::sun::star::uno::XInterface; +singleton LC_TIME: com::sun::star::uno::XInterface; +singleton L_tmpnam: com::sun::star::uno::XInterface; +singleton MB_CUR_MAX: com::sun::star::uno::XInterface; +singleton NULL: com::sun::star::uno::XInterface; +singleton RAND_MAX: com::sun::star::uno::XInterface; +singleton SEEK_CUR: com::sun::star::uno::XInterface; +singleton SEEK_END: com::sun::star::uno::XInterface; +singleton SEEK_SET: com::sun::star::uno::XInterface; +singleton SIGABRT: com::sun::star::uno::XInterface; +singleton SIGFPE: com::sun::star::uno::XInterface; +singleton SIGILL: com::sun::star::uno::XInterface; +singleton SIGINT: com::sun::star::uno::XInterface; +singleton SIGSEGV: com::sun::star::uno::XInterface; +singleton SIGTERM: com::sun::star::uno::XInterface; +singleton SIG_DFL: com::sun::star::uno::XInterface; +singleton SIG_ERR: com::sun::star::uno::XInterface; +singleton SIG_IGN: com::sun::star::uno::XInterface; +singleton TMP_MAX: com::sun::star::uno::XInterface; +singleton WCHAR_MAX: com::sun::star::uno::XInterface; +singleton WCHAR_MIN: com::sun::star::uno::XInterface; +singleton WEOF: com::sun::star::uno::XInterface; +singleton assert: com::sun::star::uno::XInterface; +singleton errno: com::sun::star::uno::XInterface; +singleton offsetof: com::sun::star::uno::XInterface; +singleton setjmp: com::sun::star::uno::XInterface; +singleton stderr: com::sun::star::uno::XInterface; +singleton stdin: com::sun::star::uno::XInterface; +singleton stdout: com::sun::star::uno::XInterface; + +singleton CHAR_BIT: com::sun::star::uno::XInterface; +singleton CHAR_MAX: com::sun::star::uno::XInterface; +singleton CHAR_MIN: com::sun::star::uno::XInterface; +singleton DBL_DIG: com::sun::star::uno::XInterface; +singleton DBL_EPSILON: com::sun::star::uno::XInterface; +singleton DBL_MANT_DIG: com::sun::star::uno::XInterface; +singleton DBL_MAX: com::sun::star::uno::XInterface; +singleton DBL_MAX_10_EXP: com::sun::star::uno::XInterface; +singleton DBL_MAX_EXP: com::sun::star::uno::XInterface; +singleton DBL_MIN: com::sun::star::uno::XInterface; +singleton DBL_MIN_10_EXP: com::sun::star::uno::XInterface; +singleton DBL_MIN_EXP: com::sun::star::uno::XInterface; +singleton FLT_DIG: com::sun::star::uno::XInterface; +singleton FLT_EPSILON: com::sun::star::uno::XInterface; +singleton FLT_MANT_DIG: com::sun::star::uno::XInterface; +singleton FLT_MAX: com::sun::star::uno::XInterface; +singleton FLT_MAX_10_EXP: com::sun::star::uno::XInterface; +singleton FLT_MAX_EXP: com::sun::star::uno::XInterface; +singleton FLT_MIN: com::sun::star::uno::XInterface; +singleton FLT_MIN_10_EXP: com::sun::star::uno::XInterface; +singleton FLT_MIN_EXP: com::sun::star::uno::XInterface; +singleton FLT_RADIX: com::sun::star::uno::XInterface; +singleton FLT_ROUNDS: com::sun::star::uno::XInterface; +singleton INT_MAX: com::sun::star::uno::XInterface; +singleton INT_MIN: com::sun::star::uno::XInterface; +singleton LDBL_DIG: com::sun::star::uno::XInterface; +singleton LDBL_EPSILON: com::sun::star::uno::XInterface; +singleton LDBL_MANT_DIG: com::sun::star::uno::XInterface; +singleton LDBL_MAX: com::sun::star::uno::XInterface; +singleton LDBL_MAX_10_EXP: com::sun::star::uno::XInterface; +singleton LDBL_MAX_EXP: com::sun::star::uno::XInterface; +singleton LDBL_MIN: com::sun::star::uno::XInterface; +singleton LDBL_MIN_10_EXP: com::sun::star::uno::XInterface; +singleton LDBL_MIN_EXP: com::sun::star::uno::XInterface; +singleton LONG_MAX: com::sun::star::uno::XInterface; +singleton LONG_MIN: com::sun::star::uno::XInterface; +singleton MB_LEN_MAX: com::sun::star::uno::XInterface; +singleton SCHAR_MAX: com::sun::star::uno::XInterface; +singleton SCHAR_MIN: com::sun::star::uno::XInterface; +singleton SHRT_MAX: com::sun::star::uno::XInterface; +singleton SHRT_MIN: com::sun::star::uno::XInterface; +singleton UCHAR_MAX: com::sun::star::uno::XInterface; +singleton UINT_MAX: com::sun::star::uno::XInterface; +singleton ULONG_MAX: com::sun::star::uno::XInterface; +singleton USHRT_MAX: com::sun::star::uno::XInterface; + +singleton FILE: com::sun::star::uno::XInterface; +singleton lconv: com::sun::star::uno::XInterface; +singleton tm: com::sun::star::uno::XInterface; + +singleton std: com::sun::star::uno::XInterface; + +singleton NDEBUG: com::sun::star::uno::XInterface; + +singleton get: com::sun::star::uno::XInterface; + +}; + +enum HelperEnum { ZERO, ONE }; + +struct HelperStruct { boolean m1; com::sun::star::uno::XInterface m2; }; + +typedef byte TDByte; +typedef HelperEnum TDEnum1; +typedef TDEnum1 TDEnum; + +struct BigStruct { + boolean m1; + byte m2; + short m3; + unsigned short m4; + long m5; + unsigned long m6; + hyper m7; + unsigned hyper m8; + float m9; + double m10; + char m11; + string m12; + type m13; + any m14; + sequence<boolean> m15; + HelperEnum m16; + HelperStruct m17; + com::sun::star::uno::XInterface m18; + TDByte m19; + TDEnum m20; + sequence<unsigned short> m21; + sequence<char> m22; + sequence< sequence<char> > m23; +}; + +struct Struct<T, U> { + T member1; + sequence<SequenceAny> member2; +}; + +struct StructUsage { + Struct< long, short > member1; + sequence< + sequence< + Struct< + sequence< Struct< any, boolean > >, + com::sun::star::uno::XInterface > > > + member2; +}; + +struct AlignmentBaseStruct { + double member1; + short member2; +}; + +struct AlignmentDerivedStruct: AlignmentBaseStruct { + short member3; +}; + +exception TestException1: com::sun::star::uno::RuntimeException { + long m1; + any m2; + HelperEnum m3; + Struct<long, long> m4; + unsigned short m5; +}; + +exception TestException2: TestException1 {}; + +constants Constants { + const byte byteMin = -128; + const byte byteMax = 127; + const byte byteNeg = 255; + const short shortMin = -32768; + const short shortMax = 32767; + const unsigned short unsignedShortMin = 0; + const unsigned short unsignedShortMax = 65535; + const long longMin = -2147483648; + const long longMax = 2147483647; + const unsigned long unsignedLongMin = 0; + const unsigned long unsignedLongMax = 4294967295; + const hyper hyperMin = -9223372036854775808; + const hyper hyperMax = 9223372036854775807; + const unsigned hyper unsignedHyperMin = 0; + const unsigned hyper unsignedHyperMax = 18446744073709551615; +}; + +}; }; }; diff --git a/codemaker/test/cppumaker/version.map b/codemaker/test/cppumaker/version.map new file mode 100644 index 000000000000..7321bbca16ad --- /dev/null +++ b/codemaker/test/cppumaker/version.map @@ -0,0 +1,34 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +UDK_3_0_0 { + global: + registerAllTestFunction; + + local: + *; +}; diff --git a/codemaker/test/javamaker/Test.java b/codemaker/test/javamaker/Test.java new file mode 100644 index 000000000000..532b9de76c9d --- /dev/null +++ b/codemaker/test/javamaker/Test.java @@ -0,0 +1,559 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +package test.codemaker.javamaker; + +import com.sun.star.comp.helper.Bootstrap; +import com.sun.star.lang.XEventListener; +import com.sun.star.uno.Any; +import com.sun.star.uno.DeploymentException; +import com.sun.star.uno.Type; +import com.sun.star.uno.XComponentContext; +import com.sun.star.uno.XNamingService; +import complexlib.ComplexTestCase; +import java.util.EventListener; +import test.codemaker.javamaker.Enum1; +import test.codemaker.javamaker.Enum2; +import test.codemaker.javamaker.PolyStruct; +import test.codemaker.javamaker.S2; +import test.codemaker.javamaker.Struct2; +import test.codemaker.javamaker.services.service_abstract; +import test.codemaker.javamaker.services.service_assert; +import test.codemaker.javamaker.services.service_break; +import test.codemaker.javamaker.services.service_catch; +import test.codemaker.javamaker.services.service_class; +import test.codemaker.javamaker.services.service_continue; +import test.codemaker.javamaker.services.service_do; +import test.codemaker.javamaker.services.service_else; +import test.codemaker.javamaker.services.service_extends; +import test.codemaker.javamaker.services.service_final; +import test.codemaker.javamaker.services.service_finally; +import test.codemaker.javamaker.services.service_for; +import test.codemaker.javamaker.services.service_goto; +import test.codemaker.javamaker.services.service_if; +import test.codemaker.javamaker.services.service_implements; +import test.codemaker.javamaker.services.service_import; +import test.codemaker.javamaker.services.service_instanceof; +import test.codemaker.javamaker.services.service_int; +import test.codemaker.javamaker.services.service_native; +import test.codemaker.javamaker.services.service_new; +import test.codemaker.javamaker.services.service_package; +import test.codemaker.javamaker.services.service_private; +import test.codemaker.javamaker.services.service_protected; +import test.codemaker.javamaker.services.service_public; +import test.codemaker.javamaker.services.service_return; +import test.codemaker.javamaker.services.service_static; +import test.codemaker.javamaker.services.service_strictfp; +import test.codemaker.javamaker.services.service_super; +import test.codemaker.javamaker.services.service_synchronized; +import test.codemaker.javamaker.services.service_this; +import test.codemaker.javamaker.services.service_throw; +import test.codemaker.javamaker.services.service_throws; +import test.codemaker.javamaker.services.service_try; +import test.codemaker.javamaker.services.service_volatile; +import test.codemaker.javamaker.services.service_while; +import test.codemaker.javamaker.singleton_abstract; + +public final class Test extends ComplexTestCase { + public String[] getTestMethodNames() { + return new String[] { + "testEnum1", "testEnum2", "testPolyStruct", "testEmptyStruct2", + "testFullStruct2", "testXEventListener", "testS1", "testS2", + "testKeywordServices", "testSingletons" }; + } + + public void before() throws Exception { + context = Bootstrap.createInitialComponentContext(null); + } + + public void testEnum1() { + assure(Enum1.VALUE1.getValue() == -100); + assure(Enum1.VALUE2.getValue() == 100); + assure(Enum1.VALUE1_value == -100); + assure(Enum1.VALUE2_value == 100); + assure(Enum1.getDefault() == Enum1.VALUE1); + assure(Enum1.fromInt(-101) == null); + assure(Enum1.fromInt(-100) == Enum1.VALUE1); + assure(Enum1.fromInt(-99) == null); + assure(Enum1.fromInt(0) == null); + assure(Enum1.fromInt(99) == null); + assure(Enum1.fromInt(100) == Enum1.VALUE2); + assure(Enum1.fromInt(101) == null); + } + + public void testEnum2() { + assure(Enum2.VALUE0.getValue() == 0); + assure(Enum2.VALUE1.getValue() == 1); + assure(Enum2.VALUE2.getValue() == 2); + assure(Enum2.VALUE4.getValue() == 4); + assure(Enum2.VALUE0_value == 0); + assure(Enum2.VALUE1_value == 1); + assure(Enum2.VALUE2_value == 2); + assure(Enum2.VALUE4_value == 4); + assure(Enum2.getDefault() == Enum2.VALUE0); + assure(Enum2.fromInt(-1) == null); + assure(Enum2.fromInt(0) == Enum2.VALUE0); + assure(Enum2.fromInt(1) == Enum2.VALUE1); + assure(Enum2.fromInt(2) == Enum2.VALUE2); + assure(Enum2.fromInt(3) == null); + assure(Enum2.fromInt(4) == Enum2.VALUE4); + assure(Enum2.fromInt(5) == null); + } + + public void testPolyStruct() { + PolyStruct s = new PolyStruct(); + assure(s.member1 == null); + assure(s.member2 == 0); + s = new PolyStruct("ABC", 5); + assure(s.member1.equals("ABC")); + assure(s.member2 == 5); + } + + public void testEmptyStruct2() { + Struct2 s = new Struct2(); + assure(s.p1 == false); + assure(s.p2 == 0); + assure(s.p3 == 0); + assure(s.p4 == 0); + assure(s.p5 == 0); + assure(s.p6 == 0); + assure(s.p7 == 0L); + assure(s.p8 == 0L); + assure(s.p9 == 0.0f); + assure(s.p10 == 0.0); + assure(s.p11 == '\u0000'); + assure(s.p12.equals("")); + assure(s.p13.equals(Type.VOID)); + assure(s.p14.equals(Any.VOID)); + assure(s.p15 == Enum2.VALUE0); + assure(s.p16.member1 == 0); + assure(s.p17 == null); + assure(s.p18 == null); + assure(s.t1 == false); + assure(s.t2 == 0); + assure(s.t3 == 0); + assure(s.t4 == 0); + assure(s.t5 == 0); + assure(s.t6 == 0); + assure(s.t7 == 0L); + assure(s.t8 == 0L); + assure(s.t9 == 0.0f); + assure(s.t10 == 0.0); + assure(s.t11 == '\u0000'); + assure(s.t12.equals("")); + assure(s.t13.equals(Type.VOID)); + assure(s.t14.equals(Any.VOID)); + assure(s.t15 == Enum2.VALUE0); + assure(s.t16.member1 == 0); + assure(s.t17 == null); + assure(s.t18 == null); + assure(s.a1.length == 0); + assure(s.a2.length == 0); + assure(s.a3.length == 0); + assure(s.a4.length == 0); + assure(s.a5.length == 0); + assure(s.a6.length == 0); + assure(s.a7.length == 0); + assure(s.a8.length == 0); + assure(s.a9.length == 0); + assure(s.a10.length == 0); + assure(s.a11.length == 0); + assure(s.a12.length == 0); + assure(s.a13.length == 0); + assure(s.a14.length == 0); + assure(s.a15.length == 0); + assure(s.a16.length == 0); + assure(s.a17.length == 0); + assure(s.a18.length == 0); + assure(s.aa1.length == 0); + assure(s.aa2.length == 0); + assure(s.aa3.length == 0); + assure(s.aa4.length == 0); + assure(s.aa5.length == 0); + assure(s.aa6.length == 0); + assure(s.aa7.length == 0); + assure(s.aa8.length == 0); + assure(s.aa9.length == 0); + assure(s.aa10.length == 0); + assure(s.aa11.length == 0); + assure(s.aa12.length == 0); + assure(s.aa13.length == 0); + assure(s.aa14.length == 0); + assure(s.aa15.length == 0); + assure(s.aa16.length == 0); + assure(s.aa17.length == 0); + assure(s.aa18.length == 0); + assure(s.at1.length == 0); + assure(s.at2.length == 0); + assure(s.at3.length == 0); + assure(s.at4.length == 0); + assure(s.at5.length == 0); + assure(s.at6.length == 0); + assure(s.at7.length == 0); + assure(s.at8.length == 0); + assure(s.at9.length == 0); + assure(s.at10.length == 0); + assure(s.at11.length == 0); + assure(s.at12.length == 0); + assure(s.at13.length == 0); + assure(s.at14.length == 0); + assure(s.at15.length == 0); + assure(s.at16.length == 0); + assure(s.at17.length == 0); + assure(s.at18.length == 0); + } + + public void testFullStruct2() { + //TODO: + Struct2 s = new Struct2( + true, (byte) 1, (short) 2, (short) 3, 4, 5, 6L, 7L, 0.8f, 0.9, 'A', + "BCD", Type.UNSIGNED_HYPER, new Integer(22), Enum2.VALUE4, + new Struct1(1), null, null, false, (byte) 0, (short) 0, (short) 0, + 0, 0, 0L, 0L, 0.0f, 0.0, '\u0000', "", Type.VOID, Any.VOID, + Enum2.VALUE0, new Struct1(), null, null, + new boolean[] { false, true }, new byte[] { (byte) 1, (byte) 2 }, + new short[0], new short[0], new int[0], new int[0], + new long[0], new long[0], new float[0], new double[0], new char[0], + new String[0], new Type[0], new Object[0], new Enum2[0], + new Struct1[] { new Struct1(1), new Struct1(2) }, new Object[0], + new XNamingService[0], new boolean[0][], new byte[0][], + new short[0][], new short[0][], new int[0][], new int[0][], + new long[0][], new long[0][], new float[0][], new double[0][], + new char[0][], new String[0][], new Type[0][], new Object[0][], + new Enum2[0][], new Struct1[0][], new Object[0][], + new XNamingService[0][], new boolean[0][], new byte[0][], + new short[0][], new short[0][], new int[0][], new int[0][], + new long[0][], new long[0][], new float[0][], new double[0][], + new char[0][], new String[0][], new Type[0][], new Object[0][], + new Enum2[0][], new Struct1[0][], new Object[0][], + new XNamingService[0][]); + assure(s.p1 == true); + assure(s.p2 == 1); + assure(s.p3 == 2); + assure(s.p4 == 3); + assure(s.p5 == 4); + assure(s.p6 == 5); + assure(s.p7 == 6L); + assure(s.p8 == 7L); + assure(s.p9 == 0.8f); + assure(s.p10 == 0.9); + assure(s.p11 == 'A'); + assure(s.p12.equals("BCD")); + assure(s.p13.equals(Type.UNSIGNED_HYPER)); + assure(s.p14.equals(new Integer(22))); + assure(s.p15 == Enum2.VALUE4); + assure(s.p16.member1 == 1); + assure(s.p17 == null); + assure(s.p18 == null); + assure(s.t1 == false); + assure(s.t2 == 0); + assure(s.t3 == 0); + assure(s.t4 == 0); + assure(s.t5 == 0); + assure(s.t6 == 0); + assure(s.t7 == 0L); + assure(s.t8 == 0L); + assure(s.t9 == 0.0f); + assure(s.t10 == 0.0); + assure(s.t11 == '\u0000'); + assure(s.t12.equals("")); + assure(s.t13.equals(Type.VOID)); + assure(s.t14.equals(Any.VOID)); + assure(s.t15 == Enum2.VALUE0); + assure(s.t16.member1 == 0); + assure(s.t17 == null); + assure(s.t18 == null); + assure(s.a1.length == 2); + assure(s.a1[0] == false); + assure(s.a1[1] == true); + assure(s.a2.length == 2); + assure(s.a2[0] == 1); + assure(s.a2[1] == 2); + assure(s.a3.length == 0); + assure(s.a4.length == 0); + assure(s.a5.length == 0); + assure(s.a6.length == 0); + assure(s.a7.length == 0); + assure(s.a8.length == 0); + assure(s.a9.length == 0); + assure(s.a10.length == 0); + assure(s.a11.length == 0); + assure(s.a12.length == 0); + assure(s.a13.length == 0); + assure(s.a14.length == 0); + assure(s.a15.length == 0); + assure(s.a16.length == 2); + assure(s.a16[0].member1 == 1); + assure(s.a16[1].member1 == 2); + assure(s.a17.length == 0); + assure(s.a18.length == 0); + assure(s.aa1.length == 0); + assure(s.aa2.length == 0); + assure(s.aa3.length == 0); + assure(s.aa4.length == 0); + assure(s.aa5.length == 0); + assure(s.aa6.length == 0); + assure(s.aa7.length == 0); + assure(s.aa8.length == 0); + assure(s.aa9.length == 0); + assure(s.aa10.length == 0); + assure(s.aa11.length == 0); + assure(s.aa12.length == 0); + assure(s.aa13.length == 0); + assure(s.aa14.length == 0); + assure(s.aa15.length == 0); + assure(s.aa16.length == 0); + assure(s.aa17.length == 0); + assure(s.aa18.length == 0); + assure(s.at1.length == 0); + assure(s.at2.length == 0); + assure(s.at3.length == 0); + assure(s.at4.length == 0); + assure(s.at5.length == 0); + assure(s.at6.length == 0); + assure(s.at7.length == 0); + assure(s.at8.length == 0); + assure(s.at9.length == 0); + assure(s.at10.length == 0); + assure(s.at11.length == 0); + assure(s.at12.length == 0); + assure(s.at13.length == 0); + assure(s.at14.length == 0); + assure(s.at15.length == 0); + assure(s.at16.length == 0); + assure(s.at17.length == 0); + assure(s.at18.length == 0); + } + + public void testXEventListener() { + assure(EventListener.class.isAssignableFrom(XEventListener.class)); + } + + public void testS1() throws com.sun.star.uno.Exception { + //TODO: + try { + S1.create1(context); + failed("S1.create1"); + } catch (DeploymentException e) {} + try { + S1.create2(context, new Any[0]); + failed("S1.create2"); + } catch (com.sun.star.uno.Exception e) {} + try { + S1.create3(context, new Any[0]); + failed("S1.create3"); + } catch (DeploymentException e) {} + try { + S1.create4(context, 0, 0, 0); + failed("S1.create4"); + } catch (DeploymentException e) {} + try { + S1.create5( + context, false, (byte) 0, (short) 0, (short) 0, 0, 0, 0L, 0L, + 0.0f, 0.0, '\u0000', "", Type.VOID, Any.VOID, Enum2.VALUE0, + new Struct1(), null, null, false, (byte) 0, (short) 0, + (short) 0, 0, 0, 0L, 0L, 0.0f, 0.0, '\u0000', "", Type.VOID, + Any.VOID, Enum2.VALUE0, new Struct1(), null, null, + new boolean[0], new byte[0], new short[0], new short[0], + new int[0], new int[0], new long[0], new long[0], new float[0], + new double[0], new char[0], new String[0], new Type[0], + new Object[0], new Enum2[0], new Struct1[0], new Object[0], + new XNamingService[0], new boolean[0][], new byte[0][], + new short[0][], new short[0][], new int[0][], new int[0][], + new long[0][], new long[0][], new float[0][], new double[0][], + new char[0][], new String[0][], new Type[0][], new Object[0][], + new Enum2[0][], new Struct1[0][], new Object[0][], + new XNamingService[0][], new boolean[0][], new byte[0][], + new short[0][], new short[0][], new int[0][], new int[0][], + new long[0][], new long[0][], new float[0][], new double[0][], + new char[0][], new String[0][], new Type[0][], new Object[0][], + new Enum2[0][], new Struct1[0][], new Object[0][], + new XNamingService[0][]); + failed("S1.create4"); + } catch (DeploymentException e) {} + } + + public void testS2() { + //TODO + } + + public void testKeywordServices() { + try { + service_abstract.method_abstract(context, 0); + failed("service_abstract.method_abstract"); + } catch (DeploymentException e) {} + try { + service_assert.method_assert(context, 0); + failed("service_assert.method_assert"); + } catch (DeploymentException e) {} + try { + service_break.method_break(context, 0); + failed("service_break.method_break"); + } catch (DeploymentException e) {} + try { + service_catch.method_catch(context, 0); + failed("service_catch.method_catch"); + } catch (DeploymentException e) {} + try { + service_class.method_class(context, 0); + failed("service_class.method_class"); + } catch (DeploymentException e) {} + try { + service_continue.method_continue(context, 0); + failed("service_continue.method_continue"); + } catch (DeploymentException e) {} + try { + service_do.method_do(context, 0); + failed("service_do.method_do"); + } catch (DeploymentException e) {} + try { + service_else.method_else(context, 0); + failed("service_else.method_else"); + } catch (DeploymentException e) {} + try { + service_extends.method_extends(context, 0); + failed("service_extends.method_extends"); + } catch (DeploymentException e) {} + try { + service_final.method_final(context, 0); + failed("service_final.method_final"); + } catch (DeploymentException e) {} + try { + service_finally.method_finally(context, 0); + failed("service_finally.method_finally"); + } catch (DeploymentException e) {} + try { + service_for.method_for(context, 0); + failed("service_for.method_for"); + } catch (DeploymentException e) {} + try { + service_goto.method_goto(context, 0); + failed("service_goto.method_goto"); + } catch (DeploymentException e) {} + try { + service_if.method_if(context, 0); + failed("service_if.method_if"); + } catch (DeploymentException e) {} + try { + service_implements.method_implements(context, 0); + failed("service_implements.method_implements"); + } catch (DeploymentException e) {} + try { + service_import.method_import(context, 0); + failed("service_import.method_import"); + } catch (DeploymentException e) {} + try { + service_instanceof.method_instanceof(context, 0); + failed("service_instanceof.method_instanceof"); + } catch (DeploymentException e) {} + try { + service_int.method_int(context, 0); + failed("service_int.method_int"); + } catch (DeploymentException e) {} + try { + service_native.method_native(context, 0); + failed("service_native.method_native"); + } catch (DeploymentException e) {} + try { + service_new.method_new(context, 0); + failed("service_new.method_new"); + } catch (DeploymentException e) {} + try { + service_package.method_package(context, 0); + failed("service_package.method_package"); + } catch (DeploymentException e) {} + try { + service_private.method_private(context, 0); + failed("service_private.method_private"); + } catch (DeploymentException e) {} + try { + service_protected.method_protected(context, 0); + failed("service_protected.method_protected"); + } catch (DeploymentException e) {} + try { + service_public.method_public(context, 0); + failed("service_public.method_public"); + } catch (DeploymentException e) {} + try { + service_return.method_return(context, 0); + failed("service_return.method_return"); + } catch (DeploymentException e) {} + try { + service_static.method_static(context, 0); + failed("service_static.method_static"); + } catch (DeploymentException e) {} + try { + service_strictfp.method_strictfp(context, 0); + failed("service_strictfp.method_strictfp"); + } catch (DeploymentException e) {} + try { + service_super.method_super(context, 0); + failed("service_super.method_super"); + } catch (DeploymentException e) {} + try { + service_synchronized.method_synchronized(context, 0); + failed("service_synchronized.method_synchronized"); + } catch (DeploymentException e) {} + try { + service_this.method_this(context, 0); + failed("service_this.method_this"); + } catch (DeploymentException e) {} + try { + service_throw.method_throw(context, 0); + failed("service_throw.method_throw"); + } catch (DeploymentException e) {} + try { + service_throws.method_throws(context, 0); + failed("service_throws.method_throws"); + } catch (DeploymentException e) {} + try { + service_try.method_try(context, 0); + failed("service_try.method_try"); + } catch (DeploymentException e) {} + try { + service_volatile.method_volatile(context, 0); + failed("service_volatile.method_volatile"); + } catch (DeploymentException e) {} + try { + service_while.method_while(context, 0); + failed("service_while.method_while"); + } catch (DeploymentException e) {} + } + + public void testSingletons() { + try { + S4.get(context); + failed("S4"); + } catch (DeploymentException e) {} + try { + singleton_abstract.get(context); + failed("singleton_abstract"); + } catch (DeploymentException e) {} + } + + private XComponentContext context; +} diff --git a/codemaker/test/javamaker/java15/Test.java b/codemaker/test/javamaker/java15/Test.java new file mode 100644 index 000000000000..de5e43367198 --- /dev/null +++ b/codemaker/test/javamaker/java15/Test.java @@ -0,0 +1,100 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +package test.codemaker.javamaker.java15; + +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.uno.DeploymentException; +import com.sun.star.uno.XComponentContext; +import complexlib.ComplexTestCase; + +public final class Test extends ComplexTestCase { + public String[] getTestMethodNames() { + return new String[] { + "testPlainPolyStruct", "testBooleanPolyStruct", "testStruct", + "testService" }; + } + + public void testPlainPolyStruct() { + PolyStruct s = new PolyStruct(); + assure(s.member1 == null); + assure(s.member2 == 0); + s = new PolyStruct("ABC", 5); + assure(s.member1.equals("ABC")); + assure(s.member2 == 5); + } + + public void testBooleanPolyStruct() { + PolyStruct<Boolean,Object> s = new PolyStruct<Boolean,Object>(); + assure(s.member1 == null); + assure(s.member2 == 0); + s = new PolyStruct<Boolean,Object>(true, 5); + assure(s.member1 == true); + assure(s.member2 == 5); + } + + public void testStruct() { + Struct s = new Struct(); + assure(s.member.member1 == null); + assure(s.member.member2 == 0); + s = new Struct( + new PolyStruct<PolyStruct<boolean[], Object>, Integer>( + new PolyStruct<boolean[], Object>(new boolean[] { true }, 3), + 4)); + assure(s.member.member1.member1.length == 1); + assure(s.member.member1.member1[0] == true); + assure(s.member.member1.member2 == 3); + assure(s.member.member2 == 4); + } + + public void testService() { + XComponentContext context = new XComponentContext() { + public Object getValueByName(String name) { + return null; + } + + public XMultiComponentFactory getServiceManager() { + return null; + } + }; + try { + Service.create(context); + failed(); + } catch (DeploymentException e) {} + try { + Service.create( + context, false, (byte) 1, (short) 2, Integer.valueOf(4)); + failed(); + } catch (DeploymentException e) {} + } + + private static final class Ifc implements XIfc { + public void f1(PolyStruct<Integer, Integer> arg) {} + + public void f2(PolyStruct<Object, Object> arg) {} + } +} diff --git a/codemaker/test/javamaker/java15/makefile.mk b/codemaker/test/javamaker/java15/makefile.mk new file mode 100644 index 000000000000..b4d65209d41d --- /dev/null +++ b/codemaker/test/javamaker/java15/makefile.mk @@ -0,0 +1,41 @@ +#************************************************************************* +# +# 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 := test_codemaker_javamaker_java15 + +PACKAGE := test$/codemaker$/javamaker$/java15 +JAVATESTFILES := Test.java +IDLTESTFILES := types.idl +JARFILES := ridl.jar + +JAVAMAKER = $(BIN)$/javamaker$(EXECPOST) + +.INCLUDE: javaunittest.mk + +$(MISC)$/$(TARGET).javamaker.flag: $(BIN)$/javamaker$(EXECPOST) diff --git a/codemaker/test/javamaker/java15/types.idl b/codemaker/test/javamaker/java15/types.idl new file mode 100644 index 000000000000..b2f96818dd72 --- /dev/null +++ b/codemaker/test/javamaker/java15/types.idl @@ -0,0 +1,50 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "com/sun/star/uno/XInterface.idl" + +module test { module codemaker { module javamaker { module java15 { + +struct PolyStruct<if,else> { + if member1; + long member2; +}; + +struct Struct { + PolyStruct<PolyStruct<sequence<boolean>,any>,long> member; +}; + +service Service: com::sun::star::uno::XInterface { + create([in] any... args); +}; + +interface XIfc { + void f1([in] PolyStruct<long, long> arg); + void f2([in] PolyStruct<any, com::sun::star::uno::XInterface> arg); +}; + +}; }; }; }; diff --git a/codemaker/test/javamaker/makefile.mk b/codemaker/test/javamaker/makefile.mk new file mode 100644 index 000000000000..e62e138aae2f --- /dev/null +++ b/codemaker/test/javamaker/makefile.mk @@ -0,0 +1,41 @@ +#************************************************************************* +# +# 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 := test_codemaker_javamaker + +PACKAGE := test$/codemaker$/javamaker +JAVATESTFILES := Test.java +IDLTESTFILES := types.idl +JARFILES := juh.jar jurt.jar ridl.jar + +JAVAMAKER = $(BIN)$/javamaker$(EXECPOST) + +.INCLUDE: javaunittest.mk + +$(MISC)$/$(TARGET).javamaker.flag: $(BIN)$/javamaker$(EXECPOST) diff --git a/codemaker/test/javamaker/types.idl b/codemaker/test/javamaker/types.idl new file mode 100644 index 000000000000..81710430acb7 --- /dev/null +++ b/codemaker/test/javamaker/types.idl @@ -0,0 +1,433 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "com/sun/star/lang/ClassNotFoundException.idl" +#include "com/sun/star/lang/IllegalAccessException.idl" +#include "com/sun/star/uno/DeploymentException.idl" +#include "com/sun/star/uno/Exception.idl" +#include "com/sun/star/uno/RuntimeException.idl" +#include "com/sun/star/uno/XInterface.idl" +#include "com/sun/star/uno/XNamingService.idl" + +module test { module codemaker { module javamaker { + +enum Enum1 { VALUE1 = -100, VALUE2 = 100 }; + +enum Enum2 { VALUE0 = 0, VALUE1 = 1, VALUE2 = 2, VALUE4 = 4 }; + +struct Struct1 { long member1; }; + +struct PolyStruct<if,else> { + if member1; + long member2; +}; + +interface XTest { + boolean test(); + + [attribute, bound] long A1; + [attribute, bound, readonly] long A2; + [attribute] long A3 { + get raises + (com::sun::star::uno::Exception, + com::sun::star::lang::ClassNotFoundException); + set raises (com::sun::star::uno::RuntimeException); + }; + [attribute, readonly] long A4 { + get raises (com::sun::star::uno::DeploymentException); + }; +}; + +typedef boolean Boolean; +typedef byte Byte; +typedef short Short; +typedef unsigned short UnsignedShort; +typedef long Long; +typedef unsigned long UnsignedLong; +typedef hyper Hyper; +typedef unsigned hyper UnsignedHyper; +typedef float Float; +typedef double Double; +typedef char Char; +typedef string String; +typedef type Type; +typedef any Any; +typedef Enum2 Enum; +typedef Struct1 Struct; +typedef com::sun::star::uno::XInterface XInterface; +typedef com::sun::star::uno::XNamingService XNamingService; + +typedef sequence< Boolean > SequenceBoolean; +typedef sequence< Byte > SequenceByte; +typedef sequence< Short > SequenceShort; +typedef sequence< UnsignedShort > SequenceUnsignedShort; +typedef sequence< Long > SequenceLong; +typedef sequence< UnsignedLong > SequenceUnsignedLong; +typedef sequence< Hyper > SequenceHyper; +typedef sequence< UnsignedHyper > SequenceUnsignedHyper; +typedef sequence< Float > SequenceFloat; +typedef sequence< Double > SequenceDouble; +typedef sequence< Char > SequenceChar; +typedef sequence< String > SequenceString; +typedef sequence< Type > SequenceType; +typedef sequence< Any > SequenceAny; +typedef sequence< Enum > SequenceEnum; +typedef sequence< Struct > SequenceStruct; +typedef sequence< XInterface > SequenceXInterface; +typedef sequence< XNamingService > SequenceXNamingService; + +struct Struct2 { + boolean p1; + byte p2; + short p3; + unsigned short p4; + long p5; + unsigned long p6; + hyper p7; + unsigned hyper p8; + float p9; + double p10; + char p11; + string p12; + type p13; + any p14; + Enum2 p15; + Struct1 p16; + com::sun::star::uno::XInterface p17; + com::sun::star::uno::XNamingService p18; + Boolean t1; + Byte t2; + Short t3; + UnsignedShort t4; + Long t5; + UnsignedLong t6; + Hyper t7; + UnsignedHyper t8; + Float t9; + Double t10; + Char t11; + String t12; + Type t13; + Any t14; + Enum t15; + Struct t16; + XInterface t17; + XNamingService t18; + sequence< boolean > a1; + sequence< byte > a2; + sequence< short > a3; + sequence< unsigned short > a4; + sequence< long > a5; + sequence< unsigned long > a6; + sequence< hyper > a7; + sequence< unsigned hyper > a8; + sequence< float > a9; + sequence< double > a10; + sequence< char > a11; + sequence< string > a12; + sequence< type > a13; + sequence< any > a14; + sequence< Enum2 > a15; + sequence< Struct1 > a16; + sequence< com::sun::star::uno::XInterface > a17; + sequence< com::sun::star::uno::XNamingService > a18; + sequence< sequence< boolean > > aa1; + sequence< sequence< byte > > aa2; + sequence< sequence< short > > aa3; + sequence< sequence< unsigned short > > aa4; + sequence< sequence< long > > aa5; + sequence< sequence< unsigned long > > aa6; + sequence< sequence< hyper > > aa7; + sequence< sequence< unsigned hyper > > aa8; + sequence< sequence< float > > aa9; + sequence< sequence< double > > aa10; + sequence< sequence< char > > aa11; + sequence< sequence< string > > aa12; + sequence< sequence< type > > aa13; + sequence< sequence< any > > aa14; + sequence< sequence< Enum2 > > aa15; + sequence< sequence< Struct1 > > aa16; + sequence< sequence< com::sun::star::uno::XInterface > > aa17; + sequence< sequence< com::sun::star::uno::XNamingService > > aa18; + sequence< SequenceBoolean > at1; + sequence< SequenceByte > at2; + sequence< SequenceShort > at3; + sequence< SequenceUnsignedShort > at4; + sequence< SequenceLong > at5; + sequence< SequenceUnsignedLong > at6; + sequence< SequenceHyper > at7; + sequence< SequenceUnsignedHyper > at8; + sequence< SequenceFloat > at9; + sequence< SequenceDouble > at10; + sequence< SequenceChar > at11; + sequence< SequenceString > at12; + sequence< SequenceType > at13; + sequence< SequenceAny > at14; + sequence< SequenceEnum > at15; + sequence< SequenceStruct > at16; + sequence< SequenceXInterface > at17; + sequence< SequenceXNamingService > at18; +}; + +service S1: XTest { + create1(); + + create2([in] any... create2) + raises (com::sun::star::uno::RuntimeException, + com::sun::star::lang::ClassNotFoundException, + com::sun::star::uno::Exception, + com::sun::star::lang::IllegalAccessException, + com::sun::star::uno::DeploymentException); + + create3([in] sequence<any> S1) + raises (com::sun::star::uno::RuntimeException, + com::sun::star::lang::ClassNotFoundException, + com::sun::star::lang::IllegalAccessException, + com::sun::star::uno::DeploymentException); + + create4([in] long javamaker, [in] long S1, [in] long create4); + + create5( + [in] boolean p1, + [in] byte p2, + [in] short p3, + [in] unsigned short p4, + [in] long p5, + [in] unsigned long p6, + [in] hyper p7, + [in] unsigned hyper p8, + [in] float p9, + [in] double p10, + [in] char p11, + [in] string p12, + [in] type p13, + [in] any p14, + [in] Enum2 p15, + [in] Struct1 p16, + [in] com::sun::star::uno::XInterface p17, + [in] com::sun::star::uno::XNamingService p18, + [in] Boolean t1, + [in] Byte t2, + [in] Short t3, + [in] UnsignedShort t4, + [in] Long t5, + [in] UnsignedLong t6, + [in] Hyper t7, + [in] UnsignedHyper t8, + [in] Float t9, + [in] Double t10, + [in] Char t11, + [in] String t12, + [in] Type t13, + [in] Any t14, + [in] Enum t15, + [in] Struct t16, + [in] XInterface t17, + [in] XNamingService t18, + [in] sequence< boolean > a1, + [in] sequence< byte > a2, + [in] sequence< short > a3, + [in] sequence< unsigned short > a4, + [in] sequence< long > a5, + [in] sequence< unsigned long > a6, + [in] sequence< hyper > a7, + [in] sequence< unsigned hyper > a8, + [in] sequence< float > a9, + [in] sequence< double > a10, + [in] sequence< char > a11, + [in] sequence< string > a12, + [in] sequence< type > a13, + [in] sequence< any > a14, + [in] sequence< Enum2 > a15, + [in] sequence< Struct1 > a16, + [in] sequence< com::sun::star::uno::XInterface > a17, + [in] sequence< com::sun::star::uno::XNamingService > a18, + [in] sequence< sequence< boolean > > aa1, + [in] sequence< sequence< byte > > aa2, + [in] sequence< sequence< short > > aa3, + [in] sequence< sequence< unsigned short > > aa4, + [in] sequence< sequence< long > > aa5, + [in] sequence< sequence< unsigned long > > aa6, + [in] sequence< sequence< hyper > > aa7, + [in] sequence< sequence< unsigned hyper > > aa8, + [in] sequence< sequence< float > > aa9, + [in] sequence< sequence< double > > aa10, + [in] sequence< sequence< char > > aa11, + [in] sequence< sequence< string > > aa12, + [in] sequence< sequence< type > > aa13, + [in] sequence< sequence< any > > aa14, + [in] sequence< sequence< Enum2 > > aa15, + [in] sequence< sequence< Struct1 > > aa16, + [in] sequence< sequence< com::sun::star::uno::XInterface > > aa17, + [in] sequence< sequence< com::sun::star::uno::XNamingService > > aa18, + [in] sequence< SequenceBoolean > at1, + [in] sequence< SequenceByte > at2, + [in] sequence< SequenceShort > at3, + [in] sequence< SequenceUnsignedShort > at4, + [in] sequence< SequenceLong > at5, + [in] sequence< SequenceUnsignedLong > at6, + [in] sequence< SequenceHyper > at7, + [in] sequence< SequenceUnsignedHyper > at8, + [in] sequence< SequenceFloat > at9, + [in] sequence< SequenceDouble > at10, + [in] sequence< SequenceChar > at11, + [in] sequence< SequenceString > at12, + [in] sequence< SequenceType > at13, + [in] sequence< SequenceAny > at14, + [in] sequence< SequenceEnum > at15, + [in] sequence< SequenceStruct > at16, + [in] sequence< SequenceXInterface > at17, + [in] sequence< SequenceXNamingService > at18); +}; + +service S2: XTest; + +service S3 { interface XTest; }; + +module services { + +service abstract: com::sun::star::uno::XInterface { + abstract([in] long abstract); }; +service assert: com::sun::star::uno::XInterface { assert([in] long assert); }; +//TODO: boolean +service break: com::sun::star::uno::XInterface { break([in] long break); }; +//TODO: byte +//TODO: case +service catch: com::sun::star::uno::XInterface { catch([in] long catch); }; +//TODO: char +service class: com::sun::star::uno::XInterface { class([in] long class); }; +//TODO: const +service continue: com::sun::star::uno::XInterface { + continue([in] long continue); }; +//TODO: default +service do: com::sun::star::uno::XInterface { do([in] long do); }; +//TODO: double +service else: com::sun::star::uno::XInterface { else([in] long else); }; +//TODO: enum +service extends: com::sun::star::uno::XInterface { + extends([in] long extends); }; +service final: com::sun::star::uno::XInterface { final([in] long final); }; +service finally: com::sun::star::uno::XInterface { + finally([in] long finally); }; +//TODO: float +service for: com::sun::star::uno::XInterface { for([in] long for); }; +service goto: com::sun::star::uno::XInterface { goto([in] long goto); }; +service if: com::sun::star::uno::XInterface { if([in] long if); }; +service implements: com::sun::star::uno::XInterface { + implements([in] long implements); }; +service import: com::sun::star::uno::XInterface { import([in] long import); }; +service instanceof: com::sun::star::uno::XInterface { + instanceof([in] long instanceof); }; +service int: com::sun::star::uno::XInterface { int([in] long int); }; +//TODO: interface +//TODO: long +service native: com::sun::star::uno::XInterface { native([in] long native); }; +service new: com::sun::star::uno::XInterface { new([in] long new); }; +service package: com::sun::star::uno::XInterface { + package([in] long package); }; +service private: com::sun::star::uno::XInterface { + private([in] long private); }; +service protected: com::sun::star::uno::XInterface { + protected([in] long protected); }; +service public: com::sun::star::uno::XInterface { public([in] long public); }; +service return: com::sun::star::uno::XInterface { return([in] long return); }; +//TODO: short +service static: com::sun::star::uno::XInterface { static([in] long static); }; +service strictfp: com::sun::star::uno::XInterface { + strictfp([in] long strictfp); }; +service super: com::sun::star::uno::XInterface { super([in] long super); }; +//TODO: switch +service synchronized: com::sun::star::uno::XInterface { + synchronized([in] long synchronized); }; +service this: com::sun::star::uno::XInterface { this([in] long this); }; +service throw: com::sun::star::uno::XInterface { throw([in] long throw); }; +service throws: com::sun::star::uno::XInterface { throws([in] long throws); }; +//TODO: transient +service try: com::sun::star::uno::XInterface { try([in] long try); }; +//TODO: void +service volatile: com::sun::star::uno::XInterface { + volatile([in] long volatile); }; +service while: com::sun::star::uno::XInterface { while([in] long while); }; + +}; + +singleton S4: XTest; + +singleton S5 { service S2; }; + +singleton abstract: com::sun::star::uno::XNamingService; +singleton assert: com::sun::star::uno::XNamingService; +//TODO: singleton boolean: com::sun::star::uno::XNamingService; +singleton break: com::sun::star::uno::XNamingService; +//TODO: singleton byte: com::sun::star::uno::XNamingService; +//TODO: singleton case: com::sun::star::uno::XNamingService; +singleton catch: com::sun::star::uno::XNamingService; +//TODO: singleton char: com::sun::star::uno::XNamingService; +singleton class: com::sun::star::uno::XNamingService; +//TODO: singleton const: com::sun::star::uno::XNamingService; +singleton continue: com::sun::star::uno::XNamingService; +//TODO: singleton default: com::sun::star::uno::XNamingService; +singleton do: com::sun::star::uno::XNamingService; +//TODO: singleton double: com::sun::star::uno::XNamingService; +singleton else: com::sun::star::uno::XNamingService; +//TODO: singleton enum: com::sun::star::uno::XNamingService; +singleton extends: com::sun::star::uno::XNamingService; +singleton final: com::sun::star::uno::XNamingService; +singleton finally: com::sun::star::uno::XNamingService; +//TODO: singleton float: com::sun::star::uno::XNamingService; +singleton for: com::sun::star::uno::XNamingService; +singleton goto: com::sun::star::uno::XNamingService; +singleton if: com::sun::star::uno::XNamingService; +singleton implements: com::sun::star::uno::XNamingService; +singleton import: com::sun::star::uno::XNamingService; +singleton instanceof: com::sun::star::uno::XNamingService; +singleton int: com::sun::star::uno::XNamingService; +//TODO: singleton interface: com::sun::star::uno::XNamingService; +//TODO: singleton long: com::sun::star::uno::XNamingService; +singleton native: com::sun::star::uno::XNamingService; +singleton new: com::sun::star::uno::XNamingService; +singleton package: com::sun::star::uno::XNamingService; +singleton private: com::sun::star::uno::XNamingService; +singleton protected: com::sun::star::uno::XNamingService; +singleton public: com::sun::star::uno::XNamingService; +singleton return: com::sun::star::uno::XNamingService; +//TODO: singleton short: com::sun::star::uno::XNamingService; +singleton static: com::sun::star::uno::XNamingService; +singleton strictfp: com::sun::star::uno::XNamingService; +singleton super: com::sun::star::uno::XNamingService; +//TODO: singleton switch: com::sun::star::uno::XNamingService; +singleton synchronized: com::sun::star::uno::XNamingService; +singleton this: com::sun::star::uno::XNamingService; +singleton throw: com::sun::star::uno::XNamingService; +singleton throws: com::sun::star::uno::XNamingService; +//TODO: singleton transient: com::sun::star::uno::XNamingService; +singleton try: com::sun::star::uno::XNamingService; +//TODO: singleton void: com::sun::star::uno::XNamingService; +singleton volatile: com::sun::star::uno::XNamingService; +singleton while: com::sun::star::uno::XNamingService; + +}; }; }; |