diff options
Diffstat (limited to 'codemaker')
52 files changed, 16221 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..91cf382d39f8 --- /dev/null +++ b/codemaker/inc/codemaker/codemaker.hxx @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/inc/codemaker/commoncpp.hxx b/codemaker/inc/codemaker/commoncpp.hxx new file mode 100644 index 000000000000..5ccb5e30efcb --- /dev/null +++ b/codemaker/inc/codemaker/commoncpp.hxx @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/inc/codemaker/commonjava.hxx b/codemaker/inc/codemaker/commonjava.hxx new file mode 100644 index 000000000000..9fa36efc60fd --- /dev/null +++ b/codemaker/inc/codemaker/commonjava.hxx @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/inc/codemaker/dependencies.hxx b/codemaker/inc/codemaker/dependencies.hxx new file mode 100644 index 000000000000..07989f59ef01 --- /dev/null +++ b/codemaker/inc/codemaker/dependencies.hxx @@ -0,0 +1,152 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_DEPENDENCIES_HXX +#define INCLUDED_CODEMAKER_DEPENDENCIES_HXX + +#include "rtl/string.hxx" + +#include <boost/unordered_map.hpp> + +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 boost::unordered_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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/inc/codemaker/exceptiontree.hxx b/codemaker/inc/codemaker/exceptiontree.hxx new file mode 100644 index 000000000000..e8edb35fab57 --- /dev/null +++ b/codemaker/inc/codemaker/exceptiontree.hxx @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/inc/codemaker/generatedtypeset.hxx b/codemaker/inc/codemaker/generatedtypeset.hxx new file mode 100644 index 000000000000..6829d0cd5bd7 --- /dev/null +++ b/codemaker/inc/codemaker/generatedtypeset.hxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_GENERATEDTYPESET_HXX +#define INCLUDED_CODEMAKER_GENERATEDTYPESET_HXX + +#include "rtl/string.hxx" + +#include <boost/unordered_set.hpp> + +/// @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 + + boost::unordered_set< rtl::OString, rtl::OStringHash > m_set; +}; + +} + +#endif // INCLUDED_CODEMAKER_GENERATEDTYPESET_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/inc/codemaker/global.hxx b/codemaker/inc/codemaker/global.hxx new file mode 100644 index 000000000000..2406305db451 --- /dev/null +++ b/codemaker/inc/codemaker/global.hxx @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/inc/codemaker/options.hxx b/codemaker/inc/codemaker/options.hxx new file mode 100644 index 000000000000..76c3328668f3 --- /dev/null +++ b/codemaker/inc/codemaker/options.hxx @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_OPTIONS_HXX +#define INCLUDED_CODEMAKER_OPTIONS_HXX + +#include <boost/unordered_map.hpp> + +#include <codemaker/global.hxx> + +typedef ::boost::unordered_map +< + ::rtl::OString, + ::rtl::OString, + HashString, + EqualString +> OptionMap; + +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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/inc/codemaker/typemanager.hxx b/codemaker/inc/codemaker/typemanager.hxx new file mode 100644 index 000000000000..129dbfe69898 --- /dev/null +++ b/codemaker/inc/codemaker/typemanager.hxx @@ -0,0 +1,174 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#ifndef INCLUDED_CODEMAKER_TYPEMANAGER_HXX +#define INCLUDED_CODEMAKER_TYPEMANAGER_HXX + +#include "codemaker/global.hxx" +#include "registry/registry.hxx" +#include "registry/types.h" + +#include <boost/unordered_map.hpp> +#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; + +typedef ::boost::unordered_map +< + ::rtl::OString, // Typename + RTTypeClass, // TypeClass + HashString, + EqualString +> T2TypeClassMap; + +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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/inc/codemaker/unotype.hxx b/codemaker/inc/codemaker/unotype.hxx new file mode 100644 index 000000000000..e79e760530d7 --- /dev/null +++ b/codemaker/inc/codemaker/unotype.hxx @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 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..fbe55a4f00f4 --- /dev/null +++ b/codemaker/inc/pch/precompiled_codemaker.cxx @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#include "precompiled_codemaker.hxx" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/inc/pch/precompiled_codemaker.hxx b/codemaker/inc/pch/precompiled_codemaker.hxx new file mode 100644 index 000000000000..443b3f60ee23 --- /dev/null +++ b/codemaker/inc/pch/precompiled_codemaker.hxx @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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): Generated on 2006-09-01 17:49:33.874150 + +#ifdef PRECOMPILED_HEADERS +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/prj/build.lst b/codemaker/prj/build.lst new file mode 100644 index 000000000000..a0fa864ebd8e --- /dev/null +++ b/codemaker/prj/build.lst @@ -0,0 +1,9 @@ +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/codemaker/codemaker.cxx b/codemaker/source/codemaker/codemaker.cxx new file mode 100644 index 000000000000..8ce02ab0a1d5 --- /dev/null +++ b/codemaker/source/codemaker/codemaker.cxx @@ -0,0 +1,191 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "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 + } + } + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/codemaker/dependencies.cxx b/codemaker/source/codemaker/dependencies.cxx new file mode 100644 index 000000000000..da8d33e1f88e --- /dev/null +++ b/codemaker/source/codemaker/dependencies.cxx @@ -0,0 +1,284 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "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; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/codemaker/exceptiontree.cxx b/codemaker/source/codemaker/exceptiontree.cxx new file mode 100644 index 000000000000..e54483d39561 --- /dev/null +++ b/codemaker/source/codemaker/exceptiontree.cxx @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "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; + } + } + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/codemaker/global.cxx b/codemaker/source/codemaker/global.cxx new file mode 100644 index 000000000000..52e4e3486aa6 --- /dev/null +++ b/codemaker/source/codemaker/global.cxx @@ -0,0 +1,452 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "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; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 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..8748db53c2c8 --- /dev/null +++ b/codemaker/source/codemaker/options.cxx @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "codemaker/options.hxx" + +using ::rtl::OString; + +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."); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/codemaker/typemanager.cxx b/codemaker/source/codemaker/typemanager.cxx new file mode 100644 index 000000000000..639a7cca71e6 --- /dev/null +++ b/codemaker/source/codemaker/typemanager.cxx @@ -0,0 +1,409 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "rtl/alloc.h" +#include "codemaker/typemanager.hxx" +#include "registry/reader.hxx" +#include "registry/version.h" + +using ::rtl::OUString; +using ::rtl::OString; +using ::rtl::OStringToOUString; +using ::rtl::OUStringToOString; + +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; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/codemaker/unotype.cxx b/codemaker/source/codemaker/unotype.cxx new file mode 100644 index 000000000000..cd3ce6d83752 --- /dev/null +++ b/codemaker/source/codemaker/unotype.cxx @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "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); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/commoncpp/commoncpp.cxx b/codemaker/source/commoncpp/commoncpp.cxx new file mode 100644 index 000000000000..c8da1873846d --- /dev/null +++ b/codemaker/source/commoncpp/commoncpp.cxx @@ -0,0 +1,358 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "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; + } +} + +} } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 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..fe2fad09eb43 --- /dev/null +++ b/codemaker/source/commonjava/commonjava.cxx @@ -0,0 +1,170 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "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; + } +} + +} } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 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..ae24f4291d8e --- /dev/null +++ b/codemaker/source/cppumaker/cppumaker.cxx @@ -0,0 +1,247 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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/generatedtypeset.hxx" + +#include "cppuoptions.hxx" +#include "cpputype.hxx" + +using ::rtl::OString; +using ::rtl::OUString; + +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; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/cppumaker/cppuoptions.cxx b/codemaker/source/cppumaker/cppuoptions.cxx new file mode 100644 index 000000000000..37b843b6544c --- /dev/null +++ b/codemaker/source/cppumaker/cppuoptions.cxx @@ -0,0 +1,367 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 <string.h> + +#include "cppuoptions.hxx" +#include "osl/thread.h" +#include "osl/process.h" + +using ::rtl::OUString; +using ::rtl::OUStringToOString; +using ::rtl::OString; + +#ifdef SAL_UNX +#define SEPARATOR '/' +#else +#define SEPARATOR '\\' +#endif + +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; + + OString name(av[0]); + sal_Int32 index = name.lastIndexOf(SEPARATOR); + m_program = name.copy((index > 0 ? index+1 : 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\n"; + help += prepareVersion(); + + return help; +} + +OString CppuOptions::prepareVersion() +{ + OString version(m_program); + version += " Version 2.0\n\n"; + return version; +} + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/cppumaker/cppuoptions.hxx b/codemaker/source/cppumaker/cppuoptions.hxx new file mode 100644 index 000000000000..567372e91c5d --- /dev/null +++ b/codemaker/source/cppumaker/cppuoptions.hxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/cppumaker/cpputype.cxx b/codemaker/source/cppumaker/cpputype.cxx new file mode 100644 index 000000000000..735591f1a476 --- /dev/null +++ b/codemaker/source/cppumaker/cpputype.cxx @@ -0,0 +1,4510 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 <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 codemaker::cpp; + +using ::rtl::OUString; +using ::rtl::OString; +using ::rtl::OStringBuffer; + +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(RTL_CONSTASCII_USTRINGPARAM(\"" << 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(); +} +*/ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/cppumaker/cpputype.hxx b/codemaker/source/cppumaker/cpputype.hxx new file mode 100644 index 000000000000..2823e9c30159 --- /dev/null +++ b/codemaker/source/cppumaker/cpputype.hxx @@ -0,0 +1,408 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/cppumaker/dumputils.cxx b/codemaker/source/cppumaker/dumputils.cxx new file mode 100644 index 000000000000..05f178eed2fe --- /dev/null +++ b/codemaker/source/cppumaker/dumputils.cxx @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "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); +} + +} } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/cppumaker/dumputils.hxx b/codemaker/source/cppumaker/dumputils.hxx new file mode 100644 index 000000000000..265110dedbea --- /dev/null +++ b/codemaker/source/cppumaker/dumputils.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/cppumaker/includes.cxx b/codemaker/source/cppumaker/includes.cxx new file mode 100644 index 000000000000..02021e660522 --- /dev/null +++ b/codemaker/source/cppumaker/includes.cxx @@ -0,0 +1,283 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "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; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/cppumaker/includes.hxx b/codemaker/source/cppumaker/includes.hxx new file mode 100644 index 000000000000..075e63057614 --- /dev/null +++ b/codemaker/source/cppumaker/includes.hxx @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 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/javamaker/classfile.cxx b/codemaker/source/javamaker/classfile.cxx new file mode 100644 index 000000000000..9ab2e4296228 --- /dev/null +++ b/codemaker/source/javamaker/classfile.cxx @@ -0,0 +1,906 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "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)); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/javamaker/classfile.hxx b/codemaker/source/javamaker/classfile.hxx new file mode 100644 index 000000000000..974a827b0c81 --- /dev/null +++ b/codemaker/source/javamaker/classfile.hxx @@ -0,0 +1,252 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/javamaker/javamaker.cxx b/codemaker/source/javamaker/javamaker.cxx new file mode 100644 index 000000000000..4deeb727a4c0 --- /dev/null +++ b/codemaker/source/javamaker/javamaker.cxx @@ -0,0 +1,249 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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/generatedtypeset.hxx" +#include "javaoptions.hxx" +#include "javatype.hxx" + +using ::rtl::OUString; +using ::rtl::OString; +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; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/javamaker/javaoptions.cxx b/codemaker/source/javamaker/javaoptions.cxx new file mode 100644 index 000000000000..e29280b211d2 --- /dev/null +++ b/codemaker/source/javamaker/javaoptions.cxx @@ -0,0 +1,311 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 <string.h> +#include "javaoptions.hxx" +#include "osl/process.h" +#include "osl/thread.h" + +using ::rtl::OUString; +using ::rtl::OString; +using ::rtl::OUStringToOString; + +#ifdef SAL_UNX +#define SEPARATOR '/' +#else +#define SEPARATOR '\\' +#endif + +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; + + OString name(av[0]); + sal_Int32 index = name.lastIndexOf(SEPARATOR); + m_program = name.copy((index > 0 ? index+1 : 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\n"; + help += prepareVersion(); + + return help; +} + +OString JavaOptions::prepareVersion() +{ + OString version(m_program); + version += " Version 2.0\n\n"; + return version; +} + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/javamaker/javaoptions.hxx b/codemaker/source/javamaker/javaoptions.hxx new file mode 100644 index 000000000000..e7f2f48b3960 --- /dev/null +++ b/codemaker/source/javamaker/javaoptions.hxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/javamaker/javatype.cxx b/codemaker/source/javamaker/javatype.cxx new file mode 100644 index 000000000000..4b99ef9f116b --- /dev/null +++ b/codemaker/source/javamaker/javatype.cxx @@ -0,0 +1,3377 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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 "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; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/codemaker/source/javamaker/javatype.hxx b/codemaker/source/javamaker/javatype.hxx new file mode 100644 index 000000000000..e294aa6ab94f --- /dev/null +++ b/codemaker/source/javamaker/javatype.hxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; 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. + * + ************************************************************************/ + +#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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 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/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; + +}; }; }; |